v1.0.0.0
StocketBase
- <?php
-
- declare(strict_types=1);
-
- if (count(get_included_files()) === 1) {
- http_response_code(403);
- exit;
- }
-
- $db = Database::site();
- $isAdmin = Auth::hasRoleAtLeast(Auth::ROLE_STORE_OWNER);
-
- $statement = $isAdmin
- ? $db->query('SELECT p.id, p.title, p.trashed_status, p.deleted_at, t.display_name FROM products p JOIN team_accounts t ON t.id = p.created_by WHERE p.deleted_at IS NOT NULL ORDER BY p.deleted_at DESC')
- : $db->prepare('SELECT p.id, p.title, p.trashed_status, p.deleted_at, t.display_name FROM products p JOIN team_accounts t ON t.id = p.created_by WHERE p.deleted_at IS NOT NULL AND p.created_by = :id ORDER BY p.deleted_at DESC');
-
- if (!$isAdmin) {
- $statement->execute(['id' => $currentUser['id']]);
- }
-
- $trashed = $statement->fetchAll();
-
- $trashedFileCounts = [];
- if (!empty($trashed)) {
- $trashedIds = array_map(static fn(array $row): int => (int) $row['id'], $trashed);
- $placeholders = implode(',', array_fill(0, count($trashedIds), '?'));
- try {
- $countStatement = $db->prepare("SELECT product_id, COUNT(*) AS files FROM product_files WHERE product_id IN ({$placeholders}) GROUP BY product_id");
- $countStatement->execute($trashedIds);
- foreach ($countStatement->fetchAll() as $countRow) {
- $trashedFileCounts[(int) $countRow['product_id']] = (int) $countRow['files'];
- }
- } catch (PDOException $exception) {
- $trashedFileCounts = [];
- }
- }
- $trashHasFiles = array_sum($trashedFileCounts) > 0;
-
- $renderFileDialog = static function (string $dialogId, string $action, ?int $productId, string $question, int $fileCount): string {
- return '<dialog class="dash-dialog" id="' . htmlspecialchars($dialogId) . '">'
- . '<form method="post">'
- . Csrf::field()
- . '<input type="hidden" name="action" value="' . htmlspecialchars($action) . '">'
- . ($productId !== null ? '<input type="hidden" name="product_id" value="' . $productId . '">' : '')
- . '<h2 class="dash-dialog-title">' . Icons::icon('download', 'icon icon-sm') . htmlspecialchars($question) . '</h2>'
- . '<p class="dash-dialog-text">This will permanently delete the product' . ($productId === null ? 's' : '') . '. '
- . 'Attached downloadable files: ' . $fileCount . '.</p>'
- . '<p class="dash-dialog-text"><strong>Do you also want to remove access to the files?</strong></p>'
- . '<ul class="dash-dialog-list">'
- . '<li><strong>Keep files</strong> — customers who already bought the product can still download them. The files stay under Files.</li>'
- . '<li><strong>Delete files</strong> — the files are erased and every customer loses access. This cannot be undone.</li>'
- . '</ul>'
- . '<div class="dash-dialog-actions">'
- . '<button type="button" class="dash-btn" onclick="this.closest(\'dialog\').close();">Cancel</button>'
- . '<button type="submit" name="file_action" value="keep" class="dash-btn dash-btn-primary">Delete product, keep files</button>'
- . '<button type="submit" name="file_action" value="delete" class="dash-btn dash-btn-danger">Delete product and files</button>'
- . '</div>'
- . '</form>'
- . '</dialog>';
- };
-
- ?>
- <div class="dash-header-row">
- <h1 class="dash-title"><?= Icons::icon('trash', 'icon icon-lg') ?>Trash</h1>
- <a href="dashboard.php?view=products" class="dash-btn"><?= Icons::icon('grid', 'icon icon-sm') ?>Back to products</a>
- <?php if (!empty($trashed)): ?>
- <?php if ($trashHasFiles): ?>
- <button type="button" class="dash-btn dash-btn-danger" onclick="document.getElementById('trash-dialog-all').showModal();"><?= Icons::icon('trash', 'icon icon-sm') ?>Empty trash</button>
- <?= $renderFileDialog('trash-dialog-all', 'empty_trash', null, 'Empty the trash?', array_sum($trashedFileCounts)) ?>
- <?php else: ?>
- <form method="post" style="display:inline;" onsubmit="return confirm('Permanently delete everything in the trash? This cannot be undone.');">
- <?= Csrf::field() ?>
- <input type="hidden" name="action" value="empty_trash">
- <button type="submit" class="dash-btn dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Empty trash</button>
- </form>
- <?php endif; ?>
- <?php endif; ?>
- </div>
-
- <table class="dash-table">
- <thead>
- <tr>
- <th><?= Icons::icon('heading', 'icon icon-sm') ?>Title</th>
- <th><?= Icons::icon('user', 'icon icon-sm') ?>Created by</th>
- <th><?= Icons::icon('flag', 'icon icon-sm') ?>Was</th>
- <th><?= Icons::icon('clock', 'icon icon-sm') ?>Deleted</th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($trashed as $product): ?>
- <tr>
- <td><?= htmlspecialchars($product['title']) ?><?php if (($trashedFileCounts[(int) $product['id']] ?? 0) > 0): ?> <span class="status-pill status-scheduled"><?= (int) $trashedFileCounts[(int) $product['id']] ?> file<?= $trashedFileCounts[(int) $product['id']] === 1 ? '' : 's' ?></span><?php endif; ?></td>
- <td><?= htmlspecialchars($product['display_name']) ?></td>
- <td><?= htmlspecialchars((string) ($product['trashed_status'] ?? 'draft')) ?></td>
- <td><?= htmlspecialchars($product['deleted_at']) ?></td>
- <td class="dash-table-actions">
- <form method="post" style="display:inline;">
- <?= Csrf::field() ?>
- <input type="hidden" name="action" value="restore_product">
- <input type="hidden" name="product_id" value="<?= (int) $product['id'] ?>">
- <button type="submit" class="dash-btn-small dash-btn-success"><?= Icons::icon('refresh', 'icon icon-sm') ?>Restore</button>
- </form>
- <?php $productFileCount = $trashedFileCounts[(int) $product['id']] ?? 0; ?>
- <?php if ($productFileCount > 0): ?>
- <button type="button" class="dash-btn-small dash-btn-danger" onclick="document.getElementById('trash-dialog-<?= (int) $product['id'] ?>').showModal();"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete forever</button>
- <?= $renderFileDialog('trash-dialog-' . (int) $product['id'], 'purge_product', (int) $product['id'], 'Delete "' . $product['title'] . '" forever?', $productFileCount) ?>
- <?php else: ?>
- <form method="post" style="display:inline;" onsubmit="return confirm('Permanently delete this product? This cannot be undone.');">
- <?= Csrf::field() ?>
- <input type="hidden" name="action" value="purge_product">
- <input type="hidden" name="product_id" value="<?= (int) $product['id'] ?>">
- <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete forever</button>
- </form>
- <?php endif; ?>
- </td>
- </tr>
- <?php endforeach; ?>
- <?php if (empty($trashed)): ?>
- <tr><td colspan="5">The trash is empty.</td></tr>
- <?php endif; ?>
- </tbody>
- </table>
-