getMessage()) n'est plus affiche a l'ecran ; il est * journalise via error_log() et un message generique est montre a * l'administrateur. */ declare(strict_types=1); require_once __DIR__ . '/admin_auth.php'; require_once __DIR__ . '/../lib/db.php'; require_once __DIR__ . '/../lib/ntm_import_to_staging.php'; require_once __DIR__ . '/_nav.php'; require_admin_auth(); $db = pdo(); $user = current_admin_username(); $successMessage = null; $errorMessage = null; $importStats = null; $previewGroups = []; $lastImportId = null; /** * Meme logique de regroupement que admin/review.php, dupliquee ici * volontairement pour ne pas creer de dependance croisee entre pages * admin. Si vous ajustez le decalage de bits ou la logique de * regroupement dans review.php, reportez le changement ici aussi. */ function deriveSiteKeyForPreview(array $row): string { $mcc = $row['mcc']; $mnc = $row['mnc']; if ($row['tech'] === '4G' && !empty($row['sub_id2'])) { return "enb:{$mcc}:{$mnc}:{$row['area_code']}:{$row['sub_id2']}"; } $latR = $row['lat'] !== null ? round((float)$row['lat'], 4) : 'na'; $lonR = $row['lon'] !== null ? round((float)$row['lon'], 4) : 'na'; return "geo:{$mcc}:{$mnc}:{$row['area_code']}:{$latR}:{$lonR}"; } const MAX_UPLOAD_SIZE_BYTES = 10 * 1024 * 1024; // 10 Mo, garde-fou raisonnable pour un fichier .ntm if ($_SERVER['REQUEST_METHOD'] === 'POST') { require_csrf_token(); $countryId = (int)($_POST['country_id'] ?? 0); if (!$countryId) { $errorMessage = "Selectionnez un pays avant d'importer."; } elseif (empty($_FILES['ntm_file']) || $_FILES['ntm_file']['error'] !== UPLOAD_ERR_OK) { $uploadErrors = [ UPLOAD_ERR_INI_SIZE => "Le fichier depasse la taille maximale autorisee par le serveur (php.ini).", UPLOAD_ERR_FORM_SIZE => "Le fichier depasse la taille maximale autorisee par le formulaire.", UPLOAD_ERR_PARTIAL => "Le fichier n'a ete que partiellement televerse. Reessayez.", UPLOAD_ERR_NO_FILE => "Aucun fichier selectionne.", ]; $code = $_FILES['ntm_file']['error'] ?? UPLOAD_ERR_NO_FILE; $errorMessage = $uploadErrors[$code] ?? "Erreur lors du televersement du fichier."; } else { $tmpPath = $_FILES['ntm_file']['tmp_name']; $originalName = $_FILES['ntm_file']['name']; $fileSize = $_FILES['ntm_file']['size']; $extension = strtolower(pathinfo($originalName, PATHINFO_EXTENSION)); if ($extension !== 'ntm') { $errorMessage = "Seuls les fichiers .ntm sont acceptes (extension detectee : ." . htmlspecialchars($extension, ENT_QUOTES, 'UTF-8') . ")."; } elseif ($fileSize > MAX_UPLOAD_SIZE_BYTES) { $errorMessage = "Le fichier depasse la limite de " . (MAX_UPLOAD_SIZE_BYTES / 1024 / 1024) . " Mo."; } elseif (!is_uploaded_file($tmpPath)) { $errorMessage = "Televersement invalide (fichier non reconnu comme upload legitime)."; } else { $safeFilename = preg_replace('/[^A-Za-z0-9._-]/', '_', $originalName); $uploadsDir = __DIR__ . '/../uploads'; if (!is_dir($uploadsDir)) { mkdir($uploadsDir, 0750, true); } $destPath = $uploadsDir . '/' . uniqid('ntm_', true) . '_' . $safeFilename; if (!move_uploaded_file($tmpPath, $destPath)) { $errorMessage = "Impossible d'enregistrer le fichier televerse sur le serveur."; } else { try { $importStats = importNtmFileToStaging($destPath, $safeFilename, $countryId); $successMessage = "Import termine : {$importStats['staged']} ligne(s) placee(s) en validation" . ($importStats['already_known'] > 0 ? ", dont {$importStats['already_known']} deja connue(s) en base" : "") . ($importStats['error'] > 0 ? ", {$importStats['error']} erreur(s)" : "") . "."; // Recupere l'ID de l'import qui vient d'etre cree pour l'apercu de regroupement $lastImportId = (int)$db->query('SELECT MAX(id) FROM imports')->fetchColumn(); $previewStmt = $db->prepare(' SELECT sc.*, o.brand AS operator_brand FROM staging_cells sc LEFT JOIN operators o ON o.id = sc.operator_guess WHERE sc.import_id = ? '); $previewStmt->execute([$lastImportId]); $importedRows = $previewStmt->fetchAll(PDO::FETCH_ASSOC); foreach ($importedRows as $row) { $key = deriveSiteKeyForPreview($row); $previewGroups[$key]['cells'][] = $row; $previewGroups[$key]['operator_brand'] = $row['operator_brand']; $previewGroups[$key]['lat'] = $previewGroups[$key]['lat'] ?? $row['lat']; $previewGroups[$key]['lon'] = $previewGroups[$key]['lon'] ?? $row['lon']; } } catch (Throwable $e) { error_log('[import_ntm] ' . $e->getMessage()); $errorMessage = "Une erreur est survenue lors du traitement du fichier. Consultez les journaux du serveur."; } } } } } $countries = $db->query('SELECT id, iso2, name FROM countries ORDER BY name')->fetchAll(PDO::FETCH_ASSOC); $importHistory = $db->query(' SELECT i.*, c.name AS country_name FROM imports i LEFT JOIN countries c ON c.id = i.country_id ORDER BY i.uploaded_at DESC LIMIT 20 ')->fetchAll(PDO::FETCH_ASSOC); ?> NetMonster Admin - Import .ntm

Importer un fichier .ntm

Deposez un fichier .ntm pour l'analyser et placer ses antennes en file de validation. Rien n'est ecrit dans la base finale sans validation manuelle.

Nouveau depot

Selectionnez un fichier .ntm (taille maximale : 10 Mo)

Resultat de l'import

ligne(s) lues
placee(s) en validation
deja connue(s) (doublon potentiel)
erreur(s)

Apercu du regroupement par site ( site(s) detecte(s))

Verification rapide que les cellules d'un meme site (meme eNB pour la 4G, ou meme position GPS pour les autres technos) sont bien reunies ensemble.

· , · cellule 1 ? 's' : '' ?>

· Cell ID · Area code · eNB/RNC · · Deja en base #

Aller a la page de validation →

Historique des imports

FichierPaysDateLignesEn validationErreursStatut
Aucun import pour le moment.