Actualiser api.php

This commit is contained in:
2026-06-26 14:00:03 +02:00
parent 60e0903c4f
commit 61352a6aa2
+230 -419
View File
@@ -16,15 +16,12 @@ try {
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC 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 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 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))"); $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) {} 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)"); $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) {} 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; } } catch (\PDOException $e) { echo json_encode(["error" => "Erreur BDD : " . $e->getMessage()]); exit; }
// ── FONCTIONS UTILITAIRES ── // ── FONCTIONS UTILITAIRES ──
@@ -50,7 +47,7 @@ function encryptData($data) {
function decryptData($str) { function decryptData($str) {
$decoded = base64_decode($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); 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)); 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; 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 (!$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); $ch = curl_init($url);
curl_setopt_array($ch, [ curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
@@ -80,20 +104,20 @@ function httpGet($url, $timeout = 10, $ua = null) {
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $ua, CURLOPT_USERAGENT => $ua,
CURLOPT_FOLLOWLOCATION => true, 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 => [ CURLOPT_HTTPHEADER => [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Content-Type: application/x-www-form-urlencoded',
'Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Connection: keep-alive', 'Accept-Language: fr-FR,fr;q=0.8',
'Upgrade-Insecure-Requests: 1' 'Origin: https://www.cinemapassion.com'
], ],
]); ]);
$res = curl_exec($ch); $res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); curl_close($ch);
return ($code === 200 && is_string($res) && strlen($res) > 0) ? $res : null;
// Si le code est 403, le site vous a banni, essayez de ralentir les requêtes
return ($code === 200) ? $res : null;
} }
function cleanTitle($title) { function cleanTitle($title) {
@@ -113,12 +137,7 @@ function detectFormat($title, $desc = '') {
return 'Blu-ray'; return 'Blu-ray';
} }
function extractYear($dateStr) { // ── FONCTION PRINCIPALE : CINEMAPASSION.COM ──
if (preg_match('/(\d{4})/', $dateStr, $m)) return $m[1];
return '';
}
// ── FONCTION POUR RÉCUPÉRER LES IMAGES DEPUIS CINEMAPASSION.COM ──
function fetchCinemaPassion($title, $year = '', $ean = '', $pdo = null) { function fetchCinemaPassion($title, $year = '', $ean = '', $pdo = null) {
$defaultPoster = 'assets/img/default_physical_media.jpg'; $defaultPoster = 'assets/img/default_physical_media.jpg';
$cleanTitle = cleanTitle($title); $cleanTitle = cleanTitle($title);
@@ -127,151 +146,78 @@ function fetchCinemaPassion($title, $year = '', $ean = '', $pdo = null) {
return ['poster' => $defaultPoster, 'title' => '', 'format' => 'Blu-ray']; 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 ── if ($searchRes) {
$searchUrl = "https://www.cinemapassion.com/moteur2.php"; // ÉTAPE 2 : Extraire le lien vers la page du film
// Pattern : href='../film/Saw-3814.php' ou href='film/Saw-3814.php'
$ch = curl_init($searchUrl); if (preg_match('/href=["\']?(?:\.\.\/)?film\/([^"\'\s]+)-(\d+)\.php["\']?/i', $searchRes, $matches)) {
curl_setopt_array($ch, [ $filmName = $matches[1];
CURLOPT_RETURNTRANSFER => true, $filmId = $matches[2];
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); // ÉTAPE 3 : Essayer plusieurs pages pour trouver l'image
if (strpos($filmPath, '/') !== 0) { $pagesToTry = [
$filmUrl = 'https://www.cinemapassion.com/' . $filmPath; "https://www.cinemapassion.com/jaquette-dvd-{$filmName}-{$filmId}.php",
} else { "https://www.cinemapassion.com/jaquette-blu-ray-{$filmName}-{$filmId}.php",
$filmUrl = 'https://www.cinemapassion.com' . $filmPath; "https://www.cinemapassion.com/film/{$filmName}-{$filmId}.php",
} "https://www.cinemapassion.com/sticker-dvd-{$filmName}-{$filmId}.php",
];
if (preg_match('/film\/([^\/]+)-(\d+)\.php/i', $filmUrl, $filmMatches)) { foreach ($pagesToTry as $pageUrl) {
$filmName = $filmMatches[1]; $pageRes = httpGet($pageUrl, 10);
$filmId = $filmMatches[2];
// ── ÉTAPE 3 : Essayer plusieurs pages pour trouver l'image ── if ($pageRes) {
$pagesToTry = [ // Pattern : src='http://www.cinemapassion.com/covers_temp/covers3/Saw-13005811062007.jpg'
"https://www.cinemapassion.com/jaquette-dvd-{$filmName}-{$filmId}.php", if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/covers_temp\/covers\d*\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
"https://www.cinemapassion.com/jaquette-blu-ray-{$filmName}-{$filmId}.php", $posterUrl = $imgMatches[1];
$filmUrl, $posterUrl = str_replace('http://', 'https://', $posterUrl);
"https://www.cinemapassion.com/sticker-dvd-{$filmName}-{$filmId}.php", error_log("CinemaPassion OK: '{$cleanTitle}' → {$posterUrl}");
]; return ['poster' => $posterUrl, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
}
foreach ($pagesToTry as $pageUrl) {
$pageRes = httpGet($pageUrl, 10, $userAgent);
// ✅ CORRECTION : Vérifier que $pageRes est une string valide // Fallback : image dans lesaffiches/
if ($pageRes && is_string($pageRes) && strlen($pageRes) > 0) { if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/lesaffiches\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
// Pattern pour l'image $posterUrl = $imgMatches[1];
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $pageRes, $imgMatches)) { $posterUrl = str_replace('http://', 'https://', $posterUrl);
$posterUrl = $imgMatches[1]; error_log("CinemaPassion OK (affiche): '{$cleanTitle}' → {$posterUrl}");
$posterUrl = str_replace('http://', 'https://', $posterUrl); return ['poster' => $posterUrl, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
error_log("CinemaPassion: Image trouvée pour '{$cleanTitle}' → {$posterUrl}");
return [
'poster' => $posterUrl,
'title' => $cleanTitle,
'format' => 'Blu-ray'
];
}
} }
} }
} }
} }
// ── FALLBACK : Chercher directement une image dans les résultats ── // Fallback : chercher directement une image covers_temp dans les résultats
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $html, $imgMatches)) { if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/covers_temp\/covers\d*\/[^"\'\s>]+\.jpg)["\']?/i', $searchRes, $imgMatches)) {
$posterUrl = str_replace('http://', 'https://', $imgMatches[1]); $posterUrl = str_replace('http://', 'https://', $imgMatches[1]);
error_log("CinemaPassion: Image trouvée (fallback) pour '{$cleanTitle}' → {$posterUrl}"); error_log("CinemaPassion OK (direct): '{$cleanTitle}' → {$posterUrl}");
return [ return ['poster' => $posterUrl, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
'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']; 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) ── // ── API TMDB (uniquement pour les critiques) ──
function fetchTMDBFull($title, $year, $apiKey, $pdo) { function fetchTMDBFull($title, $year, $apiKey, $pdo) {
if (empty($apiKey) || empty($title)) return null; if (empty($apiKey) || empty($title)) return null;
$cleanTitle = cleanTitle($title); $cleanTitle = cleanTitle($title);
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($cleanTitle) . "&year={$year}&language=fr-FR"; $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($cleanTitle) . "&year={$year}&language=fr-FR";
$searchRes = httpGet($searchUrl, 5); $searchRes = httpGet($searchUrl, 5);
$searchData = $searchRes ? json_decode($searchRes, true) : []; $searchData = $searchRes ? json_decode($searchRes, true) : [];
if (empty($searchData['results'])) { if (empty($searchData['results'])) {
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($cleanTitle) . "&language=fr-FR"; $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($cleanTitle) . "&language=fr-FR";
$searchRes = httpGet($searchUrl, 5); $searchRes = httpGet($searchUrl, 5);
$searchData = $searchRes ? json_decode($searchRes, true) : []; $searchData = $searchRes ? json_decode($searchRes, true) : [];
} }
if (empty($searchData['results'])) return null; if (empty($searchData['results'])) return null;
$movieId = $searchData['results'][0]['id']; $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"; $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); $detailsRes = httpGet($detailsUrl, 5);
if (!$detailsRes) return null; if (!$detailsRes) return null;
$details = json_decode($detailsRes, true); $details = json_decode($detailsRes, true);
$frenchTitle = $details['title'] ?? ''; $frenchTitle = $details['title'] ?? '';
if (!empty($details['translations']['translations'])) { if (!empty($details['translations']['translations'])) {
foreach ($details['translations']['translations'] as $translation) { foreach ($details['translations']['translations'] as $translation) {
if ($translation['iso_3166_1'] === 'FR' && !empty($translation['data']['title'])) { if ($translation['iso_3166_1'] === 'FR' && !empty($translation['data']['title'])) {
@@ -280,7 +226,6 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
} }
} }
} }
$director = ''; $director = '';
if (!empty($details['credits']['crew'])) { if (!empty($details['credits']['crew'])) {
$directorsList = []; $directorsList = [];
@@ -289,15 +234,11 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
} }
$director = implode(', ', $directorsList); $director = implode(', ', $directorsList);
} }
$cast = []; $cast = [];
if (!empty($details['credits']['cast'])) { if (!empty($details['credits']['cast'])) {
$topCast = array_slice($details['credits']['cast'], 0, 4); $topCast = array_slice($details['credits']['cast'], 0, 4);
foreach ($topCast as $actor) $cast[] = $actor['name']; foreach ($topCast as $actor) $cast[] = $actor['name'];
} }
$overview = $details['overview'] ?? '';
$streaming = ''; $streaming = '';
$frProviders = $details['watch/providers']['results']['FR'] ?? []; $frProviders = $details['watch/providers']['results']['FR'] ?? [];
$platforms = []; $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($frProviders['buy'])) { foreach ($frProviders['buy'] as $p) $platforms[] = $p['provider_name'] . ' (achat)'; }
} }
if (!empty($platforms)) $streaming = implode(', ', array_unique($platforms)); if (!empty($platforms)) $streaming = implode(', ', array_unique($platforms));
return [
$result = [
'title' => $frenchTitle, 'title' => $frenchTitle,
'year' => !empty($details['release_date']) ? substr($details['release_date'], 0, 4) : '', 'year' => !empty($details['release_date']) ? substr($details['release_date'], 0, 4) : '',
'director' => $director, 'director' => $director,
'poster' => !empty($details['poster_path']) ? "https://image.tmdb.org/t/p/w500" . $details['poster_path'] : '', 'poster' => !empty($details['poster_path']) ? "https://image.tmdb.org/t/p/w500" . $details['poster_path'] : '',
'length' => !empty($details['runtime']) ? $details['runtime'] . ' min' : '', 'length' => !empty($details['runtime']) ? $details['runtime'] . ' min' : '',
'streaming' => $streaming, 'streaming' => $streaming,
'overview' => $overview, 'overview' => $details['overview'] ?? '',
'cast' => $cast 'cast' => $cast
]; ];
return $result;
} }
// ── ROUTEUR PRINCIPAL ── // ── ROUTEUR PRINCIPAL ──
@@ -351,20 +289,20 @@ switch ($action) {
echo json_encode(["success" => true]); echo json_encode(["success" => true]);
break; break;
case 'get_config_keys': case 'get_config_keys':
checkAuth($pdo); checkAuth($pdo);
$stmt = $pdo->prepare("SELECT key_name, key_value FROM config WHERE key_name IN ('tmdb_api_key', 'fanart_api_key')"); $stmt = $pdo->prepare("SELECT key_name, key_value FROM config WHERE key_name IN ('tmdb_api_key', 'fanart_api_key')");
$stmt->execute(); $stmt->execute();
$rows = $stmt->fetchAll(); $rows = $stmt->fetchAll();
$config = []; $config = [];
foreach ($rows as $row) { foreach ($rows as $row) {
$config[$row['key_name']] = $row['key_value'] ? '••••••••' : ''; $config[$row['key_name']] = $row['key_value'] ? '••••••••' : '';
} }
if (!isset($config['tmdb_api_key'])) $config['tmdb_api_key'] = ''; if (!isset($config['tmdb_api_key'])) $config['tmdb_api_key'] = '';
if (!isset($config['fanart_api_key'])) $config['fanart_api_key'] = ''; if (!isset($config['fanart_api_key'])) $config['fanart_api_key'] = '';
echo json_encode($config); echo json_encode($config);
break; break;
case 'save_config': case 'save_config':
checkAuth($pdo); checkAuth($pdo);
$keyName = $data['key_name'] ?? ''; $keyName = $data['key_name'] ?? '';
@@ -389,7 +327,6 @@ case 'get_config_keys':
ORDER BY id DESC ORDER BY id DESC
"; ";
$result = $pdo->query($sql)->fetchAll(); $result = $pdo->query($sql)->fetchAll();
foreach ($result as $row) { foreach ($result as $row) {
if ($row['rating'] !== null) { if ($row['rating'] !== null) {
$ratingVal = (float)$row['rating']; $ratingVal = (float)$row['rating'];
@@ -397,67 +334,9 @@ case 'get_config_keys':
} }
} }
unset($row); unset($row);
echo json_encode($result); echo json_encode($result);
break; 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': case 'save_film':
checkAuth($pdo); checkAuth($pdo);
$type = $data['type'] ?? 'critique'; $type = $data['type'] ?? 'critique';
@@ -468,7 +347,6 @@ case 'get_config_keys':
if ($tmdbData) { if ($tmdbData) {
if (empty($data['director'])) $data['director'] = $tmdbData['director']; if (empty($data['director'])) $data['director'] = $tmdbData['director'];
if (empty($data['poster'])) $data['poster'] = $tmdbData['poster']; if (empty($data['poster'])) $data['poster'] = $tmdbData['poster'];
if (empty($data['length']) && !empty($tmdbData['length'])) $data['length'] = $tmdbData['length'];
} }
} }
@@ -479,14 +357,12 @@ case 'get_config_keys':
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]); $stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]);
} else { } else {
if (empty($data['poster']) && !empty($data['title'])) { if (empty($data['poster']) && !empty($data['title'])) {
$format = $data['format'] ?: 'Blu-ray'; $cpData = fetchCinemaPassion($data['title'], $data['year'] ?? '', $data['ean_isbn13'] ?? '', $pdo);
$fanartData = fetchFanartTv($data['title'], $data['year'] ?? '', $format, $pdo); if (!empty($cpData['poster']) && $cpData['poster'] !== 'assets/img/default_physical_media.jpg') {
if (!empty($fanartData['poster'])) { $data['poster'] = $cpData['poster'];
$data['poster'] = $fanartData['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)"; $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 = $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'] ?? '']); $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'] ?? '']);
@@ -510,65 +386,61 @@ case 'get_config_keys':
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';
$items = $data['items'] ?? []; $items = $data['items'] ?? [];
$pdo->beginTransaction();
$imported = 0;
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)");
foreach ($items as $item) { $pdo->beginTransaction();
$title = $item['title'] ?? ''; $imported = 0;
if (empty($title)) continue;
try {
$year = $item['year'] ?? ''; if ($type === 'videotheque') {
$ean = $item['ean'] ?? ''; $stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director)
$desc = $item['description'] ?? ''; VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
$length = $item['length'] ?? ''; ON DUPLICATE KEY UPDATE
$discs = $item['number_of_discs'] ?? 1; ean_isbn13 = VALUES(ean_isbn13),
$aspect = $item['aspect_ratio'] ?? ''; poster = VALUES(poster),
$actors = $item['actors'] ?? ''; description = VALUES(description),
$publisher = $item['publisher'] ?? ''; format = VALUES(format),
$director = $item['director'] ?? ''; length = VALUES(length),
number_of_discs = VALUES(number_of_discs),
$id = makeStableId('videotheque', $title, $year); aspect_ratio = VALUES(aspect_ratio),
actors = VALUES(actors),
// Utiliser cinemapassion.com pour récupérer l'image publisher = VALUES(publisher),
$cinemaPassionData = fetchCinemaPassion($title, $year, $ean, $pdo); director = VALUES(director)");
$poster = $cinemaPassionData['poster'];
foreach ($items as $item) {
// Déterminer le format $title = $item['title'] ?? '';
$format = 'Blu-ray'; if (empty($title)) continue;
if (stripos($title, '4K') !== false || stripos($title, 'UHD') !== false) {
$format = '4K Ultra HD'; $year = $item['year'] ?? '';
} elseif (stripos($desc, 'DVD') !== false) { $ean = $item['ean'] ?? '';
$format = 'DVD'; $desc = $item['description'] ?? '';
} $length = $item['length'] ?? '';
$discs = $item['number_of_discs'] ?? 1;
$stmtVideo->execute([ $aspect = $item['aspect_ratio'] ?? '';
$id, $title, $year, $format, $poster, $ean, $desc, $actors = $item['actors'] ?? '';
$length, $discs, $aspect, $actors, $publisher, $director $publisher = $item['publisher'] ?? '';
]); $director = $item['director'] ?? '';
$imported++;
} $id = makeStableId('videotheque', $title, $year);
} else {
// CORRECTION : Initialisation des variables manquantes // ✅ UTILISER CINEMAPASSION.COM
$cpData = fetchCinemaPassion($title, $year, $ean, $pdo);
$poster = $cpData['poster'];
$format = detectFormat($title, $desc);
$stmtVideo->execute([
$id, $title, $year, $format, $poster, $ean, $desc,
$length, $discs, $aspect, $actors, $publisher, $director
]);
$imported++;
}
} else {
// ✅ CORRECTION CRITIQUE : Initialisation des variables pour les critiques
$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),
@@ -586,7 +458,7 @@ case 'get_config_keys':
$rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null; $rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null;
$review = $rowData['Review'] ?? $rowData['review'] ?? ''; $review = $rowData['Review'] ?? $rowData['review'] ?? '';
$director = ''; $poster = ''; $streaming = ''; $director = ''; $poster = ''; $streaming = '';
if ($tmdbApiKey && !empty($title)) { if ($tmdbApiKey && !empty($title)) {
$tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo); $tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo);
if ($tmdbData) { if ($tmdbData) {
@@ -598,173 +470,112 @@ case 'get_config_keys':
} }
} }
if (empty($streaming)) $streaming = 'Support physique / Cinéma'; if (empty($streaming)) $streaming = 'Support physique / Cinéma';
$stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]); $stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]);
$imported++; $imported++;
} }
} }
$pdo->commit(); $pdo->commit();
echo json_encode(["success" => true, "imported" => $imported]); echo json_encode(["success" => true, "imported" => $imported]);
break; } catch (Exception $e) {
$pdo->rollBack();
// ── ENDPOINT DE DEBUG DÉTAILLÉ ── error_log("import_batch error: " . $e->getMessage());
case 'debug_cinemapassion_detailed': http_response_code(500);
$title = $_GET['title'] ?? 'Saw'; echo json_encode(["success" => false, "error" => $e->getMessage()]);
$year = $_GET['year'] ?? ''; }
$ean = $_GET['ean'] ?? ''; break;
$debugInfo = [ // ── ENDPOINT DE DEBUG DÉTAILLÉ ──
'title' => $title, case 'debug_cinemapassion':
'year' => $year, $title = $_GET['title'] ?? 'Saw';
'ean' => $ean, $year = $_GET['year'] ?? '';
'cleanTitle' => cleanTitle($title), $ean = $_GET['ean'] ?? '';
'steps' => []
]; $debugInfo = [
'title' => $title,
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'; 'year' => $year,
'cleanTitle' => cleanTitle($title),
// ÉTAPE 1 : Test de la recherche POST 'steps' => []
$searchUrl = "https://www.cinemapassion.com/moteur2.php"; ];
$ch = curl_init($searchUrl);
curl_setopt_array($ch, [ // Test 1 : POST sur moteur2.php
CURLOPT_RETURNTRANSFER => true, $searchRes = httpPost('https://www.cinemapassion.com/moteur2.php', ['recherche' => cleanTitle($title)]);
CURLOPT_TIMEOUT => 15, $debugInfo['steps']['search_post'] = [
CURLOPT_CONNECTTIMEOUT => 5, 'success' => !empty($searchRes),
CURLOPT_SSL_VERIFYPEER => false, 'length' => $searchRes ? strlen($searchRes) : 0
CURLOPT_USERAGENT => $userAgent, ];
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_POST => true, if ($searchRes) {
CURLOPT_POSTFIELDS => http_build_query(['recherche' => cleanTitle($title)]), // Test 2 : Extraction du lien film
CURLOPT_REFERER => 'https://www.cinemapassion.com/', if (preg_match('/href=["\']?(?:\.\.\/)?film\/([^"\'\s]+)-(\d+)\.php["\']?/i', $searchRes, $matches)) {
CURLOPT_HTTPHEADER => [ $debugInfo['steps']['film_found'] = [
'Content-Type: application/x-www-form-urlencoded', 'success' => true,
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'filmName' => $matches[1],
'Accept-Language: fr-FR,fr;q=0.8', 'filmId' => $matches[2]
'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)
];
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
];
// ÉTAPE 3 : Extraction du nom et ID
if (preg_match('/film\/([^\/]+)-(\d+)\.php/i', $filmUrl, $filmMatches)) {
$filmName = $filmMatches[1];
$filmId = $filmMatches[2];
$debugInfo['steps']['film_details'] = [
'filmName' => $filmName,
'filmId' => $filmId
]; ];
// ÉTAPE 4 : Test des pages de jaquettes $filmName = $matches[1];
$filmId = $matches[2];
// Test 3 : Pages de jaquettes
$pagesToTry = [ $pagesToTry = [
"https://www.cinemapassion.com/jaquette-dvd-{$filmName}-{$filmId}.php", "https://www.cinemapassion.com/jaquette-dvd-{$filmName}-{$filmId}.php",
"https://www.cinemapassion.com/jaquette-blu-ray-{$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 $index => $pageUrl) { foreach ($pagesToTry as $i => $pageUrl) {
$pageRes = httpGet($pageUrl, 10, $userAgent); $pageRes = httpGet($pageUrl, 10);
// ✅ CORRECTION : Vérifier que $pageRes est une string
$pageResStr = ($pageRes && is_string($pageRes)) ? $pageRes : '';
$pageDebug = [ $pageDebug = [
'url' => $pageUrl, 'url' => $pageUrl,
'success' => (strlen($pageResStr) > 0), 'success' => !empty($pageRes),
'response_length' => strlen($pageResStr) 'length' => $pageRes ? strlen($pageRes) : 0
]; ];
if (strlen($pageResStr) > 0) { if ($pageRes) {
// Test du pattern d'image if (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/covers_temp\/covers\d*\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $pageResStr, $imgMatches)) {
$posterUrl = str_replace('http://', 'https://', $imgMatches[1]);
$pageDebug['image_found'] = true; $pageDebug['image_found'] = true;
$pageDebug['image_url'] = $posterUrl; $pageDebug['image_url'] = str_replace('http://', 'https://', $imgMatches[1]);
} elseif (preg_match('/src=["\']?(https?:\/\/(?:www\.)?cinemapassion\.com\/lesaffiches\/[^"\'\s>]+\.jpg)["\']?/i', $pageRes, $imgMatches)) {
$debugInfo['steps']['pages_tested'][$index] = $pageDebug; $pageDebug['affiche_found'] = true;
$debugInfo['final_result'] = [ $pageDebug['image_url'] = str_replace('http://', 'https://', $imgMatches[1]);
'success' => true,
'poster' => $posterUrl,
'title' => cleanTitle($title),
'format' => 'Blu-ray'
];
echo json_encode($debugInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
} else { } else {
$pageDebug['image_found'] = false; $pageDebug['image_found'] = false;
// Extraire un extrait du HTML pour debug // Extraire un extrait pour debug
$pageDebug['html_snippet'] = substr($pageResStr, 0, 500); $pageDebug['html_snippet'] = substr($pageRes, 0, 1000);
} }
} }
$debugInfo['steps']['pages_tested'][$index] = $pageDebug; $debugInfo['steps']['pages'][$i] = $pageDebug;
if (!empty($pageDebug['image_found']) || !empty($pageDebug['affiche_found'])) {
$debugInfo['final_result'] = [
'success' => true,
'poster' => $pageDebug['image_url'],
'title' => cleanTitle($title),
'format' => 'Blu-ray'
];
echo json_encode($debugInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
}
} }
} else {
$debugInfo['steps']['film_found'] = [
'success' => false,
'html_snippet' => substr($searchRes, 0, 2000)
];
} }
} else { }
$debugInfo['steps']['film_link'] = [
'found' => false, if (!isset($debugInfo['final_result'])) {
'html_snippet' => substr($searchResStr, 0, 1000) $debugInfo['final_result'] = [
'success' => false,
'poster' => 'assets/img/default_physical_media.jpg'
]; ];
} }
// Test du fallback echo json_encode($debugInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
if (preg_match('/src=["\']?(https?:\/\/[^"\'\s>]*cinemapassion\.com[^"\'\s>]*covers[^"\'\s>]*\.jpg)["\']?/i', $searchResStr, $imgMatches)) { exit;
$posterUrl = str_replace('http://', 'https://', $imgMatches[1]); break;
$debugInfo['steps']['fallback'] = [
'success' => true,
'image_url' => $posterUrl
];
$debugInfo['final_result'] = [
'success' => true,
'poster' => $posterUrl,
'title' => cleanTitle($title),
'format' => 'Blu-ray'
];
} else {
$debugInfo['steps']['fallback'] = [
'success' => false
];
}
}
if (!isset($debugInfo['final_result'])) {
$debugInfo['final_result'] = [
'success' => false,
'poster' => 'assets/img/default_physical_media.jpg',
'title' => cleanTitle($title),
'format' => 'Blu-ray'
];
}
echo json_encode($debugInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
break;
} }
?> ?>