diff --git a/api.php b/api.php index e1f0700..a3f0a4e 100644 --- a/api.php +++ b/api.php @@ -144,30 +144,83 @@ function fetchUPCitemdb($ean, $pdo) { return null; } - function fetchDVDFr($ean, $pdo) { - if (empty($ean) || strlen($ean) < 8) return null; - $cacheKey = 'dvdfr_' . md5($ean); - $cached = getCache($pdo, $cacheKey); - if ($cached) return $cached; - - $url = "https://www.dvdfr.com/api/search.php?gencode=" . urlencode($ean); - $res = httpGet($url, 2); // 🔥 Timeout réduit - if (!$res) return null; - - // 🔥 SÉCURISATION : Empêche le crash fatal si DVDfr renvoie du HTML ou une erreur - libxml_use_internal_errors(true); - $xml = simplexml_load_string($res); - libxml_clear_errors(); - - if ($xml && isset($xml->dvd) && isset($xml->dvd[0]->cover)) { - $poster = (string)$xml->dvd[0]->cover; - if (!empty($poster)) { - setCache($pdo, $cacheKey, $poster, 'dvdfr'); - return $poster; - } - } - return null; +function fetchDVDFr($ean, $pdo) { + if (empty($ean) || strlen($ean) < 8) return null; + $cacheKey = 'dvdfr_' . md5($ean); + $cached = getCache($pdo, $cacheKey); + if ($cached) return $cached; + + // DVDFr exige un User-Agent propre à l'application (sinon INVALID_UA) + $ua = 'MonCinema/1.0 (collection privée; contact@moncineapp.fr)'; + + // Étape 1 : recherche par gencode → récupère l'id DVDFr + $searchUrl = "https://www.dvdfr.com/api/search.php?gencode=" . urlencode($ean); + $ch = curl_init($searchUrl); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 5, + CURLOPT_CONNECTTIMEOUT => 3, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_USERAGENT => $ua, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTPHEADER => ['Accept: application/xml, text/xml, */*'], + ]); + $res = curl_exec($ch); + curl_close($ch); + if (!$res) return null; + + libxml_use_internal_errors(true); + $xml = simplexml_load_string($res); + libxml_clear_errors(); + if (!$xml || !isset($xml->dvd[0]->id)) return null; + + $dvdId = (string)$xml->dvd[0]->id; + if (empty($dvdId)) return null; + + // Étape 2 : fiche complète via dvd.php?id= (quota 200/semaine, utilise le cache) + $ficheUrl = "https://www.dvdfr.com/api/dvd.php?id=" . urlencode($dvdId); + $ch2 = curl_init($ficheUrl); + curl_setopt_array($ch2, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 5, + CURLOPT_CONNECTTIMEOUT => 3, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_USERAGENT => $ua, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTPHEADER => ['Accept: application/xml, text/xml, */*'], + ]); + $res2 = curl_exec($ch2); + curl_close($ch2); + if (!$res2) return null; + + libxml_use_internal_errors(true); + $fiche = simplexml_load_string($res2); + libxml_clear_errors(); + if (!$fiche || !isset($fiche->dvd[0])) return null; + + $dvd = $fiche->dvd[0]; + + // Extraction de la jaquette (nouvelle structure après refonte) + $poster = ''; + if (isset($dvd->cover)) $poster = (string)$dvd->cover; + if (empty($poster) && isset($dvd->covers->cover[0])) $poster = (string)$dvd->covers->cover[0]; + + // Extraction des métadonnées techniques + $result = [ + 'poster' => $poster, + 'publisher' => isset($dvd->editeur) ? (string)$dvd->editeur : '', + 'format' => isset($dvd->type) ? (string)$dvd->type : '', + 'length' => isset($dvd->duree) ? (string)$dvd->duree : '', + 'aspect' => isset($dvd->formatimage) ? (string)$dvd->formatimage : '', + 'discs' => isset($dvd->nbdisques) ? (string)$dvd->nbdisques : '', + ]; + + // Ne met en cache que si on a au moins une affiche ou un éditeur + if (!empty($result['poster']) || !empty($result['publisher'])) { + setCache($pdo, $cacheKey, $result, 'dvdfr'); } + return !empty($result['poster']) || !empty($result['publisher']) ? $result : null; +} // ── 2. API TMDB (Full Extract avec Synopsis et Acteurs) ── function fetchTMDBFull($title, $year, $apiKey, $pdo) { @@ -329,10 +382,15 @@ switch ($action) { $result['format'] = $upcData['format']; } - // 🔥 NOUVEAU : DVDFr pour remplacer l'affiche lors d'un ajout manuel - $dvdfrCover = fetchDVDFr($ean, $pdo); - if (!empty($dvdfrCover)) { - $result['poster'] = $dvdfrCover; + // DVDFr : affiche FR + métadonnées techniques (format, éditeur, durée, aspect) + $dvdfrData = fetchDVDFr($ean, $pdo); + if (!empty($dvdfrData)) { + if (!empty($dvdfrData['poster'])) $result['poster'] = $dvdfrData['poster']; + if (!empty($dvdfrData['publisher'])) $result['publisher'] = $dvdfrData['publisher']; + if (!empty($dvdfrData['format'])) $result['format'] = $dvdfrData['format']; + if (!empty($dvdfrData['length'])) $result['length'] = $dvdfrData['length']; + if (!empty($dvdfrData['aspect'])) $result['aspect_ratio'] = $dvdfrData['aspect']; + if (!empty($dvdfrData['discs'])) $result['number_of_discs'] = (int)$dvdfrData['discs']; } $tmdbKey = getTmdbApiKey($pdo); if ($tmdbKey && $tmdbQueryTitle) { @@ -454,9 +512,16 @@ switch ($action) { if (empty($publisher)) $publisher = $upcData['publisher']; if (empty($format) || $format === 'Blu-ray') $format = $upcData['format']; } - // 1.5 DVDFr - $dvdfrCover = fetchDVDFr($ean, $pdo); - if (!empty($dvdfrCover)) $poster = $dvdfrCover; + // 1.5 DVDFr : affiche FR + métadonnées (priorité sur UPCitemdb) + $dvdfrData = fetchDVDFr($ean, $pdo); + if (!empty($dvdfrData)) { + if (!empty($dvdfrData['poster'])) $poster = $dvdfrData['poster']; + if (!empty($dvdfrData['publisher'])) $publisher = $dvdfrData['publisher']; + if (!empty($dvdfrData['format']) && (empty($format) || $format === 'Blu-ray')) $format = $dvdfrData['format']; + if (!empty($dvdfrData['length']) && empty($length)) $length = $dvdfrData['length']; + if (!empty($dvdfrData['aspect']) && empty($aspect)) $aspect = $dvdfrData['aspect']; + if (!empty($dvdfrData['discs']) && $discs === 1) $discs = (int)$dvdfrData['discs']; + } } // 2. TMDB @@ -507,6 +572,7 @@ switch ($action) { } $pdo->beginTransaction(); + $pdo->beginTransaction(); try { foreach ($items as $rowData) { $title = $rowData['title'] ?? $rowData['Name'] ?? $rowData['Title'] ?? 'Sans titre'; @@ -554,8 +620,15 @@ switch ($action) { if (empty($publisher)) $publisher = $upcData['publisher']; if (empty($format) || $format === 'Blu-ray') $format = $upcData['format']; } - $dvdfrCover = fetchDVDFr($ean, $pdo); - if (!empty($dvdfrCover)) $poster = $dvdfrCover; + $dvdfrData = fetchDVDFr($ean, $pdo); + if (!empty($dvdfrData)) { + if (!empty($dvdfrData['poster'])) $poster = $dvdfrData['poster']; + if (!empty($dvdfrData['publisher'])) $publisher = $dvdfrData['publisher']; + if (!empty($dvdfrData['format']) && (empty($format) || $format === 'Blu-ray')) $format = $dvdfrData['format']; + if (!empty($dvdfrData['length']) && empty($length)) $length = $dvdfrData['length']; + if (!empty($dvdfrData['aspect']) && empty($aspect)) $aspect = $dvdfrData['aspect']; + if (!empty($dvdfrData['discs']) && $discs === 1) $discs = (int)$dvdfrData['discs']; + } } if ($tmdbApiKey && !empty($title)) { @@ -639,5 +712,6 @@ switch ($action) { // On renvoie l'erreur en JSON pour que le JavaScript puisse l'afficher proprement echo json_encode(["success" => false, "error" => "Erreur serveur : " . $e->getMessage()]); } + echo json_encode(["success" => true, "imported" => $imported]); break; } \ No newline at end of file