| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- <?php
- /**
- * controllers/updateSoilSpecification.php
- *
- * AJAX POST handler: updates a single cell in soil_specifications.
- * Returns JSON { success: true } or { success: false, error: "..." }.
- */
- if (session_status() === PHP_SESSION_NONE) {
- session_start();
- }
- require_once __DIR__ . '/../config/database.php';
- require_once __DIR__ . '/../lib/auth.php';
- require_once __DIR__ . '/../lib/csrf.php';
- header('Content-Type: application/json');
- if (!isLoggedIn()) {
- http_response_code(401);
- echo json_encode(['success' => false, 'error' => 'Not authenticated']);
- exit;
- }
- if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
- http_response_code(405);
- echo json_encode(['success' => false, 'error' => 'Method not allowed']);
- exit;
- }
- if (!verifyCsrfToken($_POST['csrf_token'] ?? '')) {
- http_response_code(403);
- echo json_encode(['success' => false, 'error' => 'Invalid CSRF token']);
- exit;
- }
- $specId = (int)($_POST['spec_id'] ?? 0);
- $column = (string)($_POST['column'] ?? '');
- $value = trim((string)($_POST['value'] ?? ''));
- if (!$specId || $column === '') {
- http_response_code(400);
- echo json_encode(['success' => false, 'error' => 'Missing required fields']);
- exit;
- }
- // Allowlist — only columns present in soil_specifications (excluding system cols)
- $allowed = [
- 'soil_type',
- 'cec', 'NO3_N', 'NH3_N',
- 'p_mehlick', 'p_bray2', 'p_morgan', 'p_colwell',
- 'k_morgan', 'ca_morgan', 'mg_morgan', 'na_morgan',
- 'ch_h2o', 'ocarbon', 'omatter', 'fe', 'ec',
- 'ph_cacl2', 'ph_h2o', 's_morgan',
- 'b_cacl2', 'mn_dtpa', 'zn_dtpa', 'fe_dtpa', 'cu_dtpa',
- 'al', 'sl_cacl2', 'm_dtpa', 'co_dtpa', 'se',
- 'ca_mehlick3', 'mg_mehlick3', 'k_mehlick3', 'na_mehlick3', 'al_mehlick3',
- 'BS_ca2', 'BS_ca_ppm', 'BS_mg2', 'BS_mg_ppm',
- 'BS_k', 'BS_k_ppm', 'BS_na', 'BS_na_ppm',
- 'BS_al3', 'BS_ob', 'BS_h',
- 'ca_mg_ratio', 'c_n_ratio',
- // spec-range columns
- 'ca_ppm_min', 'ca_ppm_max', 'mg_ppm_min', 'mg_ppm_max',
- 'k_ppm_min', 'k_ppm_max', 'na_ppm_min', 'na_ppm_max',
- 'cabs_min', 'cabs_max', 'mgbs_min', 'mgbs_max',
- 'kbs_min', 'kbs_max', 'nabs_min', 'nabs_max',
- 'ob_rec', 'h_rec', 'ca_mg_ratio', 'c_n_ratio', 'ph',
- ];
- if (!in_array($column, $allowed, true)) {
- http_response_code(400);
- echo json_encode(['success' => false, 'error' => 'Column not editable']);
- exit;
- }
- try {
- $pdo = getDBConnection();
- $userId = getCurrentUserId();
- // The backtick-quoted column name is safe because it is validated against the allowlist above.
- $stmt = $pdo->prepare("UPDATE soil_specifications SET `{$column}` = ? WHERE id = ? AND modx_user_id = ?");
- $stmt->execute([$value, $specId, $userId]);
- if ($stmt->rowCount() === 0) {
- http_response_code(404);
- echo json_encode(['success' => false, 'error' => 'Record not found']);
- exit;
- }
- echo json_encode(['success' => true]);
- } catch (PDOException $e) {
- error_log('DB error in updateSoilSpecification.php: ' . $e->getMessage());
- http_response_code(500);
- echo json_encode(['success' => false, 'error' => 'Database error']);
- }
- exit;
|