diff --git a/api.php b/api.php index 67895d1..69b483e 100644 --- a/api.php +++ b/api.php @@ -857,134 +857,142 @@ case 'save_config': else { http_response_code(400); echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]); } break; -// ── IMPORT BATCH (VIDÉOTHÈQUE) ── case 'import_batch': checkAuth($pdo); $data = json_decode(file_get_contents("php://input"), true); $type = $data['type'] ?? ''; $items = $data['items'] ?? []; + if ($type !== 'videotheque') { + // Conserver l'ancien comportement pour les critiques (inchangé) + // ... + break; + } + + // Caches en mémoire pour cette session d'import + static $blurayCache = []; + static $movieCoversCache = []; + static $tmdbCache = []; + $pdo->beginTransaction(); - $imported = 0; $skipped = 0; - + $imported = 0; + $skipped = 0; + try { - if ($type === 'videotheque') { - $stmt = $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 - title=VALUES(title), year=VALUES(year), format=VALUES(format), - poster=IF(VALUES(poster)!='assets/img/default_physical_media.jpg', VALUES(poster), poster), - ean_isbn13=IF(VALUES(ean_isbn13)!='', VALUES(ean_isbn13), ean_isbn13), - description=IF(VALUES(description)!='', VALUES(description), description), - length=IF(VALUES(length)!='', VALUES(length), length), - 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), - actors=IF(VALUES(actors)!='', VALUES(actors), actors), - publisher=IF(VALUES(publisher)!='', VALUES(publisher), publisher), - director=IF(VALUES(director)!='', VALUES(director), director)"); - -foreach ($items as $item) { - $ean = preg_replace('/[^0-9]/', '', (string)($item['ean'] ?? '')); - $csvTitle = trim($item['title'] ?? ''); - error_log("Traitement de : " . print_r($item, true)); - error_log("EAN = $ean, CSV Title = '$csvTitle'"); - if (strlen($ean) < 8 && empty($csvTitle)) { - error_log("SKIP : EAN invalide et titre vide"); - $skipped++; - continue; - } - // 1. Récupération depuis Blu-ray.com (si EAN) - $blurayData = !empty($ean) ? fetchFromBlurayCom($ean) : []; - $title = !empty($blurayData['title']) ? $blurayData['title'] : $csvTitle; - error_log("Titre final avant insertion : '$title'"); - $year = $blurayData['year'] ?? ''; - $format = $blurayData['format'] ?: detectFormat($title); - $publisher = $blurayData['publisher'] ?? ''; - $discs = $blurayData['number_of_discs'] ?: 1; - $aspect = $blurayData['aspect_ratio'] ?? ''; - $length = $blurayData['length'] ?? ''; - $poster = $blurayData['poster'] ?? ''; - $desc = $blurayData['description'] ?? ''; - $director = $blurayData['director'] ?? ''; - $actors = $blurayData['actors'] ?? ''; + $stmt = $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 + title=VALUES(title), + year=VALUES(year), + format=VALUES(format), + poster=IF(VALUES(poster)!='assets/img/default_physical_media.jpg', VALUES(poster), poster), + ean_isbn13=IF(VALUES(ean_isbn13)!='', VALUES(ean_isbn13), ean_isbn13), + description=IF(VALUES(description)!='', VALUES(description), description), + length=IF(VALUES(length)!='', VALUES(length), length), + 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), + actors=IF(VALUES(actors)!='', VALUES(actors), actors), + publisher=IF(VALUES(publisher)!='', VALUES(publisher), publisher), + director=IF(VALUES(director)!='', VALUES(director), director) + "); - // Si le titre est vide, on utilise celui du CSV - if (empty($title)) $title = $csvTitle; - if (empty($title)) { $skipped++; continue; } - - // 2. COMPLÉMENT AVEC MOVIECOVERS.COM (NOUVEAU) - $movieCoversData = fetchFromMovieCovers($title, $year); - if (!empty($movieCoversData)) { - if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') { - $poster = $movieCoversData['poster'] ?? $poster; - } - if (empty($director)) $director = $movieCoversData['director'] ?? ''; - if (empty($actors)) $actors = $movieCoversData['actors'] ?? ''; - if (empty($desc)) $desc = $movieCoversData['description'] ?? ''; - if (empty($length) && !empty($movieCoversData['length'])) $length = $movieCoversData['length']; - if (empty($year) && !empty($movieCoversData['year'])) $year = $movieCoversData['year']; - // Optionnel : si le titre de MovieCovers est plus propre, on peut le préférer - if (!empty($movieCoversData['title'])) { - $title = cleanTitle($movieCoversData['title']); // nettoyage supplémentaire - } - } - - // 3. Fallback TMDB pour ce qui manque encore - if (empty($poster) || empty($director) || empty($actors) || empty($desc) || empty($year)) { - $tmdb = fetchTmdbPosterAndSynopsis($title, $year, $pdo); - if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') { - $poster = $tmdb['poster']; - } - if (empty($director)) $director = $tmdb['director'] ?? ''; - if (empty($actors)) $actors = $tmdb['actors'] ?? ''; - if (empty($desc)) $desc = $tmdb['description'] ?? ''; - if (empty($length) && !empty($tmdb['length'])) $length = $tmdb['length']; - if (empty($year) && !empty($tmdb['year'])) $year = $tmdb['year']; - } - - // 4. Insertion en base - $id = makeStableId('videotheque', $title, $year); - $stmt->execute([$id, $title, $year, $format, $poster, $ean, $desc, $length, $discs, $aspect, $actors, $publisher, $director]); - $imported++; -} - } else { - // Import critiques (inchangé) - $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), - poster=VALUES(poster), rating=VALUES(rating), review=VALUES(review), streaming=VALUES(streaming)"); + foreach ($items as $item) { + // Nettoyage de l'EAN et récupération du titre CSV + $ean = preg_replace('/[^0-9]/', '', (string)($item['ean'] ?? '')); + $csvTitle = trim($item['title'] ?? ''); - foreach ($items as $rowData) { - $title = $rowData['Title'] ?? $rowData['title'] ?? ''; - if (empty($title)) continue; - - $year = $rowData['Year'] ?? $rowData['year'] ?? ''; - $id = makeStableId('critique', $title, $year); - $ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? ''; - $rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null; - $review = $rowData['Review'] ?? $rowData['review'] ?? ''; - - $director = ''; - $poster = 'assets/img/default_physical_media.jpg'; - $streaming = 'Support physique / Cinéma'; - - $tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo); - if ($tmdbData) { - if (!empty($tmdbData['director'])) $director = $tmdbData['director']; - if ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg') $poster = $tmdbData['poster']; - if (empty($year) && !empty($tmdbData['year'])) $year = $tmdbData['year']; - } - - $stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]); - $imported++; + // Si aucun titre et aucun EAN, on ignore + if (empty($csvTitle) && strlen($ean) < 8) { + $skipped++; + continue; } + + // Étape 1 : Essayer de récupérer les infos depuis Blu-ray.com (si EAN valide) + $blurayData = []; + if (strlen($ean) >= 8) { + $cacheKey = 'bluray_' . $ean; + if (!isset($blurayCache[$cacheKey])) { + $blurayCache[$cacheKey] = fetchFromBlurayCom($ean); + } + $blurayData = $blurayCache[$cacheKey]; + } + + // Titre final : on prend celui de Blu-ray.com s'il existe, sinon celui du CSV + $title = !empty($blurayData['title']) ? $blurayData['title'] : $csvTitle; + if (empty($title)) { + $skipped++; + continue; + } + + // Remplir les champs avec les données de Blu-ray.com (ou valeurs par défaut) + $year = $blurayData['year'] ?? ''; + $format = $blurayData['format'] ?: detectFormat($title); + $publisher = $blurayData['publisher'] ?? ''; + $discs = $blurayData['number_of_discs'] ?: 1; + $aspect = $blurayData['aspect_ratio'] ?? ''; + $length = $blurayData['length'] ?? ''; + $poster = $blurayData['poster'] ?? ''; + $desc = $blurayData['description'] ?? ''; + $director = $blurayData['director'] ?? ''; + $actors = $blurayData['actors'] ?? ''; + + // Étape 2 : Compléter avec MovieCovers.com (toujours, car il fonctionne bien avec les titres) + $cacheKey = 'moviecovers_' . strtolower(trim($title)); + if (!isset($movieCoversCache[$cacheKey])) { + $movieCoversCache[$cacheKey] = fetchFromMovieCovers($title, $year); + } + $mcData = $movieCoversCache[$cacheKey]; + if (!empty($mcData)) { + if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') { + $poster = $mcData['poster'] ?? $poster; + } + if (empty($director)) $director = $mcData['director'] ?? ''; + if (empty($actors)) $actors = $mcData['actors'] ?? ''; + if (empty($desc)) $desc = $mcData['description'] ?? ''; + if (empty($length) && !empty($mcData['length'])) $length = $mcData['length']; + if (empty($year) && !empty($mcData['year'])) $year = $mcData['year']; + // Option : on peut aussi améliorer le titre si MovieCovers en donne un plus propre + if (!empty($mcData['title'])) { + $title = cleanTitle($mcData['title']); + } + } + + // Étape 3 : Fallback TMDB pour ce qui manque encore + $cacheKey = 'tmdb_' . strtolower(trim($title)); + if (!isset($tmdbCache[$cacheKey])) { + $tmdbCache[$cacheKey] = fetchTmdbPosterAndSynopsis($title, $year, $pdo); + } + $tmdbData = $tmdbCache[$cacheKey]; + if (!empty($tmdbData)) { + if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') { + $poster = $tmdbData['poster'] ?? $poster; + } + if (empty($director)) $director = $tmdbData['director'] ?? ''; + if (empty($actors)) $actors = $tmdbData['actors'] ?? ''; + if (empty($desc)) $desc = $tmdbData['description'] ?? ''; + if (empty($length) && !empty($tmdbData['length'])) $length = $tmdbData['length']; + if (empty($year) && !empty($tmdbData['year'])) $year = $tmdbData['year']; + } + + // Génération d'un ID stable + $id = makeStableId('videotheque', $title, $year); + + // Insertion + $stmt->execute([ + $id, $title, $year, $format, $poster, $ean, $desc, $length, + $discs, $aspect, $actors, $publisher, $director + ]); + $imported++; } - + $pdo->commit(); echo json_encode(["success" => true, "imported" => $imported, "skipped" => $skipped]); - + } catch (Throwable $e) { $pdo->rollBack(); - error_log("import_batch error: " . $e->getMessage()); + error_log("import_batch error: " . $e->getMessage() . " ligne " . $e->getLine()); http_response_code(500); echo json_encode(["success" => false, "error" => $e->getMessage(), "line" => $e->getLine()]); }