]*class="[^"]*productdetails[^"]*"[^>]*>.*?<\/div>/is', $productRes, $detailsBlock)) {
+ $detailsHtml = $detailsBlock[0];
+ } else {
+ $detailsHtml = $productRes;
+ }
+
+ // Détection du format
+ if (preg_match('/
Format<\/b>[:\s]*<\/td>\s*]*>([^<]+)/i', $productRes, $m)) {
+ $formatRaw = trim($m[1]);
+ if (stripos($formatRaw, '4K') !== false || stripos($formatRaw, 'UHD') !== false) {
+ $result['format'] = '4K Ultra HD';
+ } elseif (stripos($formatRaw, 'DVD') !== false) {
+ $result['format'] = 'DVD';
+ } elseif (stripos($formatRaw, 'Blu') !== false) {
+ $result['format'] = 'Blu-ray';
+ }
+ }
+
+ // Nombre de disques
+ if (preg_match('/(?:Discs?|Disques?)<\/b>[:\s]*<\/td>\s* | ]*>(\d+)/i', $productRes, $m)) {
+ $result['number_of_discs'] = (int)$m[1];
+ }
+
+ // Aspect ratio
+ if (preg_match('/Aspect\s*ratio<\/b>[:\s]*<\/td>\s* | ]*>([^<]+)/i', $productRes, $m)) {
+ $result['aspect_ratio'] = trim($m[1]);
+ }
+
+ // Durée (runtime)
+ if (preg_match('/(?:Runtime|Durée|Length)<\/b>[:\s]*<\/td>\s* | ]*>(\d+)/i', $productRes, $m)) {
+ $result['length'] = trim($m[1]) . ' min';
+ }
+
+ // Studio / Éditeur
+ if (preg_match('/(?:Studio|Label|Distributor)<\/b>[:\s]*<\/td>\s* | ]*>([^<]+)/i', $productRes, $m)) {
+ $result['publisher'] = trim($m[1]);
+ }
+
+ // Année de sortie
+ if (preg_match('/(?:Release\s*Date|Country\s*&\s*Date)<\/b>[:\s]*<\/td>\s* | ]*>[^<]*?(\d{4})/i', $productRes, $m)) {
+ $result['year'] = $m[1];
+ }
+
+ // Synopsis
+ if (preg_match('/ ]*class="[^"]*synopsis[^"]*"[^>]*>(.*?)<\/div>/is', $productRes, $m)) {
+ $result['description'] = trim(strip_tags($m[1]));
+ }
+
+ error_log("BluRay.com: Infos récupérées pour '{$title}' → " . json_encode($result));
+ return $result;
+}
+
+// ── FONCTION POUR RÉCUPÉRER LE SYNOPSIS DEPUIS TMDB ──
+function fetchTmdbSynopsis($title, $year = '', $pdo = null) {
+ $tmdbKey = getTmdbApiKey($pdo);
+ if (!$tmdbKey || empty($title)) return '';
+
+ $cleanTitle = cleanTitle($title);
+ $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query=" . urlencode($cleanTitle);
+ if (!empty($year)) $searchUrl .= "&year={$year}";
+ $searchUrl .= "&language=fr-FR";
+
+ $searchRes = httpGet($searchUrl, 5);
+ $searchData = $searchRes ? json_decode($searchRes, true) : [];
+
+ if (empty($searchData['results'])) {
+ // Retry sans l'année
+ $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query=" . urlencode($cleanTitle) . "&language=fr-FR";
+ $searchRes = httpGet($searchUrl, 5);
+ $searchData = $searchRes ? json_decode($searchRes, true) : [];
+ }
+
+ if (!empty($searchData['results'][0]['overview'])) {
+ return $searchData['results'][0]['overview'];
+ }
+
+ return '';
+}
+
+// ── FONCTION COMPLÈTE TMDB POUR POSTER + SYNOPSIS ──
+function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
+ $defaultPoster = 'assets/img/default_physical_media.jpg';
+ $tmdbKey = getTmdbApiKey($pdo);
+
+ $result = [
+ 'poster' => $defaultPoster,
+ 'description' => '',
+ 'director' => '',
+ 'actors' => '',
+ 'length' => '',
+ 'year' => $year
+ ];
+
+ if (!$tmdbKey || empty($title)) return $result;
+
+ $cleanTitle = cleanTitle($title);
+ $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query=" . urlencode($cleanTitle);
+ if (!empty($year)) $searchUrl .= "&year={$year}";
+ $searchUrl .= "&language=fr-FR";
+
+ $searchRes = httpGet($searchUrl, 5);
+ $searchData = $searchRes ? json_decode($searchRes, true) : [];
+
+ if (empty($searchData['results'])) {
+ $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query=" . urlencode($cleanTitle) . "&language=fr-FR";
+ $searchRes = httpGet($searchUrl, 5);
+ $searchData = $searchRes ? json_decode($searchRes, true) : [];
+ }
+
+ if (empty($searchData['results'])) return $result;
+
+ $movieId = $searchData['results'][0]['id'];
+ $result['poster'] = !empty($searchData['results'][0]['poster_path'])
+ ? "https://image.tmdb.org/t/p/w500" . $searchData['results'][0]['poster_path']
+ : $defaultPoster;
+ $result['description'] = $searchData['results'][0]['overview'] ?? '';
+
+ if (!empty($searchData['results'][0]['release_date'])) {
+ $result['year'] = substr($searchData['results'][0]['release_date'], 0, 4);
+ }
+
+ // Récupérer les détails pour réalisateur, acteurs, durée
+ $detailsUrl = "https://api.themoviedb.org/3/movie/{$movieId}?api_key={$tmdbKey}&append_to_response=credits&language=fr-FR";
+ $detailsRes = httpGet($detailsUrl, 5);
+ if ($detailsRes) {
+ $details = json_decode($detailsRes, true);
+
+ if (!empty($details['runtime'])) {
+ $result['length'] = $details['runtime'] . ' min';
+ }
+
+ // Réalisateur
+ if (!empty($details['credits']['crew'])) {
+ $directors = [];
+ foreach ($details['credits']['crew'] as $crew) {
+ if ($crew['job'] === 'Director') $directors[] = $crew['name'];
+ }
+ if (!empty($directors)) $result['director'] = implode(', ', $directors);
+ }
+
+ // Acteurs (top 4)
+ if (!empty($details['credits']['cast'])) {
+ $actors = [];
+ $topCast = array_slice($details['credits']['cast'], 0, 4);
+ foreach ($topCast as $actor) $actors[] = $actor['name'];
+ if (!empty($actors)) $result['actors'] = implode(', ', $actors);
+ }
+
+ // Synopsis complet si pas trouvé dans la recherche
+ if (empty($result['description']) && !empty($details['overview'])) {
+ $result['description'] = $details['overview'];
+ }
+ }
+
+ return $result;
+}
+
// ── ROUTEUR PRINCIPAL ──
$action = $_GET['action'] ?? '';
$data = json_decode(file_get_contents('php://input'), true) ?? [];
@@ -250,14 +476,47 @@ switch ($action) {
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=VALUES(director), poster=VALUES(poster), rating=VALUES(rating), review=VALUES(review), streaming=VALUES(streaming)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]);
- } else {
- // ✅ NOUVEAU : Utiliser TMDB
+} else {
+ // Récupérer les infos depuis BluRay.com et TMDB si poster vide
if (empty($data['poster']) && !empty($data['title'])) {
- $tmdbData = fetchPosterTMDB($data['title'], $data['year'] ?? '', $pdo);
- if (!empty($tmdbData['poster']) && $tmdbData['poster'] !== 'assets/img/default_physical_media.jpg') {
+ $bluRayData = fetchBluRayPhysicalInfo($data['ean_isbn13'] ?? '', $data['title'], $pdo);
+ $tmdbData = fetchTmdbPosterAndSynopsis($data['title'], $data['year'] ?? '', $pdo);
+
+ // Fusionner les données
+ if ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg') {
$data['poster'] = $tmdbData['poster'];
+ } elseif ($bluRayData['poster'] !== 'assets/img/default_physical_media.jpg') {
+ $data['poster'] = $bluRayData['poster'];
+ }
+
+ if (empty($data['description'])) {
+ $data['description'] = $tmdbData['description'] ?: $bluRayData['description'];
+ }
+ if (empty($data['director'])) {
+ $data['director'] = $tmdbData['director'];
+ }
+ if (empty($data['actors'])) {
+ $data['actors'] = $tmdbData['actors'];
+ }
+ if (empty($data['length'])) {
+ $data['length'] = $tmdbData['length'] ?: $bluRayData['length'];
+ }
+ if (empty($data['publisher'])) {
+ $data['publisher'] = $bluRayData['publisher'];
+ }
+ if (empty($data['number_of_discs']) || $data['number_of_discs'] == 1) {
+ if (!empty($bluRayData['number_of_discs'])) {
+ $data['number_of_discs'] = $bluRayData['number_of_discs'];
+ }
+ }
+ if (empty($data['aspect_ratio'])) {
+ $data['aspect_ratio'] = $bluRayData['aspect_ratio'];
+ }
+ if (empty($data['format'])) {
+ $data['format'] = $bluRayData['format'] ?: detectFormat($data['title'], $data['description'] ?? '');
}
}
+
$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'] ?? '']);
@@ -291,47 +550,94 @@ switch ($action) {
$imported = 0;
try {
- if ($type === 'videotheque') {
- $stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ON DUPLICATE KEY UPDATE
- ean_isbn13 = VALUES(ean_isbn13),
- poster = VALUES(poster),
- description = VALUES(description),
- format = VALUES(format),
- length = VALUES(length),
- number_of_discs = VALUES(number_of_discs),
- aspect_ratio = VALUES(aspect_ratio),
- actors = VALUES(actors),
- publisher = VALUES(publisher),
- director = VALUES(director)");
+ if ($type === 'videotheque') {
+ $stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ ON DUPLICATE KEY UPDATE
+ ean_isbn13 = VALUES(ean_isbn13),
+ poster = VALUES(poster),
+ description = VALUES(description),
+ format = VALUES(format),
+ length = VALUES(length),
+ number_of_discs = VALUES(number_of_discs),
+ aspect_ratio = VALUES(aspect_ratio),
+ actors = VALUES(actors),
+ publisher = VALUES(publisher),
+ director = VALUES(director),
+ year = VALUES(year)");
+
+ foreach ($items as $item) {
+ $title = $item['title'] ?? '';
+ if (empty($title)) continue;
- foreach ($items as $item) {
- $title = $item['title'] ?? '';
- if (empty($title)) continue;
-
- $year = $item['year'] ?? '';
- $ean = $item['ean'] ?? '';
- $desc = $item['description'] ?? '';
- $length = $item['length'] ?? '';
- $discs = $item['number_of_discs'] ?? 1;
- $aspect = $item['aspect_ratio'] ?? '';
- $actors = $item['actors'] ?? '';
- $publisher = $item['publisher'] ?? '';
- $director = $item['director'] ?? '';
-
- $id = makeStableId('videotheque', $title, $year);
-
- $tmdbData = fetchPosterTMDB($title, $year, $pdo);
- $poster = $tmdbData['poster'];
- $format = detectFormat($title, $desc);
-
- $stmtVideo->execute([
- $id, $title, $year, $format, $poster, $ean, $desc,
- $length, $discs, $aspect, $actors, $publisher, $director
- ]);
- $imported++;
- }
+ $year = $item['year'] ?? '';
+ $ean = $item['ean'] ?? '';
+ $descCsv = $item['description'] ?? '';
+ $lengthCsv = $item['length'] ?? '';
+ $discsCsv = $item['number_of_discs'] ?? 1;
+ $aspectCsv = $item['aspect_ratio'] ?? '';
+ $actorsCsv = $item['actors'] ?? '';
+ $publisherCsv = $item['publisher'] ?? '';
+ $directorCsv = $item['director'] ?? '';
+
+ $id = makeStableId('videotheque', $title, $year);
+
+ // ── SOURCE 1 : BLU-RAY.COM (infos physiques) ──
+ $bluRayData = fetchBluRayPhysicalInfo($ean, $title, $pdo);
+
+ // ── SOURCE 2 : TMDB (affiche + synopsis + métadonnées) ──
+ $tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
+
+ // ── FUSION DES DONNÉES (priorité : CSV > BluRay.com > TMDB) ──
+
+ // Affiche : TMDB en priorité (meilleure qualité)
+ $poster = ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg')
+ ? $tmdbData['poster']
+ : $bluRayData['poster'];
+
+ // Format : BluRay.com > détection depuis titre
+ $format = !empty($bluRayData['format'])
+ ? $bluRayData['format']
+ : detectFormat($title, $descCsv);
+
+ // Éditeur : CSV > BluRay.com
+ $publisher = !empty($publisherCsv) ? $publisherCsv : $bluRayData['publisher'];
+
+ // Nombre de disques : CSV > BluRay.com
+ $discs = !empty($discsCsv) && $discsCsv != 1
+ ? $discsCsv
+ : (!empty($bluRayData['number_of_discs']) ? $bluRayData['number_of_discs'] : ($discsCsv ?: 1));
+
+ // Aspect ratio : CSV > BluRay.com
+ $aspect = !empty($aspectCsv) ? $aspectCsv : $bluRayData['aspect_ratio'];
+
+ // Durée : CSV > BluRay.com > TMDB
+ $length = !empty($lengthCsv)
+ ? $lengthCsv
+ : (!empty($bluRayData['length']) ? $bluRayData['length'] : $tmdbData['length']);
+
+ // Description : CSV > TMDB > BluRay.com
+ $description = !empty($descCsv)
+ ? $descCsv
+ : (!empty($tmdbData['description']) ? $tmdbData['description'] : $bluRayData['description']);
+
+ // Réalisateur : CSV > TMDB
+ $director = !empty($directorCsv) ? $directorCsv : $tmdbData['director'];
+
+ // Acteurs : CSV > TMDB
+ $actors = !empty($actorsCsv) ? $actorsCsv : $tmdbData['actors'];
+
+ // Année : CSV > TMDB > BluRay.com
+ $finalYear = !empty($year) ? $year : (!empty($tmdbData['year']) ? $tmdbData['year'] : $bluRayData['year']);
+
+ error_log("Import vidéotheque '{$title}' : poster=" . ($poster !== 'assets/img/default_physical_media.jpg' ? 'OK' : 'DEFAULT') . ", format={$format}, discs={$discs}, aspect={$aspect}");
+
+ $stmtVideo->execute([
+ $id, $title, $finalYear, $format, $poster, $ean, $description,
+ $length, $discs, $aspect, $actors, $publisher, $director
+ ]);
+ $imported++;
+ }
} else {
$stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|