78 lines
3.3 KiB
PHP
78 lines
3.3 KiB
PHP
<?php
|
|
// Export de toutes les données du site en JSON (comme un dbdump mais en JSON)
|
|
// Le fichier téléchargé peut ensuite être ré-importé via importData.php
|
|
|
|
// On démarre la session
|
|
session_start();
|
|
// 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;
|
|
}
|
|
|
|
// Liste blanche des tables et colonnes exportées (empêche toute injection via noms de colonnes)
|
|
$tables = [
|
|
'settings' => ['name', 'value'],
|
|
'skills' => ['id', 'title', 'icon', 'items', 'position', 'created_at'],
|
|
'projects' => ['id', 'title', 'status', 'tags', 'description', 'image_url', 'markdown', 'link_url', 'pdf_data', 'pdf_filename', 'created_at'],
|
|
'experiences' => ['id', 'title', 'status', 'xptype', 'tags', 'description', 'duration', 'image_url', 'markdown', 'link_url', 'pdf_data', 'pdf_filename', 'created_at'],
|
|
'schools' => ['id', 'title', 'status', 'tags', 'description', 'duration', 'image_url', 'markdown', 'link_url', 'pdf_data', 'pdf_filename', 'created_at'],
|
|
'users' => ['id', 'username', 'password', 'role', 'created_at', 'last_login'],
|
|
];
|
|
|
|
// Colonnes binaires : le JSON ne peut pas contenir de binaire brut, on les encode en base64
|
|
// (+33% de taille mais nécessaire pour que le PDF survive à un export/import complet)
|
|
$colonnesBinaires = [
|
|
'projects' => ['pdf_data'],
|
|
'experiences' => ['pdf_data'],
|
|
'schools' => ['pdf_data'],
|
|
];
|
|
|
|
// Métadonnées de l'export (pratique pour s'y retrouver dans les sauvegardes)
|
|
$export = [
|
|
'_meta' => [
|
|
'site' => 'Portfolio Esteban MOUSSU',
|
|
'date_export' => date('Y-m-d H:i:s'),
|
|
'version' => 1
|
|
]
|
|
];
|
|
|
|
// Pour chaque table on récupère toutes les lignes
|
|
foreach ($tables as $table => $colonnes) {
|
|
try {
|
|
// SELECT * puis filtrage par liste blanche : fonctionne même si certaines
|
|
// colonnes optionnelles (markdown, link_url, pdf_data...) n'existent pas encore
|
|
$stmt = $dbh->query('SELECT * FROM `' . $table . '`');
|
|
$lignes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
$binaires = $colonnesBinaires[$table] ?? [];
|
|
|
|
// On ne garde que les colonnes de la liste blanche, et on encode les colonnes binaires
|
|
$export[$table] = array_map(function ($ligne) use ($colonnes, $binaires) {
|
|
$ligne = array_intersect_key($ligne, array_flip($colonnes));
|
|
foreach ($binaires as $colonne) {
|
|
if (isset($ligne[$colonne]) && $ligne[$colonne] !== null) {
|
|
$ligne[$colonne] = base64_encode($ligne[$colonne]);
|
|
}
|
|
}
|
|
return $ligne;
|
|
}, $lignes);
|
|
} catch (PDOException $e) {
|
|
// Si une table n'existe pas encore on l'exporte vide plutôt que de bloquer l'export
|
|
$export[$table] = [];
|
|
}
|
|
}
|
|
|
|
// Log Discord
|
|
sendLog("Export des données du site en JSON");
|
|
|
|
// Envoi du fichier JSON en téléchargement
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Content-Disposition: attachment; filename="portfolio-backup-' . date('Y-m-d-His') . '.json"');
|
|
echo json_encode($export, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|