From 4c9725b28289407423cbc2e62e094c596f8fc19c Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 6 Jul 2026 15:38:32 -0400 Subject: [PATCH] Enhance error handling and user feedback in static synchronization process This commit updates the connection timeout for MySQL operations and introduces new functions for managing connection errors and flash messages. The `fxStaticSyncConnectError` and `fxStaticSyncFormatConnectionError` functions provide clearer error reporting during synchronization. Additionally, the user interface is improved to display relevant flash messages, enhancing the overall user experience and robustness of the synchronization workflow. --- php/inc_fx_static_sync.php | 48 ++++++++++++++++++++++++++++++--- php/sync_static_db.php | 54 ++++++++++++++++++++++---------------- 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/php/inc_fx_static_sync.php b/php/inc_fx_static_sync.php index d1c7459..87e3877 100644 --- a/php/inc_fx_static_sync.php +++ b/php/inc_fx_static_sync.php @@ -58,7 +58,7 @@ class clsMysqlStaticSync extends clsMysql { return; } - mysqli_options($mysqli, MYSQLI_OPT_CONNECT_TIMEOUT, 3); + mysqli_options($mysqli, MYSQLI_OPT_CONNECT_TIMEOUT, 10); if (!@mysqli_real_connect( $mysqli, @@ -68,6 +68,10 @@ class clsMysqlStaticSync extends clsMysql { $arrDatabase['db'], 3306 )) { + if (!isset($GLOBALS['ms1_static_sync_connect_errors'])) { + $GLOBALS['ms1_static_sync_connect_errors'] = array(); + } + $GLOBALS['ms1_static_sync_connect_errors'][$arrDatabase['db']] = mysqli_connect_error(); return; } @@ -76,6 +80,25 @@ class clsMysqlStaticSync extends clsMysql { } } +function fxStaticSyncConnectError($strDb) { + if (empty($GLOBALS['ms1_static_sync_connect_errors'][$strDb])) { + return ''; + } + + return $GLOBALS['ms1_static_sync_connect_errors'][$strDb]; +} + +function fxStaticSyncFormatConnectionError($tabEnv) { + $strDb = isset($tabEnv['config']['db']) ? $tabEnv['config']['db'] : ''; + $strMsg = $tabEnv['label'] . ' (' . $strDb . ')'; + $strErr = fxStaticSyncConnectError($strDb); + if ($strErr !== '') { + $strMsg .= ' — ' . $strErr; + } + + return $strMsg; +} + function fxStaticSyncConnect($arrConfig) { if (empty($arrConfig['host']) || empty($arrConfig['db'])) { return null; @@ -334,9 +357,28 @@ function fxStaticSyncLoadKeyedRows($objDb, array $tabDef, array $tabCompareCols ); } -/** Sync d'écriture interdite vers client prod (comparaison seule). */ +/** Tous les environnements cibles sont syncables (dev prod, client préprod, client prod). */ function fxStaticSyncWriteAllowed($strEnvId) { - return $strEnvId !== 'client_prod'; + return true; +} + +function fxStaticSyncSetFlash($strMessage, $strType) { + $_SESSION['ms1_static_sync_flash'] = $strMessage; + $_SESSION['ms1_static_sync_flash_type'] = $strType; +} + +function fxStaticSyncPopFlash() { + if (empty($_SESSION['ms1_static_sync_flash'])) { + return null; + } + + $tabFlash = array( + 'message' => $_SESSION['ms1_static_sync_flash'], + 'type' => !empty($_SESSION['ms1_static_sync_flash_type']) ? $_SESSION['ms1_static_sync_flash_type'] : 'info', + ); + unset($_SESSION['ms1_static_sync_flash'], $_SESSION['ms1_static_sync_flash_type']); + + return $tabFlash; } function fxStaticSyncFinalizeCompareResult(array $tabCmp) { diff --git a/php/sync_static_db.php b/php/sync_static_db.php index eea01cb..47d793e 100644 --- a/php/sync_static_db.php +++ b/php/sync_static_db.php @@ -26,10 +26,15 @@ $strCsrf = fxStaticSyncEnsureCsrfToken(); $strFlash = ''; $strFlashType = 'info'; +$tabPopFlash = fxStaticSyncPopFlash(); +if (is_array($tabPopFlash)) { + $strFlash = $tabPopFlash['message']; + $strFlashType = $tabPopFlash['type']; +} + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'sync') { if (!fxStaticSyncValidateCsrf($_POST['csrf'] ?? '')) { - $strFlash = 'Jeton CSRF invalide.'; - $strFlashType = 'bad'; + fxStaticSyncSetFlash('Jeton CSRF invalide.', 'bad'); } else { $strTable = trim($_POST['table'] ?? ''); $strEnvId = trim($_POST['env'] ?? ''); @@ -37,39 +42,41 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' $tabEnv = fxStaticSyncFindEnvDef($strEnvId); if (!$tabDef || !$tabEnv || !empty($tabEnv['is_source'])) { - $strFlash = 'Paramètres invalides.'; - $strFlashType = 'bad'; - } elseif (!fxStaticSyncWriteAllowed($strEnvId)) { - $strFlash = 'Sync désactivée vers client prod — comparaison seule.'; - $strFlashType = 'bad'; + fxStaticSyncSetFlash('Paramètres invalides.', 'bad'); } else { $tabConnections = fxStaticSyncOpenConnections(); $objSource = $tabConnections['dev_preprod']; $objTarget = $tabConnections[$strEnvId]; if (!$objSource || !$objTarget) { - $strFlash = 'Connexion BD impossible.'; - $strFlashType = 'bad'; + fxStaticSyncSetFlash( + 'Connexion BD impossible — ' . fxStaticSyncFormatConnectionError($tabEnv), + 'bad' + ); } else { $tabResult = fxStaticSyncCopyTable($objSource, $objTarget, $strTable, $tabDef); if ($tabResult['ok']) { $tabVerify = fxStaticSyncCompareEnvPair($objSource, $objTarget, $tabDef); - $strFlash = $tabDef['label'] . ' → ' . $tabEnv['label'] . ' : ' . $tabResult['message']; + $strMsg = $tabDef['label'] . ' → ' . $tabEnv['label'] . ' : ' . $tabResult['message']; if ($tabVerify['status'] === 'ok') { - $strFlash .= ' Vérification : aligné.'; - $strFlashType = 'ok'; + $strMsg .= ' Vérification : aligné.'; + fxStaticSyncSetFlash($strMsg, 'ok'); } else { - $strFlash .= ' ATTENTION — après sync : ' + $strMsg .= ' ATTENTION — après sync : ' . fxStaticSyncStatusLabel($tabVerify['status'], $tabVerify) . '.'; - $strFlashType = 'bad'; + fxStaticSyncSetFlash($strMsg, 'bad'); } } else { - $strFlash = $tabDef['label'] . ' → ' . $tabEnv['label'] . ' — échec : ' . $tabResult['message']; - $strFlashType = 'bad'; + fxStaticSyncSetFlash( + $tabDef['label'] . ' → ' . $tabEnv['label'] . ' — échec : ' . $tabResult['message'], + 'bad' + ); } } } } + header('Location: sync_static_db.php#sync-result'); + exit; } $tabConnections = fxStaticSyncOpenConnections(); @@ -128,14 +135,14 @@ if ($strDetailTable !== '' && $strDetailEnv !== '') {

Sync tables statiques

Attention — opération destructive. - Sync = recopie complète depuis dev préprod (efface la cible). - Client prod : lecture seule. Un clic sur Sync — pas de confirmation à taper. + Sync = recopie complète depuis dev préprod (efface la cible). Un clic sur Sync.

Source de vérité : dev préprod (). - Comparaison vers dev prod, client préprod et client prod (lecture seule pour prod). + Comparaison vers dev prod, client préprod et client prod.

+
@@ -204,7 +211,12 @@ if ($strDetailTable !== '' && $strDetailEnv !== '') { Détails - + +
+ +
@@ -212,8 +224,6 @@ if ($strDetailTable !== '' && $strDetailEnv !== '') {
- -
Lecture seule