| Current Path : /home/happyrenas/myreco.online/administration/panel/ |
Linux webd005.cluster105.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64 |
| Current File : /home/happyrenas/myreco.online/administration/panel/importation_resultat_modele1.php |
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../');
include("../../configuration.php");
setlocale(LC_TIME, 'fr_FR.UTF-8');
// ─────────────────────────────────────────────────────────────
// Config
// ─────────────────────────────────────────────────────────────
$colonnes_attendues = [
'name','categorie','latitude','longitude','postal_code','city',
'country_code','rating','reviews','place_id','full_address','photo',
'business_status','dernier_avis'
];
// ⚠️ Seules celles-ci doivent être non vides ligne par ligne :
$colonnes_obligatoires = [
'name','latitude','longitude','postal_code','city','country_code','rating','reviews'
];
// ─────────────────────────────────────────────────────────────
// Utils
// ─────────────────────────────────────────────────────────────
function getColonnesTable($nomTable, $connexion) {
$sql = "
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '$nomTable'
AND TABLE_SCHEMA = DATABASE()
ORDER BY ORDINAL_POSITION
";
$rows = $connexion->get_results($sql);
$out = [];
if ($rows) foreach ($rows as $r) $out[] = $r->COLUMN_NAME;
return $out;
}
function isRowCompletelyEmpty(array $vals): bool {
foreach ($vals as $v) {
if ($v !== null && trim((string)$v) !== '') return false;
}
return true;
}
function normalizeHeader($h) {
$h = trim((string)$h);
// Optionnel : homogénéiser les underscores/espaces si besoin
return $h;
}
function normalizeDecimal($v) {
// Remplace la virgule décimale par un point (ex: "41,5274" → "41.5274")
return str_replace(',', '.', (string)$v);
}
// ─────────────────────────────────────────────────────────────
// Vérifie upload
// ─────────────────────────────────────────────────────────────
if (!isset($_FILES['fichier']) || $_FILES['fichier']['error'] !== UPLOAD_ERR_OK) {
die("Erreur lors de l'upload du fichier XLSX.");
}
$extension = strtolower(pathinfo($_FILES['fichier']['name'], PATHINFO_EXTENSION));
if ($extension !== 'xlsx') {
die("Format non supporté : fournissez un fichier .xlsx");
}
// ─────────────────────────────────────────────────────────────
// Lecture XLSX (PhpSpreadsheet)
// ─────────────────────────────────────────────────────────────
require_once 'phpspreadsheet/PhpOffice/autoload.php';
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
try {
$reader = new Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load($_FILES['fichier']['tmp_name']);
$sheet = $spreadsheet->getActiveSheet();
// Récupère en tableau "brut"
// toArray(null, true, true, true) -> conserve l'indexation A,B,C... mais on va re-mapper nous-mêmes
$raw = $sheet->toArray(null, true, true, true);
} catch (Exception $e) {
die("Erreur lecture XLSX : " . $e->getMessage());
}
if (!$raw || count($raw) < 2) {
die("Le fichier semble vide ou sans données.");
}
// ─────────────────────────────────────────────────────────────
// Entêtes
// ─────────────────────────────────────────────────────────────
$headerRow = array_shift($raw); // première ligne
$headers = [];
// $headerRow a des clés 'A','B','C'... -> on ne garde que les valeurs
foreach ($headerRow as $colVal) {
$headers[] = normalizeHeader($colVal);
}
// Validation entêtes
$erreurs = [];
foreach ($colonnes_obligatoires as $col) {
if (!in_array($col, $headers, true)) {
$erreurs[] = "Colonne obligatoire manquante : <strong>{$col}</strong>";
}
}
if (!empty($erreurs)) {
echo "<h3>Erreurs d'entêtes :</h3>";
foreach ($erreurs as $e) echo "<p style='color:red'>{$e}</p>";
exit;
}
// Index rapide: nomCol -> index
$idxByName = array_flip($headers);
// ─────────────────────────────────────────────────────────────
// Lignes -> tableaux associatifs
// ─────────────────────────────────────────────────────────────
$rows_assoc = [];
foreach ($raw as $row) {
// $row est encore indexé 'A','B','C'...
$vals = array_values($row);
if (isRowCompletelyEmpty($vals)) continue;
// Assure le même nombre de colonnes que les headers
if (count($vals) < count($headers)) {
$vals = array_pad($vals, count($headers), null);
} elseif (count($vals) > count($headers)) {
$vals = array_slice($vals, 0, count($headers));
}
$assoc = array_combine($headers, $vals);
// Normalisations décimales
if (isset($assoc['latitude'])) $assoc['latitude'] = normalizeDecimal($assoc['latitude']);
if (isset($assoc['longitude'])) $assoc['longitude'] = normalizeDecimal($assoc['longitude']);
if (isset($assoc['rating'])) $assoc['rating'] = normalizeDecimal($assoc['rating']);
// Valeur par défaut pour business_status
if (!isset($assoc['business_status']) || trim((string)$assoc['business_status']) === '') {
$assoc['business_status'] = 'OPERATIONAL';
}
// Valeur par défaut pour dernier_avis
if (!isset($assoc['dernier_avis']) || trim((string)$assoc['dernier_avis']) === '') {
$assoc['dernier_avis'] = '-';
}
$rows_assoc[] = $assoc;
}
// ⬇️ INSERT ICI le patch postal_code ⬇️
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
if (in_array('postal_code', $headers, true)) {
$postalIdx = array_search('postal_code', $headers, true);
$postalColLetter = Coordinate::stringFromColumnIndex($postalIdx + 1);
foreach ($rows_assoc as $i => &$assoc) {
$excelRow = $i + 2; // ligne Excel (1 = entêtes, 2 = première donnée)
$cell = $sheet->getCell($postalColLetter . $excelRow);
$formatted = $cell->getFormattedValue();
if ($formatted !== null && $formatted !== '') {
$assoc['postal_code'] = (string)$formatted;
}
}
unset($assoc);
}
if (!$rows_assoc) {
die("Aucune ligne exploitable trouvée.");
}
// ─────────────────────────────────────────────────────────────
// Validation champs obligatoires (par ligne)
// ─────────────────────────────────────────────────────────────
$donnees_valides = [];
$erreurs = [];
$ligneExcelDepart = 2; // première ligne de données = ligne 2 dans Excel
foreach ($rows_assoc as $i => $assoc) {
$ligneNum = $ligneExcelDepart + $i;
$ligneErreurs = [];
foreach ($colonnes_obligatoires as $col) {
if (!isset($assoc[$col]) || trim((string)$assoc[$col]) === '') {
$ligneErreurs[] = "Ligne {$ligneNum} : champ <strong>{$col}</strong> vide.";
}
}
if (empty($ligneErreurs)) {
$donnees_valides[] = $assoc;
} else {
$erreurs = array_merge($erreurs, $ligneErreurs);
}
}
if (!empty($erreurs)) {
echo "<h3>Erreurs détectées :</h3>";
foreach ($erreurs as $e) echo "<p style='color:red'>{$e}</p>";
echo "<p><a href='javascript:history.back()'>⤺ Retour</a></p>";
exit;
}
// ─────────────────────────────────────────────────────────────
// Insertion (sécurisée) : on ne prend que les colonnes présentes dans la table
// ─────────────────────────────────────────────────────────────
$colonnes_table = getColonnesTable('vis', $db);
// Colonnes insérables = intersection (ordre = celui du fichier)
$colonnes_inserables = array_values(array_intersect($headers, $colonnes_table));
// Option : si tu veux forcer exactement tes 14 colonnes dans cet ordre :
$colonnes_inserables = array_values(array_intersect($colonnes_attendues, $colonnes_table));
$nb = 0;
foreach ($donnees_valides as $assoc) {
$champs = [];
$valeurs = [];
// Champ "token" généré automatiquement
$token = md5(uniqid(mt_rand(), true));
$champs[] = "`token`";
$valeurs[] = "'" . $db->escape($token) . "'";
// Champ "statut" forcé à 1
$champs[] = "`statut`";
$valeurs[] = "1";
// Colonnes issues du fichier
foreach ($colonnes_inserables as $col) {
$champs[] = "`$col`";
$valeurs[] = "'" . $db->escape((string)$assoc[$col]) . "'";
}
if (!$champs) continue;
$sql = "INSERT INTO `vis` (" . implode(',', $champs) . ") VALUES (" . implode(',', $valeurs) . ");";
echo $sql . "<br>\n";
// $db->query($sql);
$nb++;
}
echo "<p style='color:green'>{$nb} lignes prêtes à être insérées (token + statut=1 inclus).</p>";
?>