mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 03:29:19 +02:00
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.
142 lines
4.7 KiB
PHP
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();
|
|
}
|