mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
403 lines
22 KiB
PHP
403 lines
22 KiB
PHP
<main id="main-content">
|
|
<h1>Modifier un TFE</h1>
|
|
|
|
<form method="post" action="/admin/actions/edit.php" class="admin-form" enctype="multipart/form-data">
|
|
<div class="admin-form-footer admin-form-footer--sticky">
|
|
<button type="submit" class="btn btn--primary">Enregistrer</button>
|
|
<a href="/admin/" class="btn btn--secondary admin-cancel-link">Annuler</a>
|
|
</div>
|
|
|
|
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
|
<input type="hidden" name="thesis_id" value="<?= $thesisId ?>">
|
|
|
|
<!-- ═══════════════════ Informations du TFE ═══════════════════ -->
|
|
<?php
|
|
$formData = array_merge($formData ?? [], ['contact_public' => $currentAuthorShowContact ?? false]);
|
|
$editOldFn = function (string $key, string $default = '') use ($thesis, $formData, $currentAuthorEmail) {
|
|
if (!empty($formData[$key])) return htmlspecialchars($formData[$key]);
|
|
$map = [
|
|
'titre' => htmlspecialchars($thesis['title']),
|
|
'subtitle' => htmlspecialchars($thesis['subtitle'] ?? ''),
|
|
'auteurice'=> htmlspecialchars($thesis['authors'] ?? ''),
|
|
'mail' => htmlspecialchars($currentAuthorEmail ?? ''),
|
|
'synopsis' => htmlspecialchars($thesis['synopsis'] ?? ''),
|
|
];
|
|
return $map[$key] ?? $default;
|
|
};
|
|
$editWithAutofocusFn = function (string $field, array $attrs = []) use ($autofocusField) {
|
|
if ($autofocusField === $field) $attrs['autofocus'] = true;
|
|
return $attrs;
|
|
};
|
|
$allowedObjet = [];
|
|
$synopsisExtra = '';
|
|
$oldFn = $editOldFn;
|
|
$withAutofocusFn = $editWithAutofocusFn;
|
|
include APP_ROOT . '/templates/partials/form/fieldset-tfe-info.php';
|
|
$formData = $_SESSION['form_data'] ?? [];
|
|
?>
|
|
|
|
<!-- Contact public checkbox (admin) -->
|
|
<fieldset>
|
|
<legend>Contact</legend>
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="contact_public" value="1"
|
|
<?= !empty($formData['contact_public']) || $currentAuthorShowContact ? 'checked' : '' ?>>
|
|
Rendre le contact visible publiquement sur la fiche du TFE
|
|
</label>
|
|
<small>L'adresse est toujours conservée en interne comme contact de référence.</small>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Langue(s) ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Langue(s)</legend>
|
|
<?php
|
|
$checkedLanguages = $formData['languages'] ?? $currentLanguages;
|
|
$name = 'languages'; $label = 'Langue(s) du TFE :'; $options = $languages; $checked = $checkedLanguages; $required = true;
|
|
include APP_ROOT . '/templates/partials/form/checkbox-list.php';
|
|
?>
|
|
<?php $name = 'language_autre'; $label = 'Autre(s) langue(s) :'; $value = old('language_autre'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Mots-clés ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Mots-clés</legend>
|
|
<?php
|
|
$editKwFormData = ['tag' => $thesis['keywords'] ?? ''];
|
|
$editKwOldFn = fn(string $key, string $default = '') => isset($editKwFormData[$key]) ? htmlspecialchars((string)$editKwFormData[$key]) : $default;
|
|
$oldFn = $editKwOldFn; $withAutofocusFn = $editWithAutofocusFn; $formData = $editKwFormData;
|
|
$name = 'tag'; $label = 'Mots-clés (max 10) :'; $value = $editKwOldFn('tag');
|
|
$placeholder = 'sociologie, anthropologie, ...';
|
|
$hint = 'Séparez par des virgules. Max 10 mots-clés.';
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Cadre académique ═══════════════════ -->
|
|
<?php
|
|
$editFormData = [
|
|
'année' => $thesis['year'],
|
|
'orientation' => $thesis['orientation'],
|
|
'ap' => $thesis['ap_program'],
|
|
'finality' => $thesis['finality_type'],
|
|
];
|
|
$editAcademicOldFn = function (string $key, string $default = '') use ($editFormData) {
|
|
return isset($editFormData[$key]) && !is_array($editFormData[$key])
|
|
? htmlspecialchars((string)$editFormData[$key]) : $default;
|
|
};
|
|
$oldFn = $editAcademicOldFn;
|
|
$withAutofocusFn = $editWithAutofocusFn;
|
|
$formData = $editFormData;
|
|
include APP_ROOT . '/templates/partials/form/fieldset-academic.php';
|
|
?>
|
|
|
|
<!-- ═══════════════════ Composition du jury ═══════════════════ -->
|
|
<?php
|
|
$juryPromoteur = null;
|
|
$juryPromoteurUlb = null;
|
|
$lecteursInternes = [];
|
|
$lecteursExternes = [];
|
|
$juryPresident = null;
|
|
foreach ($jury as $jm) {
|
|
if ($jm['role'] === 'president') {
|
|
$juryPresident = $jm['name'];
|
|
} elseif ($jm['role'] === 'promoteur') {
|
|
if (($jm['is_ulb'] ?? 0) == 1) {
|
|
$juryPromoteurUlb = $jm['name'];
|
|
} else {
|
|
$juryPromoteur = $jm['name'];
|
|
}
|
|
} elseif ($jm['role'] === 'lecteur') {
|
|
if (($jm['is_external'] ?? 0) == 1) {
|
|
$lecteursExternes[] = $jm;
|
|
} else {
|
|
$lecteursInternes[] = $jm;
|
|
}
|
|
}
|
|
}
|
|
$showPresident = true;
|
|
$showPromoteurUlb = true;
|
|
$promoteurUlbConditional = false;
|
|
require APP_ROOT . '/templates/partials/form/jury-fieldset.php';
|
|
?>
|
|
|
|
<!-- ═══════════════════ Format(s) ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Format(s)</legend>
|
|
<?php
|
|
$checkedFormats = $formData['formats'] ?? $currentFormats ?? [];
|
|
$name = 'formats'; $label = 'Format(s) du TFE :'; $options = $formatTypes; $checked = $checkedFormats; $required = true;
|
|
$hxPost = '/partage/format-website-fragment';
|
|
$hxTarget = '#website-url-fieldset';
|
|
// Capture before include unsets it
|
|
$_checkedFormatsForSiteWeb = $checked;
|
|
include APP_ROOT . '/templates/partials/form/checkbox-list.php';
|
|
?>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Fichiers ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Fichiers</legend>
|
|
|
|
<!-- Cover image -->
|
|
<div class="admin-form-group">
|
|
<label>Image de couverture :</label>
|
|
<div class="admin-file-input">
|
|
<?php if (!empty($currentCover)): ?>
|
|
<div class="admin-banner-preview">
|
|
<img src="/media.php?path=<?= urlencode($currentCover['file_path']) ?>"
|
|
alt="Couverture actuelle" style="max-height:180px;">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="remove_cover" value="1"> Supprimer la couverture
|
|
</label>
|
|
</div>
|
|
<?php endif; ?>
|
|
<input type="file" id="couverture" name="couverture" accept="image/jpeg,image/png" data-preview="fp-couverture">
|
|
<div id="fp-couverture" class="file-preview-list" aria-live="polite"></div>
|
|
<small><?= empty($currentCover) ? 'JPG, PNG. Format 4:3 recommandé. Max 20 MB.' : 'Laisser vide pour conserver la couverture actuelle. JPG, PNG. Max 20 MB.' ?></small>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Existing thesis files — sortable, with labels -->
|
|
<?php $thesisFilesList = array_values(array_filter($currentFiles, fn($f) => $f['file_type'] !== 'cover')); ?>
|
|
<?php if (!empty($thesisFilesList)): ?>
|
|
<div class="admin-form-group">
|
|
<label>Fichiers du TFE existants :</label>
|
|
<small style="display:block;margin-bottom:var(--space-2xs);color:var(--text-tertiary)">
|
|
Glissez-déposez les lignes pour réordonner les fichiers sur la page publique.
|
|
</small>
|
|
<ul id="existing-files-sortable" class="admin-file-list sortable-list">
|
|
<?php foreach ($thesisFilesList as $f):
|
|
$fExt = strtolower(pathinfo($f['file_path'] ?? '', PATHINFO_EXTENSION));
|
|
$fType = $f['file_type'] ?? 'other';
|
|
$fIcon = match(true) {
|
|
$fType === 'main' || $fExt === 'pdf' => '📄',
|
|
in_array($fExt, ['jpg','jpeg','png','gif','webp']) => '🖼️',
|
|
$fType === 'video' || in_array($fExt, ['mp4','webm','mov','ogv']) => '🎬',
|
|
$fType === 'audio' || in_array($fExt, ['mp3','ogg','wav','flac','aac','m4a']) => '🔊',
|
|
$fType === 'caption' || $fExt === 'vtt' => '💬',
|
|
$fType === 'website' => '🌐',
|
|
default => '📎',
|
|
};
|
|
$isExternalUrl = str_starts_with($f['file_path'] ?? '', 'http://') || str_starts_with($f['file_path'] ?? '', 'https://');
|
|
$fLinkHref = $isExternalUrl
|
|
? htmlspecialchars($f['file_path'])
|
|
: ('/media.php?path=' . urlencode($f['file_path']));
|
|
?>
|
|
<li class="admin-file-list-item" data-file-id="<?= (int)$f['id'] ?>">
|
|
<input type="hidden" name="file_sort_order[]" value="<?= (int)$f['id'] ?>">
|
|
<span class="admin-file-drag-handle" title="Réordonner">⠿</span>
|
|
<span class="admin-file-icon-col"><?= $fIcon ?></span>
|
|
<span class="admin-file-info">
|
|
<a href="<?= $fLinkHref ?>" target="_blank" rel="noopener" class="admin-file-name">
|
|
<?= htmlspecialchars($f['file_name'] ?? basename($f['file_path'])) ?>
|
|
</a>
|
|
<span class="admin-file-meta-row">
|
|
<span class="admin-file-type-badge"><?= htmlspecialchars($fType) ?></span>
|
|
<?php if (!empty($f['file_size']) && $f['file_size'] > 0): ?>
|
|
<span class="admin-file-size"><?= number_format($f['file_size'] / 1024 / 1024, 2) ?> MB</span>
|
|
<?php endif; ?>
|
|
</span>
|
|
<input type="text" name="file_label[<?= (int)$f['id'] ?>]"
|
|
value="<?= htmlspecialchars($f['display_label'] ?? '') ?>"
|
|
placeholder="Légende / description (optionnel)"
|
|
class="admin-file-label-input">
|
|
</span>
|
|
<label class="admin-checkbox-label admin-file-delete">
|
|
<input type="checkbox" name="delete_files[]" value="<?= (int)$f['id'] ?>"> Supprimer
|
|
</label>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- New thesis files -->
|
|
<div class="admin-form-group admin-files-fieldgroup">
|
|
<label>Ajouter des fichiers du TFE :</label>
|
|
<div class="admin-file-input">
|
|
<input type="file" id="tfe-files-input"
|
|
name="files[]" multiple
|
|
accept=".pdf,.jpg,.jpeg,.png,.gif,.webp,.mp4,.webm,.mov,.ogv,.mp3,.ogg,.oga,.wav,.flac,.aac,.m4a,.zip,.tar,.gz,.vtt"
|
|
class="tfe-file-picker">
|
|
<small class="admin-file-hint">
|
|
Types acceptés : PDF · JPG/PNG/GIF/WEBP · MP4/WebM/MOV (vidéo) · MP3/OGG/WAV/FLAC (audio) · ZIP/TAR (archives) · autres fichiers (téléchargement uniquement). Max 500 MB par fichier.
|
|
</small>
|
|
<ul id="tfe-file-queue" class="tfe-file-queue sortable-list" aria-label="Nouveaux fichiers (réordonnable)"></ul>
|
|
<p id="tfe-file-queue-empty" class="tfe-queue-empty">Aucun nouveau fichier sélectionné.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Banner image -->
|
|
<div class="admin-form-group">
|
|
<label>Image bannière (accueil) :</label>
|
|
<div class="admin-file-input">
|
|
<?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" id="banner" accept="image/jpeg,image/png,image/webp" data-preview="fp-banner">
|
|
<div id="fp-banner" class="file-preview-list" aria-live="polite"></div>
|
|
<small><?= empty($thesis['banner_path']) ? 'JPG, PNG ou WEBP. Format paysage recommandé (4:1). Max 20 MB.' : 'Laisser vide pour conserver la bannière actuelle. JPG, PNG ou WEBP. Format paysage recommandé (4:1). Max 20 MB.' ?></small>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<!-- Website URL fieldset — shown/hidden via HTMX when "Site web" checked -->
|
|
<?php
|
|
// Extract existing website URL/label from thesis_files for initial render
|
|
$existingWebsite = null;
|
|
$existingWebsiteLabel = '';
|
|
foreach ($currentFiles as $f) {
|
|
if ($f['file_type'] === 'website') {
|
|
$existingWebsite = $f['file_path'] ?? '';
|
|
$existingWebsiteLabel = $f['display_label'] ?? '';
|
|
break;
|
|
}
|
|
}
|
|
?>
|
|
<fieldset id="website-url-fieldset" style="display:none">
|
|
<legend>Site web</legend>
|
|
|
|
<div class="admin-form-group">
|
|
<label for="website_url">URL du site :</label>
|
|
<div class="admin-file-input">
|
|
<input type="url"
|
|
id="website_url"
|
|
name="website_url"
|
|
value="<?= htmlspecialchars($existingWebsite ?? '') ?>"
|
|
placeholder="https://mon-tfe.erg.be">
|
|
<small>Si le TFE est un site web, entrez son URL ici. Il sera affiché comme un site embarqué sur la page du TFE.</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="admin-form-group">
|
|
<label for="website_label">Légende :</label>
|
|
<input type="text"
|
|
id="website_label"
|
|
name="website_label"
|
|
value="<?= htmlspecialchars($existingWebsiteLabel) ?>"
|
|
placeholder="Description du site (optionnel)"
|
|
class="admin-file-label-input"
|
|
style="max-width:400px;">
|
|
</div>
|
|
</fieldset>
|
|
<?php
|
|
// Server-side: show if Site web already checked
|
|
$_stmt = Database::getInstance()->getConnection()->prepare('SELECT id FROM format_types WHERE name = ? LIMIT 1');
|
|
$_stmt->execute(['Site web']);
|
|
$_siteWebId = $_stmt->fetchColumn();
|
|
if ($_siteWebId && in_array((string)$_siteWebId, array_map('strval', $_checkedFormatsForSiteWeb), true)) {
|
|
echo '<script>document.getElementById("website-url-fieldset").style.display=""</script>';
|
|
}
|
|
?>
|
|
|
|
<!-- ═══════════════════ Métadonnées complémentaires ═══════════════════ -->
|
|
<?php
|
|
$editMetaFormData = [
|
|
'duration_pages' => $currentRaw['duration_pages'] ?? '',
|
|
'duration_minutes' => $currentRaw['duration_minutes'] ?? '',
|
|
'lien' => $thesis['baiu_link'] ?? '',
|
|
];
|
|
$editMetaOldFn = function (string $key, string $default = '') use ($editMetaFormData) {
|
|
return isset($editMetaFormData[$key]) ? htmlspecialchars((string)$editMetaFormData[$key]) : $default;
|
|
};
|
|
$oldFn = $editMetaOldFn;
|
|
$withAutofocusFn = $editWithAutofocusFn;
|
|
$formData = $editMetaFormData;
|
|
include APP_ROOT . '/templates/partials/form/fieldset-metadata.php';
|
|
?>
|
|
|
|
<!-- ═══════════════════ Degrés d'ouverture et licences ═══════════════════ -->
|
|
<?php
|
|
$formData = $_SESSION['form_data'] ?? [];
|
|
$libreEnabled = true; // always shown in admin
|
|
$interneEnabled = true;
|
|
$interditEnabled = true;
|
|
$generalitiesHtml = $helpFn('fieldset_generalites');
|
|
$defaultAccessTypeId = $currentAccessTypeId ?? 2;
|
|
$formData['access_type_id'] = $currentAccessTypeId;
|
|
$formData['license_id'] = $currentLicenseId;
|
|
$formData['license_custom'] = $currentRaw['license_custom'] ?? '';
|
|
$formData['cc2r'] = $currentRaw['cc4r'] ?? false;
|
|
include APP_ROOT . '/templates/partials/form/fieldset-licence-explanation.php';
|
|
?>
|
|
|
|
<!-- ═══════════════════ Note contextuelle ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Note contextuelle</legend>
|
|
<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>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Backoffice ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Backoffice</legend>
|
|
|
|
<div class="admin-form-group">
|
|
<label for="jury_points">Points :</label>
|
|
<input type="number" id="jury_points" name="jury_points"
|
|
value="<?= htmlspecialchars($currentRaw['jury_points'] ?? '') ?>"
|
|
step="0.01" min="0" max="20" placeholder="sur 20">
|
|
<small>Note du jury (interne, non visible publiquement).</small>
|
|
</div>
|
|
|
|
<div class="admin-form-group">
|
|
<label for="remarks">Remarques :</label>
|
|
<textarea id="remarks" name="remarks" rows="4"><?= htmlspecialchars($currentRaw['remarks'] ?? '') ?></textarea>
|
|
<small>Notes internes (non visibles publiquement).</small>
|
|
</div>
|
|
|
|
<div class="admin-form-group">
|
|
<label for="contact_interne">Contact interne :</label>
|
|
<input type="email" id="contact_interne" name="contact_interne"
|
|
value="<?= htmlspecialchars($currentRaw['contact_interne'] ?? $currentAuthorEmail ?? '') ?>"
|
|
placeholder="ton.email@exemple.be">
|
|
<small>Adresse de contact interne (non visible publiquement).</small>
|
|
</div>
|
|
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="exemplaire_baiu" value="1"
|
|
<?= !empty($currentRaw['exemplaire_baiu']) ? 'checked' : '' ?>>
|
|
Exemplaire physique BAIU
|
|
</label>
|
|
<small>Case logistique : cocher si un exemplaire physique est disponible à la BAIU.</small>
|
|
</div>
|
|
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="exemplaire_erg" value="1"
|
|
<?= !empty($currentRaw['exemplaire_erg']) ? 'checked' : '' ?>>
|
|
Exemplaire physique ERG
|
|
</label>
|
|
<small>Case logistique : cocher si un exemplaire physique est disponible à l'ERG.</small>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Publication ════════════════════════ -->
|
|
<fieldset>
|
|
<legend>Publication</legend>
|
|
<div>
|
|
<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>
|
|
</fieldset>
|
|
|
|
</form>
|
|
</main>
|