Actualiser api.php
This commit is contained in:
@@ -97,10 +97,11 @@ function removeAccentsForUrl($str) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
// CORRECTION : Ajout du modificateur /u pour une gestion parfaite de l'UTF-8 et des accents
|
||||
// CORRECTION : Nettoyage générique universel (UTF-8, parenthèses, formats et suffixes descriptifs)
|
||||
function cleanTitle($title) {
|
||||
// 1. Supprime tout contenu entre parenthèses ou crochets
|
||||
$clean = preg_replace('/\s*[\[\(].*?[\]\)]\s*/u', '', $title);
|
||||
$clean = preg_replace('/\s*-\s*(édition|Edition|Collector|Simple|Spéciale|Digibook|Ultimate|Intégrale|Combo|SteelBook|Boîtier).*$/iu', '', $clean);
|
||||
// 2. Supprime les éditions physiques et formats courants en fin de chaîne
|
||||
$clean = preg_replace('/(blu-ray|bluray|dvd|4k|ultra hd|combo|vhs|bdrip).*$/iu', '', $clean);
|
||||
return trim(preg_replace('/\s{2,}/u', ' ', $clean));
|
||||
}
|
||||
@@ -232,109 +233,6 @@ function fetchFromFnac($ean) {
|
||||
return $empty;
|
||||
}
|
||||
|
||||
function fetchFromBlurayComByTitle($title) {
|
||||
static $lastRequest = 0;
|
||||
$empty = emptyPhysicalResult();
|
||||
if (empty($title)) return $empty;
|
||||
$now = microtime(true);
|
||||
if ($lastRequest > 0 && ($now - $lastRequest) < 3) usleep((int)((3 - ($now - $lastRequest)) * 1000000));
|
||||
$lastRequest = microtime(true);
|
||||
$cleanTitle = cleanTitle($title);
|
||||
$searchUrl = "https://www.blu-ray.com/movies/search.php?keyword=" . urlencode($cleanTitle) . "&action=search";
|
||||
$ch = curl_init($searchUrl);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
|
||||
CURLOPT_HTTPHEADER => ['Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language: fr-FR,fr;q=0.9', 'Referer: https://www.blu-ray.com/']
|
||||
]);
|
||||
$searchHtml = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if (!$searchHtml || $httpCode !== 200 || !preg_match('/href="(https:\/\/www\.blu-ray\.com\/movies\/[^"]+\/(\d+)\/)"/i', $searchHtml, $matches)) return $empty;
|
||||
$movieUrl = $matches[1];
|
||||
sleep(2);
|
||||
$ch2 = curl_init($movieUrl);
|
||||
curl_setopt_array($ch2, [
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
||||
CURLOPT_HTTPHEADER => ['Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Referer: https://www.blu-ray.com/']
|
||||
]);
|
||||
$movieHtml = curl_exec($ch2);
|
||||
curl_close($ch2);
|
||||
if (!$movieHtml) return $empty;
|
||||
if (preg_match('/<h3[^>]*>([^<]+)<\/h3>\s*(?: )?\((\d{4})\)/i', $movieHtml, $m)) $empty['year'] = $m[2];
|
||||
if (preg_match('/href="[^"]*studioid=\d+[^"]*"[^>]*>([^<]+)<\/a>/i', $movieHtml, $m)) $empty['publisher'] = trim($m[1]);
|
||||
if (preg_match('/(\d+)\s*min<\/span>/i', $movieHtml, $m)) $empty['length'] = $m[1] . ' min';
|
||||
if (preg_match('/Aspect[\s-]*ratio:\s*([\d\.]+:[\d\.]+)/i', $movieHtml, $m)) $empty['aspect_ratio'] = trim($m[1]);
|
||||
if (preg_match('/(\w+)-disc\s+set/i', $movieHtml, $m)) {
|
||||
$wordToNum = ['single' => 1, 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5, 'six' => 6];
|
||||
$empty['number_of_discs'] = $wordToNum[strtolower($m[1])] ?? 1;
|
||||
} elseif (preg_match('/(\d+)-disc\s+set/i', $movieHtml, $m)) {
|
||||
$empty['number_of_discs'] = (int)$m[1];
|
||||
}
|
||||
if (strpos($movieUrl, '/4k/') !== false || stripos($movieHtml, '4K Ultra HD') !== false) $empty['format'] = '4K Ultra HD';
|
||||
elseif (strpos($movieUrl, '/3d/') !== false) $empty['format'] = '3D Blu-ray';
|
||||
else $empty['format'] = 'Blu-ray';
|
||||
if (preg_match('/src="(https:\/\/images\.static-bluray\.com\/movies\/covers\/\d+_front\.jpg[^"]*)"/i', $movieHtml, $m)) $empty['poster'] = $m[1];
|
||||
elseif (preg_match('/<img[^>]*class="coverfront"[^>]*src="([^"]+)"/i', $movieHtml, $m)) $empty['poster'] = preg_replace('/_large\.jpg/', '_front.jpg', $m[1]);
|
||||
return $empty;
|
||||
}
|
||||
|
||||
function fetchFromBlurayComByEan($ean) {
|
||||
static $lastRequest = 0;
|
||||
$empty = emptyPhysicalResult();
|
||||
$ean = preg_replace('/[^0-9]/', '', (string)$ean);
|
||||
if (strlen($ean) < 8) return $empty;
|
||||
$now = microtime(true);
|
||||
if ($lastRequest > 0 && ($now - $lastRequest) < 3) usleep((int)((3 - ($now - $lastRequest)) * 1000000));
|
||||
$lastRequest = microtime(true);
|
||||
$searchUrl = "https://www.blu-ray.com/movies/search.php?ean=" . urlencode($ean) . "&action=search";
|
||||
$ch = curl_init($searchUrl);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
|
||||
CURLOPT_HTTPHEADER => ['Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language: fr-FR,fr;q=0.9', 'Referer: https://www.blu-ray.com/']
|
||||
]);
|
||||
$searchHtml = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if (!$searchHtml || $httpCode !== 200 || !preg_match('/href="(https:\/\/www\.blu-ray\.com\/movies\/[^"]+\/(\d+)\/)"/i', $searchHtml, $matches)) return $empty;
|
||||
$movieUrl = $matches[1];
|
||||
sleep(2);
|
||||
$ch2 = curl_init($movieUrl);
|
||||
curl_setopt_array($ch2, [
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
||||
CURLOPT_HTTPHEADER => ['Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Referer: https://www.blu-ray.com/']
|
||||
]);
|
||||
$movieHtml = curl_exec($ch2);
|
||||
curl_close($ch2);
|
||||
if (!$movieHtml) return $empty;
|
||||
if (preg_match('/<div[^>]*id="movie_info"[^>]*>.*?<h3>([^<]+)<\/h3>/is', $movieHtml, $m)) $empty['title'] = trim($m[1]);
|
||||
elseif (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $movieHtml, $m)) $empty['title'] = trim(preg_replace('/\s*(Blu-ray|4K|3D|DVD|UHD).*$/i', '', trim(strip_tags($m[1]))));
|
||||
if (preg_match('/<h3[^>]*>([^<]+)<\/h3>\s*(?: )?\((\d{4})\)/i', $movieHtml, $m)) $empty['year'] = $m[2];
|
||||
if (preg_match('/href="[^"]*studioid=\d+[^"]*"[^>]*>([^<]+)<\/a>/i', $movieHtml, $m)) $empty['publisher'] = trim($m[1]);
|
||||
if (preg_match('/(\d+)\s*min<\/span>/i', $movieHtml, $m)) $empty['length'] = $m[1] . ' min';
|
||||
if (preg_match('/Aspect[\s-]*ratio:\s*([\d\.]+:[\d\.]+)/i', $movieHtml, $m)) $empty['aspect_ratio'] = trim($m[1]);
|
||||
if (preg_match('/(\w+)-disc\s+set/i', $movieHtml, $m)) {
|
||||
$wordToNum = ['single' => 1, 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5, 'six' => 6];
|
||||
$empty['number_of_discs'] = $wordToNum[strtolower($m[1])] ?? 1;
|
||||
} elseif (preg_match('/(\d+)-disc\s+set/i', $movieHtml, $m)) {
|
||||
$empty['number_of_discs'] = (int)$m[1];
|
||||
}
|
||||
if (strpos($movieUrl, '/4k/') !== false || stripos($movieHtml, '4K Ultra HD') !== false) $empty['format'] = '4K Ultra HD';
|
||||
elseif (strpos($movieUrl, '/3d/') !== false) $empty['format'] = '3D Blu-ray';
|
||||
else $empty['format'] = 'Blu-ray';
|
||||
if (preg_match('/src="(https:\/\/images\.static-bluray\.com\/movies\/covers\/\d+_front\.jpg[^"]*)"/i', $movieHtml, $m)) $empty['poster'] = $m[1];
|
||||
elseif (preg_match('/<img[^>]*class="coverfront"[^>]*src="([^"]+)"/i', $movieHtml, $m)) $empty['poster'] = preg_replace('/_large\.jpg/', '_front.jpg', $m[1]);
|
||||
return $empty;
|
||||
}
|
||||
|
||||
// CORRECTION : Fonction helper pour trouver le film le plus populaire disposant d'un poster valide
|
||||
function findBestTmdbMovie($results) {
|
||||
if (empty($results) || !is_array($results)) return null;
|
||||
$bestWithPoster = null;
|
||||
@@ -352,7 +250,7 @@ function findBestTmdbMovie($results) {
|
||||
return $bestWithPoster !== null ? $bestWithPoster : $results[0];
|
||||
}
|
||||
|
||||
// CORRECTION MAJEURE : Recherche TMDB intelligente en 4 étapes pour garantir une affiche
|
||||
// CORRECTION : Recherche TMDB avec découpage générique des sous-titres (séparateurs universels :, -, —, |)
|
||||
function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
|
||||
$default = ['poster'=>'assets/img/default_physical_media.jpg','title'=>'','description'=>'','director'=>'','actors'=>'','length'=>'','year'=>''];
|
||||
if (empty($title)) return $default;
|
||||
@@ -361,9 +259,25 @@ function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
|
||||
if (!$tmdbKey) return $default;
|
||||
|
||||
$clean = cleanTitle($title);
|
||||
$queryUrl = urlencode($clean);
|
||||
|
||||
// 1. Recherche principale en français avec l'année
|
||||
// Génération automatique des variantes de requêtes de manière générique
|
||||
$queries = [$clean];
|
||||
foreach ([':', ' - ', ' — ', ' | '] as $sep) {
|
||||
if (strpos($clean, $sep) !== false) {
|
||||
$parts = explode($sep, $clean);
|
||||
if (!empty(trim($parts[0]))) {
|
||||
$queries[] = trim($parts[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$queries = array_unique($queries);
|
||||
|
||||
$movie = null;
|
||||
|
||||
foreach ($queries as $q) {
|
||||
$queryUrl = urlencode($q);
|
||||
|
||||
// 1. Recherche en français avec l'année
|
||||
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$queryUrl}&language=fr-FR";
|
||||
if (!empty($year)) {
|
||||
$searchUrl .= "&year={$year}";
|
||||
@@ -371,36 +285,51 @@ function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
|
||||
|
||||
$res = httpGet($searchUrl, 8);
|
||||
$data = $res ? json_decode($res, true) : [];
|
||||
$movie = !empty($data['results']) ? findBestTmdbMovie($data['results']) : null;
|
||||
if (!empty($data['results'])) {
|
||||
$candidate = findBestTmdbMovie($data['results']);
|
||||
if (!empty($candidate['poster_path'])) {
|
||||
$movie = $candidate;
|
||||
break;
|
||||
} elseif (empty($movie)) {
|
||||
$movie = $candidate;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Fallback en français SANS l'année (si aucun poster valide trouvé)
|
||||
if ((empty($movie) || empty($movie['poster_path'])) && !empty($year)) {
|
||||
// 2. Recherche en français sans l'année
|
||||
if (empty($movie) || empty($movie['poster_path'])) {
|
||||
$resFallback = httpGet("https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$queryUrl}&language=fr-FR", 8);
|
||||
$dataFallback = $resFallback ? json_decode($resFallback, true) : [];
|
||||
if (!empty($dataFallback['results'])) {
|
||||
$candidate = findBestTmdbMovie($dataFallback['results']);
|
||||
if (!empty($candidate['poster_path']) || empty($movie)) {
|
||||
if (!empty($candidate['poster_path'])) {
|
||||
$movie = $candidate;
|
||||
break;
|
||||
} elseif (empty($movie)) {
|
||||
$movie = $candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback SANS restriction de langue (titre original/VO)
|
||||
// 3. Recherche globale (VO) sans filtre de langue
|
||||
if (empty($movie) || empty($movie['poster_path'])) {
|
||||
$resGlobal = httpGet("https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$queryUrl}", 8);
|
||||
$dataGlobal = $resGlobal ? json_decode($resGlobal, true) : [];
|
||||
if (!empty($dataGlobal['results'])) {
|
||||
$candidate = findBestTmdbMovie($dataGlobal['results']);
|
||||
if (!empty($candidate['poster_path']) || empty($movie)) {
|
||||
if (!empty($candidate['poster_path'])) {
|
||||
$movie = $candidate;
|
||||
break;
|
||||
} elseif (empty($movie)) {
|
||||
$movie = $candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Fallback SANS accents si le titre accentué n'a rien donné
|
||||
// 4. Dernier recours : sans accents
|
||||
if (empty($movie) || empty($movie['poster_path'])) {
|
||||
$noAccentUrl = urlencode(removeAccentsForUrl($clean));
|
||||
if ($noAccentUrl !== $queryUrl && !empty($noAccentUrl)) {
|
||||
if (!empty($noAccentUrl)) {
|
||||
$resNoAccent = httpGet("https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$noAccentUrl}", 8);
|
||||
$dataNoAccent = $resNoAccent ? json_decode($resNoAccent, true) : [];
|
||||
if (!empty($dataNoAccent['results'])) {
|
||||
@@ -718,7 +647,7 @@ switch ($action) {
|
||||
$poster = 'assets/img/default_physical_media.jpg';
|
||||
$streaming = 'Support physique / Cinéma';
|
||||
|
||||
// Appel TMDB intelligent
|
||||
// Appel TMDB intelligent avec découpage générique des sous-titres
|
||||
$tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
|
||||
if ($tmdbData) {
|
||||
if (!empty($tmdbData['director'])) $director = $tmdbData['director'];
|
||||
|
||||
Reference in New Issue
Block a user