mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
feat: implement SQLite backup & data integrity plan (Phases 2-4)
This commit is contained in:
@@ -584,6 +584,32 @@
|
||||
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||
+\\\\\\\ to: psvklxsu ec511543 "fix: exclude entire var/ from rsync --delete to preserve logs" (rebased revision)
|
||||
++ $linkName = $link['name'] ?? '';
|
||||
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: psvklxsu ec511543 "fix: exclude entire var/ from rsync --delete to preserve logs" (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: ouqzmwvn fafb3fc6 "feat: implement SQLite backup & data integrity plan (Phases 2-4)" (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: ouqzmwvn 97412d13 "feat: implement SQLite backup & data integrity plan (Phases 2-4)" (rebased revision)
|
||||
++ $linkName = $link['name'] ?? '';
|
||||
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: ouqzmwvn 97412d13 "feat: implement SQLite backup & data integrity plan (Phases 2-4)" (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: wstuyzym f5810c41 "feat: implement SQLite backup & data integrity plan (Phases 2-4)" (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: wstuyzym 5886355c "feat: implement SQLite backup & data integrity plan (Phases 2-4)" (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">
|
||||
|
||||
@@ -88,16 +88,17 @@
|
||||
<fieldset>
|
||||
<legend>Restrictions d'accès aux fichiers</legend>
|
||||
|
||||
<div class="param-form">
|
||||
<input type="hidden" id="settings-csrf" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<div class="param-form" id="param-form-restrictions">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
|
||||
<label class="param-checkbox">
|
||||
<input type="hidden" name="restricted_files_enabled" value="0">
|
||||
<input type="checkbox" name="restricted_files_enabled" value="1"
|
||||
<?= ($siteSettings['restricted_files_enabled'] ?? '0') === '1' ? 'checked' : '' ?>
|
||||
hx-post="/admin/actions/settings.php"
|
||||
hx-trigger="change"
|
||||
hx-swap="none"
|
||||
hx-include="#settings-csrf"
|
||||
hx-include="#param-form-restrictions"
|
||||
hx-vals='{"section":"formulaire"}'>
|
||||
<span>
|
||||
<strong>Activer la restriction d'accès</strong><br>
|
||||
@@ -111,16 +112,17 @@
|
||||
<legend>Degré d'ouverture</legend>
|
||||
<p>Options de visibilité disponibles dans le formulaire d'ajout de TFE.</p>
|
||||
|
||||
<div class="param-form">
|
||||
<input type="hidden" id="settings-csrf-acces" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<div class="param-form" id="param-form-acces">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
|
||||
<label class="param-checkbox">
|
||||
<input type="hidden" name="access_type_libre_enabled" value="0">
|
||||
<input type="checkbox" name="access_type_libre_enabled" value="1"
|
||||
<?= ($siteSettings['access_type_libre_enabled'] ?? '0') === '1' ? 'checked' : '' ?>
|
||||
hx-post="/admin/actions/settings.php"
|
||||
hx-trigger="change"
|
||||
hx-swap="none"
|
||||
hx-include="#settings-csrf-acces"
|
||||
hx-include="#param-form-acces"
|
||||
hx-vals='{"section":"formulaire"}'>
|
||||
<span>
|
||||
<strong>Libre</strong><br>
|
||||
@@ -129,12 +131,13 @@
|
||||
</label>
|
||||
|
||||
<label class="param-checkbox">
|
||||
<input type="hidden" name="access_type_interne_enabled" value="0">
|
||||
<input type="checkbox" name="access_type_interne_enabled" value="1"
|
||||
<?= ($siteSettings['access_type_interne_enabled'] ?? '1') === '1' ? 'checked' : '' ?>
|
||||
hx-post="/admin/actions/settings.php"
|
||||
hx-trigger="change"
|
||||
hx-swap="none"
|
||||
hx-include="#settings-csrf-acces"
|
||||
hx-include="#param-form-acces"
|
||||
hx-vals='{"section":"formulaire"}'>
|
||||
<span>
|
||||
<strong>Interne</strong><br>
|
||||
@@ -143,12 +146,13 @@
|
||||
</label>
|
||||
|
||||
<label class="param-checkbox">
|
||||
<input type="hidden" name="access_type_interdit_enabled" value="0">
|
||||
<input type="checkbox" name="access_type_interdit_enabled" value="1"
|
||||
<?= ($siteSettings['access_type_interdit_enabled'] ?? '1') === '1' ? 'checked' : '' ?>
|
||||
hx-post="/admin/actions/settings.php"
|
||||
hx-trigger="change"
|
||||
hx-swap="none"
|
||||
hx-include="#settings-csrf-acces"
|
||||
hx-include="#param-form-acces"
|
||||
hx-vals='{"section":"formulaire"}'>
|
||||
<span>
|
||||
<strong>Interdit</strong><br>
|
||||
@@ -163,8 +167,8 @@
|
||||
<p>Active ou désactive les types de travaux dans les formulaires et la consultation. Un type désactivé ne peut plus être soumis ni affiché sur le site.</p>
|
||||
<p class="param-note">Le type <strong>TFE</strong> est toujours actif et ne peut pas être désactivé.</p>
|
||||
|
||||
<div class="param-form">
|
||||
<input type="hidden" id="settings-csrf-types" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<div class="param-form" id="param-form-types">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
|
||||
<label class="param-checkbox param-checkbox--disabled">
|
||||
<input type="checkbox" disabled checked>
|
||||
@@ -175,12 +179,13 @@
|
||||
</label>
|
||||
|
||||
<label class="param-checkbox">
|
||||
<input type="hidden" name="objet_these_enabled" value="0">
|
||||
<input type="checkbox" name="objet_these_enabled" value="1"
|
||||
<?= ($siteSettings['objet_these_enabled'] ?? '1') === '1' ? 'checked' : '' ?>
|
||||
hx-post="/admin/actions/settings.php"
|
||||
hx-trigger="change"
|
||||
hx-swap="none"
|
||||
hx-include="#settings-csrf-types"
|
||||
hx-include="#param-form-types"
|
||||
hx-vals='{"section":"objet_types"}'>
|
||||
<span>
|
||||
<strong>Thèse</strong><br>
|
||||
@@ -189,12 +194,13 @@
|
||||
</label>
|
||||
|
||||
<label class="param-checkbox">
|
||||
<input type="hidden" name="objet_frart_enabled" value="0">
|
||||
<input type="checkbox" name="objet_frart_enabled" value="1"
|
||||
<?= ($siteSettings['objet_frart_enabled'] ?? '1') === '1' ? 'checked' : '' ?>
|
||||
hx-post="/admin/actions/settings.php"
|
||||
hx-trigger="change"
|
||||
hx-swap="none"
|
||||
hx-include="#settings-csrf-types"
|
||||
hx-include="#param-form-types"
|
||||
hx-vals='{"section":"objet_types"}'>
|
||||
<span>
|
||||
<strong>Frart</strong><br>
|
||||
|
||||
82
app/templates/admin/index-trash.php
Normal file
82
app/templates/admin/index-trash.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<main id="main-content" class="admin-main--list">
|
||||
<div class="admin-list-toolbar admin-list-toolbar--list">
|
||||
<div class="admin-toolbar-top">
|
||||
<div class="admin-toolbar-title-row">
|
||||
<h1><a href="/admin/" class="admin-back-btn" title="Retour à la liste"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48-88a8,8,0,0,1-8,8H107.31l18.35,18.34a8,8,0,0,1-11.32,11.32l-32-32a8,8,0,0,1,0-11.32l32-32a8,8,0,0,1,11.32,11.32L107.31,120H168A8,8,0,0,1,176,128Z"></path></svg></a> Corbeille</h1>
|
||||
<span class="admin-stat admin-stat--inline" style="margin-left:auto"><?= count($trashedTheses) ?> TFE(s)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$flash = App::consumeFlash();
|
||||
?>
|
||||
<?php if ($flash['success']): ?>
|
||||
<div class="flash-success" role="alert"><?= htmlspecialchars($flash['success']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($flash['error']): ?>
|
||||
<div class="flash-error" role="alert"><?= htmlspecialchars($flash['error']) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($trashedTheses)): ?>
|
||||
<div class="admin-empty">La corbeille est vide.</div>
|
||||
<?php else: ?>
|
||||
<form method="post" action="actions/corbeille.php" style="margin-bottom:var(--space-xs)">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="empty_trash">
|
||||
<button type="submit" class="btn btn--danger btn--sm" onclick="return confirm('Vider toute la corbeille ? Cette action est irréversible.')">
|
||||
Vider la corbeille
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Titre</th>
|
||||
<th scope="col">Auteur(s)</th>
|
||||
<th scope="col">Année</th>
|
||||
<th scope="col">Supprimé le</th>
|
||||
<th scope="col" style="width:1%">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($trashedTheses as $t): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($t['identifier'] ?? '#' . $t['id']) ?></td>
|
||||
<td>
|
||||
<strong><?= htmlspecialchars($t['title']) ?></strong>
|
||||
<?php if (!empty($t['subtitle'])): ?>
|
||||
<br><small><?= htmlspecialchars($t['subtitle']) ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($t['authors'] ?? '—') ?></td>
|
||||
<td><?= (int)$t['year'] ?></td>
|
||||
<td><?= htmlspecialchars($t['deleted_at']) ?></td>
|
||||
<td class="admin-actions-col">
|
||||
<div class="admin-actions">
|
||||
<form method="post" action="actions/corbeille.php" class="admin-inline-form" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="restore">
|
||||
<input type="hidden" name="thesis_id" value="<?= (int)$t['id'] ?>">
|
||||
<button type="submit" class="admin-icon-btn admin-icon-btn--edit" title="Restaurer">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM176,208H80a8,8,0,0,1,0-16h96a8,8,0,0,1,0,16Zm0-32H80a8,8,0,0,1,0-16h96a8,8,0,0,1,0,16Z"/></svg>
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="actions/corbeille.php" class="admin-inline-form" style="display:inline"
|
||||
onsubmit="return confirm('Supprimer définitivement ce TFE ? Cette action est irréversible.')">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="hard_delete">
|
||||
<input type="hidden" name="thesis_id" value="<?= (int)$t['id'] ?>">
|
||||
<button type="submit" class="admin-icon-btn admin-icon-btn--delete" title="Supprimer définitivement">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z"/></svg>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
@@ -32,6 +32,11 @@ document.addEventListener('htmx:afterSwap',()=>{document.querySelectorAll('input
|
||||
<div class="admin-btn-group">
|
||||
<a href="/admin/add.php" class="btn btn--primary btn--sm">+ Ajouter un TFE</a>
|
||||
<a href="/admin/tags.php" class="btn btn--primary btn--sm">Mots-clés</a>
|
||||
<?php if ($trashCount > 0): ?>
|
||||
<a href="/admin/index.php?tab=trash" class="btn btn--sm <?= $tab === 'trash' ? 'btn--primary' : 'btn--secondary' ?>">
|
||||
Corbeille (<?= $trashCount ?>)
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="btn btn--primary btn--sm" id="import-dialog-btn"
|
||||
onclick="document.getElementById('import-dialog').showModal()">
|
||||
Importer
|
||||
|
||||
Reference in New Issue
Block a user