Actualiser api.php
This commit is contained in:
@@ -62,6 +62,13 @@ function getTmdbApiKey($pdo) {
|
|||||||
return $row ? decryptData($row['key_value']) : null;
|
return $row ? decryptData($row['key_value']) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFanartApiKey($pdo) {
|
||||||
|
$stmt = $pdo->prepare("SELECT key_value FROM config WHERE key_name = 'fanart_api_key'");
|
||||||
|
$stmt->execute();
|
||||||
|
$row = $stmt->fetch();
|
||||||
|
return $row ? decryptData($row['key_value']) : null;
|
||||||
|
}
|
||||||
|
|
||||||
function httpGet($url, $timeout = 3, $ua = null) {
|
function httpGet($url, $timeout = 3, $ua = null) {
|
||||||
if (!$ua) $ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.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/120.0.0.0 Safari/537.36';
|
||||||
|
|
||||||
@@ -113,142 +120,95 @@ function extractYear($dateStr) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── DVDCover.com via API REST WordPress ──
|
function fetchFanartTv($title, $year = '', $format = 'bluray', $pdo = null) {
|
||||||
function fetchDVDCover($title, $year = '', $format = 'bluray') {
|
|
||||||
if (empty($title)) return null;
|
if (empty($title)) return null;
|
||||||
|
|
||||||
$cleanTitle = cleanTitle($title);
|
$cleanTitle = cleanTitle($title);
|
||||||
if (empty($cleanTitle)) return null;
|
if (empty($cleanTitle)) return null;
|
||||||
|
|
||||||
// API REST WordPress de DVDcover
|
// Récupérer la clé API
|
||||||
$searchUrl = "https://www.dvdcover.com/wp-json/wp/v2/posts?search=" . urlencode($cleanTitle) . "&_embed&per_page=10";
|
$apiKey = getFanartApiKey($pdo);
|
||||||
|
if (empty($apiKey)) {
|
||||||
|
// Fallback sur la clé en dur si non configurée
|
||||||
|
$apiKey = '70f9747dafe9b27f9b14ef80ee0cacc9';
|
||||||
|
}
|
||||||
|
|
||||||
$json = httpGet($searchUrl, 10);
|
// Étape 1 : Chercher le film sur TMDB pour obtenir son ID
|
||||||
if (!$json) {
|
$tmdbKey = getTmdbApiKey($pdo);
|
||||||
error_log("DVDCover API: Échec requête pour '$title'");
|
if (!$tmdbKey) {
|
||||||
|
error_log("Fanart.tv: Clé TMDB requise pour obtenir l'ID du film");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$posts = json_decode($json, true);
|
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query=" . urlencode($cleanTitle);
|
||||||
if (!is_array($posts) || empty($posts)) {
|
if (!empty($year)) {
|
||||||
error_log("DVDCover API: Aucun résultat pour '$title'");
|
$searchUrl .= "&year={$year}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$searchRes = httpGet($searchUrl, 5);
|
||||||
|
$searchData = $searchRes ? json_decode($searchRes, true) : [];
|
||||||
|
|
||||||
|
if (empty($searchData['results'])) {
|
||||||
|
error_log("Fanart.tv: Film non trouvé sur TMDB pour '$title'");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cleanTitleLower = strtolower($cleanTitle);
|
$tmdbId = $searchData['results'][0]['id'];
|
||||||
$bestPost = null;
|
|
||||||
$bestScore = 0;
|
|
||||||
|
|
||||||
foreach ($posts as $post) {
|
// Étape 2 : Récupérer les artworks depuis fanart.tv
|
||||||
$postTitle = $post['title']['rendered'] ?? '';
|
$fanartUrl = "https://webservice.fanart.tv/v3/movies/{$tmdbId}?api_key={$apiKey}";
|
||||||
$postTitleLower = strtolower($postTitle);
|
$fanartRes = httpGet($fanartUrl, 5);
|
||||||
|
$fanartData = $fanartRes ? json_decode($fanartRes, true) : [];
|
||||||
|
|
||||||
$score = 0;
|
if (isset($fanartData['error'])) {
|
||||||
if (strpos($postTitleLower, $cleanTitleLower) !== false) {
|
error_log("Fanart.tv: Erreur API - " . $fanartData['error']);
|
||||||
$score += 50;
|
return null;
|
||||||
}
|
|
||||||
if (!empty($year) && strpos($postTitle, $year) !== false) {
|
|
||||||
$score += 30;
|
|
||||||
}
|
|
||||||
$formatLower = strtolower($format);
|
|
||||||
if (stripos($postTitle, $format) !== false ||
|
|
||||||
stripos($postTitle, str_replace('-', ' ', $format)) !== false) {
|
|
||||||
$score += 20;
|
|
||||||
}
|
|
||||||
if (stripos($postTitle, 'cover') !== false) {
|
|
||||||
$score += 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($score > $bestScore) {
|
|
||||||
$bestScore = $score;
|
|
||||||
$bestPost = $post;
|
|
||||||
}
|
|
||||||
if ($score >= 100) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$bestPost && !empty($posts)) {
|
|
||||||
$bestPost = $posts[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$bestPost) return null;
|
|
||||||
|
|
||||||
// Extraire l'image du post
|
|
||||||
$poster = '';
|
$poster = '';
|
||||||
|
|
||||||
// Méthode 1 : Image mise en avant (_embedded.wp:featuredmedia)
|
// Priorité aux movieposter (jaquettes complètes)
|
||||||
if (isset($bestPost['_embedded']['wp:featuredmedia'][0])) {
|
if (!empty($fanartData['movieposter'])) {
|
||||||
$featured = $bestPost['_embedded']['wp:featuredmedia'][0];
|
// Filtrer par langue (fr d'abord, puis en, puis tout)
|
||||||
if (!empty($featured['media_details']['sizes'])) {
|
$posters = $fanartData['movieposter'];
|
||||||
$sizes = $featured['media_details']['sizes'];
|
$preferredLangs = ['fr', 'en', ''];
|
||||||
$preferredSizes = ['full', 'large', 'medium', 'thumbnail'];
|
|
||||||
foreach ($preferredSizes as $size) {
|
foreach ($preferredLangs as $lang) {
|
||||||
if (isset($sizes[$size]['source_url'])) {
|
$filtered = array_filter($posters, function($p) use ($lang) {
|
||||||
$poster = $sizes[$size]['source_url'];
|
return ($lang === '' || ($p['lang'] ?? '') === $lang);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!empty($filtered)) {
|
||||||
|
// Trier par likes (le plus populaire en premier)
|
||||||
|
usort($filtered, function($a, $b) {
|
||||||
|
return ($b['likes'] ?? 0) - ($a['likes'] ?? 0);
|
||||||
|
});
|
||||||
|
$poster = $filtered[0]['url'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (empty($poster) && !empty($featured['source_url'])) {
|
|
||||||
$poster = $featured['source_url'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Méthode 2 : Images dans le contenu du post
|
// Fallback sur hdmovielogo si pas de movieposter
|
||||||
if (empty($poster) && !empty($bestPost['content']['rendered'])) {
|
if (empty($poster) && !empty($fanartData['hdmovielogo'])) {
|
||||||
$content = $bestPost['content']['rendered'];
|
$logos = $fanartData['hdmovielogo'];
|
||||||
if (preg_match_all('/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content, $matches)) {
|
$poster = $logos[0]['url'];
|
||||||
foreach ($matches[1] as $img) {
|
|
||||||
if (strpos($img, 'logo') === false &&
|
|
||||||
strpos($img, 'icon') === false &&
|
|
||||||
strpos($img, 'banner') === false &&
|
|
||||||
strpos($img, 'bg') === false &&
|
|
||||||
strpos($img, 'button') === false &&
|
|
||||||
strpos($img, 'social') === false &&
|
|
||||||
(strpos($img, '.jpg') !== false || strpos($img, '.jpeg') !== false || strpos($img, '.png') !== false || strpos($img, '.webp') !== false)) {
|
|
||||||
$poster = $img;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback sur moviebackground
|
||||||
|
if (empty($poster) && !empty($fanartData['moviebackground'])) {
|
||||||
|
$backgrounds = $fanartData['moviebackground'];
|
||||||
|
$poster = $backgrounds[0]['url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($poster)) {
|
if (empty($poster)) {
|
||||||
error_log("DVDCover API: Pas d'image trouvée pour le post ID " . ($bestPost['id'] ?? '?'));
|
error_log("Fanart.tv: Aucune jaquette trouvée pour TMDB ID {$tmdbId}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// S'assurer que l'URL est absolue
|
|
||||||
if (strpos($poster, 'http') !== 0) {
|
|
||||||
$poster = 'https://www.dvdcover.com' . (strpos($poster, '/') === 0 ? '' : '/') . ltrim($poster, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Supprimer les suffixes de taille WordPress
|
|
||||||
$poster = preg_replace('/-\d+x\d+(\.\w+)$/', '$1', $poster);
|
|
||||||
|
|
||||||
// VÉRIFICATION : Tester si l'image est accessible
|
|
||||||
// Essayer différentes variantes d'URL
|
|
||||||
$urlVariants = [
|
|
||||||
$poster,
|
|
||||||
str_replace('dvdcover.com', 'www.dvdcover.com', $poster),
|
|
||||||
str_replace('https://www.dvdcover.com', 'https://dvdcover.com', $poster),
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($urlVariants as $testUrl) {
|
|
||||||
if (urlExists($testUrl, 3)) {
|
|
||||||
error_log("DVDCover API: Image valide trouvée - $testUrl");
|
|
||||||
return [
|
|
||||||
'poster' => $testUrl,
|
|
||||||
'title' => $bestPost['title']['rendered'] ?? $cleanTitle,
|
|
||||||
'format' => $format,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si aucune URL ne fonctionne, retourner quand même la première (peut-être un problème temporaire)
|
|
||||||
error_log("DVDCover API: Aucune URL d'image valide trouvée, retour de la première URL");
|
|
||||||
return [
|
return [
|
||||||
'poster' => $poster,
|
'poster' => $poster,
|
||||||
'title' => $bestPost['title']['rendered'] ?? $cleanTitle,
|
'title' => $cleanTitle,
|
||||||
'format' => $format,
|
'format' => $format,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -384,16 +344,28 @@ switch ($action) {
|
|||||||
|
|
||||||
case 'get_config_keys':
|
case 'get_config_keys':
|
||||||
checkAuth($pdo);
|
checkAuth($pdo);
|
||||||
$stmt = $pdo->prepare("SELECT key_value FROM config WHERE key_name = 'tmdb_api_key'");
|
$stmt = $pdo->prepare("SELECT key_value FROM config WHERE key_name IN ('tmdb_api_key', 'fanart_api_key')");
|
||||||
$stmt->execute(); $row = $stmt->fetch();
|
$stmt->execute();
|
||||||
echo json_encode(['tmdb_api_key' => $row ? '••••••••' : '']);
|
$rows = $stmt->fetchAll();
|
||||||
|
$config = [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
if ($row['key_name'] === 'tmdb_api_key') {
|
||||||
|
$config['tmdb_api_key'] = $row['key_value'] ? '••••••••' : '';
|
||||||
|
} elseif ($row['key_name'] === 'fanart_api_key') {
|
||||||
|
$config['fanart_api_key'] = $row['key_value'] ? '••••••••' : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Valeurs par défaut si non configurées
|
||||||
|
if (!isset($config['tmdb_api_key'])) $config['tmdb_api_key'] = '';
|
||||||
|
if (!isset($config['fanart_api_key'])) $config['fanart_api_key'] = '';
|
||||||
|
echo json_encode($config);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'save_config':
|
case 'save_config':
|
||||||
checkAuth($pdo);
|
checkAuth($pdo);
|
||||||
$keyName = $data['key_name'] ?? '';
|
$keyName = $data['key_name'] ?? '';
|
||||||
$keyValue = $data['key_value'] ?? '';
|
$keyValue = $data['key_value'] ?? '';
|
||||||
if ($keyName === 'tmdb_api_key' && !empty($keyValue)) {
|
if (in_array($keyName, ['tmdb_api_key', 'fanart_api_key']) && !empty($keyValue)) {
|
||||||
$stmt = $pdo->prepare("REPLACE INTO config (key_name, key_value) VALUES (?, ?)");
|
$stmt = $pdo->prepare("REPLACE INTO config (key_name, key_value) VALUES (?, ?)");
|
||||||
$stmt->execute([$keyName, encryptData($keyValue)]);
|
$stmt->execute([$keyName, encryptData($keyValue)]);
|
||||||
echo json_encode(["success" => true]);
|
echo json_encode(["success" => true]);
|
||||||
@@ -413,7 +385,7 @@ switch ($action) {
|
|||||||
";
|
";
|
||||||
$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'];
|
||||||
$row['rating'] = ($ratingVal == floor($ratingVal)) ? (int)$ratingVal : $ratingVal;
|
$row['rating'] = ($ratingVal == floor($ratingVal)) ? (int)$ratingVal : $ratingVal;
|
||||||
@@ -457,9 +429,8 @@ switch ($action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($type === 'videotheque') {
|
if ($type === 'videotheque') {
|
||||||
// DVDCover API pour vidéothèque
|
|
||||||
$format = $result['format'] ?: 'Blu-ray';
|
$format = $result['format'] ?: 'Blu-ray';
|
||||||
$dcData = fetchDVDCover($titleForSearch, $result['year'], $format);
|
$dcData = fetchFanartTv($titleForSearch, $result['year'], $format, $pdo);
|
||||||
if (!empty($dcData)) {
|
if (!empty($dcData)) {
|
||||||
if (!empty($dcData['poster'])) $result['poster'] = $dcData['poster'];
|
if (!empty($dcData['poster'])) $result['poster'] = $dcData['poster'];
|
||||||
if (!empty($dcData['title'])) $result['title'] = $dcData['title'];
|
if (!empty($dcData['title'])) $result['title'] = $dcData['title'];
|
||||||
@@ -503,10 +474,9 @@ switch ($action) {
|
|||||||
$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 {
|
||||||
// Vidéothèque : DVDCover API pour la jaquette
|
|
||||||
if (empty($data['poster']) && !empty($data['title'])) {
|
if (empty($data['poster']) && !empty($data['title'])) {
|
||||||
$format = $data['format'] ?: 'Blu-ray';
|
$format = $data['format'] ?: 'Blu-ray';
|
||||||
$dcData = fetchDVDCover($data['title'], $data['year'] ?? '', $format);
|
$dcData = fetchFanartTv($data['title'], $data['year'] ?? '', $format, $pdo);
|
||||||
if (!empty($dcData['poster'])) {
|
if (!empty($dcData['poster'])) {
|
||||||
$data['poster'] = $dcData['poster'];
|
$data['poster'] = $dcData['poster'];
|
||||||
}
|
}
|
||||||
@@ -614,7 +584,7 @@ switch ($action) {
|
|||||||
// Récupération jaquette via DVDCover API
|
// Récupération jaquette via DVDCover API
|
||||||
$cleanTitleForDC = cleanTitle($title);
|
$cleanTitleForDC = cleanTitle($title);
|
||||||
if (!empty($cleanTitleForDC)) {
|
if (!empty($cleanTitleForDC)) {
|
||||||
$dcData = fetchDVDCover($cleanTitleForDC, $year, $format);
|
$dcData = fetchFanartTv($cleanTitleForDC, $year, $format, $pdo);
|
||||||
if (!empty($dcData)) {
|
if (!empty($dcData)) {
|
||||||
if (!empty($dcData['poster'])) {
|
if (!empty($dcData['poster'])) {
|
||||||
$poster = $dcData['poster'];
|
$poster = $dcData['poster'];
|
||||||
|
|||||||
Reference in New Issue
Block a user