'Erreur de sécurité : token invalide.']); } else { die("Erreur de sécurité : token invalide."); } exit; } $urlKeys = ['erg_site_url', 'source_code_url']; $groupKeys = ['contacts']; $linkListKeys = ['sidebar_links']; $allowedKeys = array_merge($urlKeys, $groupKeys, $linkListKeys); $aproposKey = $_POST['apropos_key'] ?? ''; if (!in_array($aproposKey, $allowedKeys)) { if ($isAjax) { http_response_code(400); header('Content-Type: application/json'); echo json_encode(['error' => 'Clé invalide.']); } else { die("Clé invalide."); } exit; } require_once __DIR__ . '/../../../src/Database.php'; require_once __DIR__ . '/../../../src/AdminLogger.php'; require_once __DIR__ . '/../../../src/ErrorHandler.php'; try { $db = new Database(); if (in_array($aproposKey, $urlKeys)) { // ── URL-based keys (legacy sidebar links) ── $url = trim($_POST['url'] ?? ''); if ($url !== '' && !filter_var($url, FILTER_VALIDATE_URL)) { if ($isAjax) { http_response_code(400); header('Content-Type: application/json'); echo json_encode(['error' => 'URL invalide.']); } else { die("URL invalide."); } exit; } $db->saveAproposContent($aproposKey, $url); } elseif (in_array($aproposKey, $linkListKeys)) { // ── Sidebar links list ── $links = $_POST['links'] ?? []; $cleaned = []; foreach ($links as $link) { $label = trim($link['label'] ?? ''); $url = trim($link['url'] ?? ''); if ($label === '') continue; if ($url !== '' && !filter_var($url, FILTER_VALIDATE_URL)) { if ($isAjax) { http_response_code(400); header('Content-Type: application/json'); echo json_encode(['error' => 'URL invalide: ' . htmlspecialchars($label)]); } else { die("URL invalide: " . htmlspecialchars($label)); } exit; } $cleaned[] = ['label' => $label, 'url' => $url]; } $db->saveAproposContent($aproposKey, $cleaned); } else { // ── Group-based keys (contacts) ── $groups = $_POST['groups'] ?? []; $cleaned = []; foreach ($groups as $group) { $role = trim($group['role'] ?? ''); $entries = []; foreach ($group['entries'] ?? [] as $entry) { $text = trim($entry['text'] ?? ''); if ($text === '') continue; $e = [ 'text' => $text, 'email' => trim($entry['email'] ?? ''), ]; $urlEntry = trim($entry['url'] ?? ''); if ($urlEntry !== '') $e['url'] = $urlEntry; $entries[] = $e; } // Keep group if it has a role OR at least one entry if ($role === '' && empty($entries)) continue; $cleaned[] = ['role' => $role, 'entries' => $entries]; } if (empty($cleaned)) { if ($isAjax) { http_response_code(400); header('Content-Type: application/json'); echo json_encode(['error' => 'Au moins un groupe avec des entrées est requis.']); } else { die("Au moins un groupe avec des entrées est requis."); } exit; } $db->saveAproposContent($aproposKey, $cleaned); } AdminLogger::make()->logAproposEdit($aproposKey); if ($isAjax) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); header('Content-Type: application/json'); echo json_encode([ 'success' => true, 'csrf_token' => $_SESSION['csrf_token'], ]); } else { App::flash('success', "Contenu « $aproposKey » mis à jour avec succès."); header('Location: /admin/contenus.php'); } } catch (Exception $e) { ErrorHandler::log('apropos', $e); $msg = 'Erreur lors de la sauvegarde : ' . htmlspecialchars(ErrorHandler::userMessage($e)); if ($isAjax) { http_response_code(500); header('Content-Type: application/json'); echo json_encode(['error' => $msg]); } else { die($msg); } exit; } exit;