Lectures/admin/api/import-stories.php

179 lines
5.9 KiB
PHP

<?php
require_once '../../includes/config.php';
require_once '../../includes/auth.php';
require_once '../../includes/stories.php';
if (!Auth::check()) {
header('Location: ../login.php');
exit;
}
$success = '';
$error = '';
try {
if (!isset($_FILES['importFile']) || $_FILES['importFile']['error'] !== UPLOAD_ERR_OK) {
throw new Exception('Erreur lors de l\'upload du fichier');
}
$overwrite = isset($_POST['overwrite']) && $_POST['overwrite'] === '1';
$tempDir = sys_get_temp_dir() . '/story_import_' . uniqid();
mkdir($tempDir);
// Extraire l'archive
$zip = new ZipArchive();
if ($zip->open($_FILES['importFile']['tmp_name']) !== true) {
throw new Exception('Impossible d\'ouvrir l\'archive ZIP');
}
$zip->extractTo($tempDir);
$zip->close();
// Vérifier la présence du manifeste
$manifestFile = $tempDir . '/manifest.json';
if (!file_exists($manifestFile)) {
throw new Exception('Archive invalide : manifeste manquant');
}
$manifest = json_decode(file_get_contents($manifestFile), true);
if (!$manifest || !isset($manifest['stories'])) {
throw new Exception('Manifeste invalide');
}
$importedCount = 0;
$skippedCount = 0;
$errors = [];
// Parcourir chaque roman dans le manifeste
foreach ($manifest['stories'] as $storyInfo) {
try {
$storyId = $storyInfo['id'];
$storyDir = $tempDir . '/' . $storyId;
if (!file_exists($storyDir . '/story.json')) {
throw new Exception("Fichier story.json manquant pour {$storyInfo['title']}");
}
$story = json_decode(file_get_contents($storyDir . '/story.json'), true);
if (!$story) {
throw new Exception("Données JSON invalides pour {$storyInfo['title']}");
}
// Vérifier si le roman existe déjà
$existingStory = Stories::get($storyId);
if ($existingStory && !$overwrite) {
$skippedCount++;
continue;
}
// Créer les dossiers nécessaires
$coverDir = __DIR__ . '/../../assets/images/covers/';
$chaptersImgDir = __DIR__ . '/../../assets/images/chapters/' . $storyId;
if (!file_exists($coverDir)) mkdir($coverDir, 0755, true);
if (!file_exists($chaptersImgDir)) mkdir($chaptersImgDir, 0755, true);
// Gérer l'image de couverture
if (!empty($story['cover'])) {
$coverFile = $storyDir . '/' . $story['cover'];
if (file_exists($coverFile)) {
$newCoverPath = 'assets/images/covers/' . $storyId . '.' . pathinfo($coverFile, PATHINFO_EXTENSION);
copy($coverFile, __DIR__ . '/../../' . $newCoverPath);
$story['cover'] = $newCoverPath;
}
}
// Gérer les images des chapitres
foreach ($story['chapters'] as &$chapter) {
if (!empty($chapter['content'])) {
$content = $chapter['content'];
if (is_string($content) && isJson($content)) {
$content = json_decode($content, true);
}
if (is_array($content) && isset($content['ops'])) {
foreach ($content['ops'] as &$op) {
if (is_array($op['insert']) && isset($op['insert']['image'])) {
$imgPath = $storyDir . '/' . $op['insert']['image'];
if (file_exists($imgPath)) {
$newImgName = 'image_' . uniqid() . '.' . pathinfo($imgPath, PATHINFO_EXTENSION);
copy($imgPath, $chaptersImgDir . '/' . $newImgName);
$op['insert']['image'] = 'assets/images/chapters/' . $storyId . '/' . $newImgName;
}
}
}
$chapter['content'] = json_encode($content);
}
}
}
// Sauvegarder le roman
Stories::save($story);
$importedCount++;
} catch (Exception $e) {
$errors[] = "Erreur pour {$storyInfo['title']}: " . $e->getMessage();
}
}
// Nettoyer
deleteDir($tempDir);
// Préparer le message de résultat
$messages = [];
if ($importedCount > 0) {
$messages[] = "$importedCount roman(s) importé(s)";
}
if ($skippedCount > 0) {
$messages[] = "$skippedCount roman(s) ignoré(s) (déjà existants)";
}
if (!empty($errors)) {
$messages[] = "Erreurs : " . implode(", ", $errors);
}
$_SESSION['import_result'] = [
'success' => implode(", ", $messages),
'error' => !empty($errors) ? implode("\n", $errors) : ''
];
header('Location: ../export-import.php');
exit;
} catch (Exception $e) {
if (isset($tempDir) && file_exists($tempDir)) {
deleteDir($tempDir);
}
$_SESSION['import_result'] = [
'error' => 'Erreur lors de l\'import : ' . $e->getMessage()
];
header('Location: ../export-import.php');
exit;
}
// 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 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);
}