/submit - POST endpoint for form submissions via share link
+ * /partage/recapitulatif.php?id=N - Post-submission confirmation page
*/
require_once __DIR__ . '/../../bootstrap.php';
@@ -83,7 +83,7 @@ if (!$validationResult['valid']) {
exit;
}
-// Link is valid — render the form
+// Link is valid - render the form
$link = $validationResult['link'];
renderShareLinkForm($slug, $link);
@@ -222,7 +222,7 @@ function renderShareLinkForm(string $slug, array $link): void
// Build old()-compatible callable from $formData (share forms use the array variant).
$shareOldFn = fn(string $key, string $default = '') => old($formData, $key, $default);
- // No autofocus in the share form — identity function.
+ // No autofocus in the share form - identity function.
$shareWithAutofocusFn = fn(string $field, array $attrs = []) => $attrs;
// Load all form help blocks in one query.
@@ -267,7 +267,8 @@ function renderShareLinkForm(string $slug, array $link): void
= htmlspecialchars($flashError) ?>
- = htmlspecialchars($flashWarning) ?>
+ = htmlspecialchars($flashWarning) ?>
+
= htmlspecialchars($flashSuccess) ?>
@@ -460,7 +461,7 @@ function handleShareLinkSubmission(string $slug): void
unset($_SESSION[$shareCsrfKey]);
unset($_SESSION['share_verified_' . $slug]);
- // Send confirmation e-mail — on delivery failure, redirect to retry page
+ // Send confirmation e-mail - on delivery failure, redirect to retry page
$emailError = null;
try {
$emailSent = StudentEmail::sendConfirmation(Database::getInstance(), $thesisId, $_POST);
@@ -472,7 +473,7 @@ function handleShareLinkSubmission(string $slug): void
header('Location: /partage/retry-email?id=' . urlencode((string)$thesisId));
exit();
}
- // Non-recipient errors (relay down, etc.) — skip email silently
+ // Non-recipient errors (relay down, etc.) - skip email silently
$_SESSION['share_email_sent'] = false;
}
@@ -488,9 +489,10 @@ function handleShareLinkSubmission(string $slug): void
error_log('Share link duplicate submission: ' . $e->getMessage());
// Repopulate the form and surface a clear warning to the student.
- $_SESSION['_flash_warning'] = 'Votre soumission ressemble à un TFE déjà enregistré ('
- . htmlspecialchars($e->existingIdentifier . ' — ' . $e->existingTitle . ', ' . $e->existingYear)
- . '). Si vous pensez qu’il s’agit d’une erreur, veuillez contacter l’équipe.';
+ // Store as plain text — htmlspecialchars() is applied at render time.
+ $_SESSION['_flash_warning'] = 'Votre soumission ressemble à un TFE déjà enregistré.'
+ . "\n" . $e->existingIdentifier . ' — ' . $e->existingTitle . ' (' . $e->existingYear . ')'
+ . "\nSi vous pensez qu'il s'agit d'une erreur, veuillez contacter l'équipe.";
$_SESSION['form_data_share_' . $slug] = $_POST;
$_SESSION[$shareCsrfKey] = bin2hex(random_bytes(32)); // Regenerate token
diff --git a/app/storage/logs/form-submissions.log b/app/storage/logs/form-submissions.log
index 49b0402..a63417e 100644
--- a/app/storage/logs/form-submissions.log
+++ b/app/storage/logs/form-submissions.log
@@ -9,3 +9,8 @@
{"source":"partage","action":"submit","status":"success","thesis_id":23,"identifier":"2025-020","author":"Zoé Lambert","share_slug":"20260429-DZESJT6X","timestamp":"2026-04-30T11:46:49+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
{"source":"partage","action":"submit","status":"success","thesis_id":24,"identifier":"2025-021","author":"Emma Renard","share_slug":"20260429-DZESJT6X","timestamp":"2026-04-30T11:49:49+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
{"source":"partage","action":"submit","status":"success","thesis_id":25,"identifier":"2025-001","author":"Emma Renard","share_slug":"20260429-DZESJT6X","timestamp":"2026-04-30T12:17:35+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
+{"source":"admin","action":"submit","status":"success","thesis_id":37,"identifier":"2025-012","author":"Théo Marchand","timestamp":"2026-05-04T14:56:37+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
+{"source":"admin","action":"submit","status":"duplicate","author":"Théo Marchand","existing_thesis_id":37,"existing_identifier":"2025-012","timestamp":"2026-05-04T14:56:53+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
+{"source":"partage","action":"submit","status":"duplicate","author":"Théo Marchand","existing_thesis_id":37,"existing_identifier":"2025-012","share_slug":"20260429-DZESJT6X","timestamp":"2026-05-04T15:01:08+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
+{"source":"partage","action":"submit","status":"duplicate","author":"Théo Marchand","existing_thesis_id":37,"existing_identifier":"2025-012","share_slug":"20260429-DZESJT6X","timestamp":"2026-05-04T15:05:04+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
+{"source":"admin","action":"submit","status":"duplicate","author":"Théo Marchand","existing_thesis_id":37,"existing_identifier":"2025-012","timestamp":"2026-05-04T15:05:31+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"}
diff --git a/app/templates/admin/footer.php b/app/templates/admin/footer.php
index f6c5028..836ef56 100644
--- a/app/templates/admin/footer.php
+++ b/app/templates/admin/footer.php
@@ -14,5 +14,13 @@
+