Files
xamxam/public/admin/actions/edit.php
Pontoporeia 592b1183db Unify flash messages: replace all legacy session key writes with App::flash()
All admin action files (account, tag, page, edit, visibility, maintenance,
publish, formulaire) now call App::flash('error'|'success', ...) instead of
writing to raw per-page session keys ($_SESSION['error'], 'admin_error',
'edit_error', 'admin_success', 'edit_success', 'form_error').

All admin display pages (add, edit, account, tags, pages, index) now include
templates/partials/flash-messages.php instead of manually reading and
unsetting the legacy session keys and inlining their own alert HTML.

App::consumeFlash() already drained all legacy key variants as a safety net,
so the partial works correctly whether called from pages that were already
migrated or any remaining stragglers. No behaviour change for end users.
2026-04-02 12:57:36 +02:00

142 lines
4.7 KiB
PHP

<?php
// Bootstrap application
require_once __DIR__ . "/../../../config/bootstrap.php";
require_once __DIR__ . '/../../../src/AdminAuth.php';
// PHP-level auth guard (defence-in-depth behind nginx Basic Auth)
AdminAuth::requireLogin();
// Only handle POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: ../index.php');
exit();
}
// Verify CSRF token
if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) ||
!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
error_log("CSRF token validation failed in edit action");
die("Erreur de sécurité : token invalide. Veuillez recharger le formulaire.");
}
$thesisId = isset($_POST['thesis_id']) ? intval($_POST['thesis_id']) : 0;
if ($thesisId <= 0) {
die("ID de TFE invalide.");
}
require_once __DIR__ . '/../../../src/Database.php';
try {
$db = new Database();
$db->beginTransaction();
// Thesis metadata
$db->updateThesis($thesisId, [
'title' => trim($_POST['titre']),
'subtitle' => trim($_POST['subtitle'] ?? ''),
'year' => intval($_POST['année']),
'orientation_id' => intval($_POST['orientation']),
'ap_program_id' => intval($_POST['ap']),
'finality_id' => intval($_POST['finality']),
'synopsis' => trim($_POST['synopsis']),
'context_note' => trim($_POST['context_note'] ?? ''),
'file_size_info' => trim($_POST['duration_info'] ?? ''),
'baiu_link' => trim($_POST['lien'] ?? ''),
'license_id' => filter_var($_POST['license_id'] ?? '', FILTER_VALIDATE_INT) ?: null,
'access_type_id' => filter_var($_POST['access_type_id'] ?? '', FILTER_VALIDATE_INT) ?: null,
'is_published' => isset($_POST['is_published']),
]);
// Authors
$authorsRaw = trim($_POST['auteurice'] ?? '');
$authorEntries = [];
if (!empty($authorsRaw)) {
$names = array_map('trim', explode(',', $authorsRaw));
foreach ($names as $index => $name) {
if ($name !== '') {
$authorEntries[] = [
'name' => $name,
'email' => $index === 0 ? ($_POST['mail'] ?? null) : null,
];
}
}
}
$db->setThesisAuthors($thesisId, $authorEntries);
// Jury
$juryMembers = [];
if (!empty(trim($_POST['jury_president'] ?? ''))) {
$juryMembers[] = ['name' => trim($_POST['jury_president']), 'role' => 'president', 'is_external' => 0];
}
if (!empty(trim($_POST['jury_promoteur'] ?? ''))) {
$juryMembers[] = [
'name' => trim($_POST['jury_promoteur']),
'role' => 'promoteur',
'is_external' => isset($_POST['jury_promoteur_ext']) ? 1 : 0,
];
}
foreach ($_POST['jury_lecteurs'] ?? [] as $i => $name) {
$name = trim($name);
if ($name !== '') {
$juryMembers[] = [
'name' => $name,
'role' => 'lecteur',
'is_external' => isset($_POST['jury_lecteurs_ext'][$i]) ? 1 : 0,
];
}
}
$db->setThesisJury($thesisId, $juryMembers);
// Languages
$db->setThesisLanguages(
$thesisId,
isset($_POST['languages']) && is_array($_POST['languages']) ? $_POST['languages'] : []
);
// Formats
$db->setThesisFormats(
$thesisId,
isset($_POST['formats']) && is_array($_POST['formats']) ? $_POST['formats'] : []
);
// Tags
$keywordsRaw = trim($_POST['tag'] ?? '');
$editKeywords = !empty($keywordsRaw) ? array_map('trim', explode(',', $keywordsRaw)) : [];
$db->setThesisTags($thesisId, $editKeywords);
$db->commit();
// Banner upload/removal (after commit, outside transaction)
if (isset($_POST['remove_banner'])) {
$currentBannerPath = $db->getThesisBannerPath($thesisId);
if ($currentBannerPath && defined('STORAGE_ROOT')) {
$absPath = STORAGE_ROOT . '/' . $currentBannerPath;
if (file_exists($absPath)) {
unlink($absPath);
}
}
$db->setBannerPath($thesisId, null);
} else {
$db->handleBannerUpload($thesisId, $_FILES['banner'] ?? null);
}
// Regenerate CSRF token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
// Flash success and redirect back to edit form
App::flash('success', "TFE mis à jour avec succès!");
header('Location: ../edit.php?id=' . $thesisId);
exit();
} catch (Exception $e) {
if (isset($db)) {
$db->rollback();
}
error_log("Edit action error: " . $e->getMessage());
App::flash('error', $e->getMessage());
header('Location: ../edit.php?id=' . $thesisId);
exit();
}