Actualiser api.php
This commit is contained in:
@@ -93,23 +93,57 @@ function httpGet($url, $timeout = 3, $ua = null) {
|
||||
return $res ?: null;
|
||||
}
|
||||
|
||||
// Vérifie si une URL existe (HEAD request)
|
||||
function urlExists($url, $timeout = 3) {
|
||||
if (!function_exists('curl_init')) return 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);
|
||||
// OPTIMISATION MAJEURE : Vérification des URLs en parallèle
|
||||
function checkUrlsParallel($urls, $timeout = 3) {
|
||||
if (empty($urls)) return false;
|
||||
if (!function_exists('curl_multi_init')) return false;
|
||||
|
||||
$multiHandle = curl_multi_init();
|
||||
$curlHandles = [];
|
||||
|
||||
foreach ($urls as $url) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_NOBODY => true, // On télécharge juste l'entête, pas l'image
|
||||
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_multi_add_handle($multiHandle, $ch);
|
||||
$curlHandles[] = $ch;
|
||||
}
|
||||
|
||||
$active = null;
|
||||
$validUrl = false;
|
||||
|
||||
do {
|
||||
$status = curl_multi_exec($multiHandle, $active);
|
||||
if ($active) curl_multi_select($multiHandle, 0.1);
|
||||
|
||||
while ($info = curl_multi_info_read($multiHandle)) {
|
||||
$ch = $info['handle'];
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
// Si on trouve UNE url valide, on arrête tout immédiatement
|
||||
if ($code >= 200 && $code < 400) {
|
||||
$validUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
||||
break 2;
|
||||
}
|
||||
curl_multi_remove_handle($multiHandle, $ch);
|
||||
}
|
||||
} while ($active && $status == CURLM_OK);
|
||||
|
||||
// Nettoyage de la mémoire
|
||||
foreach ($curlHandles as $ch) {
|
||||
curl_multi_remove_handle($multiHandle, $ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
curl_multi_close($multiHandle);
|
||||
|
||||
return $validUrl;
|
||||
}
|
||||
|
||||
function cleanTitle($title) {
|
||||
@@ -134,16 +168,13 @@ function extractYear($dateStr) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// ── COVERCENTURY.COM ──
|
||||
// Structure : https://www.covercentury.com/covers/{format}/{première_lettre}/{Nom_Normalisé}{numéro}.jpg
|
||||
// Exemple : https://www.covercentury.com/covers/dvd/t/The_Matrix_Reloaded1.jpg
|
||||
// ── COVERCENTURY.COM (Version Parallélisée) ──
|
||||
function fetchCoverCentury($title, $year = '', $format = 'bluray') {
|
||||
if (empty($title)) return null;
|
||||
|
||||
$cleanTitle = cleanTitle($title);
|
||||
if (empty($cleanTitle)) return null;
|
||||
|
||||
// Mapping des formats pour CoverCentury
|
||||
$formatMap = [
|
||||
'4k ultra hd' => '4kultrahd',
|
||||
'4k' => '4kultrahd',
|
||||
@@ -153,80 +184,67 @@ function fetchCoverCentury($title, $year = '', $format = 'bluray') {
|
||||
];
|
||||
$ccFormat = $formatMap[strtolower($format)] ?? 'bluray';
|
||||
|
||||
// Normaliser le titre pour CoverCentury
|
||||
// Ex: "The Matrix" → "The_Matrix"
|
||||
// CoverCentury utilise souvent le titre anglais, on va essayer plusieurs variantes
|
||||
$titleVariants = [];
|
||||
|
||||
// Variante 1 : titre original nettoyé
|
||||
$normalized = $cleanTitle;
|
||||
$normalized = preg_replace('/[^a-zA-Z0-9\s]/', '', $normalized);
|
||||
$normalized = trim($normalized);
|
||||
$normalized = preg_replace('/\s+/', '_', $normalized);
|
||||
$normalized = trim(preg_replace('/\s+/', '_', preg_replace('/[^a-zA-Z0-9\s]/', '', $cleanTitle)));
|
||||
if (!empty($normalized)) $titleVariants[] = $normalized;
|
||||
|
||||
// Variante 2 : sans article au début (The, Le, La, Les)
|
||||
$withoutArticle = preg_replace('/^(The|Le|La|Les|Un|Une|A)\s+/i', '', $cleanTitle);
|
||||
$withoutArticle = preg_replace('/[^a-zA-Z0-9\s]/', '', $withoutArticle);
|
||||
$withoutArticle = trim($withoutArticle);
|
||||
$withoutArticle = preg_replace('/\s+/', '_', $withoutArticle);
|
||||
$withoutArticle = trim(preg_replace('/\s+/', '_', preg_replace('/[^a-zA-Z0-9\s]/', '', preg_replace('/^(The|Le|La|Les|Un|Une|A)\s+/i', '', $cleanTitle))));
|
||||
if (!empty($withoutArticle) && $withoutArticle !== $normalized) {
|
||||
$titleVariants[] = $withoutArticle;
|
||||
}
|
||||
|
||||
// Variante 3 : ajouter l'article "The_" si absent
|
||||
if (!preg_match('/^The_/i', $normalized)) {
|
||||
$withThe = 'The_' . $normalized;
|
||||
if (!in_array($withThe, $titleVariants)) {
|
||||
$titleVariants[] = $withThe;
|
||||
}
|
||||
$titleVariants[] = 'The_' . $normalized;
|
||||
}
|
||||
|
||||
// Construire toutes les URLs candidates
|
||||
$candidates = [];
|
||||
// Groupement 1 : Le format exact (Testé en parallèle)
|
||||
$primaryCandidates = [];
|
||||
foreach ($titleVariants as $variant) {
|
||||
if (empty($variant)) continue;
|
||||
$firstLetter = strtolower(substr($variant, 0, 1));
|
||||
|
||||
// Essayer avec différents suffixes numériques (1, 2, 3, etc.)
|
||||
$primaryCandidates[] = "https://www.covercentury.com/covers/{$ccFormat}/{$firstLetter}/{$variant}.jpg";
|
||||
for ($i = 1; $i <= 5; $i++) {
|
||||
$candidates[] = "https://www.covercentury.com/covers/{$ccFormat}/{$firstLetter}/{$variant}{$i}.jpg";
|
||||
}
|
||||
// Et sans numéro
|
||||
$candidates[] = "https://www.covercentury.com/covers/{$ccFormat}/{$firstLetter}/{$variant}.jpg";
|
||||
}
|
||||
|
||||
// Tester chaque URL
|
||||
foreach ($candidates as $url) {
|
||||
if (urlExists($url, 2)) {
|
||||
return [
|
||||
'poster' => $url,
|
||||
'title' => $cleanTitle,
|
||||
'format' => $format,
|
||||
];
|
||||
$primaryCandidates[] = "https://www.covercentury.com/covers/{$ccFormat}/{$firstLetter}/{$variant}{$i}.jpg";
|
||||
}
|
||||
}
|
||||
|
||||
// Si aucun format ne marche, essayer les autres formats
|
||||
// On teste toutes les URLs du format désiré d'un seul coup (ultra rapide)
|
||||
$validUrl = checkUrlsParallel($primaryCandidates, 2);
|
||||
|
||||
if ($validUrl) {
|
||||
return [
|
||||
'poster' => $validUrl,
|
||||
'title' => $cleanTitle,
|
||||
'format' => $format,
|
||||
];
|
||||
}
|
||||
|
||||
// Groupement 2 : Si échec, on cherche sur les autres formats en parallèle
|
||||
$fallbackCandidates = [];
|
||||
$otherFormats = ['dvd', 'bluray', '4kultrahd'];
|
||||
foreach ($otherFormats as $altFormat) {
|
||||
if ($altFormat === $ccFormat) continue;
|
||||
foreach ($titleVariants as $variant) {
|
||||
if (empty($variant)) continue;
|
||||
$firstLetter = strtolower(substr($variant, 0, 1));
|
||||
$fallbackCandidates[] = "https://www.covercentury.com/covers/{$altFormat}/{$firstLetter}/{$variant}.jpg";
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$url = "https://www.covercentury.com/covers/{$altFormat}/{$firstLetter}/{$variant}{$i}.jpg";
|
||||
if (urlExists($url, 2)) {
|
||||
return [
|
||||
'poster' => $url,
|
||||
'title' => $cleanTitle,
|
||||
'format' => $format,
|
||||
];
|
||||
}
|
||||
$fallbackCandidates[] = "https://www.covercentury.com/covers/{$altFormat}/{$firstLetter}/{$variant}{$i}.jpg";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$validUrl = checkUrlsParallel($fallbackCandidates, 2);
|
||||
|
||||
if ($validUrl) {
|
||||
return [
|
||||
'poster' => $validUrl,
|
||||
'title' => $cleanTitle,
|
||||
'format' => $format,
|
||||
];
|
||||
}
|
||||
|
||||
error_log("CoverCentury: Aucune jaquette trouvée pour '$title'");
|
||||
return null;
|
||||
}
|
||||
@@ -366,12 +384,14 @@ switch ($action) {
|
||||
";
|
||||
$result = $pdo->query($sql)->fetchAll();
|
||||
|
||||
foreach ($result as $row) {
|
||||
// CORRECTION BUG: L'esperluette "&" est indispensable pour modifier la variable dans le tableau
|
||||
foreach ($result as &$row) {
|
||||
if ($row['rating'] !== null) {
|
||||
$ratingVal = (float)$row['rating'];
|
||||
$row['rating'] = ($ratingVal == floor($ratingVal)) ? (int)$ratingVal : $ratingVal;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
echo json_encode($result);
|
||||
break;
|
||||
@@ -409,7 +429,6 @@ switch ($action) {
|
||||
}
|
||||
|
||||
if ($type === 'videotheque') {
|
||||
// CoverCentury pour vidéothèque
|
||||
$format = $result['format'] ?: 'Blu-ray';
|
||||
$ccData = fetchCoverCentury($titleForSearch, $result['year'], $format);
|
||||
if (!empty($ccData)) {
|
||||
@@ -455,7 +474,6 @@ switch ($action) {
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]);
|
||||
} else {
|
||||
// Vidéothèque : CoverCentury pour la jaquette
|
||||
if (empty($data['poster']) && !empty($data['title'])) {
|
||||
$format = $data['format'] ?: 'Blu-ray';
|
||||
$ccData = fetchCoverCentury($data['title'], $data['year'] ?? '', $format);
|
||||
@@ -498,6 +516,34 @@ switch ($action) {
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
// OPTIMISATION MAJEURE : On prépare les requêtes SQL UNE SEULE FOIS en dehors de la boucle
|
||||
$sqlVideotheque = "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)";
|
||||
$stmtVideotheque = $pdo->prepare($sqlVideotheque);
|
||||
|
||||
$sqlCritiques = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
title=VALUES(title), year=VALUES(year),
|
||||
rating=VALUES(rating),
|
||||
review=IF(VALUES(review)!='',VALUES(review),review),
|
||||
director=IF(VALUES(director)!='',VALUES(director),director),
|
||||
poster=IF(VALUES(poster)!='',VALUES(poster),poster),
|
||||
streaming=IF(VALUES(streaming)!='',VALUES(streaming),streaming)";
|
||||
$stmtCritiques = $pdo->prepare($sqlCritiques);
|
||||
|
||||
foreach ($items as $rowData) {
|
||||
$title = $rowData['title'] ?? $rowData['Name'] ?? $rowData['Title'] ?? 'Sans titre';
|
||||
$publishDate = $rowData['publish_date'] ?? $rowData['Year'] ?? $rowData['year'] ?? $rowData['Date'] ?? '';
|
||||
@@ -536,7 +582,6 @@ switch ($action) {
|
||||
$poster = $rowData['poster'] ?? '';
|
||||
$director = '';
|
||||
|
||||
// Récupération jaquette via CoverCentury
|
||||
$cleanTitleForCC = cleanTitle($title);
|
||||
if (!empty($cleanTitleForCC)) {
|
||||
$ccData = fetchCoverCentury($cleanTitleForCC, $year, $format);
|
||||
@@ -550,22 +595,8 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
|
||||
$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, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $description, $actors]);
|
||||
// Exécution avec la requête préparée hors de la boucle
|
||||
$stmtVideotheque->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $description, $actors]);
|
||||
|
||||
} else {
|
||||
$ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? '';
|
||||
@@ -585,17 +616,8 @@ switch ($action) {
|
||||
}
|
||||
if (empty($streaming)) $streaming = 'Support physique / Cinéma';
|
||||
|
||||
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
title=VALUES(title), year=VALUES(year),
|
||||
rating=VALUES(rating),
|
||||
review=IF(VALUES(review)!='',VALUES(review),review),
|
||||
director=IF(VALUES(director)!='',VALUES(director),director),
|
||||
poster=IF(VALUES(poster)!='',VALUES(poster),poster),
|
||||
streaming=IF(VALUES(streaming)!='',VALUES(streaming),streaming)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]);
|
||||
// Exécution avec la requête préparée hors de la boucle
|
||||
$stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]);
|
||||
}
|
||||
$imported++;
|
||||
}
|
||||
@@ -621,7 +643,6 @@ switch ($action) {
|
||||
|
||||
$result = ['title' => $title, 'year' => $year, 'format' => $format];
|
||||
|
||||
// Afficher les variantes testées
|
||||
$cleanTitle = cleanTitle($title);
|
||||
$normalized = preg_replace('/[^a-zA-Z0-9\s]/', '', $cleanTitle);
|
||||
$normalized = trim(preg_replace('/\s+/', '_', $normalized));
|
||||
|
||||
Reference in New Issue
Block a user