) * s'executait comme JavaScript dans le navigateur de l'administrateur * connecte, permettant de voler le jeton CSRF present dans le DOM et * d'agir a sa place. * * Les popups sont maintenant construites via des elements DOM avec * textContent, qui n'interprete jamais son contenu comme HTML/JS. */ 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(); $user = current_admin_username(); $countryFilter = $_GET['country'] ?? ''; $operatorFilter = $_GET['operator'] ?? ''; $totalSites = (int)$db->query('SELECT COUNT(*) FROM sites')->fetchColumn(); $totalCells = (int)$db->query('SELECT COUNT(*) FROM cells')->fetchColumn(); $totalPending = (int)$db->query('SELECT COUNT(*) FROM staging_cells WHERE status = "pending"')->fetchColumn(); $totalCountries = (int)$db->query('SELECT COUNT(*) FROM countries')->fetchColumn(); $byOperator = $db->query(' SELECT o.brand, o.mcc, o.mnc, c.name AS country_name, COUNT(DISTINCT s.id) AS site_count, COUNT(cl.id) AS cell_count FROM operators o LEFT JOIN countries c ON c.id = o.country_id LEFT JOIN sites s ON s.operator_id = o.id LEFT JOIN cells cl ON cl.site_id = s.id GROUP BY o.id ORDER BY c.name, o.brand ')->fetchAll(PDO::FETCH_ASSOC); $byTech = $db->query(' SELECT tech, COUNT(*) AS cnt FROM cells GROUP BY tech ORDER BY FIELD(tech, "2G","3G","4G","5G","CDMA") ')->fetchAll(PDO::FETCH_ASSOC); $recentActivity = $db->query(' SELECT s.id, s.lat, s.lon, s.location_desc, s.created_at, s.created_by, o.brand AS operator_brand, c.name AS country_name FROM sites s JOIN operators o ON o.id = s.operator_id JOIN countries c ON c.id = s.country_id ORDER BY s.created_at DESC LIMIT 8 ')->fetchAll(PDO::FETCH_ASSOC); $sql = ' SELECT s.id AS site_id, s.lat, s.lon, s.location_desc, o.brand AS operator_brand, c.name AS country_name, c.iso2, GROUP_CONCAT(DISTINCT cl.tech ORDER BY cl.tech SEPARATOR ", ") AS techs, COUNT(cl.id) AS cell_count FROM sites s JOIN operators o ON o.id = s.operator_id JOIN countries c ON c.id = s.country_id LEFT JOIN cells cl ON cl.site_id = s.id WHERE 1=1 '; $params = []; if ($countryFilter !== '') { $sql .= ' AND c.iso2 = ?'; $params[] = $countryFilter; } if ($operatorFilter !== '') { $sql .= ' AND o.id = ?'; $params[] = $operatorFilter; } $sql .= ' GROUP BY s.id ORDER BY s.created_at DESC'; $stmt = $db->prepare($sql); $stmt->execute($params); $sites = $stmt->fetchAll(PDO::FETCH_ASSOC); $operators = $db->query('SELECT id, mcc, mnc, brand FROM operators ORDER BY brand')->fetchAll(PDO::FETCH_ASSOC); $countries = $db->query('SELECT iso2, name, default_lat, default_lon, default_zoom FROM countries ORDER BY name')->fetchAll(PDO::FETCH_ASSOC); $activeCountry = null; if ($countryFilter !== '') { foreach ($countries as $c) { if ($c['iso2'] === $countryFilter) { $activeCountry = $c; break; } } } if (!$activeCountry && !empty($countries)) { $activeCountry = $countries[0]; } if (!$activeCountry) { $activeCountry = ['default_lat' => 20, 'default_lon' => 0, 'default_zoom' => 2]; } $operatorColors = ['POST' => '#0057A0', 'Tango' => '#E30613', 'Orange' => '#FF7900', 'LoL' => '#2E7D32']; $mapSites = array_map(fn($s) => [ 'lat' => (float)$s['lat'], 'lon' => (float)$s['lon'], 'operator' => $s['operator_brand'], 'techs' => $s['techs'], 'cell_count' => (int)$s['cell_count'], 'desc' => $s['location_desc'], 'country' => $s['country_name'], ], $sites); ?>
Vue d'ensemble de la base validee, tous pays et operateurs confondus.
= count($sites) ?> site(s) affiche(s) sur la carte.
| Operateur | Pays | Sites | Cellules |
|---|---|---|---|
| = htmlspecialchars($o['brand'], ENT_QUOTES, 'UTF-8') ?> | = htmlspecialchars($o['country_name'] ?? '?', ENT_QUOTES, 'UTF-8') ?> | = (int)$o['site_count'] ?> | = (int)$o['cell_count'] ?> |
| Techno | Cellules |
|---|---|
| = htmlspecialchars($t['tech'], ENT_QUOTES, 'UTF-8') ?> | = (int)$t['cnt'] ?> |
| Aucune cellule validee pour le moment. | |
Aucun site valide pour le moment.