mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
- Updated 6 admin templates: add.php, edit.php, login.php, account.php,
import.php, pages-edit.php — replaced <div class="admin-submit-wrap">
with <div class="admin-form-footer">
- Updated 8 CSS selectors in admin.css:
- .admin-form-footer { margin-top/padding-top } (was .admin-submit-wrap)
- .admin-form > div:not(.admin-form-footer) grid exclusion guard (×3)
- .admin-login-box .admin-form > div:not(.admin-form-footer) overrides (×2)
- .admin-login-box .admin-form-footer compact spacing override
- No visual change; purely a semantic rename to a descriptive class name
- Also marked status-badge.php partial and WCAG 1.3.1 badge tasks as
already-done in todo/02-php-components.md and todo/04-accessibility.md
(partial + CSS were fully implemented but todo had not been updated)
187 lines
9.0 KiB
PHP
187 lines
9.0 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;
|
|
|
|
if ($thesisId <= 0) {
|
|
die("ID invalide");
|
|
}
|
|
|
|
// Flash messages are consumed by the flash-messages partial below.
|
|
|
|
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 include APP_ROOT . '/templates/partials/flash-messages.php'; ?>
|
|
|
|
<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 ?>">
|
|
|
|
<?php $name = 'auteurice'; $label = 'Auteur·ice(s) :'; $value = htmlspecialchars($thesis['authors']); $required = true; $attrs = ['autocomplete' => 'name']; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
<?php $name = 'mail'; $label = 'Contact :'; $value = ''; $attrs = ['autocomplete' => 'email']; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
|
|
<?php
|
|
$name = 'année'; $label = 'Année :'; $value = htmlspecialchars((string)$thesis['year']); $required = true;
|
|
$type = 'number';
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
|
|
<?php $name = 'orientation'; $label = 'Orientation :'; $options = $orientations; $selected = $thesis['orientation']; $required = true; $placeholder = null; include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
|
|
|
<?php $name = 'ap'; $label = 'Atelier pluridisciplinaire :'; $options = $apPrograms; $selected = $thesis['ap_program']; $required = true; $placeholder = null; include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
|
|
|
<?php $name = 'finality'; $label = 'Finalité du master :'; $options = $finalityTypes; $selected = $thesis['finality_type']; $required = true; $placeholder = null; include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
|
|
|
<!-- 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'; ?>
|
|
|
|
<?php
|
|
// Access type select: options need 'id'+'name'; description appended inline
|
|
$accessOptions = array_map(function($at) {
|
|
$label = $at['name'];
|
|
if (!empty($at['description'])) {
|
|
$label .= ' - ' . mb_strimwidth($at['description'], 0, 60, '...');
|
|
}
|
|
return ['id' => $at['id'], 'name' => $label];
|
|
}, $accessTypes);
|
|
$name = 'access_type_id'; $label = 'Visibilité / Accès :'; $options = $accessOptions; $selected = $currentAccessTypeId; $placeholder = '- Non défini -';
|
|
include APP_ROOT . '/templates/partials/form/select-field.php';
|
|
?>
|
|
|
|
<!-- Context note (textarea — no text-field partial for textarea) -->
|
|
<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>
|
|
|
|
<?php $name = 'license_id'; $label = 'Licence :'; $options = $licenseTypes; $selected = $currentLicenseId; $placeholder = '- Inconnue -'; include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
|
|
|
<?php $name = 'titre'; $label = 'Titre :'; $value = htmlspecialchars($thesis['title']); $required = true; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
<?php $name = 'subtitle'; $label = 'Sous-titre :'; $value = htmlspecialchars($thesis['subtitle'] ?? ''); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
|
|
<!-- Synopsis (textarea — not covered by text-field partial) -->
|
|
<div>
|
|
<label for="synopsis">Synopsis :</label>
|
|
<textarea id="synopsis" name="synopsis" rows="7" required><?= htmlspecialchars($thesis['synopsis'] ?? '') ?></textarea>
|
|
</div>
|
|
|
|
<?php $name = 'languages'; $label = 'Langue(s) :'; $options = $languages; $checked = $currentLanguages; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
|
|
|
|
<?php $name = 'formats'; $label = 'Format(s) :'; $options = $formatTypes; $checked = $currentFormats; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
|
|
|
|
<?php $name = 'tag'; $label = 'Mots-clés :'; $value = htmlspecialchars($thesis['keywords'] ?? ''); $hint = 'Séparer par des virgules. Max 10.'; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
|
|
<?php $name = 'duration_info'; $label = 'Durée / Taille :'; $value = htmlspecialchars($thesis['file_size_info'] ?? ''); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
|
|
<?php $name = 'lien'; $label = 'Lien externe :'; $value = htmlspecialchars($thesis['baiu_link'] ?? ''); $type = 'url'; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
|
|
<!-- Image bannière (custom: includes current banner preview + remove checkbox) -->
|
|
<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>
|
|
|
|
<!-- Publication toggle -->
|
|
<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-form-footer">
|
|
<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'; ?>
|