" en repli. * * Corrige suite a l'audit du 20/09/2026 : le detail technique des * exceptions n'est plus affiche a l'ecran ; il est journalise via * error_log(). * * Note : le controle par role (require_admin_role) est volontairement * absent de cette version, la separation des privileges etant reportee * a une migration dediee. */ declare(strict_types=1); require_once __DIR__ . '/admin_auth.php'; require_once __DIR__ . '/../lib/db.php'; require_once __DIR__ . '/_nav.php'; require_admin_auth(); $db = pdo(); $feedback = null; $feedbackType = 'success'; if ($_SERVER['REQUEST_METHOD'] === 'POST') { require_csrf_token(); $action = $_POST['action'] ?? ''; $confirmed = isset($_POST['confirm']) && $_POST['confirm'] === '1'; if (!$confirmed) { $feedback = 'Action refusee : la confirmation explicite est obligatoire.'; $feedbackType = 'error'; } elseif ($action === 'delete_cell') { $cellId = filter_input(INPUT_POST, 'cell_id', FILTER_VALIDATE_INT); if ($cellId === false || $cellId === null) { $feedback = 'Identifiant de cellule invalide.'; $feedbackType = 'error'; } else { try { $stmt = $db->prepare('DELETE FROM cells WHERE id = ? LIMIT 1'); $stmt->execute([$cellId]); $feedback = $stmt->rowCount() > 0 ? sprintf('Cellule #%d supprimee.', $cellId) : 'Aucune cellule correspondante trouvee (deja supprimee ?).'; } catch (Throwable $e) { error_log('[duplicates] delete_cell: ' . $e->getMessage()); $feedback = 'Une erreur est survenue lors de la suppression.'; $feedbackType = 'error'; } } } elseif ($action === 'merge_sites') { $keepId = filter_input(INPUT_POST, 'keep_site_id', FILTER_VALIDATE_INT); $dropId = filter_input(INPUT_POST, 'drop_site_id', FILTER_VALIDATE_INT); if (!$keepId || !$dropId || $keepId === $dropId) { $feedback = 'Selection de sites invalide pour la fusion.'; $feedbackType = 'error'; } else { try { $db->beginTransaction(); $stmt = $db->prepare('UPDATE cells SET site_id = ? WHERE site_id = ?'); $stmt->execute([$keepId, $dropId]); $moved = $stmt->rowCount(); $stmt = $db->prepare('DELETE FROM sites WHERE id = ? LIMIT 1'); $stmt->execute([$dropId]); $db->commit(); $feedback = sprintf( 'Fusion effectuee : %d cellule(s) rattachee(s) au site #%d, site #%d supprime.', $moved, $keepId, $dropId ); } catch (Throwable $e) { $db->rollBack(); error_log('[duplicates] merge_sites: ' . $e->getMessage()); $feedback = 'Une erreur est survenue lors de la fusion. Aucune donnee n\'a ete modifiee.'; $feedbackType = 'error'; } } } } /** * Collisions eNB/Cell ID : deux cellules distinctes qui partagent le * meme couple (sub_id2, cell_id) sur la meme technologie sont des * candidates a la fusion ou a la correction manuelle. area_code est * volontairement exclu de ce regroupement (contrairement a uniq_cell) * pour repérer aussi les cas ou le TAC differe par erreur de saisie * entre deux lignes du meme eNB. */ $cellDuplicates = $db->query( "SELECT c.sub_id2, c.cell_id, c.tech, COUNT(*) AS occurrences, GROUP_CONCAT(c.id ORDER BY c.id SEPARATOR ',') AS cell_ids, GROUP_CONCAT( DISTINCT COALESCE(s.address_desc, s.location_desc, CONCAT('Site #', s.id)) ORDER BY s.id SEPARATOR ' | ' ) AS site_names FROM cells c LEFT JOIN sites s ON s.id = c.site_id WHERE c.sub_id2 IS NOT NULL AND c.cell_id IS NOT NULL GROUP BY c.sub_id2, c.cell_id, c.tech HAVING occurrences > 1 ORDER BY occurrences DESC LIMIT 200" )->fetchAll(PDO::FETCH_ASSOC); $siteDuplicates = $db->query( "SELECT ROUND(s.lat, 5) AS lat_r, ROUND(s.lon, 5) AS lon_r, COUNT(*) AS occurrences, GROUP_CONCAT(s.id ORDER BY s.id SEPARATOR ',') AS site_ids, GROUP_CONCAT( COALESCE(s.address_desc, s.location_desc, CONCAT('Site #', s.id)) ORDER BY s.id SEPARATOR ' | ' ) AS names FROM sites s WHERE s.lat IS NOT NULL AND s.lon IS NOT NULL AND NOT (s.lat = 0 AND s.lon = 0) GROUP BY lat_r, lon_r HAVING occurrences > 1 ORDER BY occurrences DESC LIMIT 200" )->fetchAll(PDO::FETCH_ASSOC); $user = current_admin_username(); ?> Doublons & collisions — NetMonster Admin

Doublons & collisions eNB / Cell ID

Cette page detecte les collisions potentielles sans jamais modifier la base automatiquement. Toute fusion ou suppression exige une confirmation explicite.

Collisions eNB / Cell ID ()

Aucune collision detectee.

Techno eNB/RNC Cell ID Occurrences Sites concernes Action

Sites potentiellement dupliques ()

Aucun site en collision de coordonnees.

Latitude Longitude Occurrences Sites Fusionner
Garder Supprimer