From 0437ec8d15679f39670be7bd2d593e50b3bef443 Mon Sep 17 00:00:00 2001 From: Pontoporeia Date: Wed, 29 Apr 2026 21:05:53 +0200 Subject: [PATCH] fix: escape apostrophe in FORM_HELP_LABELS string (Database.php:2005) --- TODO.md | 4 + .../applied/004_add_form_help_blocks.sql | 26 +++++++ app/public/admin/actions/form-help.php | 39 ++++++++++ app/public/admin/contenus-edit.php | 16 +++- app/public/admin/contenus.php | 9 ++- app/src/Database.php | 74 +++++++++++++++++++ app/templates/admin/contenus-edit.php | 17 +++++ app/templates/admin/contenus.php | 45 +++++++++++ 8 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 app/migrations/applied/004_add_form_help_blocks.sql create mode 100644 app/public/admin/actions/form-help.php diff --git a/TODO.md b/TODO.md index 7f6e3d9..8adf3a7 100644 --- a/TODO.md +++ b/TODO.md @@ -61,3 +61,7 @@ - [x] Add CSS: `.file-preview-list`, `.fp-item`, `.fp-thumb`, `.fp-icon`, `.fp-meta`, `.fp-name`, `.fp-size` - [x] Add CSS: `.recap-file-list`, `.recap-file-item`, `.recap-file-thumb`, `.recap-file-icon`, `.recap-file-meta`, `.recap-file-type-badge`, `.recap-file-date` - [x] Add CSS: `.partage-recap`, `.recap-section`, `.recap-dl` for partage recap layout + +## Bug Fixes (2026-04-29) + +- [x] Fix parse error in `Database.php` line 2005 — escaped apostrophe in `d'introduction` diff --git a/app/migrations/applied/004_add_form_help_blocks.sql b/app/migrations/applied/004_add_form_help_blocks.sql new file mode 100644 index 0000000..4bd1e15 --- /dev/null +++ b/app/migrations/applied/004_add_form_help_blocks.sql @@ -0,0 +1,26 @@ +-- Form help blocks: stores per-fieldset student-facing explanatory text +-- displayed in the /partage share-link submission form. +-- Each row is keyed by a stable slug matching TODO locations in partage/index.php. + +CREATE TABLE IF NOT EXISTS form_help_blocks ( + key TEXT PRIMARY KEY, + content TEXT NOT NULL DEFAULT '', + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +CREATE TRIGGER IF NOT EXISTS update_form_help_blocks_timestamp +AFTER UPDATE ON form_help_blocks +BEGIN + UPDATE form_help_blocks SET updated_at = CURRENT_TIMESTAMP WHERE key = NEW.key; +END; + +-- Seed the eight block slots referenced in partage/index.php. +INSERT OR IGNORE INTO form_help_blocks (key, content) VALUES + ('partage_intro', ''), + ('fieldset_tfe_info', ''), + ('fieldset_synopsis', ''), + ('fieldset_jury', ''), + ('fieldset_academic', ''), + ('fieldset_files', ''), + ('fieldset_access', ''), + ('fieldset_email', ''); diff --git a/app/public/admin/actions/form-help.php b/app/public/admin/actions/form-help.php new file mode 100644 index 0000000..391edf8 --- /dev/null +++ b/app/public/admin/actions/form-help.php @@ -0,0 +1,39 @@ +setFormHelpBlock($key, $content); + App::flash('success', 'Bloc « ' . htmlspecialchars($key) . ' » mis à jour.'); +} catch (Exception $e) { + error_log('form-help save error: ' . $e->getMessage()); + App::flash('error', 'Erreur lors de la sauvegarde : ' . htmlspecialchars($e->getMessage())); +} + +$_SESSION['csrf_token'] = bin2hex(random_bytes(32)); +header('Location: /admin/contenus.php#form-help-blocks'); +exit; diff --git a/app/public/admin/contenus-edit.php b/app/public/admin/contenus-edit.php index 75cca79..2cdb379 100644 --- a/app/public/admin/contenus-edit.php +++ b/app/public/admin/contenus-edit.php @@ -12,8 +12,9 @@ if (empty($_SESSION["csrf_token"])) { $allowedPageSlugs = ["about", "licenses", "charte"]; $allowedApropos = ["contacts", "credits"]; -$pageSlug = $_GET["slug"] ?? ""; -$aproposKey = $_GET["apropos"] ?? ""; +$pageSlug = $_GET["slug"] ?? ""; +$aproposKey = $_GET["apropos"] ?? ""; +$formHelpKey = $_GET["form_block"] ?? ""; if ($pageSlug && !in_array($pageSlug, $allowedPageSlugs)) { $pageSlug = ""; @@ -21,8 +22,11 @@ if ($pageSlug && !in_array($pageSlug, $allowedPageSlugs)) { if ($aproposKey && !in_array($aproposKey, $allowedApropos)) { $aproposKey = ""; } +if ($formHelpKey && !in_array($formHelpKey, Database::FORM_HELP_KEYS, true)) { + $formHelpKey = ""; +} -if (!$pageSlug && !$aproposKey) { +if (!$pageSlug && !$aproposKey && !$formHelpKey) { header("Location: /admin/contenus.php"); exit(); } @@ -37,6 +41,10 @@ try { } $editTitle = $page["title"]; $editType = "page"; + } elseif ($formHelpKey) { + $editType = "form_help"; + $formHelpContent = $db->getFormHelpBlock($formHelpKey); + $editTitle = Database::FORM_HELP_LABELS[$formHelpKey] ?? $formHelpKey; } else { $editType = "apropos"; $value = $db->getAproposContent($aproposKey); @@ -65,6 +73,8 @@ JS; $initialContent = ''; if ($editType === 'page') { $initialContent = $page["content"] ?? ""; +} elseif ($editType === 'form_help') { + $initialContent = $formHelpContent; } $isAdmin = true; diff --git a/app/public/admin/contenus.php b/app/public/admin/contenus.php index 5ca39c5..4543709 100644 --- a/app/public/admin/contenus.php +++ b/app/public/admin/contenus.php @@ -6,10 +6,15 @@ require_once __DIR__ . '/../../src/Database.php'; $pageTitle = "Contenus"; +if (empty($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); +} + try { $db = new Database(); - $pages = $db->getAllPages(); - $aproposKeys = $db->getAllAproposContents(); + $pages = $db->getAllPages(); + $aproposKeys = $db->getAllAproposContents(); + $formHelpBlocks = $db->getAllFormHelpBlocks(); } catch (Exception $e) { error_log("Error loading contenus: " . $e->getMessage()); die("Erreur lors du chargement des contenus."); diff --git a/app/src/Database.php b/app/src/Database.php index bd9d4df..4f15af8 100644 --- a/app/src/Database.php +++ b/app/src/Database.php @@ -1979,6 +1979,80 @@ class Database { return $stmt->fetchAll(); } + // ======================================================================== + // FORM HELP BLOCKS + // ======================================================================== + + /** + * Known form help block keys (mirrors the seeded rows in migration 004). + */ + public const FORM_HELP_KEYS = [ + 'partage_intro', + 'fieldset_tfe_info', + 'fieldset_synopsis', + 'fieldset_jury', + 'fieldset_academic', + 'fieldset_files', + 'fieldset_access', + 'fieldset_email', + ]; + + /** + * Human-readable labels for each block key (used in the admin UI). + */ + public const FORM_HELP_LABELS = [ + 'partage_intro' => 'Introduction du formulaire', + 'fieldset_tfe_info' => 'Informations du TFE — note d\'introduction', + 'fieldset_synopsis' => 'Synopsis — explication', + 'fieldset_jury' => 'Composition du jury — note', + 'fieldset_academic' => 'Cadre académique — note', + 'fieldset_files' => 'Fichiers — note', + 'fieldset_access' => 'Visibilité / Accès — explication', + 'fieldset_email' => 'E-mail de confirmation — note', + ]; + + /** + * Get a single form help block by key. Returns '' when missing. + */ + public function getFormHelpBlock(string $key): string { + $stmt = $this->pdo->prepare( + "SELECT content FROM form_help_blocks WHERE key = ? LIMIT 1" + ); + $stmt->execute([$key]); + $val = $stmt->fetchColumn(); + return ($val !== false) ? (string)$val : ''; + } + + /** + * Upsert a form help block. + */ + public function setFormHelpBlock(string $key, string $content): void { + if (!in_array($key, self::FORM_HELP_KEYS, true)) { + throw new Exception("Unknown form help block key: $key"); + } + $this->pdo->prepare( + "INSERT INTO form_help_blocks (key, content, updated_at) + VALUES (?, ?, CURRENT_TIMESTAMP) + ON CONFLICT(key) DO UPDATE SET content = excluded.content, + updated_at = CURRENT_TIMESTAMP" + )->execute([$key, $content]); + } + + /** + * Return all form help blocks as [ key => ['content' => ..., 'updated_at' => ...] ]. + */ + public function getAllFormHelpBlocks(): array { + $stmt = $this->pdo->query( + "SELECT key, content, updated_at FROM form_help_blocks ORDER BY key" + ); + $rows = $stmt->fetchAll(); + $out = []; + foreach ($rows as $r) { + $out[$r['key']] = ['content' => $r['content'], 'updated_at' => $r['updated_at']]; + } + return $out; + } + // ======================================================================== // SINGLETON PATTERN ENFORCEMENT // ======================================================================== diff --git a/app/templates/admin/contenus-edit.php b/app/templates/admin/contenus-edit.php index fd90249..342ccfd 100644 --- a/app/templates/admin/contenus-edit.php +++ b/app/templates/admin/contenus-edit.php @@ -17,6 +17,23 @@ + +

Ce texte est affiché dans le formulaire de soumission des étudiant·es (lien de partage). Supporte le Markdown.

+
+ + + + + +
+ + +
+

Contenus

+ + + + + + + +

Pages statiques

@@ -58,4 +69,38 @@
+ +

Blocs d'aide du formulaire étudiant·e

+

Ces textes apparaissent dans le formulaire de soumission accessible via les liens de partage. Ils permettent d'expliquer aux étudiant·es comment remplir chaque section. Supporte le Markdown.

+ + + + + + + + + + + + + '', 'updated_at' => null]; + $label = Database::FORM_HELP_LABELS[$key] ?? $key; + $preview = $block['content'] !== '' + ? mb_strimwidth($block['content'], 0, 80, '…') + : '— vide —'; + ?> + + + + + + + + +
BlocAperçuMis à jourAction
+ Éditer +