Actualiser api.php
This commit is contained in:
@@ -97,10 +97,11 @@ function removeAccentsForUrl($str) {
|
|||||||
return $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) {
|
function cleanTitle($title) {
|
||||||
|
// 1. Supprime tout contenu entre parenthèses ou crochets
|
||||||
$clean = preg_replace('/\s*[\[\(].*?[\]\)]\s*/u', '', $title);
|
$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);
|
$clean = preg_replace('/(blu-ray|bluray|dvd|4k|ultra hd|combo|vhs|bdrip).*$/iu', '', $clean);
|
||||||
return trim(preg_replace('/\s{2,}/u', ' ', $clean));
|
return trim(preg_replace('/\s{2,}/u', ' ', $clean));
|
||||||
}
|
}
|
||||||
@@ -232,109 +233,6 @@ function fetchFromFnac($ean) {
|
|||||||
return $empty;
|
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) {
|
function findBestTmdbMovie($results) {
|
||||||
if (empty($results) || !is_array($results)) return null;
|
if (empty($results) || !is_array($results)) return null;
|
||||||
$bestWithPoster = null;
|
$bestWithPoster = null;
|
||||||
@@ -352,7 +250,7 @@ function findBestTmdbMovie($results) {
|
|||||||
return $bestWithPoster !== null ? $bestWithPoster : $results[0];
|
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) {
|
function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
|
||||||
$default = ['poster'=>'assets/img/default_physical_media.jpg','title'=>'','description'=>'','director'=>'','actors'=>'','length'=>'','year'=>''];
|
$default = ['poster'=>'assets/img/default_physical_media.jpg','title'=>'','description'=>'','director'=>'','actors'=>'','length'=>'','year'=>''];
|
||||||
if (empty($title)) return $default;
|
if (empty($title)) return $default;
|
||||||
@@ -361,46 +259,77 @@ function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
|
|||||||
if (!$tmdbKey) return $default;
|
if (!$tmdbKey) return $default;
|
||||||
|
|
||||||
$clean = cleanTitle($title);
|
$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
|
||||||
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$queryUrl}&language=fr-FR";
|
$queries = [$clean];
|
||||||
if (!empty($year)) {
|
foreach ([':', ' - ', ' — ', ' | '] as $sep) {
|
||||||
$searchUrl .= "&year={$year}";
|
if (strpos($clean, $sep) !== false) {
|
||||||
}
|
$parts = explode($sep, $clean);
|
||||||
|
if (!empty(trim($parts[0]))) {
|
||||||
$res = httpGet($searchUrl, 8);
|
$queries[] = trim($parts[0]);
|
||||||
$data = $res ? json_decode($res, true) : [];
|
|
||||||
$movie = !empty($data['results']) ? findBestTmdbMovie($data['results']) : null;
|
|
||||||
|
|
||||||
// 2. Fallback en français SANS l'année (si aucun poster valide trouvé)
|
|
||||||
if ((empty($movie) || empty($movie['poster_path'])) && !empty($year)) {
|
|
||||||
$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)) {
|
|
||||||
$movie = $candidate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$queries = array_unique($queries);
|
||||||
// 3. Fallback SANS restriction de langue (titre original/VO)
|
|
||||||
if (empty($movie) || empty($movie['poster_path'])) {
|
$movie = null;
|
||||||
$resGlobal = httpGet("https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$queryUrl}", 8);
|
|
||||||
$dataGlobal = $resGlobal ? json_decode($resGlobal, true) : [];
|
foreach ($queries as $q) {
|
||||||
if (!empty($dataGlobal['results'])) {
|
$queryUrl = urlencode($q);
|
||||||
$candidate = findBestTmdbMovie($dataGlobal['results']);
|
|
||||||
if (!empty($candidate['poster_path']) || empty($movie)) {
|
// 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}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = httpGet($searchUrl, 8);
|
||||||
|
$data = $res ? json_decode($res, true) : [];
|
||||||
|
if (!empty($data['results'])) {
|
||||||
|
$candidate = findBestTmdbMovie($data['results']);
|
||||||
|
if (!empty($candidate['poster_path'])) {
|
||||||
$movie = $candidate;
|
$movie = $candidate;
|
||||||
|
break;
|
||||||
|
} elseif (empty($movie)) {
|
||||||
|
$movie = $candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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'])) {
|
||||||
|
$movie = $candidate;
|
||||||
|
break;
|
||||||
|
} elseif (empty($movie)) {
|
||||||
|
$movie = $candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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'])) {
|
||||||
|
$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'])) {
|
if (empty($movie) || empty($movie['poster_path'])) {
|
||||||
$noAccentUrl = urlencode(removeAccentsForUrl($clean));
|
$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);
|
$resNoAccent = httpGet("https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query={$noAccentUrl}", 8);
|
||||||
$dataNoAccent = $resNoAccent ? json_decode($resNoAccent, true) : [];
|
$dataNoAccent = $resNoAccent ? json_decode($resNoAccent, true) : [];
|
||||||
if (!empty($dataNoAccent['results'])) {
|
if (!empty($dataNoAccent['results'])) {
|
||||||
@@ -718,7 +647,7 @@ switch ($action) {
|
|||||||
$poster = 'assets/img/default_physical_media.jpg';
|
$poster = 'assets/img/default_physical_media.jpg';
|
||||||
$streaming = 'Support physique / Cinéma';
|
$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);
|
$tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
|
||||||
if ($tmdbData) {
|
if ($tmdbData) {
|
||||||
if (!empty($tmdbData['director'])) $director = $tmdbData['director'];
|
if (!empty($tmdbData['director'])) $director = $tmdbData['director'];
|
||||||
|
|||||||
Reference in New Issue
Block a user