Actualiser api.php

This commit is contained in:
2026-06-19 09:56:11 +02:00
parent 87fbb8085c
commit 644a4bc78b
+172 -35
View File
@@ -3,7 +3,6 @@ header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"); header("Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization"); header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache"); header("Pragma: no-cache");
@@ -20,10 +19,22 @@ try {
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)"); // Création des tables si elles n'existent pas
$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 INT DEFAULT 3, review TEXT, streaming VARCHAR(255))"); $pdo->exec("CREATE TABLE IF NOT EXISTS users (
$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)"); 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 critiques (
id BIGINT PRIMARY KEY, title VARCHAR(255) NOT NULL, year VARCHAR(10), director VARCHAR(255),
poster TEXT, rating INT DEFAULT 3, review TEXT, streaming VARCHAR(255)
)");
$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
)");
} catch (\PDOException $e) { } catch (\PDOException $e) {
echo json_encode(["error" => "Erreur BDD : " . $e->getMessage()]); echo json_encode(["error" => "Erreur BDD : " . $e->getMessage()]);
exit; exit;
@@ -43,6 +54,7 @@ function checkAuth($pdo) {
$headers = apache_request_headers(); $headers = apache_request_headers();
$token = $headers['Authorization'] ?? $headers['authorization'] ?? ''; $token = $headers['Authorization'] ?? $headers['authorization'] ?? '';
} }
if ($token !== md5(ENCRYPTION_KEY . 'session')) { if ($token !== md5(ENCRYPTION_KEY . 'session')) {
http_response_code(403); http_response_code(403);
echo json_encode(["error" => "Accès interdit."]); echo json_encode(["error" => "Accès interdit."]);
@@ -50,6 +62,84 @@ function checkAuth($pdo) {
} }
} }
// ── FONCTIONS TMDB & CHIFFREMENT ──
function tmdbHttpGet($url) {
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
return @file_get_contents($url);
}
function getTmdbApiKey($pdo) {
$stmt = $pdo->prepare("SELECT key_value FROM config WHERE key_name = 'tmdb_api_key'");
$stmt->execute();
$row = $stmt->fetch();
if (!$row) return null;
$encrypted = $row['key_value'];
$decoded = base64_decode($encrypted);
// Séparation des données et du IV (format base64(data::iv))
if (strpos($decoded, '::') !== false) {
list($encData, $iv) = explode('::', $decoded, 2);
} else {
$encData = $decoded;
$iv = str_repeat("\0", 16);
}
// ⚠️ ADAPTEZ CETTE PARTIE SI VOTRE MÉTHODE DE CHIFFREMENT CÔTÉ FRONT EST DIFFÉRENTE
$key = hash('sha256', ENCRYPTION_KEY, true);
$iv = substr($iv, 0, 16);
$decrypted = openssl_decrypt($encData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decrypted ?: null;
}
function fetchTmdbData($title, $year, $apiKey) {
if (empty($apiKey) || empty($title)) return null;
$searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$apiKey}&query=" . urlencode($title) . "&year={$year}&language=fr-FR";
$searchRes = tmdbHttpGet($searchUrl);
if (!$searchRes) return null;
$searchData = json_decode($searchRes, true);
if (empty($searchData['results'])) return null;
$movie = $searchData['results'][0];
$movieId = $movie['id'];
$poster = !empty($movie['poster_path']) ? "https://image.tmdb.org/t/p/w500" . $movie['poster_path'] : '';
// Récupération du réalisateur
$creditsUrl = "https://api.themoviedb.org/3/movie/{$movieId}/credits?api_key={$apiKey}&language=fr-FR";
$creditsRes = tmdbHttpGet($creditsUrl);
$director = '';
if ($creditsRes) {
$creditsData = json_decode($creditsRes, true);
if (!empty($creditsData['crew'])) {
foreach ($creditsData['crew'] as $crew) {
if ($crew['job'] === 'Director' || $crew['job'] === 'Directing') {
$director = $crew['name'];
break;
}
}
}
}
return [
'director' => $director,
'poster' => $poster
];
}
// ── ROUTEUR PRINCIPAL ──
$action = $_GET['action'] ?? ''; $action = $_GET['action'] ?? '';
$data = json_decode(file_get_contents('php://input'), true) ?? []; $data = json_decode(file_get_contents('php://input'), true) ?? [];
@@ -96,14 +186,36 @@ switch ($action) {
$type = $data['type'] ?? 'critique'; $type = $data['type'] ?? 'critique';
$id = !empty($data['id']) ? $data['id'] : makeStableId($data['title'] ?? '', $data['year'] ?? '0000'); $id = !empty($data['id']) ? $data['id'] : makeStableId($data['title'] ?? '', $data['year'] ?? '0000');
// 🔍 RÉCUPÉRATION AUTO TMDB SI CHAMPS VIDES
if (empty($data['director']) || empty($data['poster'])) {
$apiKey = getTmdbApiKey($pdo);
$tmdbData = fetchTmdbData($data['title'] ?? '', $data['year'] ?? '', $apiKey);
if ($tmdbData) {
if (empty($data['director'])) $data['director'] = $tmdbData['director'];
if (empty($data['poster'])) $data['poster'] = $tmdbData['poster'];
}
}
if ($type === 'critique') { if ($type === 'critique') {
$sql = "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)"; $sql = "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)";
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3, $data['review'] ?? '', $data['streaming'] ?? '']); $stmt->execute([
$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '',
$data['poster'] ?? '', $data['rating'] ?? 3, $data['review'] ?? '', $data['streaming'] ?? ''
]);
} else { } else {
$sql = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=VALUES(director), poster=VALUES(poster), format=VALUES(format), length=VALUES(length), publisher=VALUES(publisher), ean_isbn13=VALUES(ean_isbn13), number_of_discs=VALUES(number_of_discs), aspect_ratio=VALUES(aspect_ratio), description=VALUES(description)"; $sql = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=VALUES(director), poster=VALUES(poster), format=VALUES(format), length=VALUES(length), publisher=VALUES(publisher), ean_isbn13=VALUES(ean_isbn13), number_of_discs=VALUES(number_of_discs), aspect_ratio=VALUES(aspect_ratio), description=VALUES(description)";
$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'] ?? '']); $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'] ?? ''
]);
} }
echo json_encode(["success" => true]); echo json_encode(["success" => true]);
break; break;
@@ -113,7 +225,7 @@ switch ($action) {
$type = $_GET['type'] ?? 'critique'; $type = $_GET['type'] ?? 'critique';
$table = ($type === 'videotheque') ? 'videotheque' : 'critiques'; $table = ($type === 'videotheque') ? 'videotheque' : 'critiques';
$id = $_GET['id'] ?? null; $id = $_GET['id'] ?? null;
if (!$id) break; if (!$id) { http_response_code(400); echo json_encode(["error" => "ID manquant."]); break; }
$stmt = $pdo->prepare("DELETE FROM $table WHERE id = ?"); $stmt = $pdo->prepare("DELETE FROM $table WHERE id = ?");
$stmt->execute([$id]); $stmt->execute([$id]);
echo json_encode(["success" => true]); echo json_encode(["success" => true]);
@@ -129,6 +241,9 @@ switch ($action) {
$stmt = $pdo->prepare("DELETE FROM $table WHERE id IN ($placeholders)"); $stmt = $pdo->prepare("DELETE FROM $table WHERE id IN ($placeholders)");
$stmt->execute($ids); $stmt->execute($ids);
echo json_encode(["success" => true]); echo json_encode(["success" => true]);
} else {
http_response_code(400);
echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]);
} }
break; break;
@@ -138,55 +253,77 @@ switch ($action) {
$file = $_FILES['csv_file']['tmp_name']; $file = $_FILES['csv_file']['tmp_name'];
$type = $_POST['type'] ?? 'critique'; $type = $_POST['type'] ?? 'critique';
if (($handle = fopen($file, "r")) !== FALSE) { // On récupère la clé une seule fois pour tout l'import
// Suppression du BOM si présent (fréquent sur Excel) $tmdbApiKey = getTmdbApiKey($pdo);
$bom = fread($handle, 3);
if ($bom !== "\xEF\xBB\xBF") rewind($handle);
if (($handle = fopen($file, "r")) !== FALSE) {
$header = fgetcsv($handle, 0, ","); $header = fgetcsv($handle, 0, ",");
$header = array_map('trim', $header); $header = array_map('trim', $header);
while (($row = fgetcsv($handle, 0, ",")) !== FALSE) { while (($row = fgetcsv($handle, 0, ",")) !== FALSE) {
while (count($row) < count($header)) $row[] = ''; if (count($row) !== count($header)) continue;
if (count($row) > count($header)) $row = array_slice($row, 0, count($header));
$rowData = array_combine($header, $row); $rowData = array_combine($header, $row);
// Noms de colonnes flexibles pour s'adapter à Letterboxd $title = $rowData['Name'] ?? $rowData['title'] ?? 'Sans titre';
$title = $rowData['Name'] ?? $rowData['title'] ?? $rowData['Title'] ?? '';
if (empty($title)) continue;
$year = $rowData['Year'] ?? $rowData['year'] ?? '0000'; $year = $rowData['Year'] ?? $rowData['year'] ?? '0000';
$director = $rowData['Director'] ?? ''; $director = $rowData['Director'] ?? $rowData['director'] ?? '';
$poster = $rowData['Poster'] ?? ''; $poster = $rowData['Poster'] ?? $rowData['poster'] ?? $rowData['image'] ?? '';
// 🔍 RÉCUPÉRATION AUTO TMDB SI CHAMPS VIDES DANS LE CSV
if (empty($director) || empty($poster)) {
$tmdbData = fetchTmdbData($title, $year, $tmdbApiKey);
if ($tmdbData) {
if (empty($director)) $director = $tmdbData['director'];
if (empty($poster)) $poster = $tmdbData['poster'];
}
}
$id = makeStableId($title, $year); $id = makeStableId($title, $year);
if ($type === 'critique') { if ($type === 'critique') {
$ratingStr = $rowData['Rating'] ?? '3'; $rating = isset($rowData['Rating']) ? (int)round($rowData['Rating'] * 1) : 3;
$rating = (int)round((float)$ratingStr); $review = $rowData['Review'] ?? $rowData['review'] ?? '';
$review = $rowData['Review'] ?? ''; $streaming = $rowData['Streaming'] ?? $rowData['streaming'] ?? '';
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE
rating = VALUES(rating), rating = VALUES(rating),
review = IF(VALUES(review) != '', VALUES(review), review), review = IF(VALUES(review) != '', VALUES(review), review),
director = IF(VALUES(director) != '', VALUES(director), director), director = IF(VALUES(director) != '', VALUES(director), director),
poster = IF(VALUES(poster) != '', VALUES(poster), poster)"; poster = IF(VALUES(poster) != '', VALUES(poster), poster),
streaming = IF(VALUES(streaming) != '', VALUES(streaming), streaming)";
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute([$id, $title, $year, $director, $poster, $rating, $review]); $stmt->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]);
} else { } else {
$sql = "INSERT INTO videotheque (id, title, year, director, poster) $format = $rowData['format'] ?? $rowData['Format'] ?? '';
VALUES (?, ?, ?, ?, ?) $length = $rowData['length'] ?? $rowData['Length'] ?? '';
ON DUPLICATE KEY UPDATE title=VALUES(title)"; $publisher = $rowData['publisher'] ?? $rowData['Publisher'] ?? '';
$ean = $rowData['ean_isbn13'] ?? $rowData['EAN'] ?? '';
$discs = $rowData['number_of_discs'] ?? 1;
$aspect = $rowData['aspect_ratio'] ?? '';
$desc = $rowData['description'] ?? $rowData['Description'] ?? '';
$sql = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
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)";
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute([$id, $title, $year, $director, $poster]); $stmt->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $desc]);
} }
} }
fclose($handle); fclose($handle);
} }
echo json_encode(["success" => true]); echo json_encode(["success" => true]);
} else {
http_response_code(400);
echo json_encode(["error" => "Aucun fichier reçu."]);
} }
break; break;
} }