From c0bd9c69b18daeb1db215eac227f8a42ac88b902 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Sat, 5 Apr 2025 11:43:40 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20mise=20=C3=A0=20jour=20de=20la=20gestio?= =?UTF-8?q?n=20des=20chapitres=20en=20rempla=C3=A7ant=20les=20types=20d'id?= =?UTF-8?q?entifiants=20par=20des=20flottants=20pour=20une=20meilleure=20c?= =?UTF-8?q?oh=C3=A9rence,=20ajout=20de=20la=20documentation=20pour=20les?= =?UTF-8?q?=20m=C3=A9thodes=20de=20recherche=20de=20chapitres,=20et=20am?= =?UTF-8?q?=C3=A9lioration=20de=20la=20gestion=20des=20exceptions=20lors?= =?UTF-8?q?=20de=20la=20r=C3=A9cup=C3=A9ration=20des=20chapitres.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FetchMangaChaptersHandler.php | 10 +++++----- .../Repository/MangaRepositoryInterface.php | 4 ++++ .../Persistence/LegacyMangaRepository.php | 8 ++++++-- .../CommandHandler/ScrapeChapterHandler.php | 2 ++ .../Repository/ChapterRepositoryInterface.php | 5 ++++- src/Domain/Scraping/Domain/Model/Chapter.php | 6 +++--- .../Persistence/LegacyChapterRepository.php | 18 +++++++++--------- .../Adapter/InMemoryChapterRepository.php | 5 +++-- 8 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/Domain/Manga/Application/CommandHandler/FetchMangaChaptersHandler.php b/src/Domain/Manga/Application/CommandHandler/FetchMangaChaptersHandler.php index f97847a..7149cba 100644 --- a/src/Domain/Manga/Application/CommandHandler/FetchMangaChaptersHandler.php +++ b/src/Domain/Manga/Application/CommandHandler/FetchMangaChaptersHandler.php @@ -52,20 +52,20 @@ readonly class FetchMangaChaptersHandler // Définir les règles de priorité des langues (fr > en > autres) $shouldReplaceChapter = false; - if (!isset($chaptersByNumber[$chapterNumber])) { + if (!isset($chaptersByNumber[(string) $chapterNumber])) { // Si c'est le premier chapitre avec ce numéro qu'on rencontre $shouldReplaceChapter = true; $chapterNumbers[] = $chapterNumber; } else if ($language === 'fr') { // Le français est toujours prioritaire $shouldReplaceChapter = true; - } else if ($language === 'en' && $chapterLanguages[$chapterNumber] !== 'fr') { + } else if ($language === 'en' && $chapterLanguages[(string) $chapterNumber] !== 'fr') { // L'anglais est prioritaire sur les autres langues, sauf le français $shouldReplaceChapter = true; } if ($shouldReplaceChapter) { - $chaptersByNumber[$chapterNumber] = new Chapter( + $chaptersByNumber[(string) $chapterNumber] = new Chapter( new ChapterId((string) Uuid::uuid4()), $manga->getId()->getValue(), $chapterNumber, @@ -75,7 +75,7 @@ readonly class FetchMangaChaptersHandler false, new \DateTimeImmutable() ); - $chapterLanguages[$chapterNumber] = $language; + $chapterLanguages[(string) $chapterNumber] = $language; } } @@ -94,7 +94,7 @@ readonly class FetchMangaChaptersHandler // Sauvegarde uniquement les nouveaux chapitres foreach ($chaptersByNumber as $chapterNumber => $chapter) { - if (!isset($existingChapters[$chapterNumber])) { + if (!isset($existingChapters[(float) $chapterNumber])) { $this->mangaRepository->saveChapter($chapter); } } diff --git a/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php b/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php index fc97771..6c1fea2 100644 --- a/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php +++ b/src/Domain/Manga/Domain/Contract/Repository/MangaRepositoryInterface.php @@ -21,5 +21,9 @@ interface MangaRepositoryInterface public function findBySlug(MangaSlug $slug): ?Manga; public function search(string $query, int $page = 1, int $limit = 20): array; public function countSearch(string $query): int; + /** + * @param float[] $chapterNumbers + * @return array + */ public function findExistingChaptersByNumbers(string $mangaId, array $chapterNumbers): array; } diff --git a/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php b/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php index 61e450e..af5342e 100644 --- a/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php +++ b/src/Domain/Manga/Infrastructure/Persistence/LegacyMangaRepository.php @@ -200,6 +200,10 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface ->getSingleScalarResult(); } + /** + * @param float[] $chapterNumbers + * @return array + */ public function findExistingChaptersByNumbers(string $mangaId, array $chapterNumbers): array { $queryBuilder = $this->entityManager->createQueryBuilder() @@ -208,13 +212,13 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface ->where('c.manga = :mangaId') ->andWhere('c.number IN (:chapterNumbers)') ->setParameter('mangaId', $mangaId) - ->setParameter('chapterNumbers', $chapterNumbers); + ->setParameter('chapterNumbers', array_map('floatval', $chapterNumbers)); $chapters = $queryBuilder->getQuery()->getResult(); $chaptersByNumber = []; foreach ($chapters as $chapter) { - $chaptersByNumber[$chapter->getNumber()] = $this->toChapterDomain($chapter); + $chaptersByNumber[(float) $chapter->getNumber()] = $this->toChapterDomain($chapter); } return $chaptersByNumber; diff --git a/src/Domain/Scraping/Application/CommandHandler/ScrapeChapterHandler.php b/src/Domain/Scraping/Application/CommandHandler/ScrapeChapterHandler.php index bad3337..20f4357 100644 --- a/src/Domain/Scraping/Application/CommandHandler/ScrapeChapterHandler.php +++ b/src/Domain/Scraping/Application/CommandHandler/ScrapeChapterHandler.php @@ -11,6 +11,7 @@ use App\Domain\Scraping\Domain\Contract\Service\ImageDownloaderInterface; use App\Domain\Scraping\Domain\Contract\Service\ScraperInterface; use App\Domain\Scraping\Domain\Event\ChapterScraped; use App\Domain\Scraping\Domain\Event\ChapterScrapingFailed; +use App\Domain\Scraping\Domain\Model\Chapter; use App\Domain\Scraping\Domain\Model\ScrapingJob; use App\Domain\Scraping\Domain\Model\Source; use App\Domain\Scraping\Domain\Model\ValueObject\CbzGenerationRequest; @@ -41,6 +42,7 @@ readonly class ScrapeChapterHandler $job = null; try { // 1. Récupération du chapitre + /**@var Chapter $chapter */ $chapter = $this->chapterRepository->getById($command->chapterId); if (!$chapter) { throw new \InvalidArgumentException("Chapter not found with ID: {$command->chapterId}"); diff --git a/src/Domain/Scraping/Domain/Contract/Repository/ChapterRepositoryInterface.php b/src/Domain/Scraping/Domain/Contract/Repository/ChapterRepositoryInterface.php index cfd0591..73947f7 100644 --- a/src/Domain/Scraping/Domain/Contract/Repository/ChapterRepositoryInterface.php +++ b/src/Domain/Scraping/Domain/Contract/Repository/ChapterRepositoryInterface.php @@ -7,6 +7,9 @@ use App\Domain\Scraping\Domain\Model\Chapter; interface ChapterRepositoryInterface { public function getById(string $id): ?Chapter; - public function getByMangaIdAndChapterNumber(string $mangaId, int $chapterNumber): Chapter; + /** + * @throws ChapterNotFoundException + */ + public function getByMangaIdAndChapterNumber(string $mangaId, float $chapterNumber): Chapter; public function save(Chapter $chapter): void; } diff --git a/src/Domain/Scraping/Domain/Model/Chapter.php b/src/Domain/Scraping/Domain/Model/Chapter.php index 14199eb..bd854a3 100644 --- a/src/Domain/Scraping/Domain/Model/Chapter.php +++ b/src/Domain/Scraping/Domain/Model/Chapter.php @@ -7,8 +7,8 @@ class Chapter public function __construct( public readonly string $id, public readonly string $mangaId, - public readonly int $chapterNumber, - public readonly int $volumeNumber, - public ?string $cbzPath = null, + public readonly float $chapterNumber, + public readonly ?int $volumeNumber, + public ?string $cbzPath, ) {} } diff --git a/src/Domain/Scraping/Infrastructure/Persistence/LegacyChapterRepository.php b/src/Domain/Scraping/Infrastructure/Persistence/LegacyChapterRepository.php index 00c2f5e..97773b4 100644 --- a/src/Domain/Scraping/Infrastructure/Persistence/LegacyChapterRepository.php +++ b/src/Domain/Scraping/Infrastructure/Persistence/LegacyChapterRepository.php @@ -36,23 +36,23 @@ readonly class LegacyChapterRepository implements ChapterRepositoryInterface /** * @throws ChapterNotFoundException */ - public function getByMangaIdAndChapterNumber(string $mangaId, int $chapterNumber): Chapter + public function getByMangaIdAndChapterNumber(string $mangaId, float $chapterNumber): Chapter { - $chapterEntity = $this->entityManager->getRepository(EntityChapter::class)->findOneBy([ + $entity = $this->entityManager->getRepository(EntityChapter::class)->findOneBy([ 'manga' => $mangaId, - 'number' => $chapterNumber, + 'number' => $chapterNumber ]); - if (!$chapterEntity) { + if ($entity === null) { throw new ChapterNotFoundException(); } return new Chapter( - id: $chapterEntity->getId(), - mangaId: $chapterEntity->getManga()->getId(), - chapterNumber: $chapterEntity->getNumber(), - volumeNumber: $chapterEntity->getVolume(), - cbzPath: $chapterEntity->getCbzPath(), + id: $entity->getId(), + mangaId: $entity->getManga()->getId(), + chapterNumber: $entity->getNumber(), + volumeNumber: $entity->getVolume(), + cbzPath: $entity->getCbzPath(), ); } diff --git a/tests/Domain/Scraping/Adapter/InMemoryChapterRepository.php b/tests/Domain/Scraping/Adapter/InMemoryChapterRepository.php index cf91f74..b0ec0cb 100644 --- a/tests/Domain/Scraping/Adapter/InMemoryChapterRepository.php +++ b/tests/Domain/Scraping/Adapter/InMemoryChapterRepository.php @@ -4,6 +4,7 @@ namespace App\Tests\Domain\Scraping\Adapter; use App\Domain\Scraping\Domain\Contract\Repository\ChapterRepositoryInterface; use App\Domain\Scraping\Domain\Model\Chapter; +use App\Domain\Scraping\Domain\Exception\ChapterNotFoundException; class InMemoryChapterRepository implements ChapterRepositoryInterface { @@ -14,7 +15,7 @@ class InMemoryChapterRepository implements ChapterRepositoryInterface return $this->chapters[$id] ?? null; } - public function getByMangaIdAndChapterNumber(string $mangaId, int $chapterNumber): Chapter + public function getByMangaIdAndChapterNumber(string $mangaId, float $chapterNumber): Chapter { foreach ($this->chapters as $chapter) { if ($chapter->mangaId === $mangaId && $chapter->chapterNumber === $chapterNumber) { @@ -22,7 +23,7 @@ class InMemoryChapterRepository implements ChapterRepositoryInterface } } - throw new \RuntimeException('Chapter not found'); + throw new ChapterNotFoundException(); } public function save(Chapter $chapter): void