mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
426 lines
21 KiB
PHP
426 lines
21 KiB
PHP
<main class="tfe-main" id="main-content">
|
||
<article class="tfe-layout">
|
||
|
||
<!-- LEFT: info — article header -->
|
||
<section class="tfe-left">
|
||
<!-- Author above title -->
|
||
<p class="tfe-author"><?= htmlspecialchars(
|
||
$data["authors"] ?? "Auteur inconnu",
|
||
) ?></p>
|
||
|
||
<h1 class="tfe-title">
|
||
<?= htmlspecialchars($data["title"]) ?>
|
||
<?php if (!empty($data["subtitle"])): ?>
|
||
– <?= htmlspecialchars($data["subtitle"]) ?>
|
||
<?php endif; ?>
|
||
</h1>
|
||
|
||
<div class="tfe-meta">
|
||
<?php if (!empty($data["orientation"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Orientation :</span>
|
||
<a href="/repertoire?or[]=<?= urlencode($data["orientation"]) ?>"><?= htmlspecialchars($data["orientation"]) ?></a>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["ap_program"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Atelier pluridisciplinaire :</span>
|
||
<a href="/repertoire?ap[]=<?= urlencode($data["ap_program"]) ?>"><?= htmlspecialchars($data["ap_program"]) ?></a>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["year"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Date :</span>
|
||
<a href="/repertoire?fy[]=<?= urlencode($data["year"]) ?>"><?= htmlspecialchars($data["year"]) ?></a>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["languages"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Langue :</span>
|
||
<?php
|
||
$langs = array_map("trim", explode(",", $data["languages"]));
|
||
$langLinks = array_map(
|
||
fn($l) => '<a href="/search?query=' . urlencode($l) . '">' . htmlspecialchars(mb_strtolower($l)) . '</a>',
|
||
$langs,
|
||
);
|
||
echo implode(", ", $langLinks);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["formats"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Format :</span>
|
||
<?php
|
||
$fmts = array_map("trim", explode(",", $data["formats"]));
|
||
$fmtLinks = array_map(
|
||
fn($f) => '<a href="/search?query=' . urlencode($f) . '">' . htmlspecialchars(mb_strtolower($f)) . '</a>',
|
||
$fmts,
|
||
);
|
||
echo implode(", ", $fmtLinks);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["keywords"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Mots-clés :</span>
|
||
<?php
|
||
$kws = array_map("trim", explode(",", $data["keywords"]));
|
||
$kwLinks = array_map(
|
||
fn($k) => '<a href="/repertoire?kw[]=' . urlencode($k) . '">' . htmlspecialchars(mb_strtolower($k)) . '</a>',
|
||
$kws,
|
||
);
|
||
echo implode(", ", $kwLinks);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($promoteursInternes)): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Promoteur·ice interne :</span>
|
||
<?php
|
||
$links = array_map(
|
||
fn($n) => '<a href="/search?query=' . urlencode($n) . '">' . htmlspecialchars($n) . '</a>',
|
||
$promoteursInternes,
|
||
);
|
||
echo implode(", ", $links);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($promoteursExternes)): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Promoteur·ice externe :</span>
|
||
<?php
|
||
$links = array_map(
|
||
fn($n) => '<a href="/search?query=' . urlencode($n) . '">' . htmlspecialchars($n) . '</a>',
|
||
$promoteursExternes,
|
||
);
|
||
echo implode(", ", $links);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($promoteursUlb)): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Promoteur·ice ULB :</span>
|
||
<?php
|
||
$links = array_map(
|
||
fn($n) => '<a href="/search?query=' . urlencode($n) . '">' . htmlspecialchars($n) . '</a>',
|
||
$promoteursUlb,
|
||
);
|
||
echo implode(", ", $links);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($juryPresidents)): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Président·e du jury :</span>
|
||
<?php
|
||
$links = array_map(
|
||
fn($n) => '<a href="/search?query=' . urlencode($n) . '">' . htmlspecialchars($n) . '</a>',
|
||
$juryPresidents,
|
||
);
|
||
echo implode(", ", $links);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($juryLecteursInternes)): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Lecteur·ice(s) interne :</span>
|
||
<?php
|
||
$links = array_map(
|
||
fn($n) => '<a href="/search?query=' . urlencode($n) . '">' . htmlspecialchars($n) . '</a>',
|
||
$juryLecteursInternes,
|
||
);
|
||
echo implode(", ", $links);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($juryLecteursExternes)): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Lecteur·ice(s) externe :</span>
|
||
<?php
|
||
$links = array_map(
|
||
fn($n) => '<a href="/search?query=' . urlencode($n) . '">' . htmlspecialchars($n) . '</a>',
|
||
$juryLecteursExternes,
|
||
);
|
||
echo implode(", ", $links);
|
||
?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["access_type"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Accès :</span>
|
||
<?= htmlspecialchars($data["access_type"]) ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php
|
||
$_cc2r = !empty($data["cc2r"]);
|
||
$_lic = !empty($data["license_type"]) ? $data["license_type"] : ($data["license_custom"] ?? null);
|
||
if ($_cc2r || $_lic): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Licence :</span>
|
||
<?= htmlspecialchars(implode(", ", array_filter([$_cc2r ? "CC2r" : null, $_lic]))) ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["context_note"])): ?>
|
||
<p class="tfe-meta-item tfe-meta-note">
|
||
<span class="tfe-meta-label">Note :</span>
|
||
<span class="tfe-note-value"><?= nl2br(htmlspecialchars($data["context_note"])) ?></span>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["contact_interne"]) && !empty($data["contact_public"])): ?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Contact :</span>
|
||
<?php
|
||
$_contact = $data["contact_interne"];
|
||
$_isUrl = filter_var($_contact, FILTER_VALIDATE_URL) !== false;
|
||
$_isEmail = !$_isUrl && str_contains($_contact, "@");
|
||
if ($_isUrl):
|
||
$_host = parse_url($_contact, PHP_URL_HOST);
|
||
$_path = parse_url($_contact, PHP_URL_PATH) ?? '';
|
||
$_isInstagram = $_host && str_contains($_host, 'instagram.com');
|
||
$_isMastodon = $_path && str_contains($_path, '/@');
|
||
if ($_isInstagram):
|
||
$_username = trim($_path, '/');
|
||
$_display = $_username ? '@' . $_username : preg_replace("#^https?://(www\.)?#i", "", rtrim($_contact, "/"));
|
||
elseif ($_isMastodon):
|
||
$_username = trim($_path, '/@');
|
||
$_display = $_username ? '@' . $_username : preg_replace("#^https?://(www\.)?#i", "", rtrim($_contact, "/"));
|
||
else:
|
||
$_display = preg_replace("#^https?://(www\.)?#i", "", rtrim($_contact, "/"));
|
||
endif; ?>
|
||
<a href="<?= htmlspecialchars($_contact) ?>" target="_blank" rel="noopener">
|
||
<?= htmlspecialchars($_display) ?>
|
||
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
|
||
</a>
|
||
<?php elseif ($_isEmail): ?>
|
||
<a href="<?= EmailObfuscator::mailto($_contact) ?>"><?= htmlspecialchars($_contact) ?></a>
|
||
<?php else: ?>
|
||
<?= htmlspecialchars($_contact) ?>
|
||
<?php endif; ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($data["baiu_link"])): ?>
|
||
<?php
|
||
$_baiuHref = htmlspecialchars($data["baiu_link"]);
|
||
$_baiuLabel = preg_replace("#^https?://(www\\.)?#i", "", rtrim($data["baiu_link"], "/"));
|
||
?>
|
||
<p class="tfe-meta-item">
|
||
<span class="tfe-meta-label">Lien :</span>
|
||
<a href="<?= $_baiuHref ?>" target="_blank" rel="noopener">
|
||
<?= htmlspecialchars($_baiuLabel) ?>
|
||
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
|
||
</a>
|
||
</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if (!empty($data["synopsis"])): ?>
|
||
<p class="tfe-synopsis-text">
|
||
<?= nl2br(htmlspecialchars($data["synopsis"])) ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
</section>
|
||
|
||
<!-- RIGHT: media — supplementary aside -->
|
||
<section class="tfe-right">
|
||
<?php $_videoIndex = 0; ?>
|
||
<?php if ($isInterdit): ?>
|
||
<p class="tfe-restricted">
|
||
<?= htmlspecialchars(
|
||
$forbiddenMessage ??
|
||
"Ce TFE n'est pas disponible en ligne.",
|
||
) ?>
|
||
</p>
|
||
<?php elseif ($shouldHideFiles): ?>
|
||
<div class="tfe-restricted-access">
|
||
<p class="tfe-restricted-message">
|
||
<strong>Accès restreint</strong><br>
|
||
<?= htmlspecialchars(
|
||
$restrictedMessage ??
|
||
'Les fichiers attachés à ce TFE sont réservés aux utilisateur·ices autorisé·es.',
|
||
) ?>
|
||
</p>
|
||
|
||
<form id="access-request-form" class="tfe-access-request-form"
|
||
data-thesis-id="<?= $thesisId ?>">
|
||
<input type="hidden" name="csrf_token"
|
||
value="<?= htmlspecialchars(
|
||
$_SESSION["csrf_token"] ?? "",
|
||
) ?>">
|
||
|
||
<div class="form-group">
|
||
<label for="access-email">Votre adresse email :</label>
|
||
<input type="email"
|
||
id="access-email"
|
||
name="email"
|
||
required
|
||
placeholder="votre@email.com">
|
||
</div>
|
||
|
||
<div id="justification-container" class="form-group" style="display: none;">
|
||
<label for="access-justification">Pourquoi souhaitez-vous accéder à ce TFE ?</label>
|
||
<textarea id="access-justification"
|
||
name="justification"
|
||
rows="4"
|
||
placeholder="Décrivez brièvement votre motivation (recherche, collaboration, etc.)"></textarea>
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn--primary tfe-btn-request-access">
|
||
Demander l'accès
|
||
</button>
|
||
|
||
<div id="access-request-message" class="tfe-access-message" style="display: none;"></div>
|
||
</form>
|
||
</div>
|
||
|
||
|
||
<?php elseif (!empty($data["files"])): ?>
|
||
<?php
|
||
// Preload PeerTube instance URL once
|
||
$_ptHasAnyPeerTube = false;
|
||
foreach ($data['files'] as $_f) {
|
||
if (str_starts_with($_f['file_path'] ?? '', 'peertube_ids:')) {
|
||
$_ptHasAnyPeerTube = true;
|
||
break;
|
||
}
|
||
}
|
||
$_ptInstanceUrl = '';
|
||
if ($_ptHasAnyPeerTube) {
|
||
require_once APP_ROOT . '/src/PeerTubeService.php';
|
||
$_ptSettings = PeerTubeService::getSettings(Database::getInstance());
|
||
$_ptInstanceUrl = $_ptSettings['instance_url'] ?? '';
|
||
}
|
||
?>
|
||
<?php foreach ($data["files"] as $file): ?>
|
||
<?php
|
||
$ext = strtolower(pathinfo($file["file_path"] ?? '', PATHINFO_EXTENSION));
|
||
$fileType = $file["file_type"] ?? '';
|
||
|
||
// Skip helper/internal types
|
||
if ($ext === 'vtt' || $fileType === 'caption') continue;
|
||
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';
|
||
$isWebsite = ($fileType === 'website');
|
||
$isOther = !($isImage || $isVideo || $isAudio || $isPdf || $isWebsite);
|
||
|
||
$_vttPath = null;
|
||
if ($isVideo) {
|
||
$_vttPath = $captionFiles[$_videoIndex] ?? null;
|
||
$_videoIndex++;
|
||
}
|
||
|
||
$caption = !empty($file["display_label"]) ? $file["display_label"] : ($file["description"] ?? '');
|
||
$filePath = $file['file_path'] ?? '';
|
||
$isExternalUrl = str_starts_with($filePath, 'http://') || str_starts_with($filePath, 'https://');
|
||
$isPeerTube = str_starts_with($filePath, 'peertube_ids:');
|
||
$mediaUrl = $isPeerTube ? '' : ($isExternalUrl ? htmlspecialchars($filePath) : ('/media?path=' . urlencode($filePath)));
|
||
$fileName = htmlspecialchars($file["file_name"] ?? basename($filePath));
|
||
?>
|
||
<?php if ($isPdf): ?>
|
||
<iframe src="<?= $mediaUrl ?>"
|
||
width="100%" height="700px"
|
||
style="border:none"
|
||
title="<?= $fileName ?>">
|
||
</iframe>
|
||
<?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'] ?? '')) ?>">
|
||
<?php elseif ($isVideo): ?>
|
||
<?php if ($isPeerTube): ?>
|
||
<?php
|
||
$peertubeUuid = substr($filePath, strlen('peertube_ids:'));
|
||
$title = $fileName;
|
||
$instanceUrl = $_ptInstanceUrl;
|
||
include APP_ROOT . '/templates/partials/peertube-embed.php';
|
||
?>
|
||
<?php else: ?>
|
||
<video width="100%" controls>
|
||
<source src="<?= $mediaUrl ?>" type="video/<?= htmlspecialchars($ext === 'mov' ? 'mp4' : $ext) ?>">
|
||
<?php if ($_vttPath): ?>
|
||
<track kind="captions"
|
||
src="/media?path=<?= urlencode($_vttPath) ?>"
|
||
srclang="fr" label="Sous-titres" default>
|
||
<?php endif; ?>
|
||
</video>
|
||
<?php endif; ?>
|
||
<?php elseif ($isAudio): ?>
|
||
<?php if ($isPeerTube): ?>
|
||
<?php
|
||
$peertubeUuid = substr($filePath, strlen('peertube_ids:'));
|
||
$title = $fileName;
|
||
$instanceUrl = $_ptInstanceUrl;
|
||
$width = 560;
|
||
$height = 150;
|
||
include APP_ROOT . '/templates/partials/peertube-embed.php';
|
||
?>
|
||
<?php else: ?>
|
||
<audio controls class="tfe-audio">
|
||
<source src="<?= $mediaUrl ?>" type="audio/<?= htmlspecialchars(match($ext) {
|
||
'mp3' => 'mpeg',
|
||
'ogg', 'oga' => 'ogg',
|
||
'wav' => 'wav',
|
||
'flac' => 'flac',
|
||
'aac' => 'aac',
|
||
'm4a' => 'mp4',
|
||
default => $ext,
|
||
}) ?>">
|
||
Votre navigateur ne supporte pas la lecture audio.
|
||
</audio>
|
||
<?php endif; ?>
|
||
<?php else: /* other — download only */ ?>
|
||
<div class="tfe-download-file">
|
||
<a href="<?= $mediaUrl ?>&download=1" class="tfe-download-link">
|
||
<span class="tfe-download-icon">📎</span>
|
||
<span><?= $fileName ?></span>
|
||
</a>
|
||
<?php if (!empty($file['file_size'])): ?>
|
||
<small class="tfe-download-size"><?= number_format($file['file_size'] / 1024 / 1024, 2) ?> MB</small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php if ($caption !== '' && !$isOther): ?>
|
||
<figcaption><?= htmlspecialchars($caption) ?></figcaption>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<p class="tfe-no-files">Aucun fichier disponible pour ce TFE.</p>
|
||
<?php endif; ?>
|
||
</section>
|
||
|
||
</article>
|
||
</main>
|