On release/v3.1.4: Sauvegarde temporaire pour changement de branche

This commit is contained in:
2025-08-21 17:51:22 +02:00
parent 6c8853e553
commit 41a4505b4b
1697 changed files with 167987 additions and 231472 deletions

View File

@@ -57,8 +57,9 @@ class EntiteController {
ville,
fk_type,
created_at,
chk_active
) VALUES (?, ?, ?, 1, NOW(), 1)
chk_active,
chk_user_delete_pass
) VALUES (?, ?, ?, 1, NOW(), 1, 0)
');
$stmt->execute([
@@ -109,7 +110,7 @@ class EntiteController {
public function getEntiteById(int $id): array|false {
try {
$stmt = $this->db->prepare('
SELECT id, encrypted_name, code_postal, ville, fk_type, chk_active
SELECT id, encrypted_name, code_postal, ville, fk_type, chk_active, chk_user_delete_pass
FROM entites
WHERE id = ? AND chk_active = 1
');
@@ -146,7 +147,7 @@ class EntiteController {
public function getEntiteByPostalCode(string $postalCode): array|false {
try {
$stmt = $this->db->prepare('
SELECT id, encrypted_name, code_postal, ville, fk_type, chk_active
SELECT id, encrypted_name, code_postal, ville, fk_type, chk_active, chk_user_delete_pass
FROM entites
WHERE code_postal = ? AND chk_active = 1
');
@@ -247,7 +248,7 @@ class EntiteController {
public function getEntites(): void {
try {
$stmt = $this->db->prepare('
SELECT id, encrypted_name, code_postal, ville, fk_type, chk_active
SELECT id, encrypted_name, code_postal, ville, fk_type, chk_active, chk_user_delete_pass
FROM entites
WHERE chk_active = 1
ORDER BY code_postal ASC
@@ -587,6 +588,11 @@ class EntiteController {
$updateFields[] = 'chk_username_manuel = ?';
$params[] = $data['chk_username_manuel'] ? 1 : 0;
}
if (isset($data['chk_user_delete_pass'])) {
$updateFields[] = 'chk_user_delete_pass = ?';
$params[] = $data['chk_user_delete_pass'] ? 1 : 0;
}
}
// Si aucun champ à mettre à jour, retourner une erreur
@@ -728,7 +734,7 @@ class EntiteController {
// Créer le dossier de destination
require_once __DIR__ . '/../Services/FileService.php';
$fileService = new \FileService();
$uploadPath = "/entites/{$entiteId}/logo";
$uploadPath = "/{$entiteId}/logo";
$fullPath = $fileService->createDirectory($entiteId, $uploadPath);
// Nom du fichier final

View File

@@ -533,7 +533,7 @@ class LoginController {
e.fk_region, r.libelle AS lib_region, e.fk_type, e.encrypted_phone as phone, e.encrypted_mobile as mobile,
e.encrypted_email as email, e.gps_lat, e.gps_lng,
e.encrypted_stripe_id as stripe_id, e.chk_demo, e.chk_mdp_manuel, e.chk_username_manuel,
e.chk_copie_mail_recu, e.chk_accept_sms, e.chk_active, e.chk_stripe
e.chk_copie_mail_recu, e.chk_accept_sms, e.chk_active, e.chk_stripe, e.chk_user_delete_pass
FROM entites e
LEFT JOIN x_regions r ON e.fk_region = r.id
WHERE e.id = ? AND e.chk_active = 1'
@@ -547,7 +547,7 @@ class LoginController {
e.fk_region, r.libelle AS lib_region, e.fk_type, e.encrypted_phone as phone, e.encrypted_mobile as mobile,
e.encrypted_email as email, e.gps_lat, e.gps_lng,
e.encrypted_stripe_id as stripe_id, e.chk_demo, e.chk_mdp_manuel, e.chk_username_manuel,
e.chk_copie_mail_recu, e.chk_accept_sms, e.chk_active, e.chk_stripe
e.chk_copie_mail_recu, e.chk_accept_sms, e.chk_active, e.chk_stripe, e.chk_user_delete_pass
FROM entites e
LEFT JOIN x_regions r ON e.fk_region = r.id
WHERE e.id != 1 AND e.chk_active = 1'
@@ -600,7 +600,7 @@ class LoginController {
e.fk_region, r.libelle AS lib_region, e.fk_type, e.encrypted_phone as phone, e.encrypted_mobile as mobile,
e.encrypted_email as email, e.gps_lat, e.gps_lng,
e.encrypted_stripe_id as stripe_id, e.chk_demo, e.chk_mdp_manuel, e.chk_username_manuel,
e.chk_copie_mail_recu, e.chk_accept_sms, e.chk_active, e.chk_stripe
e.chk_copie_mail_recu, e.chk_accept_sms, e.chk_active, e.chk_stripe, e.chk_user_delete_pass
FROM entites e
LEFT JOIN x_regions r ON e.fk_region = r.id
WHERE e.fk_type = 1 AND e.chk_active = 1'

View File

@@ -552,8 +552,26 @@ class PassageController {
'operationId' => $operationId
]);
// Envoyer la réponse immédiatement pour éviter les timeouts
Response::json([
'status' => 'success',
'message' => 'Passage créé avec succès',
'passage_id' => $passageId,
'receipt_generated' => false // On va générer le reçu en arrière-plan
], 201);
// Flush la sortie pour s'assurer que la réponse est envoyée
if (ob_get_level()) {
ob_end_flush();
}
flush();
// Fermer la connexion HTTP mais continuer le traitement
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
// Générer automatiquement un reçu si c'est un don (fk_type = 1) avec email valide
$receiptGenerated = false;
if (isset($data['fk_type']) && (int)$data['fk_type'] === 1) {
// Vérifier si un email a été fourni
$hasEmail = false;
@@ -584,13 +602,8 @@ class PassageController {
}
}
}
Response::json([
'status' => 'success',
'message' => 'Passage créé avec succès',
'passage_id' => $passageId,
'receipt_generated' => $receiptGenerated
], 201);
return; // Fin de la méthode, éviter d'exécuter le code après
} catch (Exception $e) {
LogService::log('Erreur lors de la création du passage', [
'level' => 'error',
@@ -740,25 +753,41 @@ class PassageController {
'passageId' => $passageId
]);
// Vérifier si un reçu doit être généré après la mise à jour
$receiptGenerated = false;
// Envoyer la réponse immédiatement pour éviter les timeouts
Response::json([
'status' => 'success',
'message' => 'Passage mis à jour avec succès',
'receipt_generated' => false // On va générer le reçu en arrière-plan
], 200);
// Récupérer les données actualisées du passage
$stmt = $this->db->prepare('SELECT fk_type, encrypted_email, nom_recu FROM ope_pass WHERE id = ?');
$stmt->execute([$passageId]);
$updatedPassage = $stmt->fetch(PDO::FETCH_ASSOC);
// Flush la sortie pour s'assurer que la réponse est envoyée
if (ob_get_level()) {
ob_end_flush();
}
flush();
if ($updatedPassage) {
// Générer un reçu si :
// - C'est un don (fk_type = 1)
// - Il y a un email valide
// - Il n'y a pas encore de reçu (nom_recu est vide ou null)
if ((int)$updatedPassage['fk_type'] === 1 &&
!empty($updatedPassage['encrypted_email']) &&
empty($updatedPassage['nom_recu'])) {
// Vérifier que l'email est valide en le déchiffrant
try {
// Fermer la connexion HTTP mais continuer le traitement
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
// Maintenant générer le reçu en arrière-plan après avoir envoyé la réponse
try {
// Récupérer les données actualisées du passage
$stmt = $this->db->prepare('SELECT fk_type, encrypted_email, nom_recu FROM ope_pass WHERE id = ?');
$stmt->execute([$passageId]);
$updatedPassage = $stmt->fetch(PDO::FETCH_ASSOC);
if ($updatedPassage) {
// Générer un reçu si :
// - C'est un don (fk_type = 1)
// - Il y a un email valide
// - Il n'y a pas encore de reçu (nom_recu est vide ou null)
if ((int)$updatedPassage['fk_type'] === 1 &&
!empty($updatedPassage['encrypted_email']) &&
empty($updatedPassage['nom_recu'])) {
// Vérifier que l'email est valide en le déchiffrant
$email = ApiService::decryptSearchableData($updatedPassage['encrypted_email']);
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
@@ -772,21 +801,17 @@ class PassageController {
]);
}
}
} catch (Exception $e) {
LogService::log('Erreur lors de la génération automatique du reçu après mise à jour', [
'level' => 'warning',
'error' => $e->getMessage(),
'passageId' => $passageId
]);
}
}
} catch (Exception $e) {
LogService::log('Erreur lors de la génération automatique du reçu après mise à jour', [
'level' => 'warning',
'error' => $e->getMessage(),
'passageId' => $passageId
]);
}
Response::json([
'status' => 'success',
'message' => 'Passage mis à jour avec succès',
'receipt_generated' => $receiptGenerated
], 200);
return; // Fin de la méthode, éviter d'exécuter le code après
} catch (Exception $e) {
LogService::log('Erreur lors de la mise à jour du passage', [
'level' => 'error',
@@ -818,8 +843,47 @@ class PassageController {
$passageId = (int)$id;
// Récupérer le rôle de l'utilisateur
$stmt = $this->db->prepare('SELECT fk_role, fk_entite FROM users WHERE id = ?');
$stmt->execute([$userId]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
Response::json([
'status' => 'error',
'message' => 'Utilisateur non trouvé'
], 404);
return;
}
$userRole = (int)$user['fk_role'];
$entiteId = (int)$user['fk_entite'];
// Si l'utilisateur est un membre (fk_role = 1), vérifier les permissions de l'entité
if ($userRole === 1) {
$stmt = $this->db->prepare('SELECT chk_user_delete_pass FROM entites WHERE id = ?');
$stmt->execute([$entiteId]);
$entite = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$entite || (int)$entite['chk_user_delete_pass'] !== 1) {
LogService::log('Tentative de suppression de passage non autorisée', [
'level' => 'warning',
'userId' => $userId,
'userRole' => $userRole,
'entiteId' => $entiteId,
'passageId' => $passageId,
'chk_user_delete_pass' => $entite ? $entite['chk_user_delete_pass'] : null
]);
Response::json([
'status' => 'error',
'message' => 'Vous n\'avez pas l\'autorisation de supprimer des passages'
], 403);
return;
}
}
// Vérifier que le passage existe et appartient à l'entité de l'utilisateur
$entiteId = $this->getUserEntiteId($userId);
if (!$entiteId) {
Response::json([
'status' => 'error',