Files
maria_uslugi/admin/tools/cleanup_inscriptions.php
T
2026-03-05 10:25:39 +01:00

180 lines
6.7 KiB
PHP

<?php
require_once __DIR__ . '/../../public/includes/init_admin.php';
if (session_status() !== PHP_SESSION_ACTIVE) {
@session_start();
}
// Lang (pour $translations)
function e($s): string {
return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}
const ADMIN_PRACTICIEN_ID = 88888888;
$me = (int)($_SESSION['reference_id'] ?? 0);
if ($me !== ADMIN_PRACTICIEN_ID) {
http_response_code(403);
echo '<div class="container py-5"><div class="alert alert-danger">'
. e($translations['admin_access_denied'] ?? 'Доступ запрещён.')
. '</div></div>';
exit;
}
// Reauth (10 min)
$mustReauth = function (int $ttl = 600) {
$t = (int)($_SESSION['admin_reauth_at'] ?? 0);
return ($t === 0 || (time() - $t) > $ttl);
};
if ($mustReauth()) {
$qs = http_build_query(['page' => 'reauth', 'redir' => ($_SERVER['REQUEST_URI'] ?? 'index.php?page=maintenance')]);
header('Location:?' . $qs);
exit;
}
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// CSRF
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$CSRF = $_SESSION['csrf_token'];
// Récupération des comptes non validés depuis >6h
$sql = "SELECT * FROM compte WHERE email_valide = 0 AND TIMESTAMPDIFF(HOUR, cree_le, NOW()) > 6";
$stmt = $pdo->query($sql);
$comptes = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Ajouter nom, prénom et âge du compte
foreach ($comptes as &$c) {
$nom = $prenom = ($translations['label_unknown'] ?? '(inconnu)');
if ($c['role'] === 'client') {
$stmt2 = $pdo->prepare("SELECT nom, prenom FROM client WHERE id = :id");
$stmt2->execute(['id' => $c['reference_id']]);
$info = $stmt2->fetch(PDO::FETCH_ASSOC);
if ($info) { $nom = $info['nom']; $prenom = $info['prenom']; }
} elseif ($c['role'] === 'praticien') {
$stmt2 = $pdo->prepare("SELECT nom, prenom FROM praticien WHERE id = :id");
$stmt2->execute(['id' => $c['reference_id']]);
$info = $stmt2->fetch(PDO::FETCH_ASSOC);
if ($info) { $nom = $info['nom']; $prenom = $info['prenom']; }
}
$c['nom'] = $nom;
$c['prenom'] = $prenom;
// Calculer la durée depuis création
$diff = time() - strtotime($c['cree_le']);
$heures = floor($diff / 3600);
$minutes = floor(($diff % 3600) / 60);
$c['age_humain'] = sprintf("%dh %02dmin", $heures, $minutes);
}
unset($c);
// --- Suppression sur POST ---
if ($_SERVER['REQUEST_METHOD'] === 'POST'
&& isset($_POST['csrf_token'])
&& hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])
&& !empty($_POST['ids'])) {
$idsToDelete = array_map('intval', $_POST['ids']);
$deleted = 0;
foreach ($comptes as $compte) {
if (!in_array($compte['id'], $idsToDelete, true)) continue;
$id = $compte['id'];
$role = $compte['role'];
$ref_id = $compte['reference_id'];
// Supprimer fiche associée
if ($role === 'client') {
$pdo->prepare("DELETE FROM client WHERE id = :id")->execute(['id' => $ref_id]);
} elseif ($role === 'praticien') {
$pdo->prepare("DELETE FROM praticien WHERE id = :id")->execute(['id' => $ref_id]);
}
// Supprimer le compte
$pdo->prepare("DELETE FROM compte WHERE id = :id")->execute(['id' => $id]);
$deleted++;
}
$msgTpl = ($translations['flash_unverified_deleted'] ?? '✅ {N} compte(s) non validé(s) supprimé(s).');
$msg = str_replace('{N}', (string)$deleted, $msgTpl);
echo '<div class="alert alert-success text-center p-4">'
. e($msg)
. '</div>';
exit;
}
?>
<div class="shadow p-4 rounded bg-light">
<h2 class="mb-3 text-center">
<?= e($translations['h2_unverified_accounts_6h'] ?? '🕒 Comptes non validés depuis plus de 6h') ?>
</h2>
<?php if (empty($comptes)): ?>
<div class="alert alert-success text-center">
<?= e($translations['alert_no_unverified_accounts'] ?? 'Aucun compte non validé à supprimer 🎉') ?>
</div>
<?php else: ?>
<form method="post" onsubmit="return confirm('<?= e($translations['confirm_delete_checked_accounts'] ?? '⚠️ Supprimer les comptes cochés ?') ?>');">
<input type="hidden" name="csrf_token" value="<?= e($CSRF) ?>">
<table class="table table-bordered table-sm align-middle text-center">
<thead class="table-secondary">
<tr>
<th><input type="checkbox" id="checkAll" aria-label="<?= e($translations['aria_check_all'] ?? 'Tout cocher') ?>"></th>
<th><?= e($translations['th_id'] ?? 'ID') ?></th>
<th><?= e($translations['th_email'] ?? 'Email') ?></th>
<th><?= e($translations['th_nom'] ?? 'Nom') ?></th>
<th><?= e($translations['th_prenom'] ?? 'Prénom') ?></th>
<th><?= e($translations['th_role'] ?? 'Rôle') ?></th>
<th><?= e($translations['th_created_at'] ?? 'Créé le') ?></th>
<th><?= e($translations['th_account_age'] ?? 'Âge du compte') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($comptes as $compte): ?>
<tr>
<td><input type="checkbox" name="ids[]" value="<?= (int)$compte['id'] ?>"></td>
<td><?= e($compte['id']) ?></td>
<td><?= e($compte['email']) ?></td>
<td><?= e($compte['nom']) ?></td>
<td><?= e($compte['prenom']) ?></td>
<td><?= e($compte['role']) ?></td>
<td><?= e($compte['cree_le']) ?></td>
<td><?= e($compte['age_humain']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="d-flex justify-content-between align-items-center mt-3">
<small class="text-muted">
<?php
$tpl = ($translations['label_accounts_listed'] ?? 'Comptes listés : {N}');
echo e(str_replace('{N}', (string)count($comptes), $tpl));
?>
</small>
<button type="submit" class="btn btn-danger">
<?= e($translations['btn_delete_checked_accounts'] ?? '🗑️ Supprimer les comptes cochés') ?>
</button>
</div>
</form>
<script>
// Cocher / décocher tout
document.getElementById('checkAll').addEventListener('change', function() {
const boxes = document.querySelectorAll('input[name="ids[]"]');
boxes.forEach(b => b.checked = this.checked);
});
</script>
<?php endif; ?>
</div>