Files
maria_uslugi/supprimer_compte.php
2026-03-05 10:25:39 +01:00

277 lines
10 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/public/includes/init_pr_cl.php';
$translations = $translations ?? [];
// Sécurité : rôle client ou praticien
require_login_or_redirect(['client', 'praticien']);
// Infos de session
$compteId = (int)($_SESSION['compte_id'] ?? 0);
$sessionRole = $_SESSION['role'] ?? null;
if ($compteId <= 0 || !in_array($sessionRole, ['client', 'praticien'], true)) {
header('Location: /connexion.php');
exit;
}
// CSRF
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
}
$CSRF = $_SESSION['csrf_token'];
// Messages d’erreur
$errorMsg = null;
// --------------------------------------------------
// Traitement POST : demande de suppression
// --------------------------------------------------
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf'] ?? '')) {
$errorMsg = $translations['delete_account_error_csrf'] ?? 'Erreur de sécurité, veuillez réessayer.';
} else {
$password = (string)($_POST['password'] ?? '');
$confirm = (string)($_POST['confirm_delete'] ?? '');
if ($password === '' || $confirm !== '1') {
$errorMsg = $translations['delete_account_error_form'] ?? 'Veuillez confirmer la suppression et saisir votre mot de passe.';
} else {
try {
// Récupérer le compte
$stmt = $pdo->prepare('SELECT id, email, mot_de_passe, role, reference_id FROM compte WHERE id = ? LIMIT 1');
$stmt->execute([$compteId]);
$compte = $stmt->fetch(PDO::FETCH_ASSOC);
if (
!$compte ||
!in_array($compte['role'], ['client', 'praticien'], true)
) {
$errorMsg = $translations['delete_account_error_not_found'] ?? 'Compte introuvable.';
} elseif (!password_verify($password, (string) $compte['mot_de_passe'])) {
$errorMsg = $translations['delete_account_error_password'] ?? 'Mot de passe incorrect.';
} else {
$refId = (int)$compte['reference_id'];
$pdo->beginTransaction();
if ($compte['role'] === 'client') {
// CLIENT : la plupart des FK sont en CASCADE ou SET NULL → un seul DELETE suffit
$delClient = $pdo->prepare('DELETE FROM client WHERE id = ?');
$delClient->execute([$refId]);
} elseif ($compte['role'] === 'praticien') {
// PRATICIEN : il y a des FK SANS ON DELETE CASCADE
// On nettoie d'abord les tables dépendantes
// Tokens Google
$stmt = $pdo->prepare('DELETE FROM google_tokens WHERE praticien_id = ?');
$stmt->execute([$refId]);
// Tokens Outlook
$stmt = $pdo->prepare('DELETE FROM outlook_tokens WHERE praticien_id = ?');
$stmt->execute([$refId]);
// Paiements
$stmt = $pdo->prepare('DELETE FROM paiement WHERE praticien_id = ?');
$stmt->execute([$refId]);
// (éventuellement d’autres tables si tu ajoutes des FK plus tard)
// Enfin : supprimer le praticien lui-même
$delPrat = $pdo->prepare('DELETE FROM praticien WHERE id = ?');
$delPrat->execute([$refId]);
}
// Supprimer le compte d’authentification
$delCompte = $pdo->prepare('DELETE FROM compte WHERE id = ?');
$delCompte->execute([$compte['id']]);
$pdo->commit();
// Déconnexion propre
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure'],
$params['httponly']
);
}
session_destroy();
// Redirection vers la page de confirmation
header('Location: /confirmation_suppression.php');
exit;
}
} catch (Throwable $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
error_log('Erreur suppression compte: ' . $e->getMessage());
$errorMsg = $translations['delete_account_error_generic'] ?? 'Une erreur est survenue, veuillez réessayer plus tard.';
}
}
}
}
/** Petite fonction helper pour échapper */
$e = static fn(string $s): string => htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
// --------------------------------------------------
// Textes via $translations
// --------------------------------------------------
$title = $translations['delete_account_title'] ?? 'Supprimer mon compte';
$warningTitle = $translations['delete_account_warning_title']
?? 'Attention, cette action est irréversible.';
$warningText = $translations['delete_account_warning_text']
?? "La suppression de votre compte entraînera la suppression de vos données associées selon nos règles de confidentialité.\nCette action ne peut pas être annulée.";
$pwdLabel = $translations['delete_account_password_label']
?? 'Veuillez confirmer votre mot de passe :';
$pwdPlaceholder = $translations['delete_account_password_placeholder']
?? 'Votre mot de passe';
$checkboxLabel = $translations['delete_account_checkbox_label']
?? 'Je comprends que mon compte et mes données associées seront définitivement supprimés.';
$buttonLabel = $translations['delete_account_button_label']
?? 'Supprimer mon compte';
$saTitle = $translations['delete_account_swal_title']
?? 'Êtes-vous sûr de vouloir supprimer votre compte ?';
$saText = $translations['delete_account_swal_text']
?? 'Cette action est définitive. Vous ne pourrez plus accéder à votre espace.';
$saConfirm = $translations['delete_account_swal_confirm']
?? 'Oui, supprimer';
$saCancel = $translations['delete_account_swal_cancel']
?? 'Annuler';
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title><?= $e($title) ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Montserrat + Bootstrap comme le reste du site -->
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="<?= asset('/includes/custom_style.css') ?>"> <!-- ta home -->
<link rel="stylesheet" href="<?= asset('/includes/site_style.css') ?>">
<link rel="stylesheet" href="<?= asset('/includes/mobil_style.css') ?>">
<style>
body {
background:#8CA9FF;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
</style>
</head>
<body>
<script src="/js/sweetalert2@11.js"></script>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-6">
<!-- ===================== FORMULAIRE DE SUPPRESSION ===================== -->
<div class="card shadow-sm">
<div class="card-body">
<h1 class="h4 mb-3 text-danger"><?= $e($title) ?></h1>
<div class="alert alert-warning">
<strong><?= $e($warningTitle) ?></strong><br>
<?= nl2br($e($warningText)) ?>
</div>
<?php if ($errorMsg): ?>
<div class="alert alert-danger">
<?= $e($errorMsg) ?>
</div>
<?php endif; ?>
<form method="post" id="delete-account-form" autocomplete="off">
<input type="hidden" name="csrf" value="<?= $e($CSRF) ?>">
<div class="mb-3">
<label class="form-label" for="password"><?= $e($pwdLabel) ?></label>
<input type="password"
class="form-control"
id="password"
name="password"
required
autocomplete="current-password"
placeholder="<?= $e($pwdPlaceholder) ?>">
</div>
<div class="form-check mb-3">
<input class="form-check-input"
type="checkbox"
value="1"
id="confirm_delete"
name="confirm_delete"
required>
<label class="form-check-label" for="confirm_delete">
<?= $e($checkboxLabel) ?>
</label>
</div>
<button type="submit" class="btn btn-danger w-100">
<?= $e($buttonLabel) ?>
</button>
</form>
</div>
</div>
<div class="text-center mt-3">
<a href="/" class="text-muted">&larr; <?php echo $translations['retour_avis_profil']; ?></a>
</div>
</div>
</div>
</div>
<script>
(function() {
const form = document.getElementById('delete-account-form');
if (!form) return;
form.addEventListener('submit', function(e) {
e.preventDefault();
const passwordInput = document.getElementById('password');
const checkbox = document.getElementById('confirm_delete');
if (!passwordInput.value.trim() || !checkbox.checked) {
form.reportValidity();
return;
}
Swal.fire({
title: <?= json_encode($saTitle, JSON_UNESCAPED_UNICODE) ?>,
text: <?= json_encode($saText, JSON_UNESCAPED_UNICODE) ?>,
icon: 'warning',
showCancelButton: true,
confirmButtonText: <?= json_encode($saConfirm, JSON_UNESCAPED_UNICODE) ?>,
cancelButtonText: <?= json_encode($saCancel, JSON_UNESCAPED_UNICODE) ?>,
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
form.submit();
}
});
});
})();
</script>
</body>
</html>