migrate apropos data from config/apropos.php to SQLite

- Create apropos_contents table via migration 010
- Add Database methods: getAproposContent(), saveAproposContent(), getAllAproposContents()
- Replace admin/pages.php with admin/contenus.php (renamed header from 'Pages statiques' to 'Contenus')
- Replace admin/pages-edit.php with admin/contenus-edit.php (support editing pages + apropos contents)
- Create admin/actions/apropos.php for saving apropos data (contacts, credits, erg_url)
- Update public/apropos.php to read contacts/credits/erg_url from DB
- Delete config/apropos.php
This commit is contained in:
Pontoporeia
2026-04-16 13:44:06 +02:00
parent 4158c72d08
commit bf30aab0b3
15 changed files with 538 additions and 236 deletions

View File

@@ -0,0 +1,77 @@
<?php
/**
* Save handler for apropos contents (contacts, credits, erg_url).
*/
require_once __DIR__ . "/../../../config/bootstrap.php";
require_once __DIR__ . '/../../../src/AdminAuth.php';
AdminAuth::requireLogin();
// CSRF check
if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) ||
!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die("Erreur de sécurité : token invalide.");
}
$allowedKeys = ['contacts', 'credits', 'erg_url'];
$aproposKey = $_POST['apropos_key'] ?? '';
if (!in_array($aproposKey, $allowedKeys)) {
die("Clé invalide.");
}
require_once __DIR__ . '/../../../src/Database.php';
try {
$db = new Database();
if ($aproposKey === 'erg_url') {
$value = trim($_POST['value'] ?? '');
if (strlen($value) > 500) {
die("URL trop longue (max 500 caractères).");
}
$db->saveAproposContent('erg_url', $value);
} else {
$items = $_POST['items'] ?? [];
$cleaned = [];
foreach ($items as $item) {
if ($aproposKey === 'contacts') {
$name = trim($item['name'] ?? '');
if ($name === '') continue; // skip empty rows
$entry = [
'name' => trim($item['name'] ?? ''),
'role' => trim($item['role'] ?? ''),
'email' => trim($item['email'] ?? ''),
];
$url = trim($item['url'] ?? '');
if ($url !== '') {
$entry['url'] = $url;
}
$cleaned[] = $entry;
} else { // credits
$label = trim($item['label'] ?? '');
$val = trim($item['value'] ?? '');
$url = trim($item['url'] ?? '');
if ($label === '' && $val === '') continue;
$entry = [
'label' => $label,
'value' => $val,
];
if ($url !== '') {
$entry['url'] = $url;
}
$cleaned[] = $entry;
}
}
if (empty($cleaned)) {
die("Au moins un élément est requis.");
}
$db->saveAproposContent($aproposKey, $cleaned);
}
App::flash('success', "Contenu « $aproposKey » mis à jour avec succès.");
} catch (Exception $e) {
error_log("Apropos save error: " . $e->getMessage());
die("Erreur lors de la sauvegarde : " . htmlspecialchars($e->getMessage()));
}
header('Location: /admin/contenus.php');
exit;

View File

@@ -1,35 +0,0 @@
<?php
require_once __DIR__ . "/../../../config/bootstrap.php";
require_once __DIR__ . '/../../../src/AdminAuth.php';
AdminAuth::requireLogin();
// CSRF check
if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) ||
!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die("Erreur de sécurité : token invalide.");
}
$allowedSlugs = ['about', 'licenses', 'charte', 'contact'];
$slug = $_POST['slug'] ?? '';
if (!in_array($slug, $allowedSlugs)) {
die("Slug invalide.");
}
$content = $_POST['content'] ?? '';
if (strlen($content) > 65535) {
die("Contenu trop long (max 65 535 caractères).");
}
require_once __DIR__ . '/../../../src/Database.php';
try {
$db = new Database();
$db->savePage($slug, $content);
App::flash('success', "Page «" . $slug . "» mise à jour avec succès.");
} catch (Exception $e) {
error_log("Page save error: " . $e->getMessage());
die("Erreur lors de la sauvegarde : " . htmlspecialchars($e->getMessage()));
}
header('Location: /admin/pages.php');
exit;