2025-02-16 12:22:19 +01:00
|
|
|
<?php
|
|
|
|
require_once '../../includes/config.php';
|
|
|
|
require_once '../../includes/auth.php';
|
|
|
|
require_once '../../includes/stories.php';
|
|
|
|
|
|
|
|
if (!Auth::check()) {
|
|
|
|
http_response_code(401);
|
|
|
|
exit('Non autorisé');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
|
|
http_response_code(405);
|
|
|
|
exit('Méthode non autorisée');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($_POST['stories'])) {
|
|
|
|
http_response_code(400);
|
|
|
|
exit('Aucun roman sélectionné');
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$selectedIds = $_POST['stories'];
|
|
|
|
$tempDir = sys_get_temp_dir() . '/story_export_' . uniqid();
|
|
|
|
mkdir($tempDir);
|
|
|
|
|
|
|
|
// Créer un fichier manifeste pour stocker les métadonnées
|
|
|
|
$manifest = [
|
|
|
|
'exportDate' => date('Y-m-d H:i:s'),
|
|
|
|
'stories' => []
|
|
|
|
];
|
|
|
|
|
|
|
|
foreach ($selectedIds as $storyId) {
|
|
|
|
$story = Stories::get($storyId);
|
|
|
|
if (!$story) continue;
|
|
|
|
|
|
|
|
// Créer un dossier pour ce roman
|
|
|
|
$storyDir = $tempDir . '/' . $storyId;
|
|
|
|
mkdir($storyDir);
|
|
|
|
mkdir($storyDir . '/images');
|
2025-02-17 17:52:31 +01:00
|
|
|
mkdir($storyDir . '/chapter_covers');
|
2025-02-16 12:22:19 +01:00
|
|
|
|
2025-02-17 17:52:31 +01:00
|
|
|
// Copier l'image de couverture du roman si elle existe
|
2025-02-16 12:22:19 +01:00
|
|
|
if (!empty($story['cover'])) {
|
|
|
|
$coverPath = __DIR__ . '/../../' . $story['cover'];
|
|
|
|
if (file_exists($coverPath)) {
|
2025-02-17 17:52:31 +01:00
|
|
|
$extension = '.' . pathinfo($coverPath, PATHINFO_EXTENSION);
|
|
|
|
copy($coverPath, $storyDir . '/cover' . $extension);
|
|
|
|
$story['cover'] = 'cover' . $extension;
|
2025-02-16 12:22:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extraire et copier les images des chapitres
|
|
|
|
foreach ($story['chapters'] as &$chapter) {
|
2025-02-17 17:52:31 +01:00
|
|
|
// Gestion des images de couverture des chapitres
|
|
|
|
if (!empty($chapter['cover'])) {
|
|
|
|
$chapterCoverPath = __DIR__ . '/../../' . $chapter['cover'];
|
|
|
|
if (file_exists($chapterCoverPath)) {
|
|
|
|
$extension = '.' . pathinfo($chapterCoverPath, PATHINFO_EXTENSION);
|
|
|
|
$newCoverName = 'chapter_' . $chapter['id'] . '_cover' . $extension;
|
|
|
|
copy($chapterCoverPath, $storyDir . '/chapter_covers/' . $newCoverName);
|
|
|
|
$chapter['cover'] = 'chapter_covers/' . $newCoverName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gestion du contenu et des images intégrées
|
2025-02-16 12:22:19 +01:00
|
|
|
if (!empty($chapter['content'])) {
|
|
|
|
$content = $chapter['content'];
|
|
|
|
if (is_string($content) && isJson($content)) {
|
|
|
|
$content = json_decode($content, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Traiter le contenu pour les images
|
|
|
|
if (is_array($content) && isset($content['ops'])) {
|
|
|
|
foreach ($content['ops'] as &$op) {
|
|
|
|
if (is_array($op['insert']) && isset($op['insert']['image'])) {
|
|
|
|
$imgUrl = $op['insert']['image'];
|
|
|
|
$imgPath = __DIR__ . '/../../' . preg_replace('/^(?:\.\.\/)+/', '', $imgUrl);
|
|
|
|
if (file_exists($imgPath)) {
|
2025-02-17 17:52:31 +01:00
|
|
|
$extension = '.' . pathinfo($imgPath, PATHINFO_EXTENSION);
|
|
|
|
$newImgName = 'image_' . uniqid() . $extension;
|
2025-02-16 12:22:19 +01:00
|
|
|
copy($imgPath, $storyDir . '/images/' . $newImgName);
|
|
|
|
$op['insert']['image'] = 'images/' . $newImgName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$chapter['content'] = json_encode($content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sauvegarder les données du roman
|
|
|
|
file_put_contents($storyDir . '/story.json', json_encode($story, JSON_PRETTY_PRINT));
|
|
|
|
|
|
|
|
// Ajouter au manifeste
|
|
|
|
$manifest['stories'][] = [
|
|
|
|
'id' => $story['id'],
|
|
|
|
'title' => $story['title']
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sauvegarder le manifeste
|
|
|
|
file_put_contents($tempDir . '/manifest.json', json_encode($manifest, JSON_PRETTY_PRINT));
|
|
|
|
|
|
|
|
// Créer l'archive ZIP
|
|
|
|
$zipFile = sys_get_temp_dir() . '/romans_' . date('Y-m-d_His') . '.zip';
|
|
|
|
$zip = new ZipArchive();
|
|
|
|
|
|
|
|
if ($zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
|
|
|
|
addDirToZip($zip, $tempDir, '');
|
|
|
|
$zip->close();
|
|
|
|
|
|
|
|
// Nettoyer le dossier temporaire
|
|
|
|
deleteDir($tempDir);
|
|
|
|
|
|
|
|
// Envoyer l'archive
|
|
|
|
header('Content-Type: application/zip');
|
|
|
|
header('Content-Disposition: attachment; filename="' . basename($zipFile) . '"');
|
|
|
|
header('Content-Length: ' . filesize($zipFile));
|
|
|
|
readfile($zipFile);
|
|
|
|
unlink($zipFile);
|
|
|
|
} else {
|
|
|
|
throw new Exception('Impossible de créer l\'archive ZIP');
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
if (isset($tempDir) && file_exists($tempDir)) {
|
|
|
|
deleteDir($tempDir);
|
|
|
|
}
|
|
|
|
if (isset($zipFile) && file_exists($zipFile)) {
|
|
|
|
unlink($zipFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
http_response_code(500);
|
|
|
|
echo 'Erreur lors de l\'export : ' . $e->getMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fonction pour vérifier si une chaîne est du JSON valide
|
|
|
|
function isJson($string) {
|
|
|
|
json_decode($string);
|
|
|
|
return json_last_error() === JSON_ERROR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fonction récursive pour ajouter un dossier à une archive ZIP
|
|
|
|
function addDirToZip($zip, $dir, $relativePath) {
|
|
|
|
$files = new RecursiveIteratorIterator(
|
|
|
|
new RecursiveDirectoryIterator($dir),
|
|
|
|
RecursiveIteratorIterator::LEAVES_ONLY
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach ($files as $file) {
|
|
|
|
if (!$file->isDir()) {
|
|
|
|
$filePath = $file->getRealPath();
|
|
|
|
$zipPath = $relativePath . substr($filePath, strlen($dir));
|
|
|
|
|
|
|
|
// Normaliser les séparateurs de chemin pour Windows
|
|
|
|
$zipPath = str_replace('\\', '/', $zipPath);
|
|
|
|
|
|
|
|
$zip->addFile($filePath, $zipPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fonction récursive pour supprimer un dossier et son contenu
|
|
|
|
function deleteDir($dir) {
|
|
|
|
if (!file_exists($dir)) return;
|
|
|
|
|
|
|
|
$files = new RecursiveIteratorIterator(
|
|
|
|
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
|
|
|
|
RecursiveIteratorIterator::CHILD_FIRST
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach ($files as $file) {
|
|
|
|
if ($file->isDir()) {
|
|
|
|
rmdir($file->getRealPath());
|
|
|
|
} else {
|
|
|
|
unlink($file->getRealPath());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rmdir($dir);
|
|
|
|
}
|