feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD) * DEV: Clés TEST Pierre (mode test) * REC: Clés TEST Client (mode test) * PROD: Clés LIVE Client (mode live) - Ajout de la gestion des bases de données immeubles/bâtiments * Configuration buildings_database pour DEV/REC/PROD * Service BuildingService pour enrichissement des adresses - Optimisations pages et améliorations ergonomie - Mises à jour des dépendances Composer - Nettoyage des fichiers obsolètes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
273
api/scripts/cron/CRON.md
Normal file
273
api/scripts/cron/CRON.md
Normal file
@@ -0,0 +1,273 @@
|
||||
# Documentation des tâches CRON - API Geosector
|
||||
|
||||
Ce dossier contient les scripts automatisés de maintenance et de traitement pour l'API Geosector.
|
||||
|
||||
## Scripts disponibles
|
||||
|
||||
### 1. `process_email_queue.php`
|
||||
|
||||
**Fonction** : Traite la queue d'emails en attente (reçus fiscaux, notifications)
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Traite 50 emails maximum par exécution
|
||||
- 3 tentatives maximum par email
|
||||
- Lock file pour éviter l'exécution simultanée
|
||||
- Nettoyage automatique des emails envoyés de plus de 30 jours
|
||||
|
||||
**Fréquence recommandée** : Toutes les 5 minutes
|
||||
|
||||
**Ligne crontab** :
|
||||
|
||||
```bash
|
||||
*/5 * * * * /usr/bin/php /var/www/geosector/api/scripts/cron/process_email_queue.php >> /var/www/geosector/api/logs/email_queue.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. `cleanup_security_data.php`
|
||||
|
||||
**Fonction** : Purge les données de sécurité obsolètes selon la politique de rétention
|
||||
|
||||
**Données nettoyées** :
|
||||
|
||||
- Métriques de performance : 30 jours
|
||||
- Tentatives de login échouées : 7 jours
|
||||
- Alertes résolues : 90 jours
|
||||
- IPs expirées : Déblocage immédiat
|
||||
|
||||
**Fréquence recommandée** : Quotidien à 2h du matin
|
||||
|
||||
**Ligne crontab** :
|
||||
|
||||
```bash
|
||||
0 2 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_security_data.php >> /var/www/geosector/api/logs/cleanup_security.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. `cleanup_logs.php`
|
||||
|
||||
**Fonction** : Supprime les fichiers de logs de plus de 10 jours
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Cible tous les fichiers `*.log` dans `/api/logs/`
|
||||
- Exclut le dossier `/logs/events/` (rétention 15 mois)
|
||||
- Rétention : 10 jours
|
||||
- Logs détaillés des fichiers supprimés et taille libérée
|
||||
- Lock file pour éviter l'exécution simultanée
|
||||
|
||||
**Fréquence recommandée** : Quotidien à 3h du matin
|
||||
|
||||
**Ligne crontab** :
|
||||
|
||||
```bash
|
||||
0 3 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_logs.php >> /var/www/geosector/api/logs/cleanup_logs.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. `rotate_event_logs.php`
|
||||
|
||||
**Fonction** : Rotation des logs d'événements JSONL (système EventLogService)
|
||||
|
||||
**Politique de rétention (15 mois)** :
|
||||
|
||||
- 0-15 mois : fichiers `.jsonl` conservés (non compressés pour accès API)
|
||||
- > 15 mois : suppression automatique
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Suppression des fichiers > 15 mois
|
||||
- Pas de compression (fichiers accessibles par l'API)
|
||||
- Logs détaillés des suppressions
|
||||
- Lock file pour éviter l'exécution simultanée
|
||||
|
||||
**Fréquence recommandée** : Mensuel le 1er à 3h du matin
|
||||
|
||||
**Ligne crontab** :
|
||||
|
||||
```bash
|
||||
0 3 1 * * /usr/bin/php /var/www/geosector/api/scripts/cron/rotate_event_logs.php >> /var/www/geosector/api/logs/rotation_events.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. `update_stripe_devices.php`
|
||||
|
||||
**Fonction** : Met à jour la liste des appareils Android certifiés pour Tap to Pay
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Liste de 95+ devices intégrée
|
||||
- Ajoute les nouveaux appareils certifiés
|
||||
- Met à jour les versions Android minimales
|
||||
- Désactive les appareils obsolètes
|
||||
- Notification email si changements importants
|
||||
- Possibilité de personnaliser via `/data/stripe_certified_devices.json`
|
||||
|
||||
**Fréquence recommandée** : Hebdomadaire le dimanche à 3h
|
||||
|
||||
**Ligne crontab** :
|
||||
|
||||
```bash
|
||||
0 3 * * 0 /usr/bin/php /var/www/geosector/api/scripts/cron/update_stripe_devices.php >> /var/www/geosector/api/logs/stripe_devices.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. `sync_databases.php`
|
||||
|
||||
**Fonction** : Synchronise les bases de données entre environnements
|
||||
|
||||
**Note** : Ce script est spécifique à un cas d'usage particulier. Vérifier son utilité avant activation.
|
||||
|
||||
**Fréquence recommandée** : À définir selon les besoins
|
||||
|
||||
**Ligne crontab** :
|
||||
|
||||
```bash
|
||||
# À configurer selon les besoins
|
||||
# 0 4 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/sync_databases.php >> /var/www/geosector/api/logs/sync_databases.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation sur les containers Incus
|
||||
|
||||
### 1. Déployer les scripts sur les environnements
|
||||
|
||||
```bash
|
||||
# DEV (dva-geo sur IN3)
|
||||
./deploy-api.sh
|
||||
|
||||
# RECETTE (rca-geo sur IN3)
|
||||
./deploy-api.sh rca
|
||||
|
||||
# PRODUCTION (pra-geo sur IN4)
|
||||
./deploy-api.sh pra
|
||||
```
|
||||
|
||||
### 2. Configurer le crontab sur chaque container
|
||||
|
||||
```bash
|
||||
# Se connecter au container
|
||||
incus exec dva-geo -- sh # ou rca-geo, pra-geo
|
||||
|
||||
# Éditer le crontab
|
||||
crontab -e
|
||||
|
||||
# Ajouter les lignes ci-dessous (adapter les chemins si nécessaire)
|
||||
```
|
||||
|
||||
### 3. Configuration complète recommandée
|
||||
|
||||
```bash
|
||||
# Traitement de la queue d'emails (toutes les 5 minutes)
|
||||
*/5 * * * * /usr/bin/php /var/www/geosector/api/scripts/cron/process_email_queue.php >> /var/www/geosector/api/logs/email_queue.log 2>&1
|
||||
|
||||
# Nettoyage des données de sécurité (quotidien à 2h)
|
||||
0 2 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_security_data.php >> /var/www/geosector/api/logs/cleanup_security.log 2>&1
|
||||
|
||||
# Nettoyage des anciens logs (quotidien à 3h)
|
||||
0 3 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_logs.php >> /var/www/geosector/api/logs/cleanup_logs.log 2>&1
|
||||
|
||||
# Rotation des logs événements (mensuel le 1er à 3h)
|
||||
0 3 1 * * /usr/bin/php /var/www/geosector/api/scripts/cron/rotate_event_logs.php >> /var/www/geosector/api/logs/rotation_events.log 2>&1
|
||||
|
||||
# Mise à jour des devices Stripe (hebdomadaire dimanche à 3h)
|
||||
0 3 * * 0 /usr/bin/php /var/www/geosector/api/scripts/cron/update_stripe_devices.php >> /var/www/geosector/api/logs/stripe_devices.log 2>&1
|
||||
```
|
||||
|
||||
### 4. Vérifier que les CRONs sont actifs
|
||||
|
||||
```bash
|
||||
# Lister les CRONs configurés
|
||||
crontab -l
|
||||
|
||||
# Vérifier les logs pour s'assurer qu'ils s'exécutent
|
||||
tail -f /var/www/geosector/api/logs/email_queue.log
|
||||
tail -f /var/www/geosector/api/logs/cleanup_logs.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Surveillance et monitoring
|
||||
|
||||
### Emplacement des logs
|
||||
|
||||
Tous les logs CRON sont stockés dans `/var/www/geosector/api/logs/` :
|
||||
|
||||
- `email_queue.log` : Traitement de la queue d'emails
|
||||
- `cleanup_security.log` : Nettoyage des données de sécurité
|
||||
- `cleanup_logs.log` : Nettoyage des anciens fichiers logs
|
||||
- `rotation_events.log` : Rotation des logs événements JSONL
|
||||
- `stripe_devices.log` : Mise à jour des devices Tap to Pay
|
||||
|
||||
### Vérification de l'exécution
|
||||
|
||||
```bash
|
||||
# Voir les dernières exécutions du processeur d'emails
|
||||
tail -n 50 /var/www/geosector/api/logs/email_queue.log
|
||||
|
||||
# Voir les derniers nettoyages de logs
|
||||
tail -n 50 /var/www/geosector/api/logs/cleanup_logs.log
|
||||
|
||||
# Voir les dernières rotations des logs événements
|
||||
tail -n 50 /var/www/geosector/api/logs/rotation_events.log
|
||||
|
||||
# Voir les dernières mises à jour Stripe
|
||||
tail -n 50 /var/www/geosector/api/logs/stripe_devices.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes importantes
|
||||
|
||||
1. **Détection d'environnement** : Tous les scripts détectent automatiquement l'environnement via `gethostname()` :
|
||||
|
||||
- `pra-geo` → Production (app3.geosector.fr)
|
||||
- `rca-geo` → Recette (rapp.geosector.fr)
|
||||
- `dva-geo` → Développement (dapp.geosector.fr)
|
||||
|
||||
2. **Lock files** : Les scripts critiques utilisent des fichiers de lock dans `/tmp/` pour éviter l'exécution simultanée
|
||||
|
||||
3. **Permissions** : Les scripts doivent être exécutables (`chmod +x script.php`)
|
||||
|
||||
4. **Logs** : Tous les scripts loggent via `LogService` pour traçabilité complète
|
||||
|
||||
---
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Le CRON ne s'exécute pas
|
||||
|
||||
```bash
|
||||
# Vérifier que le service cron est actif
|
||||
rc-service crond status # Alpine Linux
|
||||
|
||||
# Relancer le service si nécessaire
|
||||
rc-service crond restart
|
||||
```
|
||||
|
||||
### Erreur de permissions
|
||||
|
||||
```bash
|
||||
# Vérifier les permissions du script
|
||||
ls -l /var/www/geosector/api/scripts/cron/
|
||||
|
||||
# Rendre exécutable si nécessaire
|
||||
chmod +x /var/www/geosector/api/scripts/cron/*.php
|
||||
|
||||
# Vérifier les permissions du dossier logs
|
||||
ls -ld /var/www/geosector/api/logs/
|
||||
```
|
||||
|
||||
### Lock file bloqué
|
||||
|
||||
```bash
|
||||
# Si un script semble bloqué, supprimer le lock file
|
||||
rm /tmp/process_email_queue.lock
|
||||
rm /tmp/cleanup_logs.lock
|
||||
```
|
||||
165
api/scripts/cron/cleanup_logs.php
Executable file
165
api/scripts/cron/cleanup_logs.php
Executable file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Script CRON pour nettoyer les anciens fichiers de logs
|
||||
* Supprime les fichiers .log de plus de 10 jours dans le dossier /logs/
|
||||
*
|
||||
* À exécuter quotidiennement via crontab :
|
||||
* 0 3 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_logs.php >> /var/www/geosector/api/logs/cleanup_logs.log 2>&1
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Configuration
|
||||
define('LOG_RETENTION_DAYS', 10);
|
||||
define('LOCK_FILE', '/tmp/cleanup_logs.lock');
|
||||
|
||||
// Empêcher l'exécution multiple simultanée
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
$lockTime = filemtime(LOCK_FILE);
|
||||
// Si le lock a plus de 30 minutes, on le supprime (processus probablement bloqué)
|
||||
if (time() - $lockTime > 1800) {
|
||||
unlink(LOCK_FILE);
|
||||
} else {
|
||||
die("Le processus est déjà en cours d'exécution\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Créer le fichier de lock
|
||||
file_put_contents(LOCK_FILE, getmypid());
|
||||
|
||||
// Enregistrer un handler pour supprimer le lock en cas d'arrêt
|
||||
register_shutdown_function(function() {
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
unlink(LOCK_FILE);
|
||||
}
|
||||
});
|
||||
|
||||
// Simuler l'environnement web pour AppConfig en CLI
|
||||
if (php_sapi_name() === 'cli') {
|
||||
// Détecter l'environnement basé sur le hostname
|
||||
$hostname = gethostname();
|
||||
if (strpos($hostname, 'pra') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'app3.geosector.fr';
|
||||
} elseif (strpos($hostname, 'rca') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'rapp.geosector.fr';
|
||||
} else {
|
||||
$_SERVER['SERVER_NAME'] = 'dapp.geosector.fr'; // DVA par défaut
|
||||
}
|
||||
|
||||
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
|
||||
$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||
|
||||
// Définir getallheaders si elle n'existe pas (CLI)
|
||||
if (!function_exists('getallheaders')) {
|
||||
function getallheaders() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chargement de l'environnement
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../../src/Config/AppConfig.php';
|
||||
require_once __DIR__ . '/../../src/Services/LogService.php';
|
||||
|
||||
try {
|
||||
// Initialisation de la configuration
|
||||
$appConfig = AppConfig::getInstance();
|
||||
$environment = $appConfig->getEnvironment();
|
||||
|
||||
// Définir le chemin du dossier logs
|
||||
$logDir = __DIR__ . '/../../logs';
|
||||
|
||||
if (!is_dir($logDir)) {
|
||||
echo "Le dossier de logs n'existe pas : {$logDir}\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Date limite (10 jours en arrière)
|
||||
$cutoffDate = time() - (LOG_RETENTION_DAYS * 24 * 60 * 60);
|
||||
|
||||
// Lister tous les fichiers .log (exclure le dossier events/)
|
||||
$logFiles = glob($logDir . '/*.log');
|
||||
|
||||
// Exclure explicitement les logs du sous-dossier events/
|
||||
$logFiles = array_filter($logFiles, function($file) {
|
||||
return strpos($file, '/events/') === false;
|
||||
});
|
||||
|
||||
if (empty($logFiles)) {
|
||||
echo "Aucun fichier .log trouvé dans {$logDir}\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$deletedCount = 0;
|
||||
$deletedSize = 0;
|
||||
$deletedFiles = [];
|
||||
|
||||
foreach ($logFiles as $file) {
|
||||
$fileTime = filemtime($file);
|
||||
|
||||
// Vérifier si le fichier est plus vieux que la date limite
|
||||
if ($fileTime < $cutoffDate) {
|
||||
$fileSize = filesize($file);
|
||||
$fileName = basename($file);
|
||||
|
||||
if (unlink($file)) {
|
||||
$deletedCount++;
|
||||
$deletedSize += $fileSize;
|
||||
$deletedFiles[] = $fileName;
|
||||
echo "Supprimé : {$fileName} (" . number_format($fileSize / 1024, 2) . " KB)\n";
|
||||
} else {
|
||||
echo "ERREUR : Impossible de supprimer {$fileName}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Logger le résumé
|
||||
if ($deletedCount > 0) {
|
||||
$message = sprintf(
|
||||
"Nettoyage des logs terminé - %d fichier(s) supprimé(s) - %.2f MB libérés",
|
||||
$deletedCount,
|
||||
$deletedSize / (1024 * 1024)
|
||||
);
|
||||
|
||||
LogService::log($message, [
|
||||
'level' => 'info',
|
||||
'script' => 'cleanup_logs.php',
|
||||
'environment' => $environment,
|
||||
'deleted_count' => $deletedCount,
|
||||
'deleted_size_mb' => round($deletedSize / (1024 * 1024), 2),
|
||||
'deleted_files' => $deletedFiles
|
||||
]);
|
||||
|
||||
echo "\n" . $message . "\n";
|
||||
} else {
|
||||
echo "Aucun fichier à supprimer (tous les logs ont moins de " . LOG_RETENTION_DAYS . " jours)\n";
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$errorMsg = 'Erreur lors du nettoyage des logs : ' . $e->getMessage();
|
||||
|
||||
LogService::log($errorMsg, [
|
||||
'level' => 'error',
|
||||
'script' => 'cleanup_logs.php',
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
echo $errorMsg . "\n";
|
||||
|
||||
// Supprimer le lock en cas d'erreur
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
unlink(LOCK_FILE);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Supprimer le lock
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
unlink(LOCK_FILE);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@@ -41,14 +41,14 @@ register_shutdown_function(function() {
|
||||
if (php_sapi_name() === 'cli') {
|
||||
// Détecter l'environnement basé sur le hostname ou un paramètre
|
||||
$hostname = gethostname();
|
||||
if (strpos($hostname, 'prod') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'app.geosector.fr';
|
||||
} elseif (strpos($hostname, 'rec') !== false || strpos($hostname, 'rapp') !== false) {
|
||||
if (strpos($hostname, 'pra') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'app3.geosector.fr';
|
||||
} elseif (strpos($hostname, 'rca') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'rapp.geosector.fr';
|
||||
} else {
|
||||
$_SERVER['SERVER_NAME'] = 'app.geo.dev'; // DVA par défaut
|
||||
$_SERVER['SERVER_NAME'] = 'dapp.geosector.fr'; // DVA par défaut
|
||||
}
|
||||
|
||||
|
||||
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
|
||||
$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||
|
||||
@@ -69,6 +69,7 @@ require_once __DIR__ . '/../../src/Services/LogService.php';
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\SMTP;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use App\Services\LogService;
|
||||
|
||||
try {
|
||||
// Initialisation de la configuration
|
||||
|
||||
169
api/scripts/cron/rotate_event_logs.php
Normal file
169
api/scripts/cron/rotate_event_logs.php
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Script CRON pour rotation des logs d'événements JSONL
|
||||
*
|
||||
* Politique de rétention : 15 mois
|
||||
* - 0-15 mois : fichiers .jsonl conservés (non compressés pour accès API)
|
||||
* - > 15 mois : suppression
|
||||
*
|
||||
* À exécuter mensuellement via crontab (1er du mois à 3h) :
|
||||
* 0 3 1 * * /usr/bin/php /var/www/geosector/api/scripts/cron/rotate_event_logs.php >> /var/www/geosector/api/logs/rotation_events.log 2>&1
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Configuration
|
||||
define('RETENTION_MONTHS', 15); // Conserver 15 mois
|
||||
define('LOCK_FILE', '/tmp/rotate_event_logs.lock');
|
||||
|
||||
// Empêcher l'exécution multiple simultanée
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
$lockTime = filemtime(LOCK_FILE);
|
||||
// Si le lock a plus de 2 heures, on le supprime (processus probablement bloqué)
|
||||
if (time() - $lockTime > 7200) {
|
||||
unlink(LOCK_FILE);
|
||||
} else {
|
||||
die("Le processus est déjà en cours d'exécution\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Créer le fichier de lock
|
||||
file_put_contents(LOCK_FILE, getmypid());
|
||||
|
||||
// Enregistrer un handler pour supprimer le lock en cas d'arrêt
|
||||
register_shutdown_function(function() {
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
unlink(LOCK_FILE);
|
||||
}
|
||||
});
|
||||
|
||||
// Simuler l'environnement web pour AppConfig en CLI
|
||||
if (php_sapi_name() === 'cli') {
|
||||
// Détecter l'environnement basé sur le hostname
|
||||
$hostname = gethostname();
|
||||
if (strpos($hostname, 'pra') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'app3.geosector.fr';
|
||||
} elseif (strpos($hostname, 'rca') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'rapp.geosector.fr';
|
||||
} else {
|
||||
$_SERVER['SERVER_NAME'] = 'dapp.geosector.fr'; // DVA par défaut
|
||||
}
|
||||
|
||||
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
|
||||
$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||
|
||||
// Définir getallheaders si elle n'existe pas (CLI)
|
||||
if (!function_exists('getallheaders')) {
|
||||
function getallheaders() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chargement de l'environnement
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../../src/Config/AppConfig.php';
|
||||
require_once __DIR__ . '/../../src/Services/LogService.php';
|
||||
|
||||
try {
|
||||
// Initialisation de la configuration
|
||||
$appConfig = AppConfig::getInstance();
|
||||
$environment = $appConfig->getEnvironment();
|
||||
|
||||
// Définir le chemin du dossier des logs événements
|
||||
$eventLogDir = __DIR__ . '/../../logs/events';
|
||||
|
||||
if (!is_dir($eventLogDir)) {
|
||||
echo "Le dossier de logs événements n'existe pas : {$eventLogDir}\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Date limite de suppression
|
||||
$deletionDate = strtotime('-' . RETENTION_MONTHS . ' months');
|
||||
|
||||
// Lister tous les fichiers .jsonl
|
||||
$jsonlFiles = glob($eventLogDir . '/*.jsonl');
|
||||
|
||||
if (empty($jsonlFiles)) {
|
||||
echo "Aucun fichier .jsonl trouvé dans {$eventLogDir}\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$deletedCount = 0;
|
||||
$deletedSize = 0;
|
||||
$deletedFiles = [];
|
||||
|
||||
// ========================================
|
||||
// Suppression des fichiers > 15 mois
|
||||
// ========================================
|
||||
foreach ($jsonlFiles as $file) {
|
||||
$fileTime = filemtime($file);
|
||||
|
||||
// Vérifier si le fichier est plus vieux que la date de rétention
|
||||
if ($fileTime < $deletionDate) {
|
||||
$fileSize = filesize($file);
|
||||
$fileName = basename($file);
|
||||
|
||||
if (unlink($file)) {
|
||||
$deletedCount++;
|
||||
$deletedSize += $fileSize;
|
||||
$deletedFiles[] = $fileName;
|
||||
echo "Supprimé : {$fileName} (> " . RETENTION_MONTHS . " mois, " .
|
||||
number_format($fileSize / 1024, 2) . " KB)\n";
|
||||
} else {
|
||||
echo "ERREUR : Impossible de supprimer {$fileName}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RÉSUMÉ ET LOGGING
|
||||
// ========================================
|
||||
if ($deletedCount > 0) {
|
||||
$message = sprintf(
|
||||
"Rotation des logs événements terminée - %d fichier(s) supprimé(s) - %.2f MB libérés",
|
||||
$deletedCount,
|
||||
$deletedSize / (1024 * 1024)
|
||||
);
|
||||
|
||||
LogService::log($message, [
|
||||
'level' => 'info',
|
||||
'script' => 'rotate_event_logs.php',
|
||||
'environment' => $environment,
|
||||
'deleted_count' => $deletedCount,
|
||||
'deleted_size_mb' => round($deletedSize / (1024 * 1024), 2),
|
||||
'deleted_files' => $deletedFiles
|
||||
]);
|
||||
|
||||
echo "\n" . $message . "\n";
|
||||
} else {
|
||||
echo "Aucune rotation nécessaire - Tous les fichiers .jsonl ont moins de " . RETENTION_MONTHS . " mois\n";
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$errorMsg = 'Erreur lors de la rotation des logs événements : ' . $e->getMessage();
|
||||
|
||||
LogService::log($errorMsg, [
|
||||
'level' => 'error',
|
||||
'script' => 'rotate_event_logs.php',
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
echo $errorMsg . "\n";
|
||||
|
||||
// Supprimer le lock en cas d'erreur
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
unlink(LOCK_FILE);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Supprimer le lock
|
||||
if (file_exists(LOCK_FILE)) {
|
||||
unlink(LOCK_FILE);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@@ -1,186 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Script de test pour vérifier le processeur de queue d'emails
|
||||
* Affiche les emails en attente sans les envoyer
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Simuler l'environnement web pour AppConfig en CLI
|
||||
if (php_sapi_name() === 'cli') {
|
||||
$_SERVER['SERVER_NAME'] = $_SERVER['SERVER_NAME'] ?? 'app.geo.dev'; // DVA par défaut
|
||||
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
|
||||
$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||
|
||||
// Définir getallheaders si elle n'existe pas (CLI)
|
||||
if (!function_exists('getallheaders')) {
|
||||
function getallheaders() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../../src/Core/Database.php';
|
||||
require_once __DIR__ . '/../../src/Config/AppConfig.php';
|
||||
|
||||
try {
|
||||
// Initialiser la configuration
|
||||
$appConfig = AppConfig::getInstance();
|
||||
$dbConfig = $appConfig->getDatabaseConfig();
|
||||
|
||||
// Initialiser la base de données avec la configuration
|
||||
Database::init($dbConfig);
|
||||
$db = Database::getInstance();
|
||||
|
||||
echo "=== TEST DE LA QUEUE D'EMAILS ===\n\n";
|
||||
|
||||
// Statistiques générales
|
||||
$stmt = $db->query('
|
||||
SELECT
|
||||
status,
|
||||
COUNT(*) as count,
|
||||
MIN(created_at) as oldest,
|
||||
MAX(created_at) as newest
|
||||
FROM email_queue
|
||||
GROUP BY status
|
||||
');
|
||||
|
||||
$stats = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo "STATISTIQUES:\n";
|
||||
echo "-------------\n";
|
||||
foreach ($stats as $stat) {
|
||||
echo sprintf(
|
||||
"Status: %s - Nombre: %d (Plus ancien: %s, Plus récent: %s)\n",
|
||||
$stat['status'],
|
||||
$stat['count'],
|
||||
$stat['oldest'] ?? 'N/A',
|
||||
$stat['newest'] ?? 'N/A'
|
||||
);
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
// Emails en attente
|
||||
$stmt = $db->prepare('
|
||||
SELECT
|
||||
eq.id,
|
||||
eq.fk_pass,
|
||||
eq.to_email,
|
||||
eq.subject,
|
||||
eq.created_at,
|
||||
eq.attempts,
|
||||
eq.status,
|
||||
p.fk_type,
|
||||
p.montant,
|
||||
p.nom_recu
|
||||
FROM email_queue eq
|
||||
LEFT JOIN ope_pass p ON eq.fk_pass = p.id
|
||||
WHERE eq.status = ?
|
||||
ORDER BY eq.created_at DESC
|
||||
LIMIT 10
|
||||
');
|
||||
|
||||
$stmt->execute(['pending']);
|
||||
$pendingEmails = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (empty($pendingEmails)) {
|
||||
echo "Aucun email en attente.\n";
|
||||
} else {
|
||||
echo "EMAILS EN ATTENTE (10 plus récents):\n";
|
||||
echo "------------------------------------\n";
|
||||
foreach ($pendingEmails as $email) {
|
||||
echo sprintf(
|
||||
"ID: %d | Passage: %d | Destinataire: %s\n",
|
||||
$email['id'],
|
||||
$email['fk_pass'],
|
||||
$email['to_email']
|
||||
);
|
||||
echo sprintf(
|
||||
" Sujet: %s\n",
|
||||
$email['subject']
|
||||
);
|
||||
echo sprintf(
|
||||
" Créé le: %s | Tentatives: %d\n",
|
||||
$email['created_at'],
|
||||
$email['attempts']
|
||||
);
|
||||
if ($email['fk_pass'] > 0) {
|
||||
echo sprintf(
|
||||
" Passage - Type: %s | Montant: %.2f€ | Reçu: %s\n",
|
||||
$email['fk_type'] == 1 ? 'DON' : 'Autre',
|
||||
$email['montant'] ?? 0,
|
||||
$email['nom_recu'] ?? 'Non généré'
|
||||
);
|
||||
}
|
||||
echo "---\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Emails échoués
|
||||
$stmt = $db->prepare('
|
||||
SELECT
|
||||
id,
|
||||
fk_pass,
|
||||
to_email,
|
||||
subject,
|
||||
created_at,
|
||||
attempts,
|
||||
error_message
|
||||
FROM email_queue
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 5
|
||||
');
|
||||
|
||||
$stmt->execute(['failed']);
|
||||
$failedEmails = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!empty($failedEmails)) {
|
||||
echo "\nEMAILS ÉCHOUÉS (5 plus récents):\n";
|
||||
echo "--------------------------------\n";
|
||||
foreach ($failedEmails as $email) {
|
||||
echo sprintf(
|
||||
"ID: %d | Passage: %d | Destinataire: %s\n",
|
||||
$email['id'],
|
||||
$email['fk_pass'],
|
||||
$email['to_email']
|
||||
);
|
||||
echo sprintf(
|
||||
" Sujet: %s\n",
|
||||
$email['subject']
|
||||
);
|
||||
echo sprintf(
|
||||
" Tentatives: %d | Erreur: %s\n",
|
||||
$email['attempts'],
|
||||
$email['error_message'] ?? 'Non spécifiée'
|
||||
);
|
||||
echo "---\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Vérifier la configuration SMTP
|
||||
echo "\nCONFIGURATION SMTP:\n";
|
||||
echo "-------------------\n";
|
||||
|
||||
$smtpConfig = $appConfig->getSmtpConfig();
|
||||
$emailConfig = $appConfig->getEmailConfig();
|
||||
|
||||
echo "Host: " . ($smtpConfig['host'] ?? 'Non configuré') . "\n";
|
||||
echo "Port: " . ($smtpConfig['port'] ?? 'Non configuré') . "\n";
|
||||
echo "Username: " . ($smtpConfig['user'] ?? 'Non configuré') . "\n";
|
||||
echo "Password: " . (isset($smtpConfig['pass']) ? '***' : 'Non configuré') . "\n";
|
||||
echo "Encryption: " . ($smtpConfig['secure'] ?? 'Non configuré') . "\n";
|
||||
echo "From Email: " . ($emailConfig['from'] ?? 'Non configuré') . "\n";
|
||||
echo "Contact Email: " . ($emailConfig['contact'] ?? 'Non configuré') . "\n";
|
||||
|
||||
echo "\n=== FIN DU TEST ===\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "ERREUR: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@@ -42,7 +42,7 @@ register_shutdown_function(function() {
|
||||
if (php_sapi_name() === 'cli') {
|
||||
$hostname = gethostname();
|
||||
if (strpos($hostname, 'prod') !== false || strpos($hostname, 'pra') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'app.geosector.fr';
|
||||
$_SERVER['SERVER_NAME'] = 'app3.geosector.fr';
|
||||
} elseif (strpos($hostname, 'rec') !== false || strpos($hostname, 'rca') !== false) {
|
||||
$_SERVER['SERVER_NAME'] = 'rapp.geosector.fr';
|
||||
} else {
|
||||
@@ -67,6 +67,8 @@ require_once dirname(dirname(__DIR__)) . '/src/Config/AppConfig.php';
|
||||
require_once dirname(dirname(__DIR__)) . '/src/Core/Database.php';
|
||||
require_once dirname(dirname(__DIR__)) . '/src/Services/LogService.php';
|
||||
|
||||
use App\Services\LogService;
|
||||
|
||||
try {
|
||||
echo "[" . date('Y-m-d H:i:s') . "] Début de la mise à jour des devices Stripe certifiés\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user