mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-10 15:21:22 +02:00
cleanup: sélection multiple + page dédiée (/admin/cleanup.php)
- cleanup-tmp.php: accepte les arrays filepond_dirs[] et trash_files[] pour suppression en lot - cleanup-stats-fragment.php: ajout checkboxes + barre d'actions groupées + formulaire bulk HTMX - admin-cleanup-bulk.js: module JS pour toggleAll, updateBulk, bulkDelete - Nouvelle page /admin/cleanup.php remplace la modale (tmp-cleanup.php supprimé) - Bouton Nettoyer dans index.php devient un lien vers la page dédiée
This commit is contained in:
@@ -41,7 +41,7 @@ elseif ($staleSize > 0) { $staleHuman = $staleSize . ' B'; }
|
||||
$summaryMeta = $staleMeta;
|
||||
if ($staleHuman) $summaryMeta .= ' · ' . $staleHuman;
|
||||
|
||||
if ($totalStale === 0 && $totalFiles === 0): ?>
|
||||
<?php if ($totalStale === 0 && $totalFiles === 0): ?>
|
||||
<div id="tmp-cleanup-stats-wrapper">
|
||||
<details class="n-section" open>
|
||||
<summary>
|
||||
@@ -54,6 +54,27 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
|
||||
<?php return; endif; ?>
|
||||
|
||||
<div id="tmp-cleanup-stats-wrapper">
|
||||
<!-- 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="outerHTML"
|
||||
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>
|
||||
|
||||
<details class="n-section" open>
|
||||
<summary>
|
||||
<?= icon('paint-brush-household') ?>
|
||||
@@ -62,10 +83,11 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
|
||||
|
||||
<?php if ($fpStale > 0): ?>
|
||||
<table class="n-table">
|
||||
<thead><tr><th>Nom</th><th>Taille</th><th>Âge</th><th width="1%"></th></tr></thead>
|
||||
<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>
|
||||
@@ -93,10 +115,11 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
|
||||
Corbeille
|
||||
</p>
|
||||
<table class="n-table">
|
||||
<thead><tr><th>Nom</th><th>Taille</th><th>Âge</th><th width="1%"></th></tr></thead>
|
||||
<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>
|
||||
|
||||
@@ -43,32 +43,42 @@ $details = [];
|
||||
$db = new Database();
|
||||
$pdo = $db->getPDO();
|
||||
|
||||
// ── Individual deletion mode ────────────────────────────────────────────
|
||||
// ── Individual / bulk deletion mode ────────────────────────────────────
|
||||
$individualFilepond = trim($_POST['filepond_dir'] ?? '');
|
||||
$individualTrash = trim($_POST['trash_file'] ?? '');
|
||||
$bulkFilepond = $_POST['filepond_dirs'] ?? [];
|
||||
$bulkTrash = $_POST['trash_files'] ?? [];
|
||||
|
||||
if ($individualFilepond !== '' || $individualTrash !== '') {
|
||||
if ($individualFilepond !== '') {
|
||||
$dirPath = $filepondDir . '/' . basename($individualFilepond);
|
||||
// Normalize: single values also become arrays for unified handling
|
||||
$filepondItems = $individualFilepond !== '' ? [$individualFilepond] : (is_array($bulkFilepond) ? $bulkFilepond : []);
|
||||
$trashItems = $individualTrash !== '' ? [$individualTrash] : (is_array($bulkTrash) ? $bulkTrash : []);
|
||||
|
||||
if (!empty($filepondItems) || !empty($trashItems)) {
|
||||
foreach ($filepondItems as $item) {
|
||||
$item = trim($item);
|
||||
if ($item === '') continue;
|
||||
$dirPath = $filepondDir . '/' . basename($item);
|
||||
if (is_dir($dirPath) && str_starts_with(realpath($dirPath), realpath($filepondDir))) {
|
||||
rmdirRecursive($dirPath);
|
||||
$filepondRemoved = 1;
|
||||
$details[] = "filepond/$individualFilepond: suppression manuelle";
|
||||
$filepondRemoved++;
|
||||
$details[] = "filepond/$item: suppression manuelle";
|
||||
} else {
|
||||
$errors[] = 'Dossier introuvable : ' . htmlspecialchars($individualFilepond);
|
||||
$errors[] = 'Dossier introuvable : ' . htmlspecialchars($item);
|
||||
}
|
||||
}
|
||||
if ($individualTrash !== '') {
|
||||
$filePath = $trashDir . '/' . basename($individualTrash);
|
||||
foreach ($trashItems as $item) {
|
||||
$item = trim($item);
|
||||
if ($item === '') continue;
|
||||
$filePath = $trashDir . '/' . basename($item);
|
||||
if (is_file($filePath) && str_starts_with(realpath($filePath), realpath($trashDir))) {
|
||||
if (@unlink($filePath)) {
|
||||
$trashRemoved = 1;
|
||||
$details[] = "_trash/$individualTrash: suppression manuelle";
|
||||
$trashRemoved++;
|
||||
$details[] = "_trash/$item: suppression manuelle";
|
||||
} else {
|
||||
$errors[] = 'Impossible de supprimer : ' . htmlspecialchars($individualTrash);
|
||||
$errors[] = 'Impossible de supprimer : ' . htmlspecialchars($item);
|
||||
}
|
||||
} else {
|
||||
$errors[] = 'Fichier introuvable : ' . htmlspecialchars($individualTrash);
|
||||
$errors[] = 'Fichier introuvable : ' . htmlspecialchars($item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../bootstrap.php';
|
||||
require_once __DIR__ . '/../../src/AdminAuth.php';
|
||||
AdminAuth::requireLogin();
|
||||
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
$pageTitle = 'Nettoyer les fichiers temporaires';
|
||||
|
||||
$isAdmin = true;
|
||||
$bodyClass = 'admin-body';
|
||||
$extraCssAdmin = [];
|
||||
$extraJs = ['/assets/dist/admin.min.js'];
|
||||
|
||||
require_once APP_ROOT . '/templates/head.php';
|
||||
include APP_ROOT . '/templates/header.php';
|
||||
include APP_ROOT . '/templates/admin/cleanup.php';
|
||||
require_once APP_ROOT . '/templates/admin/footer.php';
|
||||
Reference in New Issue
Block a user