refactor: merge video/audio FilePond pools into TFE input

- Remove separate video/audio/peertube_video/peertube_audio pools from UI
- TFE pool now accepts all file types including video/audio
- When PeerTube is enabled, video/audio dropped into TFE pool auto-upload
  to PeerTube (process.php detects MIME and uploads immediately)
- PeerTube return IDs now encode type: peertube:video:UUID or peertube:audio:UUID
- load.php returns placeholder SVG for PeerTube files so they appear in FilePond
- Edit mode: all existing files (including PeerTube) shown in TFE FilePond pool
- Remove legacy  video/audio/peertube_* handling from both controllers
- Remove unused vide/audio/peertube_* entries from JS QUEUE_CONFIG
This commit is contained in:
Pontoporeia
2026-05-12 12:08:51 +02:00
parent 1ff3c70ebe
commit 6e7c0c00e3
11 changed files with 89 additions and 201 deletions

View File

@@ -45,10 +45,19 @@ $filePath = $fileRow['file_path'] ?? '';
$fileName = $fileRow['file_name'] ?? basename($filePath);
$mimeType = $fileRow['mime_type'] ?? 'application/octet-stream';
// ── Skip PeerTube and website entries (no actual file) ───────────────────
// ── PeerTube entries: return a placeholder SVG blob so FilePond can display them ─┐
if (str_starts_with($filePath, 'peertube_ids:')) {
http_response_code(404);
die('Fichier PeerTube — pas de flux direct.');
$uuid = substr($filePath, strlen('peertube_ids:'));
$isVideo = ($fileRow['file_type'] ?? '') === 'video';
$svg = $isVideo
? '<svg xmlns="http://www.w3.org/2000/svg" width="180" height="120" viewBox="0 0 180 120"><rect width="180" height="120" fill="#1a1a2e"/><polygon points="70,35 70,85 125,60" fill="#e94560"/><text x="90" y="110" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#aaa">PeerTube ' . htmlspecialchars($uuid) . '</text></svg>'
: '<svg xmlns="http://www.w3.org/2000/svg" width="180" height="120" viewBox="0 0 180 120"><rect width="180" height="120" fill="#1a1a2e"/><circle cx="55" cy="60" r="20" fill="none" stroke="#4ecca3" stroke-width="3"/><line x1="72" y1="48" x2="95" y2="38" stroke="#4ecca3" stroke-width="3"/><line x1="72" y1="60" x2="110" y2="60" stroke="#4ecca3" stroke-width="3"/><line x1="72" y1="72" x2="95" y2="82" stroke="#4ecca3" stroke-width="3"/><text x="90" y="110" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#aaa">PeerTube ' . htmlspecialchars($uuid) . '</text></svg>';
header('Content-Type: image/svg+xml');
header('Content-Length: ' . strlen($svg));
header('Content-Disposition: inline; filename="peertube.svg"');
header('Cache-Control: no-cache');
echo $svg;
exit;
}
if (str_starts_with($filePath, 'http://') || str_starts_with($filePath, 'https://')) {
http_response_code(404);

View File

@@ -209,11 +209,14 @@ chmod($targetPath, 0644);
error_log('[filepond:process] File saved to tmp | file_id=' . $fileId . ' | path=' . $targetPath);
// ── PeerTube: upload immediately (don't wait for form submit) ────────────
$isPeerTube = str_starts_with($queueType, 'peertube_');
if ($isPeerTube) {
// Handles both dedicated peertube_* queues (legacy) and video/audio in the TFE pool
$isPeerTubeQueue = str_starts_with($queueType, 'peertube_');
$isTfeAv = ($queueType === 'tfe' && preg_match('/^(video|audio)\//', $mimeType));
$shouldPeerTube = $isPeerTubeQueue || $isTfeAv;
if ($shouldPeerTube) {
require_once APP_ROOT . '/src/PeerTubeService.php';
if (PeerTubeService::isEnabled(new Database())) {
$ptFileType = ($queueType === 'peertube_video') ? 'video' : 'audio';
$ptFileType = preg_match('/^video\//', $mimeType) ? 'video' : 'audio';
try {
$result = PeerTubeService::upload(
new Database(),
@@ -223,7 +226,8 @@ if ($isPeerTube) {
''
);
// Return a special ID prefix so the controller knows not to look in tmp/
$fileId = 'peertube:' . $result['uuid'];
// Format: peertube:video:UUID or peertube:audio:UUID
$fileId = 'peertube:' . $ptFileType . ':' . $result['uuid'];
// Clean up temp file — PeerTube has its own copy now
@unlink($targetPath);
@rmdir($tmpDir);
@@ -239,11 +243,14 @@ if ($isPeerTube) {
die('Erreur lors du téléversement vers PeerTube.');
}
} else {
// PeerTube not enabled — reject the upload
@unlink($targetPath);
@rmdir($tmpDir);
http_response_code(503);
die('PeerTube n\'est pas activé.');
// PeerTube not enabled — save to disk normally (only for tfe pool, not dedicated peertube queues)
if ($isPeerTubeQueue) {
@unlink($targetPath);
@rmdir($tmpDir);
http_response_code(503);
die('PeerTube n\'est pas activé.');
}
// For TFE pool, fall through to normal disk save below
}
}

View File

@@ -31,6 +31,7 @@ if ($_SERVER['REQUEST_METHOD'] !== 'DELETE') {
$fileId = trim(file_get_contents('php://input'));
// PeerTube files have a special prefix; nothing to clean up locally
// Format: peertube:video:UUID or peertube:audio:UUID
if (str_starts_with($fileId, 'peertube:')) {
// PeerTube files are already uploaded; we don't delete them from PeerTube on revert
// (the user might still submit and associate them)

View File

@@ -33,16 +33,8 @@
"text/vtt",
"application/zip", "application/x-tar", "application/gzip"
],
// When PeerTube is active, exclude video/audio from TFE pool
acceptedFileTypesPeerTube: [
"image/jpeg", "image/png", "image/gif", "image/webp",
"application/pdf",
"text/vtt",
"application/zip", "application/x-tar", "application/gzip"
],
labelFileTypeNotAllowed: "Format non accepté",
fileValidateTypeLabelExpectedTypes: "PDF, Images, Vidéos, Audio, VTT, Archives",
fileValidateTypeLabelExpectedTypesPeerTube: "PDF, Images, VTT, Archives",
maxFileSize: "500MB",
labelMaxFileSizeExceeded: "Fichier trop volumineux",
labelMaxFileSize: "Taille max: {filesize}",
@@ -54,24 +46,6 @@
mp3: "2GB", ogg: "2GB", oga: "2GB", wav: "2GB", flac: "2GB", aac: "2GB", m4a: "2GB"
}
},
video: {
acceptedFileTypes: ["video/mp4", "video/webm", "video/ogg", "video/quicktime"],
labelFileTypeNotAllowed: "Format non accepté",
fileValidateTypeLabelExpectedTypes: "MP4, WebM, OGV, MOV",
maxFileSize: "500MB",
labelMaxFileSizeExceeded: "Fichier trop volumineux",
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: true
},
audio: {
acceptedFileTypes: ["audio/mpeg", "audio/ogg", "audio/flac", "audio/x-wav", "audio/aac", "audio/mp4"],
labelFileTypeNotAllowed: "Format non accepté",
fileValidateTypeLabelExpectedTypes: "MP3, OGG, FLAC, WAV, AAC, M4A",
maxFileSize: "500MB",
labelMaxFileSizeExceeded: "Fichier trop volumineux",
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: true
},
annexe: {
acceptedFileTypes: ["application/pdf", "application/zip", "application/x-tar", "application/gzip"],
labelFileTypeNotAllowed: "Format non accepté",
@@ -99,24 +73,6 @@
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: false
},
peertube_video: {
acceptedFileTypes: ["video/mp4", "video/webm", "video/ogg", "video/quicktime"],
labelFileTypeNotAllowed: "Format non accepté",
fileValidateTypeLabelExpectedTypes: "MP4, WebM, OGV, MOV",
maxFileSize: "500MB",
labelMaxFileSizeExceeded: "Fichier trop volumineux",
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: true
},
peertube_audio: {
acceptedFileTypes: ["audio/mpeg", "audio/ogg", "audio/flac", "audio/x-wav", "audio/aac", "audio/mp4"],
labelFileTypeNotAllowed: "Format non accepté",
fileValidateTypeLabelExpectedTypes: "MP3, OGG, FLAC, WAV, AAC, M4A",
maxFileSize: "500MB",
labelMaxFileSizeExceeded: "Fichier trop volumineux",
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: true
},
};
// ── Helpers ───────────────────────────────────────────────────────────
@@ -270,15 +226,6 @@
// Per-type max size overrides (for TFE: PDF=100MB, video/audio=2GB)
var perExtMax = cfg.perExtensionMaxSize || {};
// When PeerTube is active, restrict TFE pool to PDF/text only
var peerTubeActive = queueType === "tfe" && input.dataset.peertubeActive === "1";
var acceptedFileTypes = peerTubeActive && cfg.acceptedFileTypesPeerTube
? cfg.acceptedFileTypesPeerTube
: cfg.acceptedFileTypes;
var expectedTypesLabel = peerTubeActive && cfg.fileValidateTypeLabelExpectedTypesPeerTube
? cfg.fileValidateTypeLabelExpectedTypesPeerTube
: cfg.fileValidateTypeLabelExpectedTypes;
return {
allowMultiple: cfg.allowMultiple,
allowReorder: true,
@@ -287,9 +234,9 @@
server: buildServerConfig(queueType),
// ── Native FilePond validation ──
acceptedFileTypes: acceptedFileTypes,
acceptedFileTypes: cfg.acceptedFileTypes,
labelFileTypeNotAllowed: cfg.labelFileTypeNotAllowed,
fileValidateTypeLabelExpectedTypes: expectedTypesLabel,
fileValidateTypeLabelExpectedTypes: cfg.fileValidateTypeLabelExpectedTypes,
maxFileSize: cfg.maxFileSize,
labelMaxFileSizeExceeded: cfg.labelMaxFileSizeExceeded,
labelMaxFileSize: cfg.labelMaxFileSize,

View File

@@ -213,7 +213,7 @@ $websiteLabel = htmlspecialchars($_POST['website_label'] ?? '');
</div>
</div>
<!-- ── 3. TFE ── -->
<!-- ── 3. TFE (all files: PDF, images, video, audio, VTT, archives) ── -->
<div class="admin-form-group admin-files-fieldgroup">
<label for="tfe-files-input">TFE<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
<div class="admin-file-input">
@@ -223,17 +223,14 @@ $websiteLabel = htmlspecialchars($_POST['website_label'] ?? '');
class="tfe-file-picker"
data-queue-type="tfe"
<?= !$adminMode ? 'required' : '' ?>
data-peertube-active="<?= $peerTubeEnabled ? '1' : '0' ?>"
data-existing-files='<?= htmlspecialchars(json_encode($existingFilesJsonForTfe ?? []), ENT_QUOTES) ?>'>
<small class="admin-file-hint">
PDF (max 100 MB) · Images (max 500 MB) · Vidéo &amp; Audio (max 2 GB) · VTT · Archives (max 500 MB).
<br>Glissez pour réordonner.
<?php if ($peerTubeEnabled): ?>
PDF (max 100 MB) · Images (max 500 MB) · VTT · Archives (max 500 MB).
Vidéo & Audio → utilisez les emplacements dédiés ci-dessous.
<?php else: ?>
PDF (max 100 MB) · Images (max 500 MB) · Vidéo & Audio (max 2 GB) · VTT · Archives (max 500 MB).
<br>Vidéos et audio hébergés sur <a href="<?= htmlspecialchars($peerTubeSettings['instance_url']) ?>" target="_blank" rel="noopener">PeerTube</a>.
<?php endif; ?>
Glissez pour réordonner.
PDFs trop lourds ? <a href="https://www.bentopdf.com" target="_blank" rel="noopener">https://bentopdf.com/</a>
<br>PDFs trop lourds ? <a href="https://www.bentopdf.com" target="_blank" rel="noopener">https://bentopdf.com/</a>
</small>
</div>
</div>
@@ -254,65 +251,7 @@ $websiteLabel = htmlspecialchars($_POST['website_label'] ?? '');
</div>
</div>
<!-- ── 5. Vidéo / PeerTube ── -->
<?php if ($peerTubeEnabled): ?>
<div id="slot-video" class="admin-form-group admin-files-fieldgroup">
<label for="peertube-video-input">Vidéo (optionnel)</label>
<div class="admin-file-input">
<input type="file" id="peertube-video-input"
name="queue_file[peertube_video][]"
multiple
accept="video/mp4,video/webm,video/ogg,video/quicktime,.mp4,.webm,.ogv,.mov"
class="tfe-file-picker"
data-queue-type="peertube_video">
<small class="admin-file-hint">MP4, WebM ou MOV. Max 500 MB. Hébergé sur <a href="<?= htmlspecialchars($peerTubeSettings['instance_url']) ?>" target="_blank" rel="noopener">PeerTube</a>.</small>
</div>
</div>
<?php else: ?>
<div id="slot-video" class="admin-form-group admin-files-fieldgroup">
<label for="video-files-input">Vidéo (optionnel)</label>
<div class="admin-file-input">
<input type="file" id="video-files-input"
name="queue_file[video][]"
multiple
accept="video/mp4,video/webm,video/ogg,video/quicktime,.mp4,.webm,.ogv,.mov"
class="tfe-file-picker"
data-queue-type="video">
<small class="admin-file-hint">MP4, WebM ou MOV. Max 500 MB.</small>
</div>
</div>
<?php endif; ?>
<!-- ── 6. Audio / PeerTube ── -->
<?php if ($peerTubeEnabled): ?>
<div id="slot-audio" class="admin-form-group admin-files-fieldgroup">
<label for="peertube-audio-input">Audio (optionnel)</label>
<div class="admin-file-input">
<input type="file" id="peertube-audio-input"
name="queue_file[peertube_audio][]"
multiple
accept="audio/mpeg,audio/ogg,audio/wav,audio/flac,audio/aac,audio/mp4,.mp3,.ogg,.oga,.wav,.flac,.aac,.m4a"
class="tfe-file-picker"
data-queue-type="peertube_audio">
<small class="admin-file-hint">MP3, OGG, WAV, FLAC ou AAC. Max 500 MB. Hébergé sur <a href="<?= htmlspecialchars($peerTubeSettings['instance_url']) ?>" target="_blank" rel="noopener">PeerTube</a>.</small>
</div>
</div>
<?php else: ?>
<div id="slot-audio" class="admin-form-group admin-files-fieldgroup">
<label for="audio-files-input">Audio (optionnel)</label>
<div class="admin-file-input">
<input type="file" id="audio-files-input"
name="queue_file[audio][]"
multiple
accept="audio/mpeg,audio/ogg,audio/wav,audio/flac,audio/aac,audio/mp4,.mp3,.ogg,.oga,.wav,.flac,.aac,.m4a"
class="tfe-file-picker"
data-queue-type="audio">
<small class="admin-file-hint">MP3, OGG, WAV, FLAC ou AAC. Max 500 MB.</small>
</div>
</div>
<?php endif; ?>
<!-- ── 7. Site web url ── -->
<!-- ── 5. Site web url ── -->
<div id="slot-siteweb" class="admin-form-group">
<label for="website_url">URL du site (optionnel)</label>
<div class="admin-file-input">

View File

@@ -200,31 +200,17 @@ class ThesisCreateController
$this->handleFilePondSingleFile($thesisId, $post, 'cover', $folderPath, $filePrefix);
$this->handleFilePondSingleFile($thesisId, $post, 'note_intention', $folderPath, $filePrefix);
$nextNum = $this->handleFilePondQueueFiles($thesisId, $post, 'tfe', $folderPath, $filePrefix, 1);
$nextNum = $this->handleFilePondQueueFiles($thesisId, $post, 'video', $folderPath, $filePrefix, $nextNum);
$nextNum = $this->handleFilePondQueueFiles($thesisId, $post, 'audio', $folderPath, $filePrefix, $nextNum);
$this->handleFilePondQueueFiles($thesisId, $post, 'annexe', $folderPath, $filePrefix, 0);
$this->handleFilePondQueueFiles($thesisId, $post, 'peertube_video', $folderPath, $filePrefix, 0, null);
$this->handleFilePondQueueFiles($thesisId, $post, 'peertube_audio', $folderPath, $filePrefix, 0, null);
} else {
// Legacy path: files arrive via multipart $_FILES
$this->handleCoverUpload($thesisId, $files['couverture'] ?? null, $folderPath, $filePrefix);
$this->handleNoteIntentionUpload($thesisId, $files['note_intention'] ?? null, $folderPath, $filePrefix);
$queueFiles = $files['queue_file'] ?? [];
$qTfe = $this->extractFilesSubArray($queueFiles, 'tfe');
$qVideo = $this->extractFilesSubArray($queueFiles, 'video');
$qAudio = $this->extractFilesSubArray($queueFiles, 'audio');
$qAnnexe = $this->extractFilesSubArray($queueFiles, 'annexe');
$nextNum = $this->handleTfeQueueFiles($thesisId, $qTfe, $folderPath, $filePrefix, 1);
$nextNum = $this->handleTfeQueueFiles($thesisId, $qVideo, $folderPath, $filePrefix, $nextNum);
$nextNum = $this->handleTfeQueueFiles($thesisId, $qAudio, $folderPath, $filePrefix, $nextNum);
$this->handleAnnexeQueueFiles($thesisId, $qAnnexe, $folderPath, $filePrefix);
// ── 5b. PeerTube video / audio uploads (from FilePond queue) ──────────
$qPTVideo = $this->extractFilesSubArray($queueFiles, 'peertube_video');
$qPTAudio = $this->extractFilesSubArray($queueFiles, 'peertube_audio');
$this->handlePeerTubeQueueFiles($thesisId, $data['titre'], $qPTVideo, 'video');
$this->handlePeerTubeQueueFiles($thesisId, $data['titre'], $qPTAudio, 'audio');
}
// ── 6. Website URL — stored as thesis_files row ──────────────────────

View File

@@ -464,35 +464,21 @@ class ThesisEditController
// New path: files already on server via async FilePond uploads
$nextNum = $tfeCount + 1;
$nextNum = $this->handleFilePondQueueFiles($thesisId, $post, 'tfe', $folderPath, $filePrefix, $nextNum);
$nextNum = $this->handleFilePondQueueFiles($thesisId, $post, 'video', $folderPath, $filePrefix, $nextNum);
$this->handleFilePondQueueFiles($thesisId, $post, 'audio', $folderPath, $filePrefix, $nextNum);
$this->handleFilePondQueueFiles($thesisId, $post, 'annexe', $folderPath, $filePrefix, 0);
$this->handleFilePondQueueFiles($thesisId, $post, 'peertube_video', $folderPath, $filePrefix, 0, $progressToken);
$this->handleFilePondQueueFiles($thesisId, $post, 'peertube_audio', $folderPath, $filePrefix, 0, $progressToken);
} else {
// Legacy path: files arrive via multipart $_FILES
$queueFiles = $files['queue_file'] ?? [];
$qTfe = $this->extractFilesSubArray($queueFiles, 'tfe');
$qVideo = $this->extractFilesSubArray($queueFiles, 'video');
$qAudio = $this->extractFilesSubArray($queueFiles, 'audio');
$qAnnexe = $this->extractFilesSubArray($queueFiles, 'annexe');
$startNum = $tfeCount + 1;
$startNum = $this->handleTfeQueueFiles($thesisId, $qTfe, $folderPath, $filePrefix, $startNum);
$startNum = $this->handleTfeQueueFiles($thesisId, $qVideo, $folderPath, $filePrefix, $startNum);
$this->handleTfeQueueFiles($thesisId, $qAudio, $folderPath, $filePrefix, $startNum);
$this->handleAnnexeQueueFiles($thesisId, $qAnnexe, $folderPath, $filePrefix);
// Legacy annexe files (direct upload, non-queue path — kept for backwards compat)
if (isset($files['annexes']) && is_array($files['annexes']['name'] ?? null)) {
$this->handleAnnexeFiles($thesisId, $files['annexes'], $folderPath, $filePrefix, $post);
}
// ── PeerTube video / audio uploads (from FilePond queue) ──────────────
$qPTVideo = $this->extractFilesSubArray($queueFiles, 'peertube_video');
$qPTAudio = $this->extractFilesSubArray($queueFiles, 'peertube_audio');
$this->handlePeerTubeQueueFiles($thesisId, trim($post['titre'] ?? ''), $qPTVideo, 'video', $progressToken);
$this->handlePeerTubeQueueFiles($thesisId, trim($post['titre'] ?? ''), $qPTAudio, 'audio', $progressToken);
}
// ── Website URL — add or update ──────────────────────────────────────

View File

@@ -1001,16 +1001,18 @@ trait ThesisFileHandler
}
// PeerTube files have been uploaded already; just insert DB row
// Format: peertube:video:UUID or peertube:audio:UUID
if (str_starts_with($fileId, 'peertube:')) {
$uuid = substr($fileId, strlen('peertube:'));
$fileType = ($queueKey === 'peertube_video') ? 'video' : 'audio';
$parts = explode(':', $fileId, 3);
$fileType = ($parts[1] ?? '') === 'video' ? 'video' : 'audio';
$uuid = $parts[2] ?? '';
$storedPath = 'peertube_ids:' . $uuid;
$this->db->insertThesisFile(
$thesisId, $fileType,
$storedPath,
$uuid . ' (PeerTube)',
0,
($queueKey === 'peertube_video') ? 'video/mp4' : 'audio/mpeg',
$fileType === 'video' ? 'video/mp4' : 'audio/mpeg',
null, null
);
error_log("ThesisFileHandler: PeerTube file associated → $uuid");

View File

@@ -1559,6 +1559,19 @@
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
+\\\\\\\ to: uktvpzsn ce8e9ac6 "fix: track vendor JS files, add 'unsafe-inline' to public CSP, gitignore filepond tmp" (rebased revision)
++ $linkName = $link['name'] ?? '';
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: uktvpzsn ce8e9ac6 "fix: track vendor JS files, add 'unsafe-inline' to public CSP, gitignore filepond tmp" (rebased revision)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
- $linkName = $link['name'] ?? '';
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: tsultupz 3195eef4 "refactor: merge video/audio FilePond pools into TFE input" (rebased revision)
$linkName = $link['name'] ?? '';
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
$linkLockedYear = $link['locked_year'] ?? null;
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
+\\\\\\\ to: tsultupz 0703279b "refactor: merge video/audio FilePond pools into TFE input" (rebased revision)
++ $linkName = $link['name'] ?? '';
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
?>
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">

View File

@@ -307,7 +307,26 @@ $checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
?>
<!-- ═══════════════════ Format(s) + Fichiers ═══════════════════ -->
<?php if ($filesMode === 'add'): ?>
<?php
// Helper: build existing-files JSON for FilePond TFE pool (including PeerTube)
$_buildExistingFilesJson = function (array $files): array {
$result = [];
foreach ($files as $f) {
$ft = $f['file_type'] ?? '';
$fp = $f['file_path'] ?? '';
// Skip cover (handled separately) and website URLs (no actual file)
if ($ft === 'cover' || str_starts_with($fp, 'http://') || str_starts_with($fp, 'https://')) {
continue;
}
// Include PeerTube files too — load.php now handles them
$result[] = [
'source' => (string)((int)$f['id']),
'options' => ['type' => 'local'],
];
}
return $result;
};
if ($filesMode === 'add'): ?>
<?php
// Add / partage mode: Format + Fichiers rendered as one HTMX-swappable block.
// Synthesise POST-like data so fichiers-fragment.php can render the initial state.
@@ -324,23 +343,7 @@ $checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
$_POST['admin_mode'] = $adminMode ? '1' : '0';
$_POST['has_annexes'] = $formData['has_annexes'] ?? null;
// Build existing-files JSON for FilePond edit mode
$existingFilesJsonForTfe = [];
if (!empty($currentFiles)) {
foreach ($currentFiles as $f) {
$ft = $f['file_type'] ?? '';
$fp = $f['file_path'] ?? '';
// Skip cover (handled separately) and website/peertube (no actual file)
if ($ft === 'cover' || str_starts_with($fp, 'http://') || str_starts_with($fp, 'https://') || str_starts_with($fp, 'peertube_ids:')) {
continue;
}
// Only include files that can be streamed back via load.php
$existingFilesJsonForTfe[] = [
'source' => (string)((int)$f['id']),
'options' => ['type' => 'local'],
];
}
}
$existingFilesJsonForTfe = $_buildExistingFilesJson($currentFiles ?? []);
include APP_ROOT . '/public/partage/fichiers-fragment.php';
$_POST = $_savedPost;
@@ -359,23 +362,8 @@ $checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
$_POST['_cover'] = $currentCover['file_path'] ?? null;
$_POST['has_annexes'] = $formData['has_annexes'] ?? null;
// Build existing-files JSON for FilePond edit mode
$existingFilesJsonForTfe = [];
if (!empty($currentFiles)) {
foreach ($currentFiles as $f) {
$ft = $f['file_type'] ?? '';
$fp = $f['file_path'] ?? '';
// Skip cover (handled separately) and website/peertube (no actual file)
if ($ft === 'cover' || str_starts_with($fp, 'http://') || str_starts_with($fp, 'https://') || str_starts_with($fp, 'peertube_ids:')) {
continue;
}
// Only include files that can be streamed back via load.php
$existingFilesJsonForTfe[] = [
'source' => (string)((int)$f['id']),
'options' => ['type' => 'local'],
];
}
}
// Build existing-files JSON for FilePond edit mode (all files including PeerTube)
$existingFilesJsonForTfe = $_buildExistingFilesJson($currentFiles ?? []);
include APP_ROOT . '/public/partage/fichiers-fragment.php';
$_POST = $_savedPost;