Actualiser api.php

This commit is contained in:
2026-06-24 11:27:44 +02:00
parent 325a6df04e
commit db8cab0add
+72 -60
View File
@@ -7,7 +7,6 @@ header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }
define('ENCRYPTION_KEY', 'MaCleSecreteSuperRobuste123!');
define('CACHE_TTL', 604800); // 7 jours
try {
$pdo = new PDO("mysql:host=localhost;dbname=mon_cinema;charset=utf8mb4", "root", "", [
@@ -24,7 +23,6 @@ try {
$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) {}
$pdo->exec("CREATE TABLE IF NOT EXISTS cache_api (cache_key VARCHAR(120) PRIMARY KEY, data TEXT NOT NULL, source VARCHAR(20) NOT NULL, created_at INT NOT NULL)");
} catch (\PDOException $e) { echo json_encode(["error" => "Erreur BDD : " . $e->getMessage()]); exit; }
// ── FONCTIONS UTILITAIRES ──
@@ -76,22 +74,6 @@ function httpGet($url, $timeout = 5) {
return $res ?: null;
}
function getCache($pdo, $key) {
try {
$stmt = $pdo->prepare("SELECT data FROM cache_api WHERE cache_key = ? AND created_at > ?");
$stmt->execute([$key, time() - CACHE_TTL]);
$row = $stmt->fetch();
return $row ? json_decode($row['data'], true) : null;
} catch (\Exception $e) { return null; }
}
function setCache($pdo, $key, $data, $source) {
try {
$stmt = $pdo->prepare("REPLACE INTO cache_api (cache_key, data, source, created_at) VALUES (?, ?, ?, ?)");
$stmt->execute([$key, json_encode($data), $source, time()]);
} catch (\Exception $e) { /* ignore */ }
}
function cleanTitle($title) {
$clean = preg_replace('/\s*[\[\(].*?[\]\)]\s*/', '', $title);
$clean = preg_replace('/\s*-\s*(Édition|Edition|Collector|Simple|Spéciale|Digibook|Ultimate|Intégrale|Combo|SteelBook|Boîtier).*$/i', '', $clean);
@@ -117,66 +99,99 @@ function extractYear($dateStr) {
function fetchDVDFr($ean, $pdo) {
if (empty($ean) || strlen($ean) < 8) return null;
$cacheKey = 'dvdfr_full_' . md5($ean);
$cached = getCache($pdo, $cacheKey);
if ($cached) return $cached;
$url = "https://www.dvdfr.com/api/search.php?gencode=" . urlencode($ean);
$res = httpGet($url, 10); // Augmenté à 10s pour éviter les timeouts
if (!$res) {
file_put_contents('dvdfr_error.log', "Échec requête pour EAN: $ean");
return null;
}
$ua = 'MonCinema/1.0 (collection privée; contact@moncineapp.fr)';
try {
$xml = @simplexml_load_string($res);
if ($xml && isset($xml->dvd[0])) {
$d = $xml->dvd[0];
// On extrait tout ce que DVDfr nous donne
$data = [
'poster' => (string)$d->cover,
'format' => (string)$d->media,
'publisher' => (string)$d->editor,
'length' => (string)$d->duration,
'aspect' => (string)$d->ratio
// Étape 1 : recherche par gencode
$searchUrl = "https://www.dvdfr.com/api/search.php?gencode=" . urlencode($ean);
$ch = curl_init($searchUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $ua,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER => ['Accept: application/xml, text/xml, */*'],
]);
$res = curl_exec($ch);
curl_close($ch);
if (!$res) return null;
libxml_use_internal_errors(true);
$xml = simplexml_load_string($res);
libxml_clear_errors();
if (!$xml || !isset($xml->dvd[0]->id)) return null;
$dvdId = (string)$xml->dvd[0]->id;
if (empty($dvdId)) return null;
// Étape 2 : fiche complète
$ficheUrl = "https://www.dvdfr.com/api/dvd.php?id=" . urlencode($dvdId);
$ch2 = curl_init($ficheUrl);
curl_setopt_array($ch2, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => $ua,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER => ['Accept: application/xml, text/xml, */*'],
]);
$res2 = curl_exec($ch2);
curl_close($ch2);
if (!$res2) return null;
libxml_use_internal_errors(true);
$fiche = simplexml_load_string($res2);
libxml_clear_errors();
if (!$fiche || !isset($fiche->dvd[0])) return null;
$dvd = $fiche->dvd[0];
$poster = '';
if (isset($dvd->cover)) $poster = (string)$dvd->cover;
if (empty($poster) && isset($dvd->covers->cover[0])) $poster = (string)$dvd->covers->cover[0];
$result = [
'poster' => $poster,
'publisher' => isset($dvd->editeur) ? (string)$dvd->editeur : '',
'format' => isset($dvd->type) ? (string)$dvd->type : '',
'length' => isset($dvd->duree) ? (string)$dvd->duree : '',
'aspect' => isset($dvd->formatimage) ? (string)$dvd->formatimage : '',
'discs' => isset($dvd->nbdisques) ? (string)$dvd->nbdisques : '',
];
setCache($pdo, $cacheKey, $data, 'dvdfr');
return $data;
}
} catch (\Exception $e) { return null; }
return null;
return !empty($result['poster']) || !empty($result['publisher']) ? $result : null;
}
// ── 2. API TMDB (Full Extract avec Synopsis et Acteurs) ──
function fetchTMDBFull($title, $year, $apiKey, $pdo) {
if (empty($apiKey) || empty($title)) return null;
$cleanTitle = cleanTitle($title);
$cacheKey = 'tmdb_full_' . md5(strtolower($cleanTitle) . '|' . $year);
$cached = getCache($pdo, $cacheKey);
if ($cached) return $cached;
// 1. Tenter avec l'année
$cleanTitle = cleanTitle($title);
// 1. Recherche avec l'année
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($cleanTitle) . "&year={$year}&language=fr-FR";
$searchRes = httpGet($searchUrl, 5);
$searchData = json_decode($searchRes, true);
$searchData = $searchRes ? json_decode($searchRes, true) : [];
// 2. Fallback : Si rien trouvé, on réessaie SANS l'année (au cas où l'année dans le CSV soit fausse)
// 2. Fallback sans l'année
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 = json_decode($searchRes, true);
$searchData = $searchRes ? json_decode($searchRes, true) : [];
}
if (empty($searchData['results'])) return null;
$movieId = $searchData['results'][0]['id'];
// 3. Détails complets
$detailsUrl = "https://api.themoviedb.org/3/movie/{$movieId}?api_key={$apiKey}&append_to_response=credits,watch/providers&language=fr-FR";
$detailsRes = httpGet($detailsUrl, 5);
if (!$detailsRes) return null;
$details = json_decode($detailsRes, true);
// 🔥 Extraction de TOUS les Réalisateurs (pour les co-réalisations)
// Extraction Réalisateurs
$director = '';
if (!empty($details['credits']['crew'])) {
$directorsList = [];
@@ -188,7 +203,7 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
$director = implode(', ', $directorsList);
}
// 🔥 Extraction des 4 premiers Acteurs
// Extraction Acteurs (Top 4)
$cast = [];
if (!empty($details['credits']['cast'])) {
$topCast = array_slice($details['credits']['cast'], 0, 4);
@@ -197,10 +212,10 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
}
}
// 🔥 Extraction du Synopsis (Overview)
// Synopsis
$overview = $details['overview'] ?? '';
// Extraction Streaming
// Streaming
$streaming = '';
$frProviders = $details['watch/providers']['results']['FR'] ?? [];
$platforms = [];
@@ -211,7 +226,7 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
}
if (!empty($platforms)) $streaming = implode(', ', array_unique($platforms));
$result = [
return [
'title' => $details['title'] ?? '',
'year' => !empty($details['release_date']) ? substr($details['release_date'], 0, 4) : '',
'director' => $director,
@@ -221,9 +236,6 @@ function fetchTMDBFull($title, $year, $apiKey, $pdo) {
'overview' => $overview,
'cast' => $cast
];
setCache($pdo, $cacheKey, $result, 'tmdb');
return $result;
}
// ── ROUTEUR PRINCIPAL ──