WCAG 4.1.2: add WebVTT caption support for <video> elements on tfe.php

Problem: <video> elements on tfe.php had no <track kind="captions"> element,
violating WCAG 4.1.2 (name, role, value) for video content.

Changes:
- public/tfe.php: collect all text/vtt files from the thesis file list before
  rendering; skip standalone rendering of .vtt entries; for each MP4 emit a
  <track kind="captions" srclang="fr" label="Sous-titres" default> pointing
  to the N-th VTT file (N-th video paired with N-th caption in document order)
- public/media.php: add text/vtt to allowed MIME list; normalise finfo
  text/plain -> text/vtt for .vtt files; add vtt branch to cache/header
  block (Content-Type: text/vtt; charset=utf-8, 1-day cache)
- public/admin/actions/formulaire.php: allow .vtt uploads (text/vtt MIME,
  vtt extension); normalise text/plain finfo result; set file_type='caption'
  for VTT files so they are distinguishable from other thesis files
- public/admin/add.php: extend files field accept attr to include .vtt;
  update hint text to document the VTT sidecar convention

VTT files uploaded under theses/ inherit the same access_type visibility
gate in media.php as all other thesis content (403 for access_type_id=3).
This commit is contained in:
Pontoporeia
2026-04-03 13:24:26 +02:00
parent 6e68edfbff
commit 94e9060dc7
6 changed files with 58 additions and 8 deletions

View File

@@ -186,8 +186,8 @@ try {
}
// Define security constraints
$allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf', 'video/mp4', 'application/zip'];
$allowedExtensions = ['jpg', 'jpeg', 'png', 'pdf', 'mp4', 'zip'];
$allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf', 'video/mp4', 'application/zip', 'text/vtt'];
$allowedExtensions = ['jpg', 'jpeg', 'png', 'pdf', 'mp4', 'zip', 'vtt'];
$maxFileSize = 50 * 1024 * 1024; // 50 MB
// Process cover image
@@ -248,6 +248,11 @@ try {
$mimeType = $finfo->file($files["tmp_name"][$i]);
$fileExtension = strtolower(pathinfo($files["name"][$i], PATHINFO_EXTENSION));
// finfo may return 'text/plain' for WebVTT on some systems; normalise by extension.
if ($mimeType === 'text/plain' && $fileExtension === 'vtt') {
$mimeType = 'text/vtt';
}
if (!in_array($mimeType, $allowedMimeTypes) || !in_array($fileExtension, $allowedExtensions)) {
error_log("Invalid file type: " . $files["name"][$i] . " (MIME: $mimeType)");
continue;
@@ -266,11 +271,13 @@ try {
if (move_uploaded_file($files["tmp_name"][$i], $targetFile)) {
chmod($targetFile, 0644);
// Determine file type (simplified - could be enhanced)
// Determine file type
$fileType = 'other';
if (strpos(strtolower($files["name"][$i]), 'annex') !== false) {
if ($fileExtension === 'vtt') {
$fileType = 'caption'; // WebVTT caption sidecar
} elseif (strpos(strtolower($files["name"][$i]), 'annex') !== false) {
$fileType = 'annex';
} else if ($fileExtension === 'pdf') {
} elseif ($fileExtension === 'pdf') {
$fileType = 'main';
}

View File

@@ -94,7 +94,7 @@ function wasSelected($key, $value) {
<?php $name = 'banner'; $label = 'Image bannière (accueil) :'; $accept = 'image/jpeg,image/png,image/webp'; $hint = 'JPG, PNG ou WEBP. Format paysage recommandé (4:1). Max 5 MB.'; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
<?php $name = 'files'; $label = 'Fichiers du TFE :'; $accept = '.pdf,.jpg,.jpeg,.png,.mp4,.zip'; $hint = 'PDF, JPG, PNG, MP4, ZIP. Max 50 MB par fichier.'; $multiple = true; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
<?php $name = 'files'; $label = 'Fichiers du TFE :'; $accept = '.pdf,.jpg,.jpeg,.png,.mp4,.zip,.vtt'; $hint = 'PDF, JPG, PNG, MP4, ZIP. Max 50 MB par fichier. Pour les vidéos, un fichier .vtt de sous-titres peut être joint (il sera associé automatiquement à la vidéo correspondante).'; $multiple = true; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
<div class="admin-form-footer">
<button type="submit" name="go" class="admin-btn">Soumettre</button>