uploadDir = __DIR__ . '/../../assets/images/chapters/' . $storyId . '/covers/'; $this->ensureUploadDirectory(); } public function handleUpload($file, $chapterId) { try { // Vérifications de base if ($file['error'] !== UPLOAD_ERR_OK) { throw new Exception($this->getUploadErrorMessage($file['error'])); } // Vérification du type MIME $finfo = new finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->file($file['tmp_name']); if (!in_array($mimeType, $this->allowedTypes)) { throw new Exception('Type de fichier non autorisé. Types acceptés : JPG, PNG, GIF, WEBP'); } // Vérification de la taille if ($file['size'] > $this->maxFileSize) { throw new Exception('Fichier trop volumineux. Taille maximum : 5MB'); } // Génération du nom de fichier $extension = $this->getExtensionFromMimeType($mimeType); $filename = $chapterId . '-cover.' . $extension; $targetPath = $this->uploadDir . $filename; // Suppression de l'ancienne image si elle existe $this->removeOldCover($chapterId); // Déplacement du fichier if (!move_uploaded_file($file['tmp_name'], $targetPath)) { throw new Exception('Erreur lors du déplacement du fichier uploadé'); } // Retourner le chemin relatif pour stockage en BDD return 'assets/images/chapters/' . basename(dirname($this->uploadDir)) . '/covers/' . $filename; } catch (Exception $e) { throw $e; } } public function removeCover($chapterId) { foreach (glob($this->uploadDir . $chapterId . '-cover.*') as $file) { unlink($file); } return true; } private function ensureUploadDirectory() { if (!file_exists($this->uploadDir)) { if (!mkdir($this->uploadDir, 0755, true)) { throw new Exception('Impossible de créer le dossier d\'upload'); } } if (!is_writable($this->uploadDir)) { throw new Exception('Le dossier d\'upload n\'est pas accessible en écriture'); } } private function removeOldCover($chapterId) { foreach (glob($this->uploadDir . $chapterId . '-cover.*') as $file) { unlink($file); } } private function getExtensionFromMimeType($mimeType) { $map = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp' ]; return $map[$mimeType] ?? 'jpg'; } private function getUploadErrorMessage($error) { $errors = [ UPLOAD_ERR_INI_SIZE => 'Le fichier dépasse la taille maximale autorisée par PHP', UPLOAD_ERR_FORM_SIZE => 'Le fichier dépasse la taille maximale autorisée par le formulaire', UPLOAD_ERR_PARTIAL => 'Le fichier n\'a été que partiellement uploadé', UPLOAD_ERR_NO_FILE => 'Aucun fichier n\'a été uploadé', UPLOAD_ERR_NO_TMP_DIR => 'Dossier temporaire manquant', UPLOAD_ERR_CANT_WRITE => 'Échec de l\'écriture du fichier sur le disque', UPLOAD_ERR_EXTENSION => 'Une extension PHP a arrêté l\'upload' ]; return $errors[$error] ?? 'Erreur inconnue lors de l\'upload'; } } // Vérification de l'authentification if (!Auth::check()) { http_response_code(401); exit(json_encode(['success' => false, 'error' => 'Non autorisé'])); } // Traitement de la requête try { // Récupérer les données selon la méthode $input = json_decode(file_get_contents('php://input'), true); if ($input) { // Cas d'une requête JSON (suppression) $storyId = $input['storyId'] ?? null; $chapterId = $input['chapterId'] ?? null; $isDelete = $input['delete'] ?? false; } else { // Cas d'un upload de fichier $storyId = $_POST['storyId'] ?? null; $chapterId = $_POST['chapterId'] ?? null; $isDelete = false; } if (!$storyId || !$chapterId) { throw new Exception('Paramètres manquants'); } // Récupération du roman $story = Stories::get($storyId); if (!$story) { throw new Exception('Roman non trouvé'); } // Trouver le chapitre concerné $chapterFound = false; foreach ($story['chapters'] as &$chapter) { if ($chapter['id'] === $chapterId) { $chapterFound = true; break; } } if (!$chapterFound) { throw new Exception('Chapitre non trouvé'); } $handler = new ChapterCoverHandler($storyId); // Traitement selon le type de requête if ($isDelete) { $handler->removeCover($chapterId); $chapter['cover'] = null; } else if (isset($_FILES['cover'])) { $chapter['cover'] = $handler->handleUpload($_FILES['cover'], $chapterId); } // Sauvegarde des modifications Stories::save($story); echo json_encode(['success' => true]); } catch (Exception $e) { http_response_code(500); echo json_encode([ 'success' => false, 'error' => $e->getMessage() ]); }