Files
xamxam/public/admin/edit.php
Pontoporeia 0ab08f3aa0 admin.css: replace .admin-main, .admin-page-title, .admin-table, .admin-fieldset with semantic selectors
Replace four presentational class names in admin.css with structural selectors
that target native HTML elements already present in every admin template:

  .admin-main           → .admin-body main
  .admin-page-title     → .admin-body main > h1
  .admin-table          → .admin-body table
  .admin-fieldset       → .admin-body fieldset
  .admin-fieldset-legend → .admin-body legend

Also migrate the .admin-main > section / h2 / dl / dt / dd block to
.admin-body main > section so the thanks-page section styles survive.

Add .admin-body main > table { margin-top: 1.5rem } to absorb the inline
style="margin-top:1.5rem" that was on tags.php's <table class="admin-table">.

All 10 affected admin templates updated (add, edit, account, index, import,
pages, pages-edit, tags, system, thanks) — class attributes removed where
the element alone is now the selector.  Zero visual changes.
2026-04-02 12:16:59 +02:00

360 lines
16 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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;
if ($thesisId <= 0) {
die("ID invalide");
}
// Consume flash messages from the edit action
$error = $_SESSION['edit_error'] ?? null;
$success = $_SESSION['edit_success'] ?? null;
unset($_SESSION['edit_error'], $_SESSION['edit_success']);
try {
$db = new Database();
// Load thesis data
$thesis = $db->getThesis($thesisId);
if (!$thesis) {
die("TFE non trouvé");
}
// Load current relationships via dedicated DB methods (no raw PDO)
$currentLanguages = $db->getThesisLanguageIds($thesisId);
$currentFormats = $db->getThesisFormatIds($thesisId);
$jury = $db->getThesisJury($thesisId);
// Reference / lookup data
$orientations = $db->getAllOrientations();
$apPrograms = $db->getAllAPPrograms();
$finalityTypes = $db->getAllFinalityTypes();
$languages = $db->getAllLanguages();
$formatTypes = $db->getAllFormatTypes();
$licenseTypes = $db->getAllLicenseTypes();
$accessTypes = $db->getAccessTypes();
// Fetch raw FK IDs (view only exposes name strings)
$rawRow = $db->getThesisRawFields($thesisId);
$currentLicenseId = $rawRow['license_id'] ?? null;
$currentAccessTypeId = $rawRow['access_type_id'] ?? null;
$currentContextNote = $rawRow['context_note'] ?? '';
// 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 $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main id="main-content">
<h1>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="/admin/actions/edit.php" class="admin-form" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="thesis_id" value="<?= $thesisId ?>">
<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>
<!-- Composition du jury -->
<?php
$juryPresident = null;
$juryPromoteur = null;
$juryPromoteurExt = 0;
$juryLecteurs = [];
foreach ($jury as $jm) {
if ($jm['role'] === 'president') {
$juryPresident = $jm['name'];
} elseif ($jm['role'] === 'promoteur') {
$juryPromoteur = $jm['name'];
$juryPromoteurExt = (int)$jm['is_external'];
} elseif ($jm['role'] === 'lecteur') {
$juryLecteurs[] = $jm;
}
}
?>
<fieldset>
<legend>Composition du jury</legend>
<div class="admin-form-row">
<label class="admin-label" for="jury_president">Président·e :</label>
<input class="admin-input" type="text" id="jury_president" name="jury_president"
value="<?= htmlspecialchars($juryPresident ?? '') ?>"
placeholder="Nom (interne)">
</div>
<div class="admin-form-row">
<label class="admin-label" for="jury_promoteur">Promoteur·ice :</label>
<div class="admin-jury-row">
<input class="admin-input" type="text" id="jury_promoteur" name="jury_promoteur"
value="<?= htmlspecialchars($juryPromoteur ?? '') ?>" placeholder="Nom">
<label class="admin-checkbox-label admin-jury-ext">
<input type="checkbox" name="jury_promoteur_ext" value="1"
<?= $juryPromoteurExt ? 'checked' : '' ?>> Externe
</label>
</div>
</div>
<div class="admin-form-row">
<label class="admin-label">Lecteur·ices :</label>
<div>
<div id="jury-lecteurs-list" class="admin-jury-list">
<?php if (empty($juryLecteurs)): ?>
<div class="admin-jury-entry">
<input class="admin-input" type="text" name="jury_lecteurs[]" placeholder="Nom">
<label class="admin-checkbox-label admin-jury-ext">
<input type="checkbox" name="jury_lecteurs_ext[0]" value="1"> Externe
</label>
<button type="button" class="admin-btn-remove" onclick="removeJuryRow(this)" aria-label="Supprimer ce lecteur">✕</button>
</div>
<?php else: ?>
<?php foreach ($juryLecteurs as $li => $lm): ?>
<div class="admin-jury-entry">
<input class="admin-input" type="text" name="jury_lecteurs[]"
value="<?= htmlspecialchars($lm['name']) ?>" placeholder="Nom">
<label class="admin-checkbox-label admin-jury-ext">
<input type="checkbox" name="jury_lecteurs_ext[<?= $li ?>]" value="1"
<?= $lm['is_external'] ? 'checked' : '' ?>> Externe
</label>
<button type="button" class="admin-btn-remove" onclick="removeJuryRow(this)" aria-label="Supprimer ce lecteur">✕</button>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<button type="button" class="admin-btn-secondary admin-add-jury-btn"
onclick="addJuryRow()">+ Ajouter un·e lecteur·ice</button>
</div>
</div>
</fieldset>
<script>
var juryIdx = <?= max(count($juryLecteurs), 1) ?>;
function addJuryRow() {
var list = document.getElementById('jury-lecteurs-list');
var div = document.createElement('div');
div.className = 'admin-jury-entry';
div.innerHTML = '<input class="admin-input" type="text" name="jury_lecteurs[]" placeholder="Nom">'
+ '<label class="admin-checkbox-label admin-jury-ext">'
+ '<input type="checkbox" name="jury_lecteurs_ext[' + juryIdx + ']" value="1"> Externe'
+ '</label>'
+ '<button type="button" class="admin-btn-remove" onclick="removeJuryRow(this)" aria-label="Supprimer ce lecteur">✕</button>';
list.appendChild(div);
juryIdx++;
}
function removeJuryRow(btn) {
btn.closest('.admin-jury-entry').remove();
}
</script>
<div class="admin-form-row">
<label class="admin-label" for="access_type_id">Visibilité / Accès :</label>
<select class="admin-select" id="access_type_id" name="access_type_id">
<option value="">- Non défini -</option>
<?php foreach ($accessTypes as $at): ?>
<option value="<?= (int)$at['id'] ?>"
<?= ($currentAccessTypeId == $at['id']) ? 'selected' : '' ?>>
<?= htmlspecialchars($at['name']) ?>
<?php if (!empty($at['description'])): ?>
- <?= htmlspecialchars(mb_strimwidth($at['description'], 0, 60, '...')) ?>
<?php endif; ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="admin-form-row">
<label class="admin-label" for="context_note">Note contextuelle :</label>
<div>
<textarea class="admin-textarea" id="context_note" name="context_note"
rows="4" maxlength="1500"><?= htmlspecialchars($currentContextNote ?? '') ?></textarea>
<small>Visible publiquement pour les TFE Interne ou Interdit. Max 1 500 caractères.</small>
</div>
</div>
<div class="admin-form-row">
<label class="admin-label" for="license_id">Licence :</label>
<select class="admin-select" id="license_id" name="license_id">
<option value="">- Inconnue -</option>
<?php foreach ($licenseTypes as $lt): ?>
<option value="<?= $lt['id'] ?>"
<?= ($currentLicenseId == $lt['id']) ? 'selected' : '' ?>>
<?= htmlspecialchars($lt['name']) ?>
</option>
<?php endforeach; ?>
</select>
</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">
<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'] ?? '') ?>">
<small>Séparer par des virgules. Max 10.</small>
</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>
<!-- Image bannière -->
<div class="admin-form-row">
<label class="admin-label">Image bannière (accueil) :</label>
<div>
<?php if (!empty($thesis['banner_path'])): ?>
<div class="admin-banner-preview">
<img src="/media.php?path=<?= urlencode($thesis['banner_path']) ?>"
alt="Bannière actuelle">
<label class="admin-checkbox-label">
<input type="checkbox" name="remove_banner" value="1"> Supprimer la bannière
</label>
</div>
<?php endif; ?>
<input type="file" name="banner" accept="image/jpeg,image/png,image/webp">
<small>JPG, PNG ou WEBP. Format paysage recommandé (4:1). Max 5 MB.</small>
</div>
</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 admin-cancel-link">Annuler</a>
</div>
</form>
</main>
<?php require_once APP_ROOT . '/templates/admin/footer.php'; ?>