芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/public_html/teafund.pulsehost.co.uk/api/add_member.php
Tools with status flags instead of crashing. require_once __DIR__ . '/../includes/auth.php'; require_once __DIR__ . '/../includes/db.php'; require_manage(); function goback(string $qs) { header('Location: /admin/?tab=tools&' . $qs); exit; } // --- CSRF (with fallback) --- $csrf_ok = false; try { require_once __DIR__ . '/../includes/csrf.php'; $token = $_POST['csrf_token'] ?? ''; if (function_exists('csrf_validate')) { $csrf_ok = csrf_validate($token); } else { if (session_status() !== PHP_SESSION_ACTIVE) @session_start(); $session_token = $_SESSION['csrf_token'] ?? ''; if ($session_token && is_string($token)) $csrf_ok = hash_equals((string)$session_token, (string)$token); } } catch (Throwable $e) { error_log('[add_member csrf] ' . $e->getMessage()); } if (!$csrf_ok) goback('add_error=csrf'); // --- Inputs --- $name = trim((string)($_POST['name'] ?? '')); $email = trim((string)($_POST['email'] ?? '')); $join_raw = trim((string)($_POST['join_date'] ?? '')); $notes = trim((string)($_POST['notes'] ?? '')); $fund_id = isset($_POST['fund_id']) ? (int)$_POST['fund_id'] : 0; $year = isset($_POST['year']) ? (int)$_POST['year'] : (int)date('Y'); if ($fund_id <= 0 || $name === '' || mb_strlen($name) > 120) { goback('add_error=bad_request'); } // Validate minimal email (optional) if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) { goback('add_error=bad_email&fund_id=' . $fund_id . '&year=' . $year); } // Normalize date (YYYY-MM-DD) or NULL $join_date = null; if ($join_raw !== '') { // Accept YYYY-MM-DD or DD/MM/YYYY if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $join_raw)) { $join_date = $join_raw; } elseif (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $join_raw, $m)) { $join_date = sprintf('%04d-%02d-%02d', (int)$m[3], (int)$m[2], (int)$m[1]); } else { // Unrecognized format -> ignore rather than error $join_date = null; } } $TRACE = 'start'; try { $TRACE = 'pdo'; $pdo = get_pdo(); // Ensure funds table exists and fund is valid $TRACE = 'check_fund'; $chk = $pdo->prepare("SELECT id FROM funds WHERE id = ?"); if (!$chk || !$chk->execute([$fund_id])) goback('add_error=db_read&fund_id=' . $fund_id . '&year=' . $year); if (!$chk->fetchColumn()) goback('add_error=fund_not_found'); // Ensure members table exists (no FK to avoid errno 150 on hosts with mismatched engines) $TRACE = 'ensure_members'; $pdo->exec("CREATE TABLE IF NOT EXISTS members ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(120) NOT NULL, email VARCHAR(190) NULL, join_date DATE NULL, fund_id INT NOT NULL, notes TEXT NULL, active TINYINT(1) NOT NULL DEFAULT 1, INDEX(fund_id), INDEX(active), INDEX(name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"); // Insert $TRACE = 'insert'; $ins = $pdo->prepare("INSERT INTO members (name, email, join_date, fund_id, notes, active) VALUES (?, ?, ?, ?, ?, 1)"); $ok = $ins && $ins->execute([ $name, ($email !== '' ? $email : null), $join_date, $fund_id, ($notes !== '' ? $notes : null), ]); if (!$ok) goback('add_error=db_write&fund_id=' . $fund_id . '&year=' . $year); $newId = (int)$pdo->lastInsertId(); goback('added=1&fund_id=' . $fund_id . '&year=' . $year . '&new=' . $newId); } catch (Throwable $e) { error_log('[add_member fatal] step=' . $TRACE . ' msg=' . $e->getMessage()); goback('add_error=server&trace=' . urlencode($TRACE) . '&fund_id=' . $fund_id . '&year=' . $year); }