Files
xamxam/public/admin/edit.php
Pontoporeia 2110d2b916 Redesign UI to match target design images
- Flat purple-gradient nav bar with POSTERG/RÉPERTOIRE/À PROPOS links
- Full-width search bar with icon, bottom-border only, below nav
- Home: white bg, media card grid (thumbnail + author/title label below)
- Répertoire: 4-column index (Années/Catégories/Étudiantes/Mots-clés)
- TFE: 2-column layout (large text left, media right)
- À Propos: 2-column, large monospace text, new apropos.php page
- Admin: dark theme (#1a1a1a), purple gradient nav, bottom-border inputs
- New shared partials: templates/nav.php, templates/search-bar.php
- Rewrote all CSS: common, main, search, tfe, apropos, admin
2026-02-24 23:34:17 +01:00

331 lines
14 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();
// Generate CSRF token
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
require_once __DIR__ . '/../../src/Database.php';
$thesisId = isset($_GET['id']) ? intval($_GET['id']) : 0;
$error = null;
$success = null;
if ($thesisId <= 0) {
die("ID invalide");
}
try {
$db = new Database();
$pdo = $db->getPDO();
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['csrf_token'])) {
// Verify CSRF token
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
throw new Exception("Erreur de sécurité : token invalide.");
}
try {
$db->beginTransaction();
// Update thesis basic info
$stmt = $pdo->prepare("
UPDATE theses SET
title = ?,
subtitle = ?,
year = ?,
orientation_id = ?,
ap_program_id = ?,
finality_id = ?,
synopsis = ?,
file_size_info = ?,
baiu_link = ?,
is_published = ?,
updated_at = CURRENT_TIMESTAMP
WHERE id = ?
");
$stmt->execute([
trim($_POST['titre']),
!empty($_POST['subtitle']) ? trim($_POST['subtitle']) : null,
intval($_POST['année']),
intval($_POST['orientation']),
intval($_POST['ap']),
intval($_POST['finality']),
trim($_POST['synopsis']),
!empty($_POST['duration_info']) ? trim($_POST['duration_info']) : null,
!empty($_POST['lien']) ? trim($_POST['lien']) : null,
isset($_POST['is_published']) ? 1 : 0,
$thesisId
]);
// Update authors
$pdo->prepare("DELETE FROM thesis_authors WHERE thesis_id = ?")->execute([$thesisId]);
$authorsRaw = trim($_POST['auteurice'] ?? '');
if (!empty($authorsRaw)) {
$authors = array_map('trim', explode(',', $authorsRaw));
foreach ($authors as $index => $authorName) {
if (!empty($authorName)) {
$authorId = $db->findOrCreateAuthor($authorName, $index === 0 ? ($_POST['mail'] ?? null) : null);
$stmt = $pdo->prepare("INSERT INTO thesis_authors (thesis_id, author_id, author_order) VALUES (?, ?, ?)");
$stmt->execute([$thesisId, $authorId, $index + 1]);
}
}
}
// Update supervisors
$pdo->prepare("DELETE FROM thesis_supervisors WHERE thesis_id = ?")->execute([$thesisId]);
$supervisorsRaw = trim($_POST['promoteurice'] ?? '');
if (!empty($supervisorsRaw)) {
$supervisors = array_map('trim', explode(',', $supervisorsRaw));
foreach ($supervisors as $index => $supervisorName) {
if (!empty($supervisorName)) {
$supervisorId = $db->findOrCreateSupervisor($supervisorName);
$stmt = $pdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, supervisor_order) VALUES (?, ?, ?)");
$stmt->execute([$thesisId, $supervisorId, $index + 1]);
}
}
}
// Update languages
$pdo->prepare("DELETE FROM thesis_languages WHERE thesis_id = ?")->execute([$thesisId]);
if (isset($_POST['languages']) && is_array($_POST['languages'])) {
foreach ($_POST['languages'] as $languageId) {
$stmt = $pdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?, ?)");
$stmt->execute([$thesisId, intval($languageId)]);
}
}
// Update formats
$pdo->prepare("DELETE FROM thesis_formats WHERE thesis_id = ?")->execute([$thesisId]);
if (isset($_POST['formats']) && is_array($_POST['formats'])) {
foreach ($_POST['formats'] as $formatId) {
$stmt = $pdo->prepare("INSERT INTO thesis_formats (thesis_id, format_id) VALUES (?, ?)");
$stmt->execute([$thesisId, intval($formatId)]);
}
}
// Update keywords
$pdo->prepare("DELETE FROM thesis_keywords WHERE thesis_id = ?")->execute([$thesisId]);
$keywordsRaw = trim($_POST['tag'] ?? '');
if (!empty($keywordsRaw)) {
$keywords = array_map('trim', explode(',', $keywordsRaw));
$keywords = array_slice($keywords, 0, 10); // Max 10
foreach ($keywords as $keyword) {
if (!empty($keyword)) {
$keywordId = $db->findOrCreateKeyword($keyword);
if ($keywordId) {
$stmt = $pdo->prepare("INSERT INTO thesis_keywords (thesis_id, keyword_id) VALUES (?, ?)");
$stmt->execute([$thesisId, $keywordId]);
}
}
}
}
$db->commit();
$success = "TFE mis à jour avec succès!";
// Regenerate CSRF token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
} catch (Exception $e) {
$db->rollback();
$error = $e->getMessage();
error_log("Edit error: " . $e->getMessage());
}
}
// Load thesis data
$thesis = $db->getThesis($thesisId);
if (!$thesis) {
die("TFE non trouvé");
}
// Load current relationships
$stmt = $pdo->prepare("SELECT language_id FROM thesis_languages WHERE thesis_id = ?");
$stmt->execute([$thesisId]);
$currentLanguages = $stmt->fetchAll(PDO::FETCH_COLUMN);
$stmt = $pdo->prepare("SELECT format_id FROM thesis_formats WHERE thesis_id = ?");
$stmt->execute([$thesisId]);
$currentFormats = $stmt->fetchAll(PDO::FETCH_COLUMN);
// Load reference data
$orientations = $db->getAllOrientations();
$apPrograms = $db->getAllAPPrograms();
$finalityTypes = $db->getAllFinalityTypes();
$languages = $db->getAllLanguages();
$formatTypes = $db->getAllFormatTypes();
// Set page title for header
$pageTitle = "Éditer TFE - " . htmlspecialchars($thesis['title']);
} catch (Exception $e) {
error_log("Error loading edit page: " . $e->getMessage());
die("Erreur lors du chargement: " . $e->getMessage());
}
?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
<main class="admin-main">
<h1 class="admin-page-title">Modifier un TFE</h1>
<?php if ($error): ?>
<div class="admin-alert admin-alert--error">⚠ <?= htmlspecialchars($error) ?></div>
<?php endif; ?>
<?php if ($success): ?>
<div class="admin-alert admin-alert--success">✓ <?= htmlspecialchars($success) ?></div>
<?php endif; ?>
<form method="post" action="edit.php?id=<?= $thesisId ?>" class="admin-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<div class="admin-form-row">
<label class="admin-label" for="auteurice">Auteur·ice(s) :</label>
<input class="admin-input" type="text" id="auteurice" name="auteurice"
value="<?= htmlspecialchars($thesis['authors']) ?>" required>
</div>
<div class="admin-form-row">
<label class="admin-label" for="mail">Contact :</label>
<input class="admin-input" type="text" id="mail" name="mail" value="">
</div>
<div class="admin-form-row">
<label class="admin-label" for="année">Année :</label>
<input class="admin-input" type="number" id="année" name="année"
value="<?= $thesis['year'] ?>" required>
</div>
<div class="admin-form-row">
<label class="admin-label" for="orientation">Orientation :</label>
<select class="admin-select" id="orientation" name="orientation" required>
<?php foreach ($orientations as $o): ?>
<option value="<?= $o['id'] ?>"
<?= ($thesis['orientation'] == $o['name']) ? 'selected' : '' ?>>
<?= htmlspecialchars($o['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="admin-form-row">
<label class="admin-label" for="ap">Atelier pluridisciplinaire :</label>
<select class="admin-select" id="ap" name="ap" required>
<?php foreach ($apPrograms as $ap): ?>
<option value="<?= $ap['id'] ?>"
<?= ($thesis['ap_program'] == $ap['name']) ? 'selected' : '' ?>>
<?= htmlspecialchars($ap['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="admin-form-row">
<label class="admin-label" for="finality">Finalité du master :</label>
<select class="admin-select" id="finality" name="finality" required>
<?php foreach ($finalityTypes as $f): ?>
<option value="<?= $f['id'] ?>"
<?= ($thesis['finality_type'] == $f['name']) ? 'selected' : '' ?>>
<?= htmlspecialchars($f['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="admin-form-row">
<label class="admin-label" for="promoteurice">Promoteur·ice(s) :</label>
<input class="admin-input" type="text" id="promoteurice" name="promoteurice"
value="<?= htmlspecialchars($thesis['supervisors'] ?? '') ?>">
</div>
<div class="admin-form-row">
<label class="admin-label" for="titre">Titre :</label>
<input class="admin-input" type="text" id="titre" name="titre"
value="<?= htmlspecialchars($thesis['title']) ?>" required>
</div>
<div class="admin-form-row">
<label class="admin-label" for="subtitle">Sous-titre :</label>
<input class="admin-input" type="text" id="subtitle" name="subtitle"
value="<?= htmlspecialchars($thesis['subtitle'] ?? '') ?>">
</div>
<div class="admin-form-row" style="align-items:start;">
<label class="admin-label" for="synopsis">Synopsis :</label>
<textarea class="admin-textarea" id="synopsis" name="synopsis" rows="7" required><?= htmlspecialchars($thesis['synopsis'] ?? '') ?></textarea>
</div>
<div class="admin-form-row">
<label class="admin-label">Langue(s) :</label>
<div class="admin-checkbox-list">
<?php foreach ($languages as $lang): ?>
<label class="admin-checkbox-label">
<input type="checkbox" name="languages[]" value="<?= $lang['id'] ?>"
<?= in_array($lang['id'], $currentLanguages) ? 'checked' : '' ?>>
<?= htmlspecialchars($lang['name']) ?>
</label>
<?php endforeach; ?>
</div>
</div>
<div class="admin-form-row">
<label class="admin-label">Format(s) :</label>
<div class="admin-checkbox-list">
<?php foreach ($formatTypes as $fmt): ?>
<label class="admin-checkbox-label">
<input type="checkbox" name="formats[]" value="<?= $fmt['id'] ?>"
<?= in_array($fmt['id'], $currentFormats) ? 'checked' : '' ?>>
<?= htmlspecialchars($fmt['name']) ?>
</label>
<?php endforeach; ?>
</div>
</div>
<div class="admin-form-row">
<label class="admin-label" for="tag">Mots-clés :</label>
<div>
<input class="admin-input" type="text" id="tag" name="tag"
value="<?= htmlspecialchars($thesis['keywords'] ?? '') ?>">
<p class="admin-hint">Séparer par des virgules. Max 10.</p>
</div>
</div>
<div class="admin-form-row">
<label class="admin-label" for="duration_info">Durée / Taille :</label>
<input class="admin-input" type="text" id="duration_info" name="duration_info"
value="<?= htmlspecialchars($thesis['file_size_info'] ?? '') ?>">
</div>
<div class="admin-form-row">
<label class="admin-label" for="lien">Lien externe :</label>
<input class="admin-input" type="url" id="lien" name="lien"
value="<?= htmlspecialchars($thesis['baiu_link'] ?? '') ?>">
</div>
<div class="admin-form-row">
<label class="admin-label">Publication :</label>
<label class="admin-checkbox-label">
<input type="checkbox" name="is_published" value="1"
<?= $thesis['is_published'] ? 'checked' : '' ?>>
Publier ce TFE sur le site public
</label>
</div>
<div class="admin-submit-wrap">
<button type="submit" class="admin-btn">Enregistrer</button>
<a href="/admin/thanks.php?id=<?= $thesisId ?>" class="admin-btn-secondary" style="margin-left:.75rem;">Annuler</a>
</div>
</form>
</main>
<?php require_once APP_ROOT . '/templates/admin/footer.php'; ?>