Add website-type TFE support: URLs stored as thesis_files rows, HTMX-toggle on Site web format

This commit is contained in:
Pontoporeia
2026-05-07 21:24:46 +02:00
parent 9dc7ea98f2
commit ac0008df6c
10 changed files with 399 additions and 39 deletions

View File

@@ -36,12 +36,6 @@
<?php $name = 'language_autre'; $label = 'Autre(s) langue(s) :'; $value = old('language_autre'); $hint = 'Si votre TFE contient une langue absente de la liste, précisez-la ici.'; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
</fieldset>
<!-- ═══════════════════ Format(s) ═══════════════════ -->
<fieldset>
<legend>Format(s)</legend>
<?php $name = 'formats'; $label = 'Format(s) du TFE :'; $options = $formatTypes; $checked = $formData['formats'] ?? []; $required = true; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
</fieldset>
<!-- ═══════════════════ Mots-clés ═══════════════════ -->
<fieldset>
<legend>Mots-clés</legend>
@@ -74,9 +68,59 @@
require APP_ROOT . '/templates/partials/form/jury-fieldset.php';
?>
<!-- ═══════════════════ Format(s) ═══════════════════ -->
<fieldset>
<legend>Format(s)</legend>
<?php
$name = 'formats'; $label = 'Format(s) du TFE :'; $options = $formatTypes; $checked = $formData['formats'] ?? []; $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 ═══════════════════ -->
<?php include APP_ROOT . '/templates/partials/form/fieldset-files.php'; ?>
<!-- Website URL fieldset — shown/hidden via HTMX when "Site web" checked -->
<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($formData['website_url'] ?? '') ?>"
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($formData['website_label'] ?? '') ?>"
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 (e.g. on error redirect)
$_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
$oldFn = 'old';

View File

@@ -60,16 +60,6 @@
<?php $name = 'language_autre'; $label = 'Autre(s) langue(s) :'; $value = old('language_autre'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
</fieldset>
<!-- ═══════════════════ 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;
include APP_ROOT . '/templates/partials/form/checkbox-list.php';
?>
</fieldset>
<!-- ═══════════════════ Mots-clés ═══════════════════ -->
<fieldset>
<legend>Mots-clés</legend>
@@ -132,6 +122,20 @@
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>
@@ -173,20 +177,25 @@
$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="/media.php?path=<?= urlencode($f['file_path']) ?>" target="_blank" rel="noopener" class="admin-file-name">
<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'])): ?>
<?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>
@@ -239,6 +248,55 @@
</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 = [

View File

@@ -13,21 +13,33 @@
* array $options — each element must have 'id' and 'name' keys
* array $checked — array of 'id' values that are currently checked
* bool $required — whether at least one checkbox must be checked; default false
* string $hxPost — optional hx-post URL for HTMX live update
* string $hxTarget — optional hx-target CSS selector for HTMX swap
*/
$checked = $checked ?? [];
$required = $required ?? false;
$checked = $checked ?? [];
$required = $required ?? false;
$hxPost = $hxPost ?? '';
$hxTarget = $hxTarget ?? '';
?>
<div>
<span class="admin-row-label"><?= htmlspecialchars($label) ?><?= $required ? ' <span class="asterisk">*</span>' : '' ?></span>
<fieldset class="admin-checkbox-group"<?= $required ? ' required aria-required="true"' : '' ?>>
<fieldset class="admin-checkbox-group"
<?= $required ? ' required aria-required="true"' : '' ?>
<?php if ($hxPost !== ''): ?>
hx-post="<?= htmlspecialchars($hxPost) ?>"
hx-target="<?= htmlspecialchars($hxTarget) ?>"
hx-trigger="change"
hx-include="this, #website-url-fieldset"
hx-swap="outerHTML"
<?php endif; ?>>
<legend class="sr-only"><?= htmlspecialchars($label) ?></legend>
<ul>
<?php foreach ($options as $opt): ?>
<li>
<label class="admin-checkbox-label">
<input type="checkbox"
name="<?= htmlspecialchars($name) ?>[]"
name="<?= htmlspecialchars($name) ?>[]"
value="<?= htmlspecialchars((string)$opt['id']) ?>"
<?= in_array((string)$opt['id'], array_map('strval', $checked)) ? 'checked' : '' ?>>
<?= htmlspecialchars($opt['name']) ?>
@@ -38,4 +50,4 @@ $required = $required ?? false;
</fieldset>
</div>
<?php
unset($checked);
unset($checked, $hxPost, $hxTarget);

View File

@@ -438,11 +438,12 @@
if ($fileType === 'cover') continue;
// Determine display category
$isImage = in_array($ext, ['jpg','jpeg','png','gif','bmp','webp'], true) || $fileType === 'image';
$isVideo = in_array($ext, ['mp4','webm','mov','ogv'], true) || $fileType === 'video';
$isAudio = in_array($ext, ['mp3','ogg','oga','wav','flac','aac','m4a'], true) || $fileType === 'audio';
$isPdf = ($ext === 'pdf') || $fileType === 'main';
$isOther = !($isImage || $isVideo || $isAudio || $isPdf);
$isImage = in_array($ext, ['jpg','jpeg','png','gif','bmp','webp'], true) || $fileType === 'image';
$isVideo = in_array($ext, ['mp4','webm','mov','ogv'], true) || $fileType === 'video';
$isAudio = in_array($ext, ['mp3','ogg','oga','wav','flac','aac','m4a'], true) || $fileType === 'audio';
$isPdf = ($ext === 'pdf') || $fileType === 'main';
$isWebsite = ($fileType === 'website');
$isOther = !($isImage || $isVideo || $isAudio || $isPdf || $isWebsite);
$_vttPath = null;
if ($isVideo) {
@@ -451,8 +452,10 @@
}
$caption = !empty($file["display_label"]) ? $file["display_label"] : ($file["description"] ?? '');
$mediaUrl = '/media?path=' . urlencode($file["file_path"]);
$fileName = htmlspecialchars($file["file_name"] ?? basename($file["file_path"]));
$filePath = $file['file_path'] ?? '';
$isExternalUrl = str_starts_with($filePath, 'http://') || str_starts_with($filePath, 'https://');
$mediaUrl = $isExternalUrl ? htmlspecialchars($filePath) : ('/media?path=' . urlencode($filePath));
$fileName = htmlspecialchars($file["file_name"] ?? basename($filePath));
?>
<figure>
<?php if ($isPdf): ?>
@@ -464,6 +467,20 @@
<p class="tfe-pdf-fallback">
<a href="<?= $mediaUrl ?>&download=1">Télécharger le PDF</a>
</p>
<?php elseif ($isWebsite): ?>
<iframe src="<?= $mediaUrl ?>"
width="100%" height="700px"
style="border:none"
title="<?= $fileName ?>"
sandbox="allow-scripts allow-same-origin"
loading="lazy">
</iframe>
<p class="tfe-pdf-fallback">
<a href="<?= $mediaUrl ?>" target="_blank" rel="noopener">
Ouvrir le site dans un nouvel onglet
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
</a>
</p>
<?php elseif ($isImage): ?>
<img src="<?= $mediaUrl ?>"
alt="<?= htmlspecialchars($caption !== '' ? $caption : $data['title'] . ' — ' . ($data['authors'] ?? '')) ?>">