Corrige l'import de chapitres/volumes CBZ qui stockait le chemin du fichier CBZ comme pagesDirectory. Le reader ne trouvait aucune image car LegacyChapterRepository attend un dossier d'images individuelles. - Déplace ImageStorageInterface dans Shared (storeChapterImages + extractFromCbz + countCbzImages) - Crée ImageStorageManager dans Shared/Infrastructure (extraction ZIP + copie) - Supprime LocalImageStorage et l'ancienne interface dans Scraping - Refactore ImportChapterHandler et ImportVolumeHandler pour utiliser ImageStorageInterface - Corrige LegacyChapterRepository : construit l'URL depuis basename(pagesDirectory) au lieu de chapterId (fix pour les volumes partagés)
62 lines
2.2 KiB
PHP
62 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Domain\Manga\Application\CommandHandler;
|
|
|
|
use App\Domain\Manga\Application\Command\ImportVolume;
|
|
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
|
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
|
|
use App\Domain\Shared\Domain\Contract\ImageStorageInterface;
|
|
|
|
readonly class ImportVolumeHandler
|
|
{
|
|
public function __construct(
|
|
private MangaRepositoryInterface $mangaRepository,
|
|
private ImageStorageInterface $imageStorage
|
|
) {
|
|
}
|
|
|
|
public function handle(ImportVolume $command): void
|
|
{
|
|
// 1. Validate that the manga exists
|
|
$manga = $this->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;
|
|
}
|
|
}
|