Actualiser api.php

This commit is contained in:
2026-06-19 14:17:51 +02:00
parent 22aabe7d49
commit a97ece2e0a
+89 -94
View File
@@ -5,21 +5,18 @@ header("Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
define('ENCRYPTION_KEY', 'MaCleSecreteSuperRobuste123!');
try {
$pdo = new PDO("mysql:host=localhost;dbname=mon_cinema;charset=utf8mb4", "root", "", [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
// Création des tables (ajout de la table config)
// Création des tables (rating changé en DECIMAL(3,1) pour accepter les notes Letterboxd comme 2.5, 3.5)
$pdo->exec("CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY, username VARCHAR(50) NOT NULL, password_hash VARCHAR(255) NOT NULL
)");
@@ -27,12 +24,12 @@ try {
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)
id BIGINT PRIMARY KEY, title VARCHAR(255) NOT NULL, year VARCHAR(10), director VARCHAR(255),
poster TEXT, rating DECIMAL(3,1) DEFAULT 3.0, 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),
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) {
@@ -48,13 +45,11 @@ function makeStableId($title, $year) {
function checkAuth($pdo) {
$stmtCheck = $pdo->query("SELECT COUNT(*) FROM users");
if ($stmtCheck->fetchColumn() == 0) return true;
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (empty($token) && function_exists('apache_request_headers')) {
$headers = apache_request_headers();
$token = $headers['Authorization'] ?? $headers['authorization'] ?? '';
}
if ($token !== md5(ENCRYPTION_KEY . 'session')) {
http_response_code(403);
echo json_encode(["error" => "Accès interdit."]);
@@ -62,8 +57,6 @@ function checkAuth($pdo) {
}
}
// ── FONCTIONS TMDB & CHIFFREMENT ──
function encryptData($data) {
$iv = openssl_random_pseudo_bytes(16);
$key = hash('sha256', ENCRYPTION_KEY, true);
@@ -93,7 +86,6 @@ function getTmdbApiKey($pdo) {
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 = @file_get_contents($searchUrl);
if (!$searchRes && function_exists('curl_init')) {
@@ -104,14 +96,11 @@ function fetchTmdbData($title, $year, $apiKey) {
curl_close($ch);
}
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'] : '';
$creditsUrl = "https://api.themoviedb.org/3/movie/{$movieId}/credits?api_key={$apiKey}&language=fr-FR";
$creditsRes = @file_get_contents($creditsUrl);
if (!$creditsRes && function_exists('curl_init')) {
@@ -121,7 +110,6 @@ function fetchTmdbData($title, $year, $apiKey) {
$creditsRes = curl_exec($ch);
curl_close($ch);
}
$director = '';
if ($creditsRes) {
$creditsData = json_decode($creditsRes, true);
@@ -134,21 +122,18 @@ function fetchTmdbData($title, $year, $apiKey) {
}
}
}
return ['director' => $director, 'poster' => $poster];
}
// ── ROUTEUR PRINCIPAL ──
$action = $_GET['action'] ?? '';
$data = json_decode(file_get_contents('php://input'), true) ?? [];
switch ($action) {
case 'check_security_status':
$stmt = $pdo->query("SELECT COUNT(*) FROM users");
echo json_encode(["is_blank" => ($stmt->fetchColumn() == 0)]);
break;
case 'login':
$stmt = $pdo->query("SELECT COUNT(*) FROM users");
if ($stmt->fetchColumn() == 0) {
@@ -165,7 +150,7 @@ switch ($action) {
}
}
break;
case 'setup_admin':
case 'update_password':
checkAuth($pdo);
@@ -174,8 +159,7 @@ switch ($action) {
$stmt->execute([':pass' => password_hash($pwd, PASSWORD_BCRYPT)]);
echo json_encode(["success" => true]);
break;
// ── NOUVELLE ACTION : SAUVEGARDE DE LA CLÉ EN BASE ──
case 'save_config':
checkAuth($pdo);
$keyName = $data['key_name'] ?? '';
@@ -190,19 +174,18 @@ switch ($action) {
echo json_encode(["error" => "Données invalides."]);
}
break;
case 'get_films':
$crit = $pdo->query("SELECT *, 'critique' AS type FROM critiques ORDER BY id DESC")->fetchAll();
$video = $pdo->query("SELECT *, 'videotheque' AS type FROM videotheque ORDER BY id DESC")->fetchAll();
echo json_encode(array_merge($crit, $video));
break;
case 'save_film':
checkAuth($pdo);
$type = $data['type'] ?? 'critique';
$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);
@@ -211,7 +194,7 @@ switch ($action) {
if (empty($data['poster'])) $data['poster'] = $tmdbData['poster'];
}
}
if ($type === 'critique') {
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
@@ -219,7 +202,7 @@ switch ($action) {
$stmt = $pdo->prepare($sql);
$stmt->execute([
$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '',
$data['poster'] ?? '', $data['rating'] ?? 3, $data['review'] ?? '', $data['streaming'] ?? ''
$data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $data['streaming'] ?? ''
]);
} else {
$sql = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description)
@@ -235,7 +218,7 @@ switch ($action) {
}
echo json_encode(["success" => true]);
break;
case 'delete_film':
checkAuth($pdo);
$type = $_GET['type'] ?? 'critique';
@@ -246,7 +229,7 @@ switch ($action) {
$stmt->execute([$id]);
echo json_encode(["success" => true]);
break;
case 'bulk_delete':
checkAuth($pdo);
$ids = $data['ids'] ?? [];
@@ -262,81 +245,93 @@ switch ($action) {
echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]);
}
break;
case 'import_csv':
checkAuth($pdo);
if (isset($_FILES['csv_file'])) {
$file = $_FILES['csv_file']['tmp_name'];
$type = $_POST['type'] ?? 'critique';
$tmdbApiKey = getTmdbApiKey($pdo);
// On récupère la clé une seule fois pour tout l'import
$tmdbApiKey = getTmdbApiKey($pdo);
if (($handle = fopen($file, "r")) !== FALSE) {
$header = fgetcsv($handle, 0, ",");
$header = array_map('trim', $header);
while (($row = fgetcsv($handle, 0, ",")) !== FALSE) {
if (count($row) !== count($header)) continue;
$rowData = array_combine($header, $row);
try {
if (($handle = fopen($file, "r")) !== FALSE) {
$header = fgetcsv($handle, 0, ",");
if (!$header) throw new Exception("Impossible de lire l'en-tête du CSV.");
$title = $rowData['Name'] ?? $rowData['title'] ?? 'Sans titre';
$year = $rowData['Year'] ?? $rowData['year'] ?? '0000';
$director = $rowData['Director'] ?? $rowData['director'] ?? '';
$poster = $rowData['Poster'] ?? $rowData['poster'] ?? $rowData['image'] ?? '';
// 🧹 Nettoyage du BOM UTF-8 (très fréquent sur les exports Letterboxd/Excel)
$header[0] = str_replace("\xEF\xBB\xBF", '', $header[0]);
$header = array_map('trim', $header);
// 🔍 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'];
$imported = 0;
while (($row = fgetcsv($handle, 0, ",")) !== FALSE) {
if (count($row) !== count($header)) continue; // Ignore les lignes vides ou mal formées
$rowData = array_combine($header, $row);
$title = $rowData['Name'] ?? $rowData['title'] ?? 'Sans titre';
$year = $rowData['Year'] ?? $rowData['year'] ?? '0000';
$director = $rowData['Director'] ?? $rowData['director'] ?? '';
$poster = $rowData['Poster'] ?? $rowData['poster'] ?? $rowData['image'] ?? '';
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);
if ($type === 'critique') {
// 🌟 Conservation de la précision Letterboxd (2.5, 3.5, etc.)
$rating = isset($rowData['Rating']) && $rowData['Rating'] !== '' ? (float)$rowData['Rating'] : 3.0;
$review = $rowData['Review'] ?? $rowData['review'] ?? '';
$streaming = $rowData['Streaming'] ?? $rowData['streaming'] ?? '';
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
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]);
} else {
$format = $rowData['format'] ?? $rowData['Format'] ?? '';
$length = $rowData['length'] ?? $rowData['Length'] ?? '';
$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->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $desc]);
}
$imported++;
}
$id = makeStableId($title, $year);
if ($type === 'critique') {
$rating = isset($rowData['Rating']) ? (int)round($rowData['Rating'] * 1) : 3;
$review = $rowData['Review'] ?? $rowData['review'] ?? '';
$streaming = $rowData['Streaming'] ?? $rowData['streaming'] ?? '';
$sql = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
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]);
} else {
$format = $rowData['format'] ?? $rowData['Format'] ?? '';
$length = $rowData['length'] ?? $rowData['Length'] ?? '';
$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->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $desc]);
}
fclose($handle);
echo json_encode(["success" => true, "imported" => $imported]);
} else {
throw new Exception("Impossible d'ouvrir le fichier.");
}
fclose($handle);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(["error" => "Erreur lors de l'import : " . $e->getMessage()]);
}
echo json_encode(["success" => true]);
} else {
http_response_code(400);
echo json_encode(["error" => "Aucun fichier reçu."]);