mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-10 07:11:18 +02:00
Two critical fixes: 1. Relink flow no longer destroys/recreates FilePond instances: The relink (XamxamRelinkFile) and PeerTube relink (XamxamRelinkPeerTube) previously refreshed the entire fichiers fragment via HTMX after pond.addFile(). This triggered destroyFilePondsIn on ALL pools, which could fire server.remove callbacks and move existing files to corbeille. Now just closes the modal — the file is already added to the pool in-place, and syncOrderInput creates the hidden form input. 2. Cleanup page « Corbeille (restaurable) » now actually shows files: _cleanup-stats-data.php previously classified trash files by checking if the thesis_files DB row still existed. But both deleteThesisFileToTrash and FilepondHandler::handleRemove DELETE the DB row. So ALL trash files appeared as `stale` (not restorable). Now uses the JSON sidecar file presence as the classification criterion — if the sidecar exists and is recent, the file is restorable regardless of DB row state. Also removed unused DB query from _cleanup-stats-data.php.
182 lines
9.4 KiB
PHP
182 lines
9.4 KiB
PHP
<?php
|
|
/**
|
|
* Temp file statistics as an HTML fragment (admin).
|
|
*
|
|
* GET /admin/actions/cleanup-stats-fragment.php
|
|
*
|
|
* Returns an HTML fragment ready for HTMX innerHTML swap into #tmp-cleanup-stats-wrapper.
|
|
*/
|
|
require_once __DIR__ . '/../../../bootstrap.php';
|
|
require_once __DIR__ . '/../../../src/AdminAuth.php';
|
|
AdminAuth::requireLogin();
|
|
|
|
require_once __DIR__ . '/_cleanup-stats-data.php';
|
|
$d = getCleanupStats();
|
|
|
|
$fpStale = $d['filepond_stale_count'] ?? 0;
|
|
$fpActive = $d['filepond_active_count'] ?? 0;
|
|
$trStale = $d['trash_stale_count'] ?? 0;
|
|
$trActive = $d['trash_active_count'] ?? 0;
|
|
|
|
$totalStale = $fpStale + $trStale;
|
|
$totalFiles = $fpStale + $fpActive + $trStale + $trActive;
|
|
|
|
$staleSize = ($d['filepond_stale_size'] ?? 0) + ($d['trash_stale_size'] ?? 0);
|
|
$staleHuman = '';
|
|
if ($staleSize >= 1073741824) { $staleHuman = number_format($staleSize / 1073741824, 1) . ' GB'; }
|
|
elseif ($staleSize >= 1048576) { $staleHuman = number_format($staleSize / 1048576, 1) . ' MB'; }
|
|
elseif ($staleSize >= 1024) { $staleHuman = number_format($staleSize / 1024, 0) . ' KB'; }
|
|
elseif ($staleSize > 0) { $staleHuman = $staleSize . ' B'; }
|
|
|
|
$fpMeta = $fpStale . ' dossier' . ($fpStale > 1 ? 's' : '');
|
|
if ($fpStale > 0) {
|
|
$fpMeta .= ' · ' . ($d['filepond_stale_human'] ?? '');
|
|
}
|
|
$trMeta = $trStale . ' fichier' . ($trStale > 1 ? 's' : '');
|
|
if ($trStale > 0) {
|
|
$trMeta .= ' · ' . ($d['trash_stale_human'] ?? '');
|
|
}
|
|
?>
|
|
<?php if ($totalStale === 0 && $totalFiles === 0): ?>
|
|
<p style="margin:0;color:var(--accent-green)">✓ Aucun fichier temporaire.</p>
|
|
<?php return; endif; ?>
|
|
|
|
<!-- Bulk actions bar -->
|
|
<div id="cleanup-bulk-actions" class="admin-bulk-actions" style="display:none">
|
|
<strong><span id="cleanup-selected-count">0</span> fichier(s) sélectionné(s)</strong>
|
|
<div class="admin-bulk-btns">
|
|
<button type="button" class="btn btn--sm btn--red" onclick="cleanupBulkDelete()">
|
|
<?= icon('trash') ?> Supprimer la sélection
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hidden bulk form (HTMX-powered) -->
|
|
<form id="cleanup-bulk-form" method="post" action="/admin/actions/cleanup-tmp.php"
|
|
hx-post="/admin/actions/cleanup-tmp.php"
|
|
hx-target="#tmp-cleanup-stats-wrapper"
|
|
hx-swap="innerHTML"
|
|
hx-indicator="#tmp-cleanup-stats-wrapper"
|
|
style="display:none">
|
|
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
|
<div id="cleanup-bulk-checkboxes"></div>
|
|
</form>
|
|
|
|
<?php if ($fpStale > 0): ?>
|
|
<h3 id="tmp-filepond-heading">Téléversements abandonnés <span class="n-meta"><?= htmlspecialchars($fpMeta) ?></span></h3>
|
|
<table class="n-table" aria-labelledby="tmp-filepond-heading">
|
|
<thead><tr><th width="1%"><input type="checkbox" onchange="cleanupToggleAll(this, 'filepond')" title="Tout sélectionner"></th><th>Nom</th><th>Taille</th><th>Âge</th><th width="1%"></th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($d['filepond_stale_files'] as $f): ?>
|
|
<tr>
|
|
<td><input type="checkbox" name="filepond_dirs[]" value="<?= htmlspecialchars($f['name']) ?>" data-cleanup-group="filepond" onchange="cleanupUpdateBulk()"></td>
|
|
<td><strong><?= htmlspecialchars($f['name']) ?></strong></td>
|
|
<td style="white-space:nowrap"><?= htmlspecialchars($f['human']) ?></td>
|
|
<td style="white-space:nowrap">~<?= (int)$f['age_minutes'] ?> min</td>
|
|
<td style="white-space:nowrap">
|
|
<button type="button" class="btn btn--sm btn--danger" style="font-size:0.85em;padding:2px var(--space-xs)"
|
|
hx-post="/admin/actions/cleanup-tmp.php"
|
|
hx-confirm="Supprimer définitivement ce téléversement abandonné ?"
|
|
hx-vals='{"csrf_token":"<?= htmlspecialchars($_SESSION['csrf_token']) ?>","filepond_dir":"<?= htmlspecialchars($f['name']) ?>"}'
|
|
hx-target="#tmp-cleanup-stats-wrapper"
|
|
hx-swap="innerHTML"
|
|
hx-indicator="#tmp-cleanup-stats-wrapper">
|
|
<?= icon('trash') ?>
|
|
Supprimer
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($trStale > 0): ?>
|
|
<h3 id="tmp-trash-heading">Corbeille (à nettoyer) <span class="n-meta"><?= htmlspecialchars($trMeta) ?></span></h3>
|
|
<table class="n-table" aria-labelledby="tmp-trash-heading">
|
|
<thead><tr><th width="1%"><input type="checkbox" onchange="cleanupToggleAll(this, 'trash')" title="Tout sélectionner"></th><th>Nom</th><th>Taille</th><th>Âge</th><th width="1%"></th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($d['trash_stale_files'] as $f): ?>
|
|
<tr>
|
|
<td><input type="checkbox" name="trash_files[]" value="<?= htmlspecialchars($f['name']) ?>" data-cleanup-group="trash" onchange="cleanupUpdateBulk()"></td>
|
|
<td><strong><?= htmlspecialchars($f['name']) ?></strong></td>
|
|
<td style="white-space:nowrap"><?= htmlspecialchars($f['human']) ?></td>
|
|
<td style="white-space:nowrap">~<?= (int)$f['age_days'] ?> j</td>
|
|
<td style="white-space:nowrap">
|
|
<button type="button" class="btn btn--sm btn--danger" style="font-size:0.85em;padding:2px var(--space-xs)"
|
|
hx-post="/admin/actions/cleanup-tmp.php"
|
|
hx-confirm="Supprimer définitivement ce fichier de la corbeille ?"
|
|
hx-vals='{"csrf_token":"<?= htmlspecialchars($_SESSION['csrf_token']) ?>","trash_file":"<?= htmlspecialchars($f['name']) ?>"}'
|
|
hx-target="#tmp-cleanup-stats-wrapper"
|
|
hx-swap="innerHTML"
|
|
hx-indicator="#tmp-cleanup-stats-wrapper">
|
|
<?= icon('trash') ?>
|
|
Supprimer
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
|
|
<?php
|
|
$trActiveFiles = $d['trash_active_files'] ?? [];
|
|
if (!empty($trActiveFiles)):
|
|
$trActiveMeta = $trActive . ' fichier' . ($trActive > 1 ? 's' : '');
|
|
if ($trActive > 0) {
|
|
$trActiveMeta .= ' · ' . ($d['trash_active_human'] ?? '');
|
|
}
|
|
?>
|
|
<h3 id="tmp-trash-restore-heading">Corbeille (restaurable) <span class="n-meta"><?= htmlspecialchars($trActiveMeta) ?></span></h3>
|
|
<p style="font-size:0.85em;color:var(--text-secondary);margin:0 0 var(--space-sm)">
|
|
Fichiers récemment supprimés pour lesquels le TFE associé existe encore. Vous pouvez les restaurer ou les supprimer définitivement.
|
|
</p>
|
|
<table class="n-table" aria-labelledby="tmp-trash-restore-heading">
|
|
<thead><tr><th>Nom</th><th>Taille</th><th>Âge</th><th>Origine</th><th width="1%"></th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($trActiveFiles as $f): ?>
|
|
<tr>
|
|
<td><strong><?= htmlspecialchars($f['name']) ?></strong></td>
|
|
<td style="white-space:nowrap"><?= htmlspecialchars($f['human']) ?></td>
|
|
<td style="white-space:nowrap">~<?= (int)$f['age_days'] ?> j</td>
|
|
<td style="font-size:0.85em;color:var(--text-secondary)">
|
|
<?= $f['has_sidecar'] ? htmlspecialchars($f['original_name'] ?? '?') . ' (' . htmlspecialchars($f['file_type'] ?? '?') . ')' : 'métadonnées indisponibles' ?>
|
|
</td>
|
|
<td style="white-space:nowrap">
|
|
<?php if ($f['has_sidecar']): ?>
|
|
<button type="button" class="btn btn--sm"
|
|
style="font-size:0.85em;padding:2px var(--space-xs);margin-right:4px"
|
|
hx-post="/admin/actions/restore-trash.php"
|
|
hx-confirm="Restaurer ce fichier vers le TFE associé ?"
|
|
hx-vals='{"csrf_token":"<?= htmlspecialchars($_SESSION['csrf_token']) ?>","trash_file":"<?= htmlspecialchars($f['name']) ?>"}'
|
|
hx-target="#tmp-cleanup-stats-wrapper"
|
|
hx-swap="innerHTML"
|
|
hx-indicator="#tmp-cleanup-stats-wrapper">
|
|
↺ Restaurer
|
|
</button>
|
|
<?php endif; ?>
|
|
<button type="button" class="btn btn--sm btn--danger"
|
|
style="font-size:0.85em;padding:2px var(--space-xs)"
|
|
hx-post="/admin/actions/cleanup-tmp.php"
|
|
hx-confirm="Supprimer définitivement ce fichier de la corbeille ?"
|
|
hx-vals='{"csrf_token":"<?= htmlspecialchars($_SESSION['csrf_token']) ?>","trash_file":"<?= htmlspecialchars($f['name']) ?>"}'
|
|
hx-target="#tmp-cleanup-stats-wrapper"
|
|
hx-swap="innerHTML"
|
|
hx-indicator="#tmp-cleanup-stats-wrapper">
|
|
<?= icon('trash') ?>
|
|
Supprimer
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($fpActive > 0): ?>
|
|
<p style="margin:var(--space-sm) 0 0 0;font-size:0.85em;color:var(--text-secondary)">Conservés :
|
|
<?= $fpActive . ' téléversement(s) actif(s) (' . htmlspecialchars($d['filepond_active_human']) . ')' ?>
|
|
</p>
|
|
<?php endif; ?>
|