127 lines
5.1 KiB
PHP
127 lines
5.1 KiB
PHP
<?php
|
|
// Import d'une sauvegarde JSON (créée par exportData.php)
|
|
// ATTENTION : les données actuelles des tables présentes dans le fichier sont ÉCRASÉES
|
|
|
|
// On démarre la session
|
|
require_once(__DIR__ . '/../functions/security.php');
|
|
// On ajoute la DB
|
|
require_once('../functions/databaseConnection.php');
|
|
// On ajoute les logs Discord
|
|
require_once('../functions/sendLogs.php');
|
|
|
|
// Si l'utilisateur n'est pas admin il ne peut pas executer le reste du script
|
|
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
|
|
header('Location: ../pages/home.php');
|
|
exit;
|
|
}
|
|
|
|
// Vérification du jeton CSRF : bloque les requêtes forgées depuis un autre site
|
|
requireCsrfToken();
|
|
|
|
// La requête doit être un POST avec un fichier sinon on refuse
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['jsonfile']) || $_FILES['jsonfile']['error'] !== UPLOAD_ERR_OK) {
|
|
header('Location: ../pages/admin.php');
|
|
exit;
|
|
}
|
|
|
|
// Lecture et décodage du fichier JSON
|
|
$contenu = file_get_contents($_FILES['jsonfile']['tmp_name']);
|
|
$donnees = json_decode($contenu, true);
|
|
|
|
if (!is_array($donnees)) {
|
|
die("Erreur : le fichier n'est pas un JSON valide.");
|
|
}
|
|
|
|
// Même liste blanche que l'export : seules ces tables / colonnes peuvent être importées.
|
|
// L'ORDRE COMPTE : chaque table de PDF associée (project_pdfs...) doit être importée
|
|
// juste après sa table parente (projects...), car sa clé étrangère exige que la ligne
|
|
// parente existe déjà (voir migration Juillet 2026 (6))
|
|
$tables = [
|
|
'settings' => ['name', 'value'],
|
|
'skills' => ['id', 'title', 'icon', 'items', 'position', 'created_at'],
|
|
'projects' => ['id', 'title', 'status', 'tags', 'description', 'image_url', 'markdown', 'link_url', 'created_at'],
|
|
'project_pdfs' => ['project_id', 'pdf_filename', 'pdf_data'],
|
|
'experiences' => ['id', 'title', 'status', 'xptype', 'tags', 'description', 'duration', 'image_url', 'markdown', 'link_url', 'created_at'],
|
|
'experience_pdfs' => ['experience_id', 'pdf_filename', 'pdf_data'],
|
|
'schools' => ['id', 'title', 'status', 'tags', 'description', 'duration', 'image_url', 'markdown', 'link_url', 'created_at'],
|
|
'school_pdfs' => ['school_id', 'pdf_filename', 'pdf_data'],
|
|
'users' => ['id', 'username', 'password', 'role', 'created_at', 'last_login'],
|
|
];
|
|
|
|
// Colonnes binaires : encodées en base64 par exportData.php, à redécoder ici
|
|
$colonnesBinaires = [
|
|
'project_pdfs' => ['pdf_data'],
|
|
'experience_pdfs' => ['pdf_data'],
|
|
'school_pdfs' => ['pdf_data'],
|
|
];
|
|
|
|
try {
|
|
// Transaction : si une erreur survient, TOUT est annulé (la base reste intacte)
|
|
$dbh->beginTransaction();
|
|
|
|
foreach ($tables as $table => $colonnesAutorisees) {
|
|
// On ne touche qu'aux tables présentes dans le fichier
|
|
if (!isset($donnees[$table]) || !is_array($donnees[$table])) {
|
|
continue;
|
|
}
|
|
|
|
// Sécurité : on refuse de vider la table users si la sauvegarde n'en contient aucun
|
|
// (sinon l'admin se retrouverait enfermé dehors sans aucun compte)
|
|
if ($table === 'users' && count($donnees[$table]) === 0) {
|
|
continue;
|
|
}
|
|
|
|
// On écrase les données existantes de la table
|
|
$dbh->exec('DELETE FROM `' . $table . '`');
|
|
|
|
// Colonnes binaires (PDF) de cette table, à redécoder du base64
|
|
$binaires = $colonnesBinaires[$table] ?? [];
|
|
|
|
// Puis on insère chaque ligne de la sauvegarde
|
|
foreach ($donnees[$table] as $ligne) {
|
|
if (!is_array($ligne)) {
|
|
continue;
|
|
}
|
|
|
|
// On ne garde que les colonnes autorisées ET présentes dans la ligne
|
|
$colonnes = array_values(array_intersect($colonnesAutorisees, array_keys($ligne)));
|
|
if (empty($colonnes)) {
|
|
continue;
|
|
}
|
|
|
|
$placeholders = array_map(function ($c) { return ':' . $c; }, $colonnes);
|
|
$stmt = $dbh->prepare(
|
|
'INSERT INTO `' . $table . '` (`' . implode('`, `', $colonnes) . '`) VALUES (' . implode(', ', $placeholders) . ')'
|
|
);
|
|
|
|
foreach ($colonnes as $colonne) {
|
|
$valeur = $ligne[$colonne];
|
|
|
|
// Les colonnes binaires (pdf_data) sont ré-encodées en base64 par l'export : on les redécode
|
|
if (in_array($colonne, $binaires, true) && $valeur !== null) {
|
|
$stmt->bindValue(':' . $colonne, base64_decode($valeur), PDO::PARAM_LOB);
|
|
} else {
|
|
$stmt->bindValue(':' . $colonne, $valeur);
|
|
}
|
|
}
|
|
|
|
$stmt->execute();
|
|
}
|
|
}
|
|
|
|
// Tout s'est bien passé : on valide définitivement
|
|
$dbh->commit();
|
|
|
|
} catch (Exception $e) {
|
|
// En cas d'erreur on annule tout : la base revient à son état d'avant l'import
|
|
$dbh->rollBack();
|
|
die("Erreur pendant l'import, aucune donnée n'a été modifiée : " . $e->getMessage());
|
|
}
|
|
|
|
// Log Discord
|
|
sendLog("Import d'une sauvegarde JSON : données du site écrasées");
|
|
|
|
// On renvoie l'utilisateur sur admin.php (?import=1 déclenche la notification de succès)
|
|
header('Location: ../pages/admin.php?import=1');
|
|
exit;
|