mangaRepository->findById($command->mangaId); if (!$manga) { throw new MangaNotFoundException($command->mangaId); } // 2. Validate that the file is a valid CBZ if (!$this->isValidCbzFile($command->fileBinary)) { throw new \InvalidArgumentException('The provided file is not a valid CBZ file'); } // 3. Check if chapter exists $existingChapter = $this->chapterRepository->findByMangaIdAndChapterNumber( $command->mangaId, $command->chapterNumber ); if (!$existingChapter) { throw new ChapterNotFoundException("Chapter {$command->chapterNumber} not found for manga {$command->mangaId}"); } // 4. Save the CBZ file to storage using the path manager $cbzPath = $this->saveCbzFile($command, $manga, $existingChapter); // 5. Update existing chapter with new CBZ path $updatedChapter = new Chapter( id: new ChapterId($existingChapter->getId()), mangaId: $existingChapter->getMangaId(), number: $existingChapter->getNumber(), title: $existingChapter->getTitle(), volume: $existingChapter->getVolume(), isVisible: $existingChapter->isVisible(), cbzPath: $cbzPath, createdAt: $existingChapter->getCreatedAt() ); $this->chapterRepository->save($updatedChapter); } /** * Validate that the binary data is a valid CBZ (ZIP) file */ private function isValidCbzFile(string $fileBinary): bool { // CBZ files are ZIP archives, check for ZIP magic number $zipMagicNumber = "\x50\x4b\x03\x04"; // PK\x03\x04 return strpos($fileBinary, $zipMagicNumber) === 0; } /** * Save the CBZ file to storage and return the path */ private function saveCbzFile(ImportChapter $command, \App\Domain\Manga\Domain\Model\Manga $manga, Chapter $chapter): string { // Build the final CBZ path using the path manager (creates directories) $volumeNumber = $chapter->getVolume() ?? 0; $cbzPath = $this->pathManager->buildChapterCbzPath( $manga->getTitle()->getValue(), (string)$manga->getPublicationYear(), $volumeNumber, (string)$command->chapterNumber ); // Write the binary content directly to the CBZ path if (!file_put_contents($cbzPath, $command->fileBinary)) { throw new \RuntimeException('Failed to save CBZ file'); } return $cbzPath; } }