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:
219
api/scripts/migration2/php/lib/MigrationLogger.php
Normal file
219
api/scripts/migration2/php/lib/MigrationLogger.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Gestion des logs de migration
|
||||
*
|
||||
* Écrit dans un fichier et affiche à l'écran avec timestamps
|
||||
*/
|
||||
class MigrationLogger
|
||||
{
|
||||
private $logFile;
|
||||
private $verbose;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*
|
||||
* @param string|null $logFile Chemin du fichier de log (null = auto-généré)
|
||||
* @param bool $verbose Afficher les logs à l'écran
|
||||
*/
|
||||
public function __construct(?string $logFile = null, bool $verbose = true)
|
||||
{
|
||||
// Définir le répertoire de logs par défaut (migration2/logs/)
|
||||
$defaultLogDir = dirname(__DIR__, 2) . '/logs';
|
||||
$this->logFile = $logFile ?? $defaultLogDir . '/migration_' . date('Ymd_His') . '.log';
|
||||
$this->verbose = $verbose;
|
||||
|
||||
// Créer le dossier parent si nécessaire
|
||||
$dir = dirname($this->logFile);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
// Vérifier que le fichier est accessible en écriture
|
||||
if (!is_writable(dirname($this->logFile))) {
|
||||
throw new Exception("Log directory is not writable: " . dirname($this->logFile));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log un message avec niveau INFO
|
||||
*/
|
||||
public function info(string $message): void
|
||||
{
|
||||
$this->log($message, 'INFO');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log un message avec niveau SUCCESS
|
||||
*/
|
||||
public function success(string $message): void
|
||||
{
|
||||
$this->log($message, 'SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log un message avec niveau WARNING
|
||||
*/
|
||||
public function warning(string $message): void
|
||||
{
|
||||
$this->log($message, 'WARNING');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log un message avec niveau ERROR
|
||||
*/
|
||||
public function error(string $message): void
|
||||
{
|
||||
$this->log($message, 'ERROR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log un message avec niveau DEBUG
|
||||
*/
|
||||
public function debug(string $message): void
|
||||
{
|
||||
$this->log($message, 'DEBUG');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log une ligne de séparation
|
||||
*/
|
||||
public function separator(): void
|
||||
{
|
||||
$this->log(str_repeat('=', 80), 'INFO');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log générique
|
||||
*
|
||||
* @param string $message Message à logger
|
||||
* @param string $level Niveau: INFO, SUCCESS, WARNING, ERROR, DEBUG
|
||||
*/
|
||||
private function log(string $message, string $level = 'INFO'): void
|
||||
{
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
$logLine = "[{$timestamp}] [{$level}] {$message}\n";
|
||||
|
||||
// Écriture dans le fichier
|
||||
file_put_contents($this->logFile, $logLine, FILE_APPEND);
|
||||
|
||||
// Affichage à l'écran si verbose
|
||||
if ($this->verbose) {
|
||||
$this->printColored($message, $level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche un message coloré selon le niveau
|
||||
*/
|
||||
private function printColored(string $message, string $level): void
|
||||
{
|
||||
$colors = [
|
||||
'INFO' => "\033[0;37m", // Blanc
|
||||
'SUCCESS' => "\033[0;32m", // Vert
|
||||
'WARNING' => "\033[0;33m", // Jaune
|
||||
'ERROR' => "\033[0;31m", // Rouge
|
||||
'DEBUG' => "\033[0;36m" // Cyan
|
||||
];
|
||||
|
||||
$reset = "\033[0m";
|
||||
$color = $colors[$level] ?? $colors['INFO'];
|
||||
|
||||
echo $color . $message . $reset . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le chemin du fichier de log
|
||||
*/
|
||||
public function getLogFile(): string
|
||||
{
|
||||
return $this->logFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log des statistiques de migration
|
||||
*
|
||||
* @param array $stats Tableau associatif [table => count]
|
||||
*/
|
||||
public function logStats(array $stats): void
|
||||
{
|
||||
$this->separator();
|
||||
$this->info("📊 Statistiques de migration:");
|
||||
|
||||
foreach ($stats as $table => $count) {
|
||||
$this->info(" - {$table}: {$count} enregistrement(s)");
|
||||
}
|
||||
|
||||
$this->separator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log une ligne spéciale pour parsing automatique
|
||||
* Format: #STATS# KEY1:VAL1 KEY2:VAL2 ...
|
||||
*/
|
||||
public function logParsableStats(array $stats): void
|
||||
{
|
||||
$pairs = [];
|
||||
foreach ($stats as $key => $value) {
|
||||
$pairs[] = strtoupper($key) . ':' . $value;
|
||||
}
|
||||
|
||||
$line = '#STATS# ' . implode(' ', $pairs);
|
||||
$this->log($line, 'INFO');
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche et log un récapitulatif complet de migration
|
||||
*
|
||||
* @param array $summary Tableau de statistiques hiérarchique
|
||||
*/
|
||||
public function logMigrationSummary(array $summary): void
|
||||
{
|
||||
$this->separator();
|
||||
$this->separator();
|
||||
$this->info("📊 RÉCAPITULATIF DE LA MIGRATION");
|
||||
$this->separator();
|
||||
|
||||
// Entité
|
||||
if (isset($summary['entity'])) {
|
||||
$this->info("Entité: {$summary['entity']['name']} (ID: {$summary['entity']['id']})");
|
||||
}
|
||||
$this->info("Date: " . date('Y-m-d H:i:s'));
|
||||
$this->info("");
|
||||
|
||||
// Nombre total d'opérations
|
||||
$totalOperations = count($summary['operations'] ?? []);
|
||||
$this->success("Opérations migrées: {$totalOperations}");
|
||||
$this->info("");
|
||||
|
||||
// Détail par opération
|
||||
$operationNum = 1;
|
||||
foreach ($summary['operations'] ?? [] as $operation) {
|
||||
$this->info("Opération #{$operationNum}: \"{$operation['name']}\" (ID: {$operation['id']})");
|
||||
$this->info(" ├─ Utilisateurs: {$operation['users']}");
|
||||
$this->info(" ├─ Secteurs: {$operation['sectors']}");
|
||||
$this->info(" ├─ Passages totaux: {$operation['total_passages']}");
|
||||
|
||||
if (!empty($operation['sectors_detail'])) {
|
||||
$this->info(" └─ Détail par secteur:");
|
||||
|
||||
$sectorCount = count($operation['sectors_detail']);
|
||||
$sectorNum = 0;
|
||||
foreach ($operation['sectors_detail'] as $sector) {
|
||||
$sectorNum++;
|
||||
$isLast = ($sectorNum === $sectorCount);
|
||||
$prefix = $isLast ? " └─" : " ├─";
|
||||
|
||||
$this->info("{$prefix} {$sector['name']} (ID: {$sector['id']})");
|
||||
$this->info(" " . ($isLast ? " " : "│") . " ├─ Utilisateurs affectés: {$sector['users']}");
|
||||
$this->info(" " . ($isLast ? " " : "│") . " └─ Passages: {$sector['passages']}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->info("");
|
||||
$operationNum++;
|
||||
}
|
||||
|
||||
$this->separator();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user