Ajout du dossier api avec la géolocalisation automatique des casernes de pompiers

This commit is contained in:
d6soft
2025-05-16 21:03:04 +02:00
parent 69dcff42f8
commit f4f7882963
143 changed files with 24329 additions and 1 deletions

357
api/scripts/php/migrate.php Normal file
View File

@@ -0,0 +1,357 @@
<?php
/**
* Script de migration générique pour transférer des données entre les bases geosector et geosector_app
*
* Usage:
* php migrate.php - Exécute toutes les migrations dans l'ordre
* php migrate.php <table_name> - Exécute la migration pour une table spécifique
*
* Options:
* --truncate Vide la table cible avant la migration
* --create-table Crée la table cible si elle n'existe pas
* --help Affiche l'aide
*/
require_once dirname(__DIR__) . '/config.php';
// Définition des mappages de colonnes pour chaque table
$tableMappings = [
'x_devises' => [
'source_to_target' => [
'rowid' => 'id',
'active' => 'chk_active'
],
'primary_key' => 'rowid', // Clé primaire dans la table source
'target_primary_key' => 'id' // Clé primaire dans la table cible
],
'users' => [
'source_to_target' => [
'id' => 'id',
'user_pass_hash' => 'password_hash',
'encrypted_user_name' => 'encrypted_last_name',
'lang' => 'preferred_language',
'chk_active' => 'is_active'
],
'primary_key' => 'id',
'target_primary_key' => 'id',
'encrypted_fields' => [
'email' => ['field' => 'encrypted_email', 'searchable' => true],
'user_name' => ['field' => 'encrypted_last_name', 'searchable' => false],
'phone' => ['field' => 'encrypted_phone', 'searchable' => false],
'mobile' => ['field' => 'encrypted_mobile', 'searchable' => false]
]
],
// Ajoutez d'autres tables selon les besoins
];
// Fonction pour afficher l'aide
function showHelp() {
echo "Usage: php migrate.php <table_name> [--truncate] [--create-table]\n";
echo "\nOptions disponibles:\n";
echo " --truncate Vide la table cible avant la migration\n";
echo " --create-table Crée la table cible si elle n'existe pas\n";
echo " --help Affiche cette aide\n";
echo "\nTables disponibles:\n";
global $tableMappings;
foreach (array_keys($tableMappings) as $table) {
echo " - $table\n";
}
exit(0);
}
// Définition des scripts de migration disponibles dans l'ordre d'exécution
$migrationScripts = [
'x_devises' => __DIR__ . '/migrate_x_devises.php',
'x_entites_types' => __DIR__ . '/migrate_x_entites_types.php',
'x_types_passages' => __DIR__ . '/migrate_x_types_passages.php',
'x_types_reglements' => __DIR__ . '/migrate_x_types_reglements.php',
'x_users_roles' => __DIR__ . '/migrate_x_users_roles.php',
'x_pays' => __DIR__ . '/migrate_x_pays.php',
'x_regions' => __DIR__ . '/migrate_x_regions.php',
'x_departements' => __DIR__ . '/migrate_x_departements.php',
'x_villes' => __DIR__ . '/migrate_x_villes.php',
'entites' => __DIR__ . '/migrate_entites.php',
'users' => __DIR__ . '/migrate_users.php',
'operations' => __DIR__ . '/migrate_operations.php',
'ope_sectors' => __DIR__ . '/migrate_ope_sectors.php',
'sectors_adresses' => __DIR__ . '/migrate_sectors_adresses.php',
'ope_users' => __DIR__ . '/migrate_ope_users.php',
'ope_users_sectors' => __DIR__ . '/migrate_ope_users_sectors.php',
'ope_pass' => __DIR__ . '/migrate_ope_pass.php',
'ope_pass_histo' => __DIR__ . '/migrate_ope_pass_histo.php',
'medias' => __DIR__ . '/migrate_medias.php'
// Ajoutez d'autres scripts de migration au fur et à mesure
];
// Fonction pour exécuter un script de migration spécifique
function executeMigrationScript($scriptPath) {
echo "\nExécution du script: " . basename($scriptPath) . "\n";
echo "------------------------------------------------\n";
// Exécuter le script PHP
include $scriptPath;
echo "\n";
return true;
}
// Traitement des arguments de ligne de commande
$tableName = null;
$truncateTable = false;
$createTable = false;
$runAllScripts = true;
for ($i = 1; $i < $_SERVER['argc']; $i++) {
$arg = $_SERVER['argv'][$i];
if ($arg === '--help') {
showHelp();
} elseif ($arg === '--truncate') {
$truncateTable = true;
} elseif ($arg === '--create-table') {
$createTable = true;
} elseif (substr($arg, 0, 2) !== '--') {
$tableName = $arg;
$runAllScripts = false;
}
}
// Si aucune table n'est spécifiée, exécuter tous les scripts de migration dans l'ordre
if ($runAllScripts) {
echo "\nDémarrage de la migration complète de la base de données\n";
echo "=======================================================\n";
$startTime = microtime(true);
$successCount = 0;
$failCount = 0;
foreach ($migrationScripts as $table => $scriptPath) {
if (file_exists($scriptPath)) {
try {
executeMigrationScript($scriptPath);
$successCount++;
} catch (Exception $e) {
echo "\nErreur lors de la migration de la table $table: " . $e->getMessage() . "\n";
$failCount++;
}
} else {
echo "\nScript de migration introuvable pour la table $table: $scriptPath\n";
$failCount++;
}
}
$endTime = microtime(true);
$executionTime = round($endTime - $startTime, 2);
echo "\n=======================================================\n";
echo "Migration terminée en $executionTime secondes\n";
echo "Tables migrées avec succès: $successCount\n";
echo "Tables en échec: $failCount\n";
exit(0);
}
// Si une table spécifique est demandée, vérifier si un script dédié existe
if (isset($migrationScripts[$tableName])) {
$scriptPath = $migrationScripts[$tableName];
if (file_exists($scriptPath)) {
executeMigrationScript($scriptPath);
exit(0);
}
}
// Sinon, utiliser la méthode générique de migration (code existant)
if (!isset($tableMappings[$tableName])) {
echo "Erreur: La table '$tableName' n'est pas configurée pour la migration.\n";
echo "Tables disponibles: " . implode(', ', array_keys($tableMappings)) . "\n";
exit(1);
}
// Création du dossier de logs si nécessaire
if (!is_dir(dirname(__DIR__) . '/logs')) {
mkdir(dirname(__DIR__) . '/logs', 0755, true);
}
logOperation("Démarrage de la migration de la table $tableName");
try {
// Connexion aux bases de données
$sourceDb = getSourceConnection();
$targetDb = getTargetConnection();
// Obtenir le service API pour le chiffrement si nécessaire
$apiService = null;
if (isset($tableMappings[$tableName]['encrypted_fields'])) {
$container = $GLOBALS['container'];
$apiService = $container->get('ApiService');
}
// Récupération des données de la source
$stmt = $sourceDb->query("SELECT * FROM $tableName");
$records = $stmt->fetchAll();
logOperation("Nombre d'enregistrements à migrer: " . count($records));
// Vérifier si la table existe dans la cible
try {
$targetDb->query("SELECT 1 FROM $tableName LIMIT 1");
$tableExists = true;
} catch (PDOException $e) {
$tableExists = false;
}
// Créer la table si elle n'existe pas et si l'option est activée
if (!$tableExists && $createTable) {
logOperation("La table $tableName n'existe pas dans la base cible. Création de la table...");
// Récupérer la structure de la table source
$stmt = $sourceDb->query("SHOW CREATE TABLE $tableName");
$tableStructure = $stmt->fetch(PDO::FETCH_ASSOC);
if (isset($tableStructure['Create Table'])) {
$createTableSql = $tableStructure['Create Table'];
// Adapter les noms de colonnes selon le mapping
$mapping = $tableMappings[$tableName]['source_to_target'];
foreach ($mapping as $sourceCol => $targetCol) {
$createTableSql = str_replace("`$sourceCol`", "`$targetCol`", $createTableSql);
}
// Remplacer le nom de la clé primaire si nécessaire
$sourcePk = $tableMappings[$tableName]['primary_key'];
$targetPk = $tableMappings[$tableName]['target_primary_key'];
if ($sourcePk !== $targetPk) {
$createTableSql = str_replace("PRIMARY KEY (`$sourcePk`)", "PRIMARY KEY (`$targetPk`)", $createTableSql);
}
// Créer la table
$targetDb->exec($createTableSql);
logOperation("Table $tableName créée avec succès");
} else {
throw new Exception("Impossible de récupérer la structure de la table source");
}
}
// Vider la table cible si l'option est activée
if ($truncateTable && $tableExists) {
logOperation("Vidage de la table cible $tableName...");
$targetDb->exec("TRUNCATE TABLE $tableName");
}
// Construire la requête d'insertion dynamiquement
$mapping = $tableMappings[$tableName]['source_to_target'];
// Récupérer les colonnes de la table cible
$stmt = $targetDb->query("DESCRIBE $tableName");
$targetColumns = $stmt->fetchAll(PDO::FETCH_COLUMN);
// Construire les listes de colonnes pour l'insertion
$insertColumns = [];
$insertPlaceholders = [];
$updateClauses = [];
foreach ($targetColumns as $column) {
$insertColumns[] = "`$column`";
$insertPlaceholders[] = ":$column";
$updateClauses[] = "`$column` = VALUES(`$column`)";
}
$insertColumnsSql = implode(", ", $insertColumns);
$insertPlaceholdersSql = implode(", ", $insertPlaceholders);
$updateClausesSql = implode(", ", $updateClauses);
$insertQuery = "INSERT INTO $tableName ($insertColumnsSql) "
. "VALUES ($insertPlaceholdersSql) "
. "ON DUPLICATE KEY UPDATE $updateClausesSql";
$insertStmt = $targetDb->prepare($insertQuery);
// Compteurs
$successCount = 0;
$errorCount = 0;
// Traitement de chaque enregistrement
foreach ($records as $record) {
try {
$data = [];
// Mappage des colonnes selon la configuration
foreach ($targetColumns as $targetCol) {
// Trouver la colonne source correspondante
$sourceCol = array_search($targetCol, $mapping);
if ($sourceCol !== false) {
// La colonne existe dans le mapping
$data[$targetCol] = $record[$sourceCol];
} elseif (isset($record[$targetCol])) {
// La colonne a le même nom dans les deux tables
$data[$targetCol] = $record[$targetCol];
} else {
// Colonne non trouvée, utiliser NULL ou une valeur par défaut
$data[$targetCol] = null;
}
}
// Traitement des champs chiffrés si nécessaire
if (isset($tableMappings[$tableName]['encrypted_fields']) && $apiService) {
foreach ($tableMappings[$tableName]['encrypted_fields'] as $sourceField => $config) {
$targetField = $config['field'];
$isSearchable = $config['searchable'];
if (isset($record[$sourceField]) && !empty($record[$sourceField])) {
// Vérifier si le champ est déjà chiffré
if (isset($record["encrypted_$sourceField"])) {
$data[$targetField] = $record["encrypted_$sourceField"];
} else {
// Chiffrer la donnée selon qu'elle est recherchable ou non
if ($isSearchable) {
$data[$targetField] = $apiService->encryptSearchableData($record[$sourceField]);
} else {
$data[$targetField] = $apiService->encryptData($record[$sourceField]);
}
}
}
}
}
// Gestion spécifique pour certaines tables
if ($tableName === 'users') {
// Conversion de chk_active (0,1,2) vers is_active (booléen)
if (isset($record['chk_active'])) {
$data['is_active'] = ($record['chk_active'] > 0) ? 1 : 0;
}
}
// Insertion dans la base cible
$insertStmt->execute($data);
$successCount++;
// Identifiant pour le log
$pkField = $tableMappings[$tableName]['primary_key'];
$recordId = $record[$pkField] ?? 'inconnu';
logOperation("Enregistrement ID $recordId migré avec succès", "INFO");
} catch (Exception $e) {
$errorCount++;
$pkField = $tableMappings[$tableName]['primary_key'];
$recordId = $record[$pkField] ?? 'inconnu';
logOperation("Erreur lors de la migration de l'enregistrement ID $recordId: " . $e->getMessage(), "ERROR");
}
}
logOperation("Migration terminée. Succès: $successCount, Erreurs: $errorCount");
// Fermer le tunnel SSH
closeSshTunnel();
} catch (Exception $e) {
logOperation("Erreur critique: " . $e->getMessage(), "ERROR");
// Fermer le tunnel SSH en cas d'erreur
closeSshTunnel();
exit(1);
}