Files
xamxam/public/admin/edit.php
Pontoporeia c8a3cc0ff2 css: replace admin-form-row/admin-label/admin-input/select/textarea classes with semantic selectors
Remove five presentational classes from admin forms and replace with
structural CSS selectors scoped to .admin-form:

- .admin-form-row  → .admin-form > div:not(.admin-submit-wrap)
  Grid layout (260px label col + 1fr input col) applied directly to div
  children of the form; submit-wrap div excluded via :not().

- .admin-label     → .admin-form > div:not(.admin-submit-wrap) > label
  Scoped to the direct label child of each form row div; does not bleed
  into nested checkbox labels inside .admin-checkbox-list.

- .admin-input / .admin-select / .admin-textarea
  → .admin-form input:not([type=checkbox|radio|file|hidden|submit])
  → .admin-form select
  → .admin-form textarea
  Also extended to .admin-inline-form input/select (tags page) so the
  tags table inputs retain identical base styling and focus colour.

Templates updated: add.php, edit.php, login.php, account.php,
pages-edit.php, import.php, tags.php,
templates/partials/form/jury-fieldset.php — all class= attributes for
the five removed classes stripped.

import.php: added 'admin-form' class alongside 'admin-import-area' so
its single file-input row gets the grid row treatment; submit div was
already using admin-submit-wrap so it is correctly excluded.

No visual change — selectors target the same elements as before.
2026-04-02 12:42:49 +02:00

290 lines
11 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): ?>
<p role="alert" data-type="error">⚠ <?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<?php if ($success): ?>
<p role="status" data-type="success">✓ <?= htmlspecialchars($success) ?></p>
<?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>
<label for="auteurice">Auteur·ice(s) :</label>
<input type="text" id="auteurice" name="auteurice"
value="<?= htmlspecialchars($thesis['authors']) ?>" required>
</div>
<div>
<label for="mail">Contact :</label>
<input type="text" id="mail" name="mail" value="">
</div>
<div>
<label for="année">Année :</label>
<input type="number" id="année" name="année"
value="<?= $thesis['year'] ?>" required>
</div>
<div>
<label for="orientation">Orientation :</label>
<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>
<label for="ap">Atelier pluridisciplinaire :</label>
<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>
<label for="finality">Finalité du master :</label>
<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;
}
}
?>
<?php require APP_ROOT . '/templates/partials/form/jury-fieldset.php'; ?>
<div>
<label for="access_type_id">Visibilité / Accès :</label>
<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>
<label for="context_note">Note contextuelle :</label>
<div>
<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>
<label for="license_id">Licence :</label>
<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>
<label for="titre">Titre :</label>
<input type="text" id="titre" name="titre"
value="<?= htmlspecialchars($thesis['title']) ?>" required>
</div>
<div>
<label for="subtitle">Sous-titre :</label>
<input type="text" id="subtitle" name="subtitle"
value="<?= htmlspecialchars($thesis['subtitle'] ?? '') ?>">
</div>
<div>
<label for="synopsis">Synopsis :</label>
<textarea id="synopsis" name="synopsis" rows="7" required><?= htmlspecialchars($thesis['synopsis'] ?? '') ?></textarea>
</div>
<div>
<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>
<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>
<label for="tag">Mots-clés :</label>
<div>
<input type="text" id="tag" name="tag"
value="<?= htmlspecialchars($thesis['keywords'] ?? '') ?>">
<small>Séparer par des virgules. Max 10.</small>
</div>
</div>
<div>
<label for="duration_info">Durée / Taille :</label>
<input type="text" id="duration_info" name="duration_info"
value="<?= htmlspecialchars($thesis['file_size_info'] ?? '') ?>">
</div>
<div>
<label for="lien">Lien externe :</label>
<input type="url" id="lien" name="lien"
value="<?= htmlspecialchars($thesis['baiu_link'] ?? '') ?>">
</div>
<!-- Image bannière -->
<div>
<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>
<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'; ?>