|
@@ -2,106 +2,308 @@
|
|
|
|
|
|
|
|
## Project Overview
|
|
## Project Overview
|
|
|
|
|
|
|
|
-Crop Management Platform (CMS -> PHP migration)
|
|
|
|
|
-- Purpose: Centralize records for irrigation, weather, and soil moisture; supports real-time monitoring for Australian conditions.
|
|
|
|
|
-- Current stack: PHP 8.4, MySQL; originally built on modX CMS (template tags and resource IDs present).
|
|
|
|
|
-- Repository root: `f:\GIT_REPO\crop_monitor`
|
|
|
|
|
-
|
|
|
|
|
-## Identified Modules & Paths
|
|
|
|
|
-
|
|
|
|
|
-- Front controllers: `index.php`, `post.php`, `newClientDetails.php`
|
|
|
|
|
-- API: `api/api.php`, `api/Rest.inc.php`, `api/updateweatherstation.php`
|
|
|
|
|
-- Dashboard UI: `dashboard/*.php`, in particular `dashboard/crop-analysis/*` for soil analysis reports
|
|
|
|
|
-- Login management: `login/*.php`
|
|
|
|
|
-- Static assets: `client-assets/`, `books/`, `uploads/`, etc.
|
|
|
|
|
-
|
|
|
|
|
-## Database Schema Available
|
|
|
|
|
-
|
|
|
|
|
-- **Schema File**: `cropmonitor.sql` added to root folder
|
|
|
|
|
-- **Key Tables Identified**:
|
|
|
|
|
- - `soil_records`: Main soil analysis data with all nutrient values, base saturations, and specifications
|
|
|
|
|
- - `client_records`: Client information with weather station API keys
|
|
|
|
|
- - `soil_specifications`: Soil type specifications for different crops
|
|
|
|
|
- - `animal_records`: Animal feed analysis data
|
|
|
|
|
- - `plant_records`: Plant tissue analysis data
|
|
|
|
|
- - `fertiliser_specifications`: Fertilizer composition data
|
|
|
|
|
-
|
|
|
|
|
-## Database Validation
|
|
|
|
|
-
|
|
|
|
|
-- **Soil Records Fields**: All fields used in `lib/soil_calculations.php` confirmed present (BS_ca_ppm, ca_ppm_min/max, etc.)
|
|
|
|
|
-- **Data Types**: Most nutrient values stored as VARCHAR(10), need to handle numeric conversion in PHP
|
|
|
|
|
-- **Primary Keys**: All tables have proper primary key indexes
|
|
|
|
|
-- **Relationships**: `modx_user_id` field links records to users (legacy modX integration)
|
|
|
|
|
-
|
|
|
|
|
-## modX remnants to refactor
|
|
|
|
|
-
|
|
|
|
|
-- Template markers like `[[*longtitle]]`, `[[++site_name]]`, `[[!++site_url]]` need replacement with PHP-based logic.
|
|
|
|
|
-- Resource URL helpers such as `[[~41~]]` from modX should resolve to real PHP route URLs in migrated implementation.
|
|
|
|
|
-- Includes like `[[!Profile]]` are modX snippets; replace with traditional include/require and controller logic.
|
|
|
|
|
-
|
|
|
|
|
-## Immediate Actions (High Priority)
|
|
|
|
|
-
|
|
|
|
|
-1. Inventory all modX markers across `.php` files (grep for `\[\[.*\]\]`) and catalog them.
|
|
|
|
|
-2. Implement configuration layer for DB credentials, environment-based.
|
|
|
|
|
-3. Replace direct `mysqli_*` calls with PDO (prepared statements) for security and maintainability.
|
|
|
|
|
-4. Build PHP routing (`index.php` + `GET`/`POST` handling) and template system (Twig/Blade/manual) for consistent page output.
|
|
|
|
|
-5. Migrate each page one-by-one preserving functionality: login, dashboard, soil analysis, reports.
|
|
|
|
|
-
|
|
|
|
|
-## File-specific findings (example in `dashboard/crop-analysis/soil-analysis-pdf.php`)
|
|
|
|
|
-
|
|
|
|
|
-- Uses `$_GET` keys `cid`, `rid`, `rand`, `stid` and query, but no sanitization.
|
|
|
|
|
-- Performs `SELECT * FROM soil_records WHERE id = '$record_id' AND rand = '$rand_id'`.
|
|
|
|
|
-- Uses a modX resource reference mechanism for flow buttons; in pure PHP, build URLs manually.
|
|
|
|
|
-- Styles and assets loaded via `<link>` tags; safe to reuse.
|
|
|
|
|
-
|
|
|
|
|
-## Migration strategy recommendations
|
|
|
|
|
-
|
|
|
|
|
-- Step 1: Set up a global config `config.php` with database credentials and site constants.
|
|
|
|
|
-- Step 2: Create `lib/db.php` for database operations (PDO). Add `catch` error logging.
|
|
|
|
|
-- Step 3: Add `lib/helper.php` for URL generation, escaping, and date formatting.
|
|
|
|
|
-- Step 4: Create test data and verify with `phpunit` (?) if tests added later.
|
|
|
|
|
-
|
|
|
|
|
-## Next file audits planned
|
|
|
|
|
-
|
|
|
|
|
-- `dashboard/crop-analysis/soil-analysis.php`
|
|
|
|
|
-- `dashboard/crop-analysis/soil-report.php`, `soil-report-pdf.php`
|
|
|
|
|
-- `login/login.php`, `login/register.php`, `login/change-password.php`
|
|
|
|
|
-- `api/api.php` and REST API endpoints
|
|
|
|
|
-
|
|
|
|
|
-## Recent Progress (2026-03-27)
|
|
|
|
|
-
|
|
|
|
|
-### ✅ Completed Components
|
|
|
|
|
-- **Layout System**: Created reusable `layouts/header.php`, `layouts/footer.php`, `layouts/navbar.php`, `layouts/sidebar.php`
|
|
|
|
|
-- **Client Details Form**: Converted `[[!clientDetailsFORM]]` → `components/clientDetailsForm.php` (PDO + validation)
|
|
|
|
|
-- **New Client Modal**: Converted `[[!newClientDetails]]` → `components/newClientModal.php` + `controllers/newClientSubmit.php` (AJAX + validation)
|
|
|
|
|
-- **Soil Analysis Form**: Created `components/soilAnalysisForm.php` with comprehensive field validation
|
|
|
|
|
-- **Secure Controller**: Converted `[[!soilformSubmit]]` → `controllers/soilTestSubmit.php` (PDO + CSRF + auth)
|
|
|
|
|
-- **Database Config**: `config/database.php` with PDO connection
|
|
|
|
|
-- **Security Libraries**: `lib/auth.php`, `lib/csrf.php`, `lib/validation.php`
|
|
|
|
|
-- **Navigation System**: Converted `[[!Personalize?]]` and `[[Wayfinder?]]` → `components/navigation.php` (authentication-based navigation)- **Soil Calculations**: Created `lib/soil_calculations.php` with `soilAnalysisReportCalcs()` and `soilProgramCalcs()` functions
|
|
|
|
|
-- **Page Migration**: `soil-test-data.php` now uses include-based layout system
|
|
|
|
|
-- **Soil Analysis Migration**: `soil-analysis.php` migrated from modX to secure PHP with PDO, Bootstrap 5, and calculation functions
|
|
|
|
|
-### 🔧 Security Improvements Made
|
|
|
|
|
-- Replaced mysqli with PDO prepared statements
|
|
|
|
|
-- Added CSRF token protection
|
|
|
|
|
-- Input validation and sanitization
|
|
|
|
|
-- Session-based authentication checks
|
|
|
|
|
-- Proper error handling and logging
|
|
|
|
|
-- Removed SQL injection vulnerabilities
|
|
|
|
|
-
|
|
|
|
|
-### 📋 Remaining Tasks
|
|
|
|
|
-1. Migrate `soil-analysis.php` (data display page) - **COMPLETED**
|
|
|
|
|
-2. Update `soil-analysis-pdf.php` to use secure queries
|
|
|
|
|
-3. Convert remaining modX placeholders across all files
|
|
|
|
|
-4. Add proper user authentication system
|
|
|
|
|
-5. Test form submission and data flow
|
|
|
|
|
-
|
|
|
|
|
-## Questions for you
|
|
|
|
|
-
|
|
|
|
|
-- Do you prefer retaining the current page structure (`dashboard/crop-analysis/*`) or migrating to a MVC-style folder layout?
|
|
|
|
|
-- Are we required to keep URL slugs like existing modX IDs (e.g., page 41, 66, 37) for compatibility with external links?
|
|
|
|
|
-- Do you have existing MySQL schema docs or dumps to validate field mappings?
|
|
|
|
|
|
|
+**Crop Management Platform** — modX CMS → standalone PHP migration
|
|
|
|
|
+Purpose: Centralise records for irrigation, weather, and soil moisture; supports real-time monitoring for Australian conditions.
|
|
|
|
|
+Stack: **PHP 8.4**, **MySQL**, Bootstrap 5, jQuery, Chart.js
|
|
|
|
|
+Repository root: `f:\GIT_REPO\crop_monitor`
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-*Generated on 2026-03-27*
|
|
|
|
|
|
|
+## Directory Structure
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+crop_monitor/
|
|
|
|
|
+├── api/ # REST API endpoints (legacy)
|
|
|
|
|
+├── client-assets/ # CSS, JS, images, uploads
|
|
|
|
|
+│ ├── css/ # Bootstrap 4 + custom styles
|
|
|
|
|
+│ ├── js/ # jQuery, Chart.js, custom scripts
|
|
|
|
|
+│ ├── table/ # DataTables AJAX helpers (legacy mysqli)
|
|
|
|
|
+│ ├── FredTemplate/ # Old template assets
|
|
|
|
|
+│ └── fullcalendar/ # Calendar widget
|
|
|
|
|
+├── components/ # Reusable UI components (migrated)
|
|
|
|
|
+├── config/ # Database config (PDO)
|
|
|
|
|
+├── controllers/ # Form POST handlers (migrated)
|
|
|
|
|
+├── dashboard/ # Main application pages
|
|
|
|
|
+│ ├── crop-analysis/
|
|
|
|
|
+│ │ ├── soil-test-data/ # Soil analysis entry + display
|
|
|
|
|
+│ │ ├── plant-test-data/ # Plant tissue analysis
|
|
|
|
|
+│ │ ├── animal-dietary-balance/
|
|
|
|
|
+│ │ └── water-test-data/
|
|
|
|
|
+│ ├── client-settings/
|
|
|
|
|
+│ ├── crop-cards/
|
|
|
|
|
+│ ├── inbox.php
|
|
|
|
|
+│ └── planning-calendar.php
|
|
|
|
|
+├── layouts/ # Page templates (header, footer, nav, sidebar)
|
|
|
|
|
+├── lib/ # Utility libraries
|
|
|
|
|
+├── login/ # Auth pages (still modX templates)
|
|
|
|
|
+├── cropmonitor.sql # Full database schema dump
|
|
|
|
|
+├── index.php # Empty — routing via .htaccess
|
|
|
|
|
+├── .htaccess # Front controller rewrite rules
|
|
|
|
|
+└── .env # Empty — credentials currently in config/database.php
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Database Schema
|
|
|
|
|
+
|
|
|
|
|
+Schema file: `cropmonitor.sql`
|
|
|
|
|
+
|
|
|
|
|
+| Table | Purpose |
|
|
|
|
|
+|-------|---------|
|
|
|
|
|
+| `client_records` | Client info + weather station API keys (`modx_user_id` FK) |
|
|
|
|
|
+| `soil_records` | Soil analysis data — 80+ columns (nutrients, base saturations, calculations) |
|
|
|
|
|
+| `soil_specifications` | Min/max nutrient ranges by soil type (used for recommendations) |
|
|
|
|
|
+| `soil_comments` | Element-specific recommendation text |
|
|
|
|
|
+| `plant_records` | Plant tissue analysis |
|
|
|
|
|
+| `plant_specifications` | Nutrient ranges by crop/growth stage |
|
|
|
|
|
+| `animal_records` | Animal dietary balance |
|
|
|
|
|
+| `animal_specifications` | Nutrient requirements by species |
|
|
|
|
|
+| `water_records` | Water quality analysis |
|
|
|
|
|
+| `weather_station` | Weather station data ingestion |
|
|
|
|
|
+| `fertiliser_specifications` | Fertilizer product database |
|
|
|
|
|
+| `block_info` | Field/block metadata |
|
|
|
|
|
+| `crop_info` | Crop definitions |
|
|
|
|
|
+| `calendar_events` | User scheduling |
|
|
|
|
|
+| `reports` | Comments/notes on analyses |
|
|
|
|
|
+| `field_sensors` | IoT sensor readings |
|
|
|
|
|
+| `sensor_id` | Sensor registration |
|
|
|
|
|
+
|
|
|
|
|
+**Important data notes:**
|
|
|
|
|
+- Most nutrient values stored as `VARCHAR(10)` — always cast to float in PHP
|
|
|
|
|
+- `modx_user_id` field links all records to users (legacy modX user system)
|
|
|
|
|
+- `rand` field on `soil_records` is a secondary verification token for URL access
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Migration Status
|
|
|
|
|
+
|
|
|
|
|
+### Completed (PDO + secure)
|
|
|
|
|
+| Original modX | Migrated to |
|
|
|
|
|
+|---------------|------------|
|
|
|
|
|
+| `[[!clientDetailsFORM]]` | `components/clientDetailsForm.php` |
|
|
|
|
|
+| `[[!newClientDetails]]` | `components/newClientModal.php` + `controllers/newClientSubmit.php` |
|
|
|
|
|
+| `[[!soilformSubmit]]` | `controllers/soilTestSubmit.php` |
|
|
|
|
|
+| `[[!Personalize?]]` + `[[Wayfinder?]]` | `components/navigation.php` |
|
|
|
|
|
+| `[[$dash-header]]` + `[[$dash-footer]]` | `layouts/header.php`, `layouts/footer.php`, `layouts/navbar.php`, `layouts/sidebar.php` |
|
|
|
|
|
+| `soil-test-data.php` | Uses include-based layout system |
|
|
|
|
|
+| `soil-analysis.php` | PDO + Bootstrap 5 + calc functions |
|
|
|
|
|
+| `[[!Login]]` | `login/login.php` (session auth, CSRF, PDO) |
|
|
|
|
|
+| `[[!Register]]` | `login/register.php` (validation, auto-login, CSRF) |
|
|
|
|
|
+| `[[!ForgotPassword]]` | `login/forgot-password.php` + `login/reset-password.php` (token-based, 1hr expiry) |
|
|
|
|
|
+
|
|
|
|
|
+### Still Needs Migration (priority order)
|
|
|
|
|
+1. ~~**`login/login.php`**~~ — **DONE** (2026-03-27)
|
|
|
|
|
+2. ~~**`login/register.php`**~~ — **DONE** (2026-03-27)
|
|
|
|
|
+3. ~~**`login/forgot-password.php`**~~ — **DONE** (2026-03-27)
|
|
|
|
|
+4. **`login/change-password.php`** — modX `[[!ChangePassword]]` → rewrite using `changePassword()` in `lib/auth.php`
|
|
|
|
|
+5. **`dashboard/crop-analysis/soil-test-data/soil-analysis-pdf.php`** — mysqli → PDO, SQL injection fix
|
|
|
|
|
+6. **`dashboard/crop-analysis/soil-test-data/soil-report.php`** — display page audit
|
|
|
|
|
+7. **`dashboard/crop-analysis/soil-test-data/soil-report-pdf.php`** — mysqli → PDO
|
|
|
|
|
+8. **`dashboard/crop-analysis/plant-test-data/`** — full migration
|
|
|
|
|
+9. **`dashboard/crop-analysis/animal-dietary-balance/`** — full migration
|
|
|
|
|
+10. **`dashboard/crop-analysis/water-test-data/`** — full migration
|
|
|
|
|
+11. **`dashboard/client-settings/product-list.php`** — mysqli → PDO
|
|
|
|
|
+12. **`dashboard/client-settings/updateproduct.php`** — SQL injection fix
|
|
|
|
|
+13. **`dashboard/crop-cards/index.php`** — mysqli → PDO
|
|
|
|
|
+14. **`dashboard/dashboard.php`** — replace `[[$widget]]` chunks with PHP components
|
|
|
|
|
+15. **`api/updateweatherstation.php`** — critical SQL injection fix
|
|
|
|
|
+16. **`api/api.php`** — remove deprecated `mysql_connect()`, use PDO
|
|
|
|
|
+17. **`client-assets/table/gettable.php`** — AJAX DataTable endpoint, mysqli → PDO
|
|
|
|
|
+
|
|
|
|
|
+### Legacy files to delete after migration
|
|
|
|
|
+- `post.php` (replaced by `components/clientDetailsForm.php`)
|
|
|
|
|
+- `newClientDetails.php` (replaced by `components/newClientModal.php`)
|
|
|
|
|
+- `soilAnalysisCalcs.php` (dev/debug file)
|
|
|
|
|
+- `test-analysis.php` (dev/debug file)
|
|
|
|
|
+- `dashboard/crop-analysis/soil-test-data/soil-submit.php` (replaced by `controllers/soilTestSubmit.php`)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Security Audit
|
|
|
|
|
+
|
|
|
|
|
+### Safe (PDO prepared statements)
|
|
|
|
|
+- `config/database.php`
|
|
|
|
|
+- `lib/soil_calculations.php`
|
|
|
|
|
+- `components/clientDetailsForm.php`
|
|
|
|
|
+- `controllers/newClientSubmit.php`
|
|
|
|
|
+- `controllers/soilTestSubmit.php`
|
|
|
|
|
+- `dashboard/crop-analysis/soil-test-data/soil-analysis.php`
|
|
|
|
|
+- `dashboard/crop-analysis/soil-test-data/soil-report.php`
|
|
|
|
|
+
|
|
|
|
|
+### Critical vulnerabilities (SQL injection via unescaped params)
|
|
|
|
|
+| File | Issue |
|
|
|
|
|
+|------|-------|
|
|
|
|
|
+| `api/updateweatherstation.php` | 40+ unescaped GET params in INSERT |
|
|
|
|
|
+| `newClientDetails.php` | POST params concatenated in INSERT |
|
|
|
|
|
+| `post.php` | `$modx_user` directly in SELECT WHERE |
|
|
|
|
|
+| `soilAnalysisCalcs.php` | GET `id` directly in SELECT WHERE |
|
|
|
|
|
+| `dashboard/crop-analysis/soil-test-data/soil-submit.php` | POST params in INSERT |
|
|
|
|
|
+| `dashboard/crop-analysis/soil-test-data/soil-analysis-pdf.php` | GET params in SELECT |
|
|
|
|
|
+| `dashboard/crop-analysis/soil-test-data/soil-report-pdf.php` | GET params in SELECT |
|
|
|
|
|
+| `dashboard/crop-analysis/soil-test-data/base-saturation-pie.php` | GET params in SELECT |
|
|
|
|
|
+| `dashboard/crop-analysis/animal-dietary-balance/animal-submit.php` | POST params in INSERT |
|
|
|
|
|
+| `dashboard/crop-analysis/plant-test-data/generating-plant-analysis.php` | POST params in INSERT |
|
|
|
|
|
+| `dashboard/client-settings/updateproduct.php` | String concatenation in INSERT |
|
|
|
|
|
+| `dashboard/crop-cards/index.php` | `$client_id` in SELECT |
|
|
|
|
|
+| `client-assets/table/gettable.php` | Dynamic query from POST params |
|
|
|
|
|
+| `api/api.php` | Uses removed `mysql_connect()` (PHP 7+: fatal error) |
|
|
|
|
|
+
|
|
|
|
|
+### Other security issues
|
|
|
|
|
+- Hardcoded credentials in multiple legacy files (`root`/`R3M0T31` and `cropmonitor`/`brvnCcaEYxlPCS3`)
|
|
|
|
|
+- `.env` file is empty — credentials should move there
|
|
|
|
|
+- `lib/auth.php` `hasPermission()` always returns `true` — RBAC not yet implemented
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Key Files Reference
|
|
|
|
|
+
|
|
|
|
|
+### Config & Libraries
|
|
|
|
|
+| File | Purpose |
|
|
|
|
|
+|------|---------|
|
|
|
|
|
+| `config/database.php` | PDO connection, `getDBConnection()` function |
|
|
|
|
|
+| `lib/auth.php` | `isLoggedIn()`, `requireLogin()`, `getCurrentUserId()` |
|
|
|
|
|
+| `lib/csrf.php` | `generateCsrfToken()`, `verifyCsrfToken()`, `regenerateCsrfToken()` |
|
|
|
|
|
+| `lib/validation.php` | `sanitizeString()`, `validateNumeric()`, `ValidationException` |
|
|
|
|
|
+| `lib/soil_calculations.php` | `soilAnalysisReportCalcs()`, `soilProgramCalcs()` |
|
|
|
|
|
+| `lib/db.php` | **Empty** — intended for shared DB helpers |
|
|
|
|
|
+| `lib/flash.php` | **Empty** — intended for flash messages |
|
|
|
|
|
+
|
|
|
|
|
+### Layouts
|
|
|
|
|
+| File | Purpose |
|
|
|
|
|
+|------|---------|
|
|
|
|
|
+| `layouts/header.php` | HTML `<head>`, Bootstrap 5 CDN, CSS includes. Expects `$pageTitle`, `$siteName` |
|
|
|
|
|
+| `layouts/navbar.php` | Top navigation bar |
|
|
|
|
|
+| `layouts/sidebar.php` | Left sidebar navigation |
|
|
|
|
|
+| `layouts/footer.php` | Closing tags + JS includes |
|
|
|
|
|
+
|
|
|
|
|
+### Components
|
|
|
|
|
+| File | Purpose |
|
|
|
|
|
+|------|---------|
|
|
|
|
|
+| `components/clientDetailsForm.php` | Client dropdown + auto-fill (PDO, session user filter) |
|
|
|
|
|
+| `components/newClientModal.php` | Bootstrap modal to add client (CSRF protected) |
|
|
|
|
|
+| `components/soilAnalysisForm.php` | Full soil test entry form (~50 fields, 7 sections) |
|
|
|
|
|
+| `components/navigation.php` | Auth-aware navigation |
|
|
|
|
|
+
|
|
|
|
|
+### Controllers
|
|
|
|
|
+| File | Purpose |
|
|
|
|
|
+|------|---------|
|
|
|
|
|
+| `controllers/newClientSubmit.php` | AJAX POST handler: creates client in `client_records` |
|
|
|
|
|
+| `controllers/soilTestSubmit.php` | POST handler: validates + inserts soil test, runs calculations, redirects to analysis |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## modX Tags Reference
|
|
|
|
|
+
|
|
|
|
|
+### Replaced
|
|
|
|
|
+| Tag | Replacement |
|
|
|
|
|
+|-----|------------|
|
|
|
|
|
+| `[[!clientDetailsFORM]]` | `components/clientDetailsForm.php` |
|
|
|
|
|
+| `[[!newClientDetails]]` | `components/newClientModal.php` |
|
|
|
|
|
+| `[[!soilformSubmit]]` | `controllers/soilTestSubmit.php` |
|
|
|
|
|
+| `[[!Personalize?]]` + `[[Wayfinder?]]` | `components/navigation.php` |
|
|
|
|
|
+| `[[$dash-header]]` | `layouts/header.php` + `layouts/navbar.php` |
|
|
|
|
|
+| `[[$dash-footer]]` | `layouts/footer.php` |
|
|
|
|
|
+
|
|
|
|
|
+### Still present in codebase (needs replacement)
|
|
|
|
|
+| Tag | Location | Replace with |
|
|
|
|
|
+|-----|----------|-------------|
|
|
|
|
|
+| `[[*longtitle]]` | `login/*.php` | PHP variable `$pageTitle` |
|
|
|
|
|
+| `[[++site_name]]` | `login/*.php` | `config/constants.php` constant |
|
|
|
|
|
+| `[[!++site_url]]` | `login/*.php` | Base URL constant |
|
|
|
|
|
+| `[[++modx_charset]]` | `login/*.php` | `'UTF-8'` |
|
|
|
|
|
+| `[[*introtext]]`, `[[*description]]` | `login/*.php` | Page-level PHP vars |
|
|
|
|
|
+| `[[!Login?...]]` | `login/login.php` | Custom PHP session login |
|
|
|
|
|
+| `[[!Register?...]]` | `login/register.php` | Custom PHP registration |
|
|
|
|
|
+| `[[!ForgotPassword?...]]` | `login/forgot-password.php` | Custom PHP password reset |
|
|
|
|
|
+| `[[!ChangePassword?...]]` | `login/change-password.php` | Custom PHP password update |
|
|
|
|
|
+| `[[!Profile]]` | `login/login.php` | Session user data |
|
|
|
|
|
+| `[[$test-widget]]`, `[[$client-widget]]`, etc. | `dashboard/dashboard.php` | PHP components |
|
|
|
|
|
+| `[[~4]]`, `[[~5]]`, `[[~10]]` | `login/*.php` | Hardcoded URL constants |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Coding Patterns to Follow
|
|
|
|
|
+
|
|
|
|
|
+### Page template pattern
|
|
|
|
|
+```php
|
|
|
|
|
+<?php
|
|
|
|
|
+require_once __DIR__ . '/../../config/database.php';
|
|
|
|
|
+require_once __DIR__ . '/../../lib/auth.php';
|
|
|
|
|
+require_once __DIR__ . '/../../lib/csrf.php';
|
|
|
|
|
+
|
|
|
|
|
+requireLogin();
|
|
|
|
|
+
|
|
|
|
|
+$pageTitle = 'Page Title';
|
|
|
|
|
+$siteName = 'Crop Monitor';
|
|
|
|
|
+
|
|
|
|
|
+include __DIR__ . '/../../layouts/header.php';
|
|
|
|
|
+include __DIR__ . '/../../layouts/navbar.php';
|
|
|
|
|
+include __DIR__ . '/../../layouts/sidebar.php';
|
|
|
|
|
+?>
|
|
|
|
|
+<!-- page content -->
|
|
|
|
|
+<?php include __DIR__ . '/../../layouts/footer.php'; ?>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### PDO query pattern
|
|
|
|
|
+```php
|
|
|
|
|
+$pdo = getDBConnection();
|
|
|
|
|
+$stmt = $pdo->prepare('SELECT * FROM soil_records WHERE id = ? AND rand = ?');
|
|
|
|
|
+$stmt->execute([$recordId, $randId]);
|
|
|
|
|
+$row = $stmt->fetch();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Output escaping
|
|
|
|
|
+Always use `htmlspecialchars($value, ENT_QUOTES, 'UTF-8')` when echoing user or DB data into HTML.
|
|
|
|
|
+
|
|
|
|
|
+### CSRF in forms
|
|
|
|
|
+```php
|
|
|
|
|
+<input type="hidden" name="csrf_token" value="<?= generateCsrfToken() ?>">
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### URL parameters used by soil analysis pages
|
|
|
|
|
+| Param | Type | Meaning |
|
|
|
|
|
+|-------|------|---------|
|
|
|
|
|
+| `cid` | int | client_records.id |
|
|
|
|
|
+| `rid` | int | soil_records.id |
|
|
|
|
|
+| `rand` | float | soil_records.rand (secondary auth token) |
|
|
|
|
|
+| `stid` | string | crop/soil type |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Architecture Decisions
|
|
|
|
|
+
|
|
|
|
|
+- **No framework** — plain PHP, manual includes, no routing library
|
|
|
|
|
+- **Layout system** — `layouts/` includes (not a templating engine)
|
|
|
|
|
+- **Folder structure** — keep existing `dashboard/crop-analysis/` paths (no MVC rename needed unless requested)
|
|
|
|
|
+- **Authentication** — session-based (`$_SESSION['user_id']`); RBAC via `hasPermission()` not yet implemented
|
|
|
|
|
+- **Asset pipeline** — Bootstrap/jQuery via CDN; custom CSS/JS in `client-assets/`
|
|
|
|
|
+- **PDF generation** — `pdfchrome.php` (headless Chrome); also FPDF/mPDF patterns in some pages
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## New auth files (2026-03-27)
|
|
|
|
|
+
|
|
|
|
|
+| File | Purpose |
|
|
|
|
|
+|------|---------|
|
|
|
|
|
+| `database/migrations/001_create_users.sql` | Run once — creates `users` + `password_resets` tables |
|
|
|
|
|
+| `lib/auth.php` | `loginUser()`, `logoutUser()`, `registerUser()`, `createPasswordResetToken()`, `validatePasswordResetToken()`, `resetPassword()`, `changePassword()` |
|
|
|
|
|
+| `login/_head.php` | Shared minimal HTML head for auth pages (Bootstrap 5, no sidebar) |
|
|
|
|
|
+| `login/_foot.php` | Closing tags + Bootstrap JS |
|
|
|
|
|
+| `login/login.php` | Email + password login with CSRF |
|
|
|
|
|
+| `login/register.php` | Full registration form with server-side validation |
|
|
|
|
|
+| `login/forgot-password.php` | Email submission for reset token |
|
|
|
|
|
+| `login/reset-password.php` | Token-validated password reset |
|
|
|
|
|
+| `login/logout.php` | Session destruction + redirect |
|
|
|
|
|
+
|
|
|
|
|
+**Note on email sending:** `forgot-password.php` generates the token and logs it via `error_log()`. No email is sent until SMTP is configured. The reset link format is `/login/reset-password.php?token={token}`.
|
|
|
|
|
+
|
|
|
|
|
+## Open Questions
|
|
|
|
|
+
|
|
|
|
|
+1. **URL compatibility**: Must URL slugs matching modX resource IDs (e.g., page 41, 66) be preserved for external links?
|
|
|
|
|
+2. **Credentials**: Move DB password to `.env` file and load with `vlucas/phpdotenv` or manual `parse_ini_file()`?
|
|
|
|
|
+3. **Email / SMTP**: Configure SMTP (e.g., PHPMailer + SMTP credentials) to enable password reset emails.
|
|
|
|
|
+4. **Role-based access**: `hasPermission()` is a stub — what roles/permissions are needed?
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+*Last updated: 2026-03-27*
|