Actualiser api.php

This commit is contained in:
2026-06-27 11:25:38 +02:00
parent fe4414c302
commit 84303fea95
+70 -228
View File
@@ -154,132 +154,6 @@ function fetchPosterTMDB($title, $year = '', $pdo = null) {
return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => 'Blu-ray']; return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
} }
// ── FONCTION POUR RÉCUPÉRER LES INFOS PHYSIQUES DEPUIS BLU-RAY.COM ──
function fetchBluRayPhysicalInfo($ean, $title = '', $pdo = null) {
$defaultPoster = 'assets/img/default_physical_media.jpg';
$result = [
'poster' => $defaultPoster,
'format' => '',
'publisher' => '',
'length' => '',
'number_of_discs'=> '',
'aspect_ratio' => '',
'description' => '',
'year' => '',
'director' => '',
'actors' => ''
];
// Nettoyer l'EAN/UPC
$cleanEan = preg_replace('/[^0-9]/', '', $ean);
if (empty($cleanEan) && empty($title)) return $result;
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
$productUrl = null;
// ── ÉTAPE 1 : Recherche par EAN/UPC ──
if (!empty($cleanEan)) {
$searchUrl = "https://www.blu-ray.com/search/?quicksearch=1&searchtype=products&q=" . urlencode($cleanEan);
$searchRes = httpGet($searchUrl, 10, $userAgent);
if ($searchRes && preg_match('/<a\s+href="\/products\/\?id=(\d+)"[^>]*>/i', $searchRes, $matches)) {
$productUrl = "https://www.blu-ray.com/products/?id=" . $matches[1];
}
}
// ── ÉTAPE 2 : Fallback par titre ──
if (!$productUrl && !empty($title)) {
$cleanTitle = cleanTitle($title);
$searchUrl = "https://www.blu-ray.com/search/?quicksearch=1&searchtype=movies&q=" . urlencode($cleanTitle);
$searchRes = httpGet($searchUrl, 10, $userAgent);
if ($searchRes && preg_match('/<a\s+href="\/movies\/\?id=(\d+)"[^>]*>/i', $searchRes, $matches)) {
$productUrl = "https://www.blu-ray.com/movies/?id=" . $matches[1];
}
}
if (!$productUrl) {
error_log("BluRay.com: Film non trouvé pour EAN '{$ean}' / titre '{$title}'");
return $result;
}
error_log("BluRay.com: Accès à {$productUrl}");
$productRes = httpGet($productUrl, 10, $userAgent);
if (!$productRes) {
error_log("BluRay.com: Page inaccessible {$productUrl}");
return $result;
}
// ── ÉTAPE 3 : Extraire l'affiche ──
if (preg_match('/<img[^>]*id="home_release_img"[^>]*src="([^"]+)"/i', $productRes, $imgMatches)) {
$posterUrl = $imgMatches[1];
$posterUrl = str_replace('/resized/', '/', $posterUrl);
$posterUrl = str_replace('http://', 'https://', $posterUrl);
$result['poster'] = $posterUrl;
}
// ── ÉTAPE 4 : Extraire les informations techniques ──
// ── ÉTAPE 4 : Extraire les informations techniques ──
if (preg_match('/<div[^>]*class="[^"]*productdetails[^"]*"[^>]*>.*?<\/div>/is', $productRes, $detailsBlock)) {
$detailsHtml = $detailsBlock[0];
} else {
$detailsHtml = $productRes;
}
// Détection du format
if (preg_match('/<b>Format<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
$formatRaw = trim(strip_tags($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('/<b>(?:Discs?|Disques?)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
if (preg_match('/(\d+)/', $m[1], $num)) {
$result['number_of_discs'] = (int)$num[1];
}
}
// Aspect ratio
if (preg_match('/<b>Aspect\s*ratio<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
$result['aspect_ratio'] = trim(strip_tags($m[1]));
}
// Durée (runtime)
if (preg_match('/<b>(?:Runtime|Durée|Length)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
if (preg_match('/(\d+)/', $m[1], $num)) {
$result['length'] = $num[1] . ' min';
}
}
// Studio / Éditeur (Corrigé, ne crashe plus sur la balise <a>)
if (preg_match('/<b>(?:Studio|Label|Distributor)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
$result['publisher'] = trim(strip_tags($m[1]));
}
// Année de sortie
if (preg_match('/<b>(?:Release\s*Date|Country\s*&\s*Date)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
if (preg_match('/(\d{4})/', $m[1], $num)) {
$result['year'] = $num[1];
}
}
// Synopsis
if (preg_match('/<div[^>]*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 ── // ── FONCTION POUR RÉCUPÉRER LE SYNOPSIS DEPUIS TMDB ──
function fetchTmdbSynopsis($title, $year = '', $pdo = null) { function fetchTmdbSynopsis($title, $year = '', $pdo = null) {
$tmdbKey = getTmdbApiKey($pdo); $tmdbKey = getTmdbApiKey($pdo);
@@ -545,7 +419,7 @@ switch ($action) {
else { http_response_code(400); echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]); } else { http_response_code(400); echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]); }
break; break;
case 'import_batch': case 'import_batch':
checkAuth($pdo); checkAuth($pdo);
$data = json_decode(file_get_contents("php://input"), true); $data = json_decode(file_get_contents("php://input"), true);
$type = $data['type'] ?? 'critique'; $type = $data['type'] ?? 'critique';
@@ -555,110 +429,77 @@ switch ($action) {
$imported = 0; $imported = 0;
try { try {
if ($type === 'videotheque') { // ── On récupère la clé d'API une seule fois pour tout le monde ──
$stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director) $tmdbApiKey = getTmdbApiKey($pdo);
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE if ($type === 'videotheque') {
ean_isbn13 = VALUES(ean_isbn13), $stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director)
poster = VALUES(poster), VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
description = VALUES(description), ON DUPLICATE KEY UPDATE
format = VALUES(format), ean_isbn13 = VALUES(ean_isbn13),
length = VALUES(length), poster = VALUES(poster),
number_of_discs = VALUES(number_of_discs), description = VALUES(description),
aspect_ratio = VALUES(aspect_ratio), format = VALUES(format),
actors = VALUES(actors), length = VALUES(length),
publisher = VALUES(publisher), number_of_discs = VALUES(number_of_discs),
director = VALUES(director), aspect_ratio = VALUES(aspect_ratio),
year = VALUES(year)"); actors = VALUES(actors),
publisher = VALUES(publisher),
director = VALUES(director),
year = VALUES(year)");
foreach ($items as $item) { foreach ($items as $item) {
$title = $item['title'] ?? ''; $title = $item['title'] ?? '';
if (empty($title)) continue; if (empty($title)) continue;
$year = $item['year'] ?? '';
$id = makeStableId('videotheque', $title, $year);
// ── 1. RECUPERATION DE TOUTES LES INFOS PHYSIQUES DEPUIS LE CSV ──
$ean = $item['ean'] ?? '';
$format = $item['format'] ?? 'Inconnu';
$publisher = $item['publisher'] ?? '';
$discs = $item['number_of_discs'] ?? 1;
$aspect = $item['aspect_ratio'] ?? '';
$length = $item['length'] ?? '';
// Champs cinématographiques de base (du CSV s'ils existent)
$desc = $item['description'] ?? '';
$director = $item['director'] ?? '';
$actors = $item['actors'] ?? '';
$poster = 'assets/img/default_physical_media.jpg'; // Image par défaut
// ── 2. APPEL API (TMDB ou OMDb) POUR COMBLER LES MANQUES ──
if ($tmdbApiKey && !empty($title)) {
$apiData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo);
if ($apiData) {
if (empty($director)) $director = $apiData['director'] ?? '';
if (empty($actors)) $actors = $apiData['actors'] ?? '';
if (empty($desc)) $desc = $apiData['synopsis'] ?? '';
if (empty($length) && !empty($apiData['length'])) $length = $apiData['length'];
if (!empty($apiData['poster'])) {
$poster = $apiData['poster'];
}
}
}
error_log("Import vidéotheque '{$title}' : poster=" . ($poster !== 'assets/img/default_physical_media.jpg' ? 'OK' : 'DEFAULT') . ", format={$format}, discs={$discs}, aspect={$aspect}");
// Exécution remise À L'INTÉRIEUR de la boucle, avec les bonnes variables ($year, $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'] ?? '';
$formatCsv = $item['format'] ?? ''; // 👈 LIGNE À AJOUTER
$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 ──
$poster = ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg')
? $tmdbData['poster']
: $bluRayData['poster'];
// Priorité au CSV, puis BluRay.com, puis détection du titre
$format = !empty($formatCsv)
? $formatCsv
: (!empty($bluRayData['format']) ? $bluRayData['format'] : detectFormat($title, $descCsv));
// 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 { } else {
$stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming) $stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=VALUES(director), 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)"); poster=VALUES(poster), rating=VALUES(rating), review=VALUES(review), streaming=VALUES(streaming)");
$tmdbApiKey = getTmdbApiKey($pdo);
foreach ($items as $rowData) { foreach ($items as $rowData) {
$title = $rowData['Title'] ?? $rowData['title'] ?? ''; $title = $rowData['Title'] ?? $rowData['title'] ?? '';
@@ -675,10 +516,10 @@ switch ($action) {
if ($tmdbApiKey && !empty($title)) { if ($tmdbApiKey && !empty($title)) {
$tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo); $tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo);
if ($tmdbData) { if ($tmdbData) {
$director = $tmdbData['director']; $director = $tmdbData['director'] ?? '';
$poster = $tmdbData['poster']; $poster = $tmdbData['poster'] ?? '';
$streaming = $tmdbData['streaming']; $streaming = $tmdbData['streaming'] ?? '';
if (empty($year)) $year = $tmdbData['year']; if (empty($year)) $year = $tmdbData['year'] ?? '';
if (!empty($tmdbData['title'])) $title = $tmdbData['title']; if (!empty($tmdbData['title'])) $title = $tmdbData['title'];
} }
} }
@@ -688,6 +529,7 @@ switch ($action) {
$imported++; $imported++;
} }
} }
$pdo->commit(); $pdo->commit();
echo json_encode(["success" => true, "imported" => $imported]); echo json_encode(["success" => true, "imported" => $imported]);
} catch (Exception $e) { } catch (Exception $e) {