]*class=["\'][^"\']*fiche-technique[^"\']*["\'][^>]*>(.*?)<\/div>/is', $ficheHtml, $bloc)) {
- $techHtml = $bloc[1];
- } else {
- $techHtml = $ficheHtml;
- }
-
- // Éditeur / Distributeur
- if (preg_match('/(?:Éditeur|Editeur|Distributeur|Studio|Label)\s*<\/[^>]+>\s*<[^>]+>([^<]+)/i', $techHtml, $m)) {
- $result['publisher'] = trim(strip_tags($m[1]));
- } elseif (preg_match('/(?:Éditeur|Editeur|Distributeur|Studio|Label)\s*[:<\/][^>]*>\s*([^<\n]+)/i', $ficheHtml, $m)) {
- $result['publisher'] = trim(strip_tags($m[1]));
- }
-
- // Durée
- if (preg_match('/(?:Durée|Duree|Durata)\s*<\/[^>]+>\s*<[^>]+>(\d+)\s*(?:min|mn|h)/i', $techHtml, $m)) {
- $result['length'] = trim($m[1]) . ' min';
- } elseif (preg_match('/(?:Durée|Duree)\s*[:<\/][^>]*>\s*(\d+)\s*(?:min|mn|h)/i', $ficheHtml, $m)) {
- $result['length'] = trim($m[1]) . ' min';
- }
-
- // Nombre de disques
- if (preg_match('/(?:Nombre\s*de\s*disques?|Nb\s*disques?|Disques?)\s*<\/[^>]+>\s*<[^>]+>(\d+)/i', $techHtml, $m)) {
- $result['discs'] = trim($m[1]);
- } elseif (preg_match('/(?:Nombre\s*de\s*disques?|Nb\s*disques?)\s*[:<\/][^>]*>\s*(\d+)/i', $ficheHtml, $m)) {
- $result['discs'] = trim($m[1]);
- }
-
- // Format image / Aspect ratio
- if (preg_match('/(?:Format\s*(?:image|vidéo|video)|Ratio|Aspect\s*ratio)\s*<\/[^>]+>\s*<[^>]+>([0-9.]+\s*[:\.]\s*[0-9.]+)/i', $techHtml, $m)) {
- $result['aspect'] = trim($m[1]);
- }
-
- // Acteurs / Casting
- if (preg_match('/(?:Acteurs?|Casting|Avec)\s*<\/[^>]+>\s*<[^>]+>([^<]+)/i', $techHtml, $m)) {
- $result['actors'] = trim(strip_tags($m[1]));
- } elseif (preg_match('/(?:Avec|Acteurs?)\s*[:<\/][^>]*>\s*([^<\n]+)/i', $ficheHtml, $m)) {
- $result['actors'] = trim(strip_tags($m[1]));
- }
-
- // Description / Synopsis
- if (preg_match('/
]*class=["\'][^"\']*product-description[^"\']*["\'][^>]*>(.*?)<\/div>/is', $ficheHtml, $m)) {
- $result['description'] = trim(strip_tags($m[1]));
- } elseif (preg_match('/
]+property=["\']og:description["\'][^>]+content=["\']([^"\']+)["\']/i', $ficheHtml, $m)) {
- $result['description'] = trim($m[1]);
- }
-
- // Format (détection depuis le titre ou la fiche)
- $formatText = $result['title'] . ' ' . $ficheHtml;
- if (preg_match('/(4K\s*Ultra\s*HD|Ultra\s*HD|4K|Blu[\s-]?Ray|DVD|Coffret)/i', $formatText, $m)) {
- $fmt = strtoupper(trim($m[1]));
- if (strpos($fmt, '4K') !== false || strpos($fmt, 'ULTRA') !== false) $result['format'] = '4K Ultra HD';
- elseif (strpos($fmt, 'BLU') !== false) $result['format'] = 'Blu-ray';
- elseif (strpos($fmt, 'DVD') !== false) $result['format'] = 'DVD';
- elseif (strpos($fmt, 'COFFRET') !== false) $result['format'] = 'Coffret';
- }
-
- // Nettoyage final
- foreach ($result as $k => $v) {
- $result[$k] = trim(html_entity_decode($v, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
- }
-
- return (!empty($result['title']) || !empty($result['poster'])) ? $result : null;
+ return (!empty($result['poster'])) ? $result : null;
}
-// ── API TMDB (SANS CACHE - TITRE FRANÇAIS) ──
+// Fonction alternative pour recherche directe par URL si on connaît le format
+function fetchMovieCoversDirect($title, $format = 'bluray') {
+ if (empty($title)) return null;
+
+ $ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
+ $cleanTitle = strtolower(trim(preg_replace('/[^a-zA-Z0-9\s]/', '', $title)));
+ $cleanTitle = preg_replace('/\s+/', '-', $cleanTitle);
+
+ // Formats supportés par MovieCovers
+ $formatMap = [
+ '4k ultra hd' => '4k',
+ '4k' => '4k',
+ 'blu-ray' => 'bluray',
+ 'bluray' => 'bluray',
+ 'dvd' => 'dvd',
+ ];
+
+ $mcFormat = $formatMap[strtolower($format)] ?? 'bluray';
+
+ // URL directe vers la page du cover
+ $directUrl = "https://moviecovers.com/{$mcFormat}/{$cleanTitle}";
+ $html = httpGet($directUrl, 8, $ua);
+
+ if (!$html) {
+ // Fallback sur la recherche
+ return fetchMovieCovers($title, '', $format);
+ }
+
+ $result = [
+ 'poster' => '',
+ 'title' => '',
+ 'format' => $format,
+ ];
+
+ // Chercher l'image principale en haute qualité
+ if (preg_match('/
![]()
]+src=["\']([^"\']+\.jpg)["\'][^>]*class=["\'][^"\']*cover[^"\']*["\']/i', $html, $m)) {
+ $result['poster'] = $m[1];
+ } elseif (preg_match('/
]+property=["\']og:image["\'][^>]+content=["\']([^"\']+)["\']/i', $html, $m)) {
+ $result['poster'] = $m[1];
+ }
+
+ return (!empty($result['poster'])) ? $result : null;
+}
+
+// ── API TMDB (uniquement pour les critiques) ──
function fetchTMDBFull($title, $year, $apiKey, $pdo) {
if (empty($apiKey) || empty($title)) return null;
$cleanTitle = cleanTitle($title);
@@ -393,6 +358,7 @@ switch ($action) {
case 'search_ean_full':
$ean = $_GET['ean'] ?? '';
+ $type = $_GET['type'] ?? 'videotheque';
if (!$ean) { echo json_encode(['error' => 'EAN manquant']); exit; }
$result = [
'ean' => $ean, 'title' => '', 'director' => '', 'year' => '',
@@ -400,35 +366,56 @@ switch ($action) {
'length' => '', 'number_of_discs' => 1, 'aspect_ratio' => '', 'actors' => ''
];
- // Étape 1 : Scraping Fnac
- $fnacData = fetchFnac($ean);
- $titleForTmdb = '';
- if (!empty($fnacData)) {
- if (!empty($fnacData['title'])) $result['title'] = $fnacData['title'];
- if (!empty($fnacData['poster'])) $result['poster'] = $fnacData['poster'];
- if (!empty($fnacData['publisher'])) $result['publisher'] = $fnacData['publisher'];
- if (!empty($fnacData['format'])) $result['format'] = $fnacData['format'];
- if (!empty($fnacData['length'])) $result['length'] = $fnacData['length'];
- if (!empty($fnacData['aspect'])) $result['aspect_ratio'] = $fnacData['aspect'];
- if (!empty($fnacData['discs'])) $result['number_of_discs'] = (int)$fnacData['discs'];
- if (!empty($fnacData['actors'])) $result['actors'] = $fnacData['actors'];
-
- $titleForTmdb = cleanTitle($fnacData['title'] ?? '');
- }
-
- // Étape 2 : TMDB pour métadonnées film (réalisateur, vraie affiche, année)
+ // Pour MovieCovers, on a besoin d'un titre
+ // On essaie d'abord de trouver le titre via TMDB (pour les critiques) ou on utilise l'EAN comme base
$tmdbKey = getTmdbApiKey($pdo);
- if ($tmdbKey && !empty($titleForTmdb)) {
- $tmdbData = fetchTMDBFull($titleForTmdb, '', $tmdbKey, $pdo);
- if ($tmdbData) {
- if (!empty($tmdbData['title'])) $result['title'] = $tmdbData['title'];
- if (!empty($tmdbData['year'])) $result['year'] = $tmdbData['year'];
- if (!empty($tmdbData['director'])) $result['director'] = $tmdbData['director'];
- if (!empty($tmdbData['length'])) $result['length'] = $tmdbData['length'];
- if (!empty($tmdbData['cast'])) $result['actors'] = implode(', ', $tmdbData['cast']);
- if (!empty($tmdbData['poster'])) $result['poster'] = $tmdbData['poster']; // TMDB prioritaire
+ $titleForSearch = '';
+
+ if ($type === 'critique' && $tmdbKey) {
+ // Pour les critiques, on cherche d'abord sur TMDB
+ $searchUrl = "https://api.themoviedb.org/3/find/{$ean}?api_key={$tmdbKey}&external_source=imdb_id";
+ $searchRes = httpGet($searchUrl, 5);
+ $searchData = $searchRes ? json_decode($searchRes, true) : [];
+
+ if (!empty($searchData['movie_results'][0])) {
+ $titleForSearch = $searchData['movie_results'][0]['title'];
+ $result['title'] = $titleForSearch;
+ if (!empty($searchData['movie_results'][0]['release_date'])) {
+ $result['year'] = substr($searchData['movie_results'][0]['release_date'], 0, 4);
+ }
}
}
+
+ // Si pas de titre trouvé, on utilise l'EAN comme référence (peu probable de trouver sur MovieCovers)
+ if (empty($titleForSearch)) {
+ echo json_encode(['success' => true, 'data' => $result, 'warning' => 'Titre non trouvé pour cet EAN']);
+ exit;
+ }
+
+ // Récupération jaquette via MovieCovers (pour vidéothèque) ou TMDB (pour critiques)
+ if ($type === 'videotheque') {
+ $format = $result['format'] ?: 'Blu-ray';
+ $mcData = fetchMovieCovers($titleForSearch, $result['year'], $format);
+ if (!empty($mcData)) {
+ if (!empty($mcData['poster'])) $result['poster'] = $mcData['poster'];
+ if (!empty($mcData['title'])) $result['title'] = $mcData['title'];
+ $result['format'] = $format;
+ }
+ } else {
+ // Critiques : TMDB complet
+ if ($tmdbKey) {
+ $tmdbData = fetchTMDBFull($titleForSearch, $result['year'], $tmdbKey, $pdo);
+ if ($tmdbData) {
+ if (!empty($tmdbData['title'])) $result['title'] = $tmdbData['title'];
+ if (!empty($tmdbData['year'])) $result['year'] = $tmdbData['year'];
+ if (!empty($tmdbData['director'])) $result['director'] = $tmdbData['director'];
+ if (!empty($tmdbData['poster'])) $result['poster'] = $tmdbData['poster'];
+ if (!empty($tmdbData['length'])) $result['length'] = $tmdbData['length'];
+ if (!empty($tmdbData['cast'])) $result['actors'] = implode(', ', $tmdbData['cast']);
+ }
+ }
+ }
+
echo json_encode(['success' => true, 'data' => $result]);
break;
@@ -437,7 +424,8 @@ switch ($action) {
$type = $data['type'] ?? 'critique';
$id = !empty($data['id']) ? $data['id'] : makeStableId($type, $data['title'] ?? '', $data['year'] ?? '0000');
- if (empty($data['director']) || empty($data['poster'])) {
+ // TMDB uniquement pour les critiques
+ if ($type === 'critique' && (empty($data['director']) || empty($data['poster']))) {
$tmdbData = fetchTMDBFull($data['title'] ?? '', $data['year'] ?? '', getTmdbApiKey($pdo), $pdo);
if ($tmdbData) {
if (empty($data['director'])) $data['director'] = $tmdbData['director'];
@@ -453,6 +441,15 @@ switch ($action) {
$stmt = $pdo->prepare($sql);
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]);
} else {
+ // Vidéothèque : MovieCovers pour la jaquette
+ if (empty($data['poster']) && !empty($data['title'])) {
+ $format = $data['format'] ?: 'Blu-ray';
+ $mcData = fetchMovieCovers($data['title'], $data['year'] ?? '', $format);
+ if (!empty($mcData['poster'])) {
+ $data['poster'] = $mcData['poster'];
+ }
+ }
+
$sql = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description, actors) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=IF(VALUES(director)!='', VALUES(director), director), poster=IF(VALUES(poster)!='', VALUES(poster), poster), format=IF(VALUES(format)!='', VALUES(format), format), length=IF(VALUES(length)!='', VALUES(length), length), publisher=IF(VALUES(publisher)!='', VALUES(publisher), publisher), ean_isbn13=IF(VALUES(ean_isbn13)!='', VALUES(ean_isbn13), ean_isbn13), number_of_discs=IF(VALUES(number_of_discs)!=1, VALUES(number_of_discs), number_of_discs), aspect_ratio=IF(VALUES(aspect_ratio)!='', VALUES(aspect_ratio), aspect_ratio), description=IF(VALUES(description)!='', VALUES(description), description), actors=IF(VALUES(actors)!='', VALUES(actors), actors)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['format'] ?? '', $data['length'] ?? '', $data['publisher'] ?? '', $data['ean_isbn13'] ?? '', $data['number_of_discs'] ?? 1, $data['aspect_ratio'] ?? '', $data['description'] ?? '', $data['actors'] ?? '']);
@@ -494,6 +491,7 @@ switch ($action) {
$id = makeStableId($type, $title, $year);
if ($type === 'videotheque') {
+ // ── VIDÉOTHÈQUE : MovieCovers pour jaquette HD, PAS de TMDB ──
$csvActors = $rowData['ensemble'] ?? $rowData['creators'] ?? '';
$actors = '';
if (!empty($csvActors)) {
@@ -525,66 +523,21 @@ switch ($action) {
$poster = $rowData['poster'] ?? '';
$director = '';
- // Enrichissement via Fnac si on a un EAN
- if (!empty($ean)) {
- $fnacData = fetchFnac($ean);
- if (!empty($fnacData)) {
- if ((empty($title) || $title === 'Sans titre') && !empty($fnacData['title'])) {
- $title = cleanTitle($fnacData['title']);
+ // Récupération jaquette via MovieCovers
+ $cleanTitleForMC = cleanTitle($title);
+ if (!empty($cleanTitleForMC)) {
+ $mcData = fetchMovieCovers($cleanTitleForMC, $year, $format);
+ if (!empty($mcData)) {
+ if (!empty($mcData['poster'])) {
+ $poster = $mcData['poster'];
}
- if (empty($publisher) && !empty($fnacData['publisher'])) {
- $publisher = $fnacData['publisher'];
- }
- if (empty($format) && !empty($fnacData['format'])) {
- $format = $fnacData['format'];
- }
- if (empty($length) && !empty($fnacData['length'])) {
- $length = $fnacData['length'];
- }
- if (empty($aspect) && !empty($fnacData['aspect'])) {
- $aspect = $fnacData['aspect'];
- }
- if ($discs === 1 && !empty($fnacData['discs'])) {
- $discs = (int)$fnacData['discs'];
- }
- if (empty($actors) && !empty($fnacData['actors'])) {
- $actors = $fnacData['actors'];
- }
- if (empty($poster) && !empty($fnacData['poster'])) {
- $poster = $fnacData['poster'];
- }
- if (empty($description) && !empty($fnacData['description'])) {
- $description = $fnacData['description'];
+ if (!empty($mcData['title']) && ($title === 'Sans titre' || empty($title))) {
+ $title = $mcData['title'];
}
}
}
- // Enrichissement via TMDB
- if ($tmdbApiKey && !empty($title)) {
- $tmdbTitle = $title;
- $tmdbTitle = preg_replace('/\s*[\[\(].*?[\]\)]\s*/', '', $tmdbTitle);
- $tmdbTitle = preg_replace('/\s*-\s*(Édition|Edition|Collector|Simple|Spéciale|Digibook|Ultimate|Intégrale|Combo|SteelBook|Boîtier|Coffret).*$/i', '', $tmdbTitle);
- $tmdbTitle = preg_replace('/\s*(Blu-ray|Bluray|DVD|4K|Ultra HD|Combo|VHS|BDRip|\[.*\]).*$/i', '', $tmdbTitle);
- $tmdbTitle = preg_replace('/\s*(Coffret|Trilogie|Quadrilogie|Collection|Anthologie).*$/i', '', $tmdbTitle);
- $tmdbTitle = preg_split('/\s*(\/|\+|:)\s*/', $tmdbTitle)[0];
- $tmdbTitle = explode(' - ', $tmdbTitle)[0];
- $tmdbTitle = trim($tmdbTitle);
-
- $tmdbData = fetchTMDBFull($tmdbTitle, $year, $tmdbApiKey, $pdo);
- if (!$tmdbData && $tmdbTitle !== $title) {
- $tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo);
- }
-
- if ($tmdbData) {
- if (!empty($tmdbData['title'])) $title = $tmdbData['title'];
- if (empty($director)) $director = $tmdbData['director'] ?? '';
- if (empty($year) && !empty($tmdbData['year'])) $year = $tmdbData['year'];
- if (empty($length) && !empty($tmdbData['length'])) $length = $tmdbData['length'];
- if (!empty($tmdbData['overview'])) $description = $tmdbData['overview'];
- if (!empty($tmdbData['cast'])) $actors = implode(', ', $tmdbData['cast']);
- if (!empty($tmdbData['poster'])) $poster = $tmdbData['poster']; // TMDB prioritaire
- }
- }
+ // PAS D'APPEL TMDB POUR LA VIDÉOTHÈQUE
$sql = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description, actors)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -604,6 +557,7 @@ switch ($action) {
$stmt->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $description, $actors]);
} else {
+ // ── CRITIQUES : TMDB complet ──
$ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? '';
$rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null;
$review = $rowData['Review'] ?? $rowData['review'] ?? '';
@@ -648,12 +602,15 @@ switch ($action) {
}
break;
- case 'debug_fnac':
- $ean = $_GET['ean'] ?? '';
- if (!$ean) { echo json_encode(['error' => 'EAN manquant']); exit; }
+ case 'debug_moviecovers':
+ $title = $_GET['title'] ?? '';
+ $year = $_GET['year'] ?? '';
+ $format = $_GET['format'] ?? 'Blu-ray';
- $result = ['ean' => $ean];
- $data = fetchFnac($ean);
+ if (!$title) { echo json_encode(['error' => 'Titre manquant']); exit; }
+
+ $result = ['title' => $title, 'year' => $year, 'format' => $format];
+ $data = fetchMovieCovers($title, $year, $format);
$result['data'] = $data;
$result['status'] = $data ? 'OK' : 'AUCUN_RÉSULTAT';