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. Get all chapters for this volume $chapters = $this->mangaRepository->findChaptersByMangaIdAndVolume( $command->mangaId, $command->volumeNumber ); if (empty($chapters)) { throw new \InvalidArgumentException( "No chapters found for manga {$command->mangaId} in volume {$command->volumeNumber}" ); } // 4. Extract CBZ into individual images storage (shared directory for all volume chapters) $volumeDirectoryId = sprintf('volume_%s_%d', $command->mangaId, $command->volumeNumber); $pagesDirectory = $this->imageStorage->extractFromCbz($volumeDirectoryId, $command->fileBinary); $pageCount = $this->imageStorage->countCbzImages($command->fileBinary); // 5. Update all chapters with the volume path through the aggregate foreach ($chapters as $chapter) { $manga->updateChapterPages($chapter, $pagesDirectory, $pageCount); } $this->mangaRepository->save($manga); } private function isValidCbzFile(string $fileBinary): bool { $zipMagicNumber = "\x50\x4b\x03\x04"; // PK\x03\x04 return strpos($fileBinary, $zipMagicNumber) === 0; } }