Actualiser api.php

This commit is contained in:
2026-06-26 14:00:03 +02:00
parent 60e0903c4f
commit 61352a6aa2
+128 -317
View File
@@ -16,15 +16,12 @@ try {
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
$pdo->exec("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, username VARCHAR(50) NOT NULL, password_hash VARCHAR(255) NOT NULL)");
$pdo->exec("CREATE TABLE IF NOT EXISTS config (key_name VARCHAR(50) PRIMARY KEY, key_value TEXT NOT NULL)");
$pdo->exec("CREATE TABLE IF NOT EXISTS critiques (id BIGINT PRIMARY KEY, title VARCHAR(255) NOT NULL, year VARCHAR(10), director VARCHAR(255), poster TEXT, rating DECIMAL(3,1) DEFAULT 3.0, review TEXT, streaming VARCHAR(255))");
try { $pdo->exec("ALTER TABLE critiques MODIFY COLUMN rating DECIMAL(3,1) DEFAULT 3.0"); } catch (\Exception $e) {}
$pdo->exec("CREATE TABLE IF NOT EXISTS videotheque (id BIGINT PRIMARY KEY, title VARCHAR(255) NOT NULL, year VARCHAR(10), director VARCHAR(255), poster TEXT, format VARCHAR(50), length VARCHAR(50), publisher VARCHAR(255), ean_isbn13 VARCHAR(50), number_of_discs INT DEFAULT 1, aspect_ratio VARCHAR(50), description TEXT, actors TEXT)");
try { $pdo->exec("ALTER TABLE videotheque ADD COLUMN actors TEXT AFTER description"); } catch (\Exception $e) {}
} catch (\PDOException $e) { echo json_encode(["error" => "Erreur BDD : " . $e->getMessage()]); exit; }
// ── FONCTIONS UTILITAIRES ──
@@ -50,7 +47,7 @@ function encryptData($data) {
function decryptData($str) {
$decoded = base64_decode($str);
if (strpos($decoded, '::') === false) return null;
if ($decoded === false || strpos($decoded, '::') === false) return null;
list($enc, $iv) = explode('::', $decoded, 2);
return openssl_decrypt($enc, 'AES-256-CBC', hash('sha256', ENCRYPTION_KEY, true), OPENSSL_RAW_DATA, substr($iv, 0, 16));
}
@@ -69,9 +66,36 @@ function getFanartApiKey($pdo) {
return $row ? decryptData($row['key_value']) : null;
}
function httpGet($url, $timeout = 10, $ua = null) {
function httpGet($url, $timeout = 5, $ua = null) {
if (!$ua) $ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36';
if (!function_exists('curl_init')) {
$ctx = stream_context_create(['http' => ['timeout' => $timeout, 'user_agent' => $ua]]);
$res = @file_get_contents($url, false, $ctx);
return $res ?: null;
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $ua,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_REFERER => 'https://www.cinemapassion.com/',
CURLOPT_HTTPHEADER => [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.8',
],
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ($code === 200 && is_string($res) && strlen($res) > 0) ? $res : null;
}
function httpPost($url, $postData, $timeout = 10) {
$ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36';
if (!function_exists('curl_init')) return null;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
@@ -80,20 +104,20 @@ function httpGet($url, $timeout = 10, $ua = null) {
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $ua,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_REFERER => 'https://www.cinemapassion.com/', // Crucial pour éviter le blocage
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => is_array($postData) ? http_build_query($postData) : $postData,
CURLOPT_REFERER => 'https://www.cinemapassion.com/',
CURLOPT_HTTPHEADER => [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.5,en;q=0.3',
'Connection: keep-alive',
'Upgrade-Insecure-Requests: 1'
'Content-Type: application/x-www-form-urlencoded',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.8',
'Origin: https://www.cinemapassion.com'
],
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Si le code est 403, le site vous a banni, essayez de ralentir les requêtes
return ($code === 200) ? $res : null;
return ($code === 200 && is_string($res) && strlen($res) > 0) ? $res : null;
}
function cleanTitle($title) {
@@ -113,12 +137,7 @@ function detectFormat($title, $desc = '') {
return 'Blu-ray';
}
function extractYear($dateStr) {
if (preg_match('/(\d{4})/', $dateStr, $m)) return $m[1];
return '';
}
// ── FONCTION POUR RÉCUPÉRER LES IMAGES DEPUIS CINEMAPASSION.COM ──
// ── FONCTION PRINCIPALE : CINEMAPASSION.COM ──
function fetchCinemaPassion($title, $year = '', $ean = '', $pdo = null) {
$defaultPoster = 'assets/img/default_physical_media.jpg';
$cleanTitle = cleanTitle($title);
@@ -127,151 +146,78 @@ function fetchCinemaPassion($title, $year = '', $ean = '', $pdo = null) {
return ['poster' => $defaultPoster, 'title' => '', 'format' => 'Blu-ray'];
}
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36';
// ÉTAPE 1 : Recherche POST sur /moteur2.php
$searchRes = httpPost('https://www.cinemapassion.com/moteur2.php', ['recherche' => $cleanTitle]);
// ── ÉTAPE 1 : Recherche via POST sur /moteur2.php ──
$searchUrl = "https://www.cinemapassion.com/moteur2.php";
if ($searchRes) {
// ÉTAPE 2 : Extraire le lien vers la page du film
// Pattern : href='../film/Saw-3814.php' ou href='film/Saw-3814.php'
if (preg_match('/href=["\']?(?:\.\.\/)?film\/([^"\'\s]+)-(\d+)\.php["\']?/i', $searchRes, $matches)) {
$filmName = $matches[1];
$filmId = $matches[2];
$ch = curl_init($searchUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $userAgent,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query(['recherche' => $cleanTitle]),
CURLOPT_REFERER => 'https://www.cinemapassion.com/',
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.8',
'Origin: https://www.cinemapassion.com'
],
]);
$searchRes = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ✅ CORRECTION : Vérifier que $searchRes n'est pas null ou false
$html = ($code === 200 && $searchRes && is_string($searchRes)) ? $searchRes : null;
if ($html) {
// ── ÉTAPE 2 : Extraire le lien vers la page du film ──
if (preg_match('/href=["\']([^"\']*film\/[^"\'\/]+-\d+\.php)["\']/i', $html, $matches)) {
$filmPath = $matches[1];
$filmPath = str_replace('../', '', $filmPath);
if (strpos($filmPath, '/') !== 0) {
$filmUrl = 'https://www.cinemapassion.com/' . $filmPath;
} else {
$filmUrl = 'https://www.cinemapassion.com' . $filmPath;
}
if (preg_match('/film\/([^\/]+)-(\d+)\.php/i', $filmUrl, $filmMatches)) {
$filmName = $filmMatches[1];
$filmId = $filmMatches[2];
// ── ÉTAPE 3 : Essayer plusieurs pages pour trouver l'image ──
// ÉTAPE 3 : Essayer plusieurs pages pour trouver l'image
$pagesToTry = [
"https://www.cinemapassion.com/jaquette-dvd-{$filmName}-{$filmId}.php",
"https://www.cinemapassion.com/jaquette-blu-ray-{$filmName}-{$filmId}.php",
$filmUrl,
"https://www.cinemapassion.com/film/{$filmName}-{$filmId}.php",
"https://www.cinemapassion.com/sticker-dvd-{$filmName}-{$filmId}.php",
];
foreach ($pagesToTry as $pageUrl) {
$pageRes = httpGet($pageUrl, 10, $userAgent);
$pageRes = httpGet($pageUrl, 10);
// ✅ CORRECTION : Vérifier que $pageRes est une string valide
if ($pageRes && is_string($pageRes) && strlen($pageRes) > 0) {
// Pattern pour l'image
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $pageRes, $imgMatches)) {
if ($pageRes) {
// Pattern : src='http://www.cinemapassion.com/covers_temp/covers3/Saw-13005811062007.jpg'
if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/covers_temp\/covers\d*\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
$posterUrl = $imgMatches[1];
$posterUrl = str_replace('http://', 'https://', $posterUrl);
error_log("CinemaPassion: Image trouvée pour '{$cleanTitle}' → {$posterUrl}");
return [
'poster' => $posterUrl,
'title' => $cleanTitle,
'format' => 'Blu-ray'
];
error_log("CinemaPassion OK: '{$cleanTitle}' → {$posterUrl}");
return ['poster' => $posterUrl, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
}
// Fallback : image dans lesaffiches/
if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/lesaffiches\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
$posterUrl = $imgMatches[1];
$posterUrl = str_replace('http://', 'https://', $posterUrl);
error_log("CinemaPassion OK (affiche): '{$cleanTitle}' → {$posterUrl}");
return ['poster' => $posterUrl, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
}
}
}
}
// ── FALLBACK : Chercher directement une image dans les résultats ──
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $html, $imgMatches)) {
// Fallback : chercher directement une image covers_temp dans les résultats
if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/covers_temp\/covers\d*\/[^"\'\s>]+\.jpg)["\']?/i', $searchRes, $imgMatches)) {
$posterUrl = str_replace('http://', 'https://', $imgMatches[1]);
error_log("CinemaPassion: Image trouvée (fallback) pour '{$cleanTitle}' → {$posterUrl}");
return [
'poster' => $posterUrl,
'title' => $cleanTitle,
'format' => 'Blu-ray'
];
error_log("CinemaPassion OK (direct): '{$cleanTitle}' → {$posterUrl}");
return ['poster' => $posterUrl, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
}
}
error_log("CinemaPassion: Image NON trouvée pour '{$cleanTitle}'");
error_log("CinemaPassion KO: Image NON trouvée pour '{$cleanTitle}'");
return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
}
// ── ROUTEUR PRINCIPAL ──
// Fonction pour vérifier si une URL existe
function urlExists($url, $timeout = 3) {
if (!function_exists('curl_init')) {
$ctx = stream_context_create(['http' => ['timeout' => $timeout, 'method' => 'HEAD']]);
$result = @get_headers($url, 0, $ctx);
return ($result && strpos($result[0], '200') !== false);
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_NOBODY => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => 2,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
CURLOPT_FOLLOWLOCATION => true,
]);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ($code >= 200 && $code < 400);
}
// ── API TMDB (uniquement pour les critiques) ──
function fetchTMDBFull($title, $year, $apiKey, $pdo) {
if (empty($apiKey) || empty($title)) return null;
$cleanTitle = cleanTitle($title);
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($cleanTitle) . "&year={$year}&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={$apiKey}&query=" . urlencode($cleanTitle) . "&language=fr-FR";
$searchRes = httpGet($searchUrl, 5);
$searchData = $searchRes ? json_decode($searchRes, true) : [];
}
if (empty($searchData['results'])) return null;
$movieId = $searchData['results'][0]['id'];
$detailsUrl = "https://api.themoviedb.org/3/movie/{$movieId}?api_key={$apiKey}&append_to_response=credits,watch/providers,translations&language=fr-FR";
$detailsRes = httpGet($detailsUrl, 5);
if (!$detailsRes) return null;
$details = json_decode($detailsRes, true);
$frenchTitle = $details['title'] ?? '';
if (!empty($details['translations']['translations'])) {
foreach ($details['translations']['translations'] as $translation) {
if ($translation['iso_3166_1'] === 'FR' && !empty($translation['data']['title'])) {
@@ -280,7 +226,6 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
}
}
}
$director = '';
if (!empty($details['credits']['crew'])) {
$directorsList = [];
@@ -289,15 +234,11 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
}
$director = implode(', ', $directorsList);
}
$cast = [];
if (!empty($details['credits']['cast'])) {
$topCast = array_slice($details['credits']['cast'], 0, 4);
foreach ($topCast as $actor) $cast[] = $actor['name'];
}
$overview = $details['overview'] ?? '';
$streaming = '';
$frProviders = $details['watch/providers']['results']['FR'] ?? [];
$platforms = [];
@@ -307,19 +248,16 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
if (!empty($frProviders['buy'])) { foreach ($frProviders['buy'] as $p) $platforms[] = $p['provider_name'] . ' (achat)'; }
}
if (!empty($platforms)) $streaming = implode(', ', array_unique($platforms));
$result = [
return [
'title' => $frenchTitle,
'year' => !empty($details['release_date']) ? substr($details['release_date'], 0, 4) : '',
'director' => $director,
'poster' => !empty($details['poster_path']) ? "https://image.tmdb.org/t/p/w500" . $details['poster_path'] : '',
'length' => !empty($details['runtime']) ? $details['runtime'] . ' min' : '',
'streaming' => $streaming,
'overview' => $overview,
'overview' => $details['overview'] ?? '',
'cast' => $cast
];
return $result;
}
// ── ROUTEUR PRINCIPAL ──
@@ -351,7 +289,7 @@ switch ($action) {
echo json_encode(["success" => true]);
break;
case 'get_config_keys':
case 'get_config_keys':
checkAuth($pdo);
$stmt = $pdo->prepare("SELECT key_name, key_value FROM config WHERE key_name IN ('tmdb_api_key', 'fanart_api_key')");
$stmt->execute();
@@ -389,7 +327,6 @@ case 'get_config_keys':
ORDER BY id DESC
";
$result = $pdo->query($sql)->fetchAll();
foreach ($result as $row) {
if ($row['rating'] !== null) {
$ratingVal = (float)$row['rating'];
@@ -397,67 +334,9 @@ case 'get_config_keys':
}
}
unset($row);
echo json_encode($result);
break;
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' => '',
'poster' => '', 'publisher' => '', 'format' => '',
'length' => '', 'number_of_discs' => 1, 'aspect_ratio' => '', 'actors' => ''
];
$tmdbKey = getTmdbApiKey($pdo);
$titleForSearch = '';
if ($tmdbKey) {
$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);
}
}
}
if (empty($titleForSearch)) {
echo json_encode(['success' => true, 'data' => $result, 'warning' => 'Titre non trouvé']);
exit;
}
if ($type === 'videotheque') {
$format = $result['format'] ?: 'Blu-ray';
$fanartData = fetchFanartTv($titleForSearch, $result['year'], $format, $pdo);
if (!empty($fanartData)) {
if (!empty($fanartData['poster'])) $result['poster'] = $fanartData['poster'];
if (!empty($fanartData['title'])) $result['title'] = $fanartData['title'];
$result['format'] = $format;
}
} else {
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;
case 'save_film':
checkAuth($pdo);
$type = $data['type'] ?? 'critique';
@@ -468,7 +347,6 @@ case 'get_config_keys':
if ($tmdbData) {
if (empty($data['director'])) $data['director'] = $tmdbData['director'];
if (empty($data['poster'])) $data['poster'] = $tmdbData['poster'];
if (empty($data['length']) && !empty($tmdbData['length'])) $data['length'] = $tmdbData['length'];
}
}
@@ -480,13 +358,11 @@ case 'get_config_keys':
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]);
} else {
if (empty($data['poster']) && !empty($data['title'])) {
$format = $data['format'] ?: 'Blu-ray';
$fanartData = fetchFanartTv($data['title'], $data['year'] ?? '', $format, $pdo);
if (!empty($fanartData['poster'])) {
$data['poster'] = $fanartData['poster'];
$cpData = fetchCinemaPassion($data['title'], $data['year'] ?? '', $data['ean_isbn13'] ?? '', $pdo);
if (!empty($cpData['poster']) && $cpData['poster'] !== 'assets/img/default_physical_media.jpg') {
$data['poster'] = $cpData['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'] ?? '']);
@@ -519,6 +395,7 @@ case 'get_config_keys':
$pdo->beginTransaction();
$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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -531,7 +408,8 @@ case 'get_config_keys':
number_of_discs = VALUES(number_of_discs),
aspect_ratio = VALUES(aspect_ratio),
actors = VALUES(actors),
publisher = VALUES(publisher)");
publisher = VALUES(publisher),
director = VALUES(director)");
foreach ($items as $item) {
$title = $item['title'] ?? '';
@@ -549,17 +427,11 @@ case 'get_config_keys':
$id = makeStableId('videotheque', $title, $year);
// Utiliser cinemapassion.com pour récupérer l'image
$cinemaPassionData = fetchCinemaPassion($title, $year, $ean, $pdo);
$poster = $cinemaPassionData['poster'];
// ✅ UTILISER CINEMAPASSION.COM
$cpData = fetchCinemaPassion($title, $year, $ean, $pdo);
$poster = $cpData['poster'];
// Déterminer le format
$format = 'Blu-ray';
if (stripos($title, '4K') !== false || stripos($title, 'UHD') !== false) {
$format = '4K Ultra HD';
} elseif (stripos($desc, 'DVD') !== false) {
$format = 'DVD';
}
$format = detectFormat($title, $desc);
$stmtVideo->execute([
$id, $title, $year, $format, $poster, $ean, $desc,
@@ -567,8 +439,8 @@ case 'get_config_keys':
]);
$imported++;
}
} else {
// CORRECTION : Initialisation des variables manquantes
} else {
// CORRECTION CRITIQUE : Initialisation des variables pour les critiques
$stmtCritiques = $pdo->prepare("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),
@@ -605,10 +477,16 @@ case 'get_config_keys':
}
$pdo->commit();
echo json_encode(["success" => true, "imported" => $imported]);
} catch (Exception $e) {
$pdo->rollBack();
error_log("import_batch error: " . $e->getMessage());
http_response_code(500);
echo json_encode(["success" => false, "error" => $e->getMessage()]);
}
break;
// ── ENDPOINT DE DEBUG DÉTAILLÉ ──
case 'debug_cinemapassion_detailed':
// ── ENDPOINT DE DEBUG DÉTAILLÉ ──
case 'debug_cinemapassion':
$title = $_GET['title'] ?? 'Saw';
$year = $_GET['year'] ?? '';
$ean = $_GET['ean'] ?? '';
@@ -616,140 +494,75 @@ case 'debug_cinemapassion_detailed':
$debugInfo = [
'title' => $title,
'year' => $year,
'ean' => $ean,
'cleanTitle' => cleanTitle($title),
'steps' => []
];
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36';
// ÉTAPE 1 : Test de la recherche POST
$searchUrl = "https://www.cinemapassion.com/moteur2.php";
$ch = curl_init($searchUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $userAgent,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query(['recherche' => cleanTitle($title)]),
CURLOPT_REFERER => 'https://www.cinemapassion.com/',
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.8',
'Origin: https://www.cinemapassion.com'
],
]);
$searchRes = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ✅ CORRECTION : Vérifier que $searchRes est une string
$searchResStr = ($searchRes && is_string($searchRes)) ? $searchRes : '';
$debugInfo['steps']['search'] = [
'url' => $searchUrl,
'http_code' => $code,
'response_length' => strlen($searchResStr),
'success' => ($code === 200 && strlen($searchResStr) > 0)
// Test 1 : POST sur moteur2.php
$searchRes = httpPost('https://www.cinemapassion.com/moteur2.php', ['recherche' => cleanTitle($title)]);
$debugInfo['steps']['search_post'] = [
'success' => !empty($searchRes),
'length' => $searchRes ? strlen($searchRes) : 0
];
if ($code === 200 && strlen($searchResStr) > 0) {
// ÉTAPE 2 : Extraction du lien film
if (preg_match('/href=["\']([^"\']*film\/[^"\'\/]+-\d+\.php)["\']/i', $searchResStr, $matches)) {
$filmPath = $matches[1];
$filmPath = str_replace('../', '', $filmPath);
$filmUrl = 'https://www.cinemapassion.com/' . $filmPath;
$debugInfo['steps']['film_link'] = [
'found' => true,
'filmPath' => $filmPath,
'filmUrl' => $filmUrl
if ($searchRes) {
// Test 2 : Extraction du lien film
if (preg_match('/href=["\']?(?:\.\.\/)?film\/([^"\'\s]+)-(\d+)\.php["\']?/i', $searchRes, $matches)) {
$debugInfo['steps']['film_found'] = [
'success' => true,
'filmName' => $matches[1],
'filmId' => $matches[2]
];
// ÉTAPE 3 : Extraction du nom et ID
if (preg_match('/film\/([^\/]+)-(\d+)\.php/i', $filmUrl, $filmMatches)) {
$filmName = $filmMatches[1];
$filmId = $filmMatches[2];
$filmName = $matches[1];
$filmId = $matches[2];
$debugInfo['steps']['film_details'] = [
'filmName' => $filmName,
'filmId' => $filmId
];
// ÉTAPE 4 : Test des pages de jaquettes
// Test 3 : Pages de jaquettes
$pagesToTry = [
"https://www.cinemapassion.com/jaquette-dvd-{$filmName}-{$filmId}.php",
"https://www.cinemapassion.com/jaquette-blu-ray-{$filmName}-{$filmId}.php",
$filmUrl,
"https://www.cinemapassion.com/sticker-dvd-{$filmName}-{$filmId}.php",
"https://www.cinemapassion.com/film/{$filmName}-{$filmId}.php",
];
foreach ($pagesToTry as $index => $pageUrl) {
$pageRes = httpGet($pageUrl, 10, $userAgent);
// ✅ CORRECTION : Vérifier que $pageRes est une string
$pageResStr = ($pageRes && is_string($pageRes)) ? $pageRes : '';
foreach ($pagesToTry as $i => $pageUrl) {
$pageRes = httpGet($pageUrl, 10);
$pageDebug = [
'url' => $pageUrl,
'success' => (strlen($pageResStr) > 0),
'response_length' => strlen($pageResStr)
'success' => !empty($pageRes),
'length' => $pageRes ? strlen($pageRes) : 0
];
if (strlen($pageResStr) > 0) {
// Test du pattern d'image
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $pageResStr, $imgMatches)) {
$posterUrl = str_replace('http://', 'https://', $imgMatches[1]);
if ($pageRes) {
if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/covers_temp\/covers\d*\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
$pageDebug['image_found'] = true;
$pageDebug['image_url'] = $posterUrl;
$debugInfo['steps']['pages_tested'][$index] = $pageDebug;
$debugInfo['final_result'] = [
'success' => true,
'poster' => $posterUrl,
'title' => cleanTitle($title),
'format' => 'Blu-ray'
];
echo json_encode($debugInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
$pageDebug['image_url'] = str_replace('http://', 'https://', $imgMatches[1]);
} elseif (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/lesaffiches\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
$pageDebug['affiche_found'] = true;
$pageDebug['image_url'] = str_replace('http://', 'https://', $imgMatches[1]);
} else {
$pageDebug['image_found'] = false;
// Extraire un extrait du HTML pour debug
$pageDebug['html_snippet'] = substr($pageResStr, 0, 500);
// Extraire un extrait pour debug
$pageDebug['html_snippet'] = substr($pageRes, 0, 1000);
}
}
$debugInfo['steps']['pages_tested'][$index] = $pageDebug;
}
}
} else {
$debugInfo['steps']['film_link'] = [
'found' => false,
'html_snippet' => substr($searchResStr, 0, 1000)
];
}
$debugInfo['steps']['pages'][$i] = $pageDebug;
// Test du fallback
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $searchResStr, $imgMatches)) {
$posterUrl = str_replace('http://', 'https://', $imgMatches[1]);
$debugInfo['steps']['fallback'] = [
'success' => true,
'image_url' => $posterUrl
];
if (!empty($pageDebug['image_found']) || !empty($pageDebug['affiche_found'])) {
$debugInfo['final_result'] = [
'success' => true,
'poster' => $posterUrl,
'poster' => $pageDebug['image_url'],
'title' => cleanTitle($title),
'format' => 'Blu-ray'
];
echo json_encode($debugInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
}
}
} else {
$debugInfo['steps']['fallback'] = [
'success' => false
$debugInfo['steps']['film_found'] = [
'success' => false,
'html_snippet' => substr($searchRes, 0, 2000)
];
}
}
@@ -757,9 +570,7 @@ case 'debug_cinemapassion_detailed':
if (!isset($debugInfo['final_result'])) {
$debugInfo['final_result'] = [
'success' => false,
'poster' => 'assets/img/default_physical_media.jpg',
'title' => cleanTitle($title),
'format' => 'Blu-ray'
'poster' => 'assets/img/default_physical_media.jpg'
];
}