sort TFE files by display category on public page: note d'intention → TFE → image → video → audio → website → annexes

This commit is contained in:
Pontoporeia
2026-07-10 19:07:14 +02:00
parent 9965529fd4
commit 64323fd17e
2 changed files with 83 additions and 1 deletions
+82 -1
View File
@@ -92,9 +92,16 @@ class TfeController
// If access is restricted and user doesn't have valid access, hide files
$shouldHideFiles = ($restrictedEnabled && $accessTypeId === 2 && !$hasRestrictedAccess);
// Caption (WebVTT) files — N-th VTT is paired with the N-th <video>
// Caption (WebVTT) files — N-th VTT is paired with the N-th <video>.
// Collect from original order so caption↔video pairing stays stable.
$captionFiles = $this->collectCaptionPaths($data['files'] ?? []);
// Sort files by display category so public order is consistent
// (note d'intention → TFE → image → video → audio → website → annexes)
if (!empty($data['files'])) {
$data['files'] = $this->sortFilesByDisplayCategory($data['files']);
}
// Jury members with interne/externe split
$jury = $this->db->getThesisJury($thesisId);
$juryByRole = $this->splitJuryByRole($jury);
@@ -285,6 +292,80 @@ class TfeController
return $captions;
}
// ── File sorting ────────────────────────────────────────────────────────
/**
* Sort files into a consistent display order: note d'intention → TFE PDF →
* image → video → audio → website → annexes.
*
* The admin's manual sort_order is preserved *within* each category group.
*
* @param array<int, array<string, mixed>> $files
* @return array<int, array<string, mixed>>
*/
protected function sortFilesByDisplayCategory(array $files): array
{
$priority = function (array $file): int {
$ext = strtolower(pathinfo($file['file_path'] ?? '', PATHINFO_EXTENSION));
$type = $file['file_type'] ?? '';
// 1. Note d'intention
if ($type === 'note_intention') {
return 1;
}
// 2. TFE PDF (main)
if ($type === 'main' || ($ext === 'pdf' && $type !== 'annex' && $type !== 'note_intention')) {
return 2;
}
// 3. Image
$isImage = in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'], true) || $type === 'image';
if ($isImage) {
return 3;
}
// 4. Video
$isVideo = in_array($ext, ['mp4', 'webm', 'mov', 'ogv'], true) || $type === 'video';
if ($isVideo) {
return 4;
}
// 5. Audio
$isAudio = in_array($ext, ['mp3', 'ogg', 'oga', 'wav', 'flac', 'aac', 'm4a'], true) || $type === 'audio';
if ($isAudio) {
return 5;
}
// 6. Website
if ($type === 'website') {
return 6;
}
// 7. Annexes (at the end)
if ($type === 'annex') {
return 7;
}
// Everything else (cover, caption, VTT, archives, unrecognized)
return 8;
};
usort($files, function (array $a, array $b) use ($priority): int {
$pa = $priority($a);
$pb = $priority($b);
if ($pa !== $pb) {
return $pa <=> $pb;
}
// Within the same category, preserve admin-chosen order
return ((int)($a['sort_order'] ?? 0)) <=> ((int)($b['sort_order'] ?? 0));
});
return $files;
}
// ── Response helpers ──────────────────────────────────────────────────────
/**