From 5b6faf93f9271f671279c3048dfaf0b5eaab9df6 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 23 Jul 2026 09:28:14 -0400 Subject: [PATCH] =?UTF-8?q?CON-333=20=E2=80=94=20Add=20functionality=20to?= =?UTF-8?q?=20remove=20excess=20"poubelle"=20entries=20from=20the=20info?= =?UTF-8?q?=20table=20during=20synchronization.=20Introduce=20a=20new=20ac?= =?UTF-8?q?tion=20for=20users=20to=20trigger=20this=20process,=20ensuring?= =?UTF-8?q?=20that=20only=20unnecessary=20entries=20are=20deleted=20while?= =?UTF-8?q?=20preserving=20valid=20labels.=20Update=20user=20interface=20m?= =?UTF-8?q?essaging=20to=20clarify=20the=20operation=20and=20its=20implica?= =?UTF-8?q?tions.=20Increment=20version=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/inc_fx_static_sync.php | 101 +++++++++++++++++++++++++++++++++++++ php/sync_static_db.php | 29 +++++++++-- 2 files changed, 126 insertions(+), 4 deletions(-) diff --git a/php/inc_fx_static_sync.php b/php/inc_fx_static_sync.php index 6338f41..9e930a5 100644 --- a/php/inc_fx_static_sync.php +++ b/php/inc_fx_static_sync.php @@ -1013,6 +1013,88 @@ function fxStaticSyncRepairInfoPoubelle($objSource, $objTarget, array $tabDef = ); } +/** + * CON-333 — info seulement : retirer les « en trop » qui sont des poubelles (texte = clé). + * Les vrais libellés présents seulement en cible sont CONSERVÉS (pas de DELETE). + */ +function fxStaticSyncRemoveInfoExtraPoubelle($objSource, $objTarget, array $tabDef = null) { + if (!$tabDef) { + $tabDef = fxStaticSyncFindTableDef('info'); + } + if (!$tabDef || $tabDef['table'] !== 'info') { + return array('ok' => false, 'message' => 'Réservé à info.'); + } + + $tabPrep = fxStaticSyncPrepareSoftWrite($objSource, $objTarget, 'info', $tabDef); + if (empty($tabPrep['ok'])) { + return $tabPrep; + } + + $tabToDelete = array(); + $intKeptReal = 0; + foreach ($tabPrep['target_rows'] as $strKey => $tabEntry) { + if (isset($tabPrep['source_rows'][$strKey])) { + continue; + } + $row = $tabEntry['row']; + if (fxStaticSyncInfoRowIsPoubelle($row)) { + $tabToDelete[] = $row; + } else { + $intKeptReal++; + } + } + + $intDel = count($tabToDelete); + if ($intDel === 0) { + return array( + 'ok' => true, + 'message' => 'Aucune poubelle en trop à retirer. ' + . $intKeptReal . ' vrai(s) libellé(s) seulement en cible — conservé(s) (pas de DELETE).', + 'deleted' => 0, + 'kept_real' => $intKeptReal, + ); + } + + $blnTransactional = (fxStaticSyncGetTableEngine($objTarget, 'info') === 'INNODB'); + if ($blnTransactional) { + $tabTx = fxStaticSyncExecQuery($objTarget, 'START TRANSACTION'); + if (!$tabTx['ok']) { + return array('ok' => false, 'message' => 'Transaction : ' . $tabTx['error']); + } + } + + $intDeleted = 0; + foreach ($tabToDelete as $row) { + $strSql = 'DELETE FROM `info` WHERE ' + . fxStaticSyncSqlWhereBusinessKeys($objTarget, $row, $tabDef['keys']) + . ' AND `info_texte`=`info_clef` LIMIT 1'; + $tabDel = fxStaticSyncExecQuery($objTarget, $strSql); + if (!$tabDel['ok']) { + if ($blnTransactional) { + fxStaticSyncExecQuery($objTarget, 'ROLLBACK'); + } + return array('ok' => false, 'message' => 'DELETE poubelle : ' . $tabDel['error']); + } + $intDeleted++; + } + + if ($blnTransactional) { + $tabCommit = fxStaticSyncExecQuery($objTarget, 'COMMIT'); + if (!$tabCommit['ok']) { + fxStaticSyncExecQuery($objTarget, 'ROLLBACK'); + return array('ok' => false, 'message' => 'Commit : ' . $tabCommit['error']); + } + } + + return array( + 'ok' => true, + 'message' => $intDeleted . ' poubelle(s) en trop retirée(s). ' + . $intKeptReal . ' vrai(s) libellé(s) seulement en cible — conservé(s) volontairement.', + 'deleted' => $intDeleted, + 'kept_real' => $intKeptReal, + ); +} + /** * CON-333 — Retirer les lignes « en trop » (catalogue accès v2). * info : jamais. Rôles : refuse si encore utilisés dans inscriptions_eve_acces. @@ -1516,6 +1598,25 @@ function fxStaticSyncCompareEnvPair($objSource, $objTarget, array $tabDef) { } $tabCmp['poubelle_keys'] = $tabPoubelle; + // CON-333 — en trop info qui sont des poubelles (retirables) vs vrais libellés (à garder). + $tabPoubExtra = array(); + $tabRealExtra = array(); + if ($tabDef['table'] === 'info') { + foreach ($tabTargetData['rows'] as $strKey => $tabTgtEntry) { + if (isset($tabSourceData['rows'][$strKey])) { + continue; + } + $tabTgt = $tabTgtEntry['row']; + if (fxStaticSyncInfoRowIsPoubelle($tabTgt)) { + $tabPoubExtra[] = $strKey; + } else { + $tabRealExtra[] = $strKey; + } + } + } + $tabCmp['poubelle_extra_keys'] = $tabPoubExtra; + $tabCmp['real_extra_keys'] = $tabRealExtra; + return $tabCmp; } diff --git a/php/sync_static_db.php b/php/sync_static_db.php index 8a485db..8af65e9 100644 --- a/php/sync_static_db.php +++ b/php/sync_static_db.php @@ -60,10 +60,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { if (!fxStaticSyncValidateCsrf($_POST['csrf'] ?? '')) { fxStaticSyncSetFlash('Jeton CSRF invalide.', 'bad'); - } elseif (!in_array($strAction, array('apply_missing', 'apply_content', 'apply_all', 'remove_extras'), true)) { + } elseif (!in_array($strAction, array('apply_missing', 'apply_content', 'apply_all', 'remove_extras', 'remove_info_poubelle_extras'), true)) { fxStaticSyncSetFlash( 'Action refusée. Sync destructif désactivé (CON-333). ' - . 'Utiliser Appliquer manquants / corrections / Retirer en trop (catalogues).', + . 'Utiliser Appliquer manquants / corrections / Retirer en trop / Retirer poubelles info.', 'bad' ); } else { @@ -99,6 +99,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { $tabResult = fxStaticSyncApplyMissingRows($objSource, $objTarget, $strTable, $tabDef); } elseif ($strAction === 'remove_extras') { $tabResult = fxStaticSyncRemoveExtras($objSource, $objTarget, $strTable, $tabDef); + } elseif ($strAction === 'remove_info_poubelle_extras') { + if ($tabDef['table'] !== 'info') { + $tabResult = array('ok' => false, 'message' => 'Réservé à info.'); + } else { + $tabResult = fxStaticSyncRemoveInfoExtraPoubelle($objSource, $objTarget, $tabDef); + } } else { $tabResult = fxStaticSyncApplyContentUpdates($objSource, $objTarget, $strTable, $tabDef); } @@ -195,8 +201,9 @@ if ($strDetailTable !== '' && $strDetailEnv !== '') {

Sync tables statiques — mode soft (CON-333)

Aucun DELETE. - On n’efface jamais info. Catalogues accès v2 (rôles / matrice / permissions) : - manquants + corrections, et Retirer en trop si besoin — sauf rôle encore utilisé en accès promoteur. + On n’efface jamais un vrai libellé info seulement en cible. + Les poubelles info en trop (texte = clé) : bouton dédié pour les retirer. + Catalogues accès v2 : Retirer en trop (sauf rôle encore utilisé).
@@ -275,6 +282,8 @@ if ($strDetailTable !== '' && $strDetailEnv !== '') { $intMissing = isset($tabCmp['missing_keys']) ? count($tabCmp['missing_keys']) : 0; $intExtra = isset($tabCmp['extra_keys']) ? count($tabCmp['extra_keys']) : 0; $intDiff = isset($tabCmp['diff_keys']) ? count($tabCmp['diff_keys']) : 0; + $intPoubExtra = isset($tabCmp['poubelle_extra_keys']) ? count($tabCmp['poubelle_extra_keys']) : 0; + $intRealExtra = isset($tabCmp['real_extra_keys']) ? count($tabCmp['real_extra_keys']) : 0; $blnCanRemoveExtras = !empty($tabDef['allow_remove_extras']); $blnCanWrite = ($tabCmp['status'] !== 'no_connection' && $tabCmp['status'] !== 'schema_mismatch' && $tabCmp['status'] !== 'missing_table' && $tabCmp['status'] !== 'error'); @@ -289,6 +298,9 @@ if ($strDetailTable !== '' && $strDetailEnv !== '') { Manque · Diff · En trop + 0) { ?> +
dont poubelles · vrais textes +
Retirer en trop () + 0) { ?> +
+ + + + + +
+