diff --git a/api.php b/api.php index 48c224d..33049f0 100644 --- a/api.php +++ b/api.php @@ -116,33 +116,93 @@ function emptyPhysicalResult() { ]; } -// ── SCRAPPING FNAC (CORRECTION v2 : vérification EAN anti-faux-positif) ── +// ── NOUVELLE FONCTION : SCRAPPING GO-UPC.COM ── +function fetchFromGoUpc($ean) { + $empty = emptyPhysicalResult(); + $url = "https://go-upc.com/search?q=" . urlencode($ean); + $html = httpGet($url, 15); + if (!$html) return $empty; + + // Recherche du titre dans les résultats + if (preg_match('/]*>([^<]+)<\/h1>/i', $html, $m)) { + $empty['title'] = trim(strip_tags($m[1])); + } elseif (preg_match('/]*>([^<]+)<\/title>/i', $html, $m)) { + $title = trim($m[1]); + $title = preg_replace('/\s*[-–]\s*GO-UPC.*$/i', '', $title); + $empty['title'] = $title; + } + + // Recherche de l'image + if (preg_match('/]*src="([^"]+\.(?:jpg|jpeg|png|webp))"[^>]*alt="[^"]*product[^"]*"[^>]*>/i', $html, $m)) { + $empty['poster'] = trim($m[1]); + } elseif (preg_match('/]*property="og:image"[^>]*content="([^"]+)"/i', $html, $m)) { + $empty['poster'] = trim($m[1]); + } + + // Nettoyage du titre + if (!empty($empty['title'])) { + $empty['title'] = html_entity_decode($empty['title'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $empty['title'] = trim($empty['title']); + } + + if (!empty($empty['title'])) { + $empty['format'] = detectFormat($empty['title']); + } + + return $empty; +} + +// ── NOUVELLE FONCTION : SCRAPPING UPCINDEX.COM ── +function fetchFromUpcIndex($ean) { + $empty = emptyPhysicalResult(); + $url = "https://www.upcindex.com/" . urlencode($ean); + $html = httpGet($url, 15); + if (!$html) return $empty; + + // Recherche du titre + if (preg_match('/]*>([^<]+)<\/h1>/i', $html, $m)) { + $empty['title'] = trim(strip_tags($m[1])); + } elseif (preg_match('/]*>([^<]+)<\/title>/i', $html, $m)) { + $title = trim($m[1]); + $title = preg_replace('/\s*[-–]\s*UPCIndex.*$/i', '', $title); + $empty['title'] = $title; + } + + // Recherche de l'image + if (preg_match('/]*src="([^"]+\.(?:jpg|jpeg|png|webp))"[^>]*alt="[^"]*product[^"]*"[^>]*>/i', $html, $m)) { + $empty['poster'] = trim($m[1]); + } elseif (preg_match('/]*property="og:image"[^>]*content="([^"]+)"/i', $html, $m)) { + $empty['poster'] = trim($m[1]); + } + + // Nettoyage du titre + if (!empty($empty['title'])) { + $empty['title'] = html_entity_decode($empty['title'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $empty['title'] = trim($empty['title']); + } + + if (!empty($empty['title'])) { + $empty['format'] = detectFormat($empty['title']); + } + + return $empty; +} + +// ── SCRAPPING FNAC ── function fetchFromFnac($ean) { $empty = emptyPhysicalResult(); $url = "https://www.fnac.com/SearchResult/ResultList.aspx?Search=" . urlencode($ean); $html = httpGet($url, 15); if (!$html) return $empty; - // 🔍 LOG DE DIAGNOSTIC — à garder tant que le bug n'est pas confirmé résolu. - // Permet de vérifier si FNAC renvoie vraiment une page de résultats - // ou une page anti-bot / fallback générique (souvent la vraie cause - // d'un titre "aléatoire" du type "Project Hail Mary"). - @file_put_contents( - __DIR__ . '/debug_fnac_' . preg_replace('/[^0-9]/', '', $ean) . '.html', - $html - ); - - // ✅ GARDE-FOU : si l'EAN recherché n'apparaît nulle part dans le HTML - // retourné, ce n'est pas une vraie page de résultats pour cet EAN - // (bannière promo, page anti-bot, page d'accueil de secours...). - // On refuse le résultat plutôt que de propager un titre erroné. + // GARDE-FOU : si l'EAN recherché n'apparaît nulle part dans le HTML $eanDigits = preg_replace('/[^0-9]/', '', (string)$ean); if ($eanDigits && strpos($html, $eanDigits) === false) { - error_log("fetchFromFnac: EAN $eanDigits absent du HTML retourné — page rejetée (probable anti-bot/fallback)."); + error_log("fetchFromFnac: EAN $eanDigits absent du HTML retourné — page rejetée."); return $empty; } - // 1. Chercher un lien avec un titre ou du texte interne + // Chercher un lien avec un titre if (preg_match('/]*href="\/(?:[^"]*\/)?(?:tp\d+|A\d+|[^"]*-s\d+\.html)"[^>]*>([^<]+)<\/a>/i', $html, $m)) { $empty['title'] = trim(strip_tags($m[1])); } @@ -413,31 +473,59 @@ function fetchFromMovieCovers($title, $year = '') { return $empty; } -// ── AGGREGATEUR PHYSIQUE (VERSION TRACÉE POUR DIAGNOSTIC) ── +// ── AGGREGATEUR PHYSIQUE (VERSION MODIFIÉE AVEC GO-UPC ET UPCINDEX) ── function fetchPhysicalByEan($ean, $pdo = null) { error_log("=== DEBUT fetchPhysicalByEan EAN=$ean ==="); - // 1. FNAC - $fnacData = fetchFromFnac($ean); - error_log("FNAC -> title='" . ($fnacData['title'] ?? '') . "' poster='" . ($fnacData['poster'] ?? '') . "'"); - $title = $fnacData['title'] ?? ''; - $res = $fnacData; + $res = emptyPhysicalResult(); + $title = ''; - // 2. Blu-ray.com par titre (si FNAC a donné un titre) + // 1. GO-UPC.COM (Priorité 1) + $goUpcData = fetchFromGoUpc($ean); + error_log("GO-UPC -> title='" . ($goUpcData['title'] ?? '') . "' poster='" . ($goUpcData['poster'] ?? '') . "'"); + if (!empty($goUpcData['title'])) { + $title = $goUpcData['title']; + $res = $goUpcData; + } + + // 2. UPCINDEX.COM (Priorité 2 - si GO-UPC n'a rien donné) + if (empty($title)) { + $upcIndexData = fetchFromUpcIndex($ean); + error_log("UPCINDEX -> title='" . ($upcIndexData['title'] ?? '') . "' poster='" . ($upcIndexData['poster'] ?? '') . "'"); + if (!empty($upcIndexData['title'])) { + $title = $upcIndexData['title']; + $res = $upcIndexData; + } + } + + // 3. FNAC (Priorité 3 - si les deux précédents n'ont rien donné) + if (empty($title)) { + $fnacData = fetchFromFnac($ean); + error_log("FNAC -> title='" . ($fnacData['title'] ?? '') . "' poster='" . ($fnacData['poster'] ?? '') . "'"); + if (!empty($fnacData['title'])) { + $title = $fnacData['title']; + $res = $fnacData; + } + } + + // 4. Blu-ray.com par titre (si on a un titre) $blurayData = []; if (!empty($title)) { $blurayData = fetchFromBlurayComByTitle($title); - error_log("BLURAY(byTitle, cherché='$title') -> title='" . ($blurayData['title'] ?? '(vide, ce champ n\'est pas rempli par cette fonction)') . "' year='" . ($blurayData['year'] ?? '') . "' publisher='" . ($blurayData['publisher'] ?? '') . "'"); + error_log("BLURAY(byTitle) -> year='" . ($blurayData['year'] ?? '') . "' publisher='" . ($blurayData['publisher'] ?? '') . "'"); } - // 3. Fallback: Blu-ray.com par EAN (si FNAC n'a rien donné) + // 5. Fallback: Blu-ray.com par EAN (si aucun titre trouvé) if (empty($blurayData) && empty($title)) { $blurayData = fetchFromBlurayComByEan($ean); $title = $blurayData['title'] ?? ''; - $res = $blurayData; - error_log("BLURAY(byEan) -> title='$title' year='" . ($blurayData['year'] ?? '') . "'"); + if (!empty($title)) { + $res = $blurayData; + error_log("BLURAY(byEan) -> title='$title'"); + } } + // Fusion des données Blu-ray.com if (!empty($blurayData)) { if (!empty($blurayData['length'])) $res['length'] = $blurayData['length']; if (!empty($blurayData['number_of_discs'])) $res['number_of_discs'] = $blurayData['number_of_discs']; @@ -448,10 +536,10 @@ function fetchPhysicalByEan($ean, $pdo = null) { if (!empty($blurayData['year'])) $res['year'] = $blurayData['year']; } - // 4. MovieCovers (par titre) + // 6. MovieCovers (par titre) if (!empty($title)) { $mc = fetchFromMovieCovers($title, $res['year'] ?? ''); - error_log("MOVIECOVERS(cherché='$title') -> title='" . ($mc['title'] ?? '') . "' poster='" . ($mc['poster'] ?? '') . "'"); + error_log("MOVIECOVERS -> poster='" . ($mc['poster'] ?? '') . "'"); if (!empty($mc['poster'])) $res['poster'] = $mc['poster']; if (!empty($mc['director'])) $res['director'] = $mc['director']; if (!empty($mc['actors'])) $res['actors'] = $mc['actors'];