'GSM', '3G' => 'UMTS', '4G' => 'LTE', '5G' => 'NR', 'CDMA' => 'CDMA']; function composeLocationForExport(string $tech, ?string $enb, ?string $band, ?string $frequency, $azimuth, ?string $bandwidth, ?string $address): string { $techLabel = TECH_RADIO_LABEL_EXPORT[$tech] ?? $tech; $segments = []; if ($enb !== null && $enb !== '' && (int)$enb !== 0) { $segments[] = "eNB ID $enb"; } $radioLine = trim($techLabel . ' ' . ($band ?? '') . ' ' . ($frequency ?? '')); if ($radioLine !== $techLabel && $radioLine !== '') { $segments[] = $radioLine; } if ($azimuth !== null && $azimuth !== '') { $segments[] = $azimuth . '°'; } if ($bandwidth !== null && $bandwidth !== '') { $segments[] = $bandwidth; } if ($address !== null && $address !== '') { $segments[] = $address; } return implode(' - ', $segments); } function sanitizeFilterValue(string $value, string $pattern): string { return preg_match($pattern, $value) ? $value : ''; } if (isset($_GET['download'])) { $format = $_GET['download'] === 'csv' ? 'csv' : 'ntm'; $countryFilter = sanitizeFilterValue($_GET['country'] ?? '', '/^[A-Z]{2}$/'); $operatorFilter = sanitizeFilterValue($_GET['operator'] ?? '', '/^\d+$/'); $techFilter = sanitizeFilterValue($_GET['tech'] ?? '', '/^(2G|3G|4G|5G|CDMA)$/'); $sql = ' SELECT cl.tech, cl.mcc, cl.mnc, cl.cell_id, cl.area_code, cl.sub_id, cl.sub_id2, cl.band, cl.frequency, cl.azimuth, cl.bandwidth, cl.arfcn, s.lat, s.lon, s.address_desc, o.brand AS operator_brand, c.name AS country_name, c.iso2 FROM cells cl JOIN sites s ON s.id = cl.site_id JOIN operators o ON o.id = s.operator_id JOIN countries c ON c.id = s.country_id WHERE 1=1 '; $params = []; if ($countryFilter !== '') { $sql .= ' AND c.iso2 = ?'; $params[] = $countryFilter; } if ($operatorFilter !== '') { $sql .= ' AND o.id = ?'; $params[] = $operatorFilter; } if ($techFilter !== '') { $sql .= ' AND cl.tech = ?'; $params[] = $techFilter; } $sql .= ' ORDER BY c.name, o.brand, cl.tech, cl.cell_id'; $stmt = $db->prepare($sql); $stmt->execute($params); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $labelParts = []; if ($countryFilter !== '') $labelParts[] = strtolower($countryFilter); if ($operatorFilter !== '') $labelParts[] = 'op' . $operatorFilter; if ($techFilter !== '') $labelParts[] = strtolower($techFilter); $suffix = $labelParts ? '_' . implode('_', $labelParts) : '_all'; $filename = 'netmonster_export' . $suffix . '_' . date('Ymd_His'); if ($format === 'csv') { header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename="' . $filename . '.csv"'); $out = fopen('php://output', 'w'); fputcsv($out, [ 'tech', 'mcc', 'mnc', 'operator', 'country', 'cell_id', 'area_code', 'sub_id', 'enb_rnc', 'band', 'frequency', 'azimuth', 'bandwidth', 'arfcn', 'lat', 'lon', 'address_desc', 'location_desc_recompose', ], ';'); foreach ($rows as $r) { $composed = composeLocationForExport($r['tech'], (string)($r['sub_id2'] ?? ''), $r['band'], $r['frequency'], $r['azimuth'], $r['bandwidth'], $r['address_desc']); fputcsv($out, [ $r['tech'], $r['mcc'], $r['mnc'], $r['operator_brand'], $r['country_name'], $r['cell_id'], $r['area_code'], $r['sub_id'], $r['sub_id2'], $r['band'], $r['frequency'], $r['azimuth'], $r['bandwidth'], $r['arfcn'], $r['lat'], $r['lon'], $r['address_desc'], $composed, ], ';'); } fclose($out); exit; } header('Content-Type: text/plain; charset=utf-8'); header('Content-Disposition: attachment; filename="' . $filename . '.ntm"'); $tagMap = ['2G' => '2G', '3G' => '3G', '4G' => '4G', '5G' => '5G', 'CDMA' => 'CD2']; foreach ($rows as $r) { $tag = $tagMap[$r['tech']] ?? $r['tech']; $lat = $r['lat'] ?? 0; $lon = $r['lon'] ?? 0; $arfcn = $r['arfcn'] ?? 0; $location = composeLocationForExport( $r['tech'], $r['tech'] === '4G' ? (string)($r['sub_id2'] ?? '') : null, $r['band'], $r['frequency'], $r['azimuth'], $r['bandwidth'], $r['address_desc'] ); if (in_array($r['tech'], ['3G', '4G'], true)) { echo implode(';', [$tag, $r['mcc'], $r['mnc'], $r['cell_id'], $r['area_code'], $r['sub_id2'] ?? 0, $r['sub_id'] ?? 0, $lat, $lon, $location, $arfcn]) . "\r\n"; } elseif ($r['tech'] === 'CDMA') { echo implode(';', [$tag, $r['mcc'], $r['mnc'], $r['cell_id'], $r['area_code'], 0, $r['sub_id'] ?? 0, $lat, $lon, $location, '']) . "\r\n"; } else { echo implode(';', [$tag, $r['mcc'], $r['mnc'], $r['cell_id'], $r['area_code'], 0, $r['sub_id'] ?? 0, $lat, $lon, $location, $arfcn]) . "\r\n"; } } exit; } $countries = $db->query('SELECT id, iso2, name FROM countries ORDER BY name')->fetchAll(PDO::FETCH_ASSOC); $operators = $db->query('SELECT id, mcc, mnc, brand FROM operators ORDER BY brand')->fetchAll(PDO::FETCH_ASSOC); $totalCells = (int)$db->query('SELECT COUNT(*) FROM cells')->fetchColumn(); $totalSites = (int)$db->query('SELECT COUNT(*) FROM sites')->fetchColumn(); $lastValidated = $db->query('SELECT MAX(validated_at) FROM cells')->fetchColumn(); $byCountryStats = $db->query(' SELECT c.name AS country_name, c.iso2, COUNT(DISTINCT s.id) AS site_count, COUNT(cl.id) AS cell_count FROM countries c LEFT JOIN sites s ON s.country_id = c.id LEFT JOIN cells cl ON cl.site_id = s.id GROUP BY c.id ORDER BY c.name ')->fetchAll(PDO::FETCH_ASSOC); $user = current_admin_username(); ?> NetMonster Admin - Export

Export de la base pour mise en production

Telechargez la base validee (sites + cellules) pour l'envoyer sur votre serveur de diffusion.

site(s) valides
cellule(s) validees
derniere validation

Repartition par pays

PaysSitesCellules

Filtrer avant export

Laissez sur "Tous" pour exporter l'integralite de la base validee.

Format .ntm

Reconstruit le format d'origine NetMonster (CSV ";"), Location recomposee depuis les champs structures, pret a etre republie tel quel.

Format .csv

Format tabulaire avec colonnes separees (bande, frequence, azimut, largeur de bande), pratique pour verification dans un tableur.