feat: migrer vers Symfony 8, PHP 8.4 et les dépendances majeures associées
- PHP 8.3 → 8.4 (Dockerfile + composer.json) - Symfony 7.0 → 8.0 (tous les composants symfony/*) - API Platform 3.x → 4.x : migration openapiContext → openapi: new Operation(...) - Doctrine DBAL 3 → 4 : suppression use_savepoints, replace prepare/executeQuery - Doctrine ORM 2.x → 3.x : ClassMetadataInfo → ClassMetadata, setParameters → setParameter - Doctrine Bundle 2.x → 3.x, Fixtures Bundle 3.x → 4.x - zenstruck/foundry 1.x → 2.x : ModelFactory → PersistentObjectFactory, getDefaults → defaults - phpmd/phpmd 2.x → 3.x-dev (seule version supportant Symfony 8) - phparkitect 0.3 → 0.8 : NotDependsOnTheseNamespaces prend un array - symfony/mercure-bundle 0.3 → 0.4, symfony/monolog-bundle 3 → 4 - Suppression de runtime/frankenphp-symfony (intégré nativement dans symfony/runtime 8) - worker.Caddyfile : suppression de APP_RUNTIME (détection automatique Symfony 8) - Routes errors.xml/wdt.xml/profiler.xml → .php (Symfony 8 supprime le XML) - Types::ARRAY → Types::JSON dans Entity/Manga.php (DBAL 4 retire array type) - Suppression de src/Schedule.php (doublon vide avec MonitoringSchedule) - Tests : hydra:Collection → Collection, hydra:member → member (API Platform 4)
This commit is contained in:
parent
5a0888eb28
commit
5ed303612a
@@ -7,7 +7,7 @@ readonly class ChapterEditData
|
||||
public function __construct(
|
||||
public string $id,
|
||||
public ?string $title = null,
|
||||
public ?int $volume = null
|
||||
public ?int $volume = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
namespace App\Domain\Manga\Application\Command;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
readonly class CheckMonitoredMangas
|
||||
{
|
||||
public function __construct(
|
||||
public ?DateTimeImmutable $since = null
|
||||
public ?\DateTimeImmutable $since = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ readonly class CreateManga
|
||||
public string $status,
|
||||
public ?string $externalId,
|
||||
public ?string $imageUrl,
|
||||
public ?float $rating
|
||||
public ?float $rating,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Domain\Manga\Application\Command;
|
||||
readonly class CreateMangaFromMangadex
|
||||
{
|
||||
public function __construct(
|
||||
public string $externalId
|
||||
public string $externalId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Domain\Shared\Domain\Contract\CommandInterface;
|
||||
readonly class DeleteCbz implements CommandInterface
|
||||
{
|
||||
public function __construct(
|
||||
public string $chapterId
|
||||
public string $chapterId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Domain\Shared\Domain\Contract\CommandInterface;
|
||||
readonly class DeleteChapter implements CommandInterface
|
||||
{
|
||||
public function __construct(
|
||||
public string $chapterId
|
||||
public string $chapterId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Domain\Shared\Domain\Contract\CommandInterface;
|
||||
readonly class DeleteManga implements CommandInterface
|
||||
{
|
||||
public function __construct(
|
||||
public string $mangaId
|
||||
public string $mangaId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ readonly class EditManga
|
||||
public ?array $genres = null,
|
||||
public ?string $status = null,
|
||||
public ?float $rating = null,
|
||||
public ?array $alternativeSlugs = null
|
||||
public ?array $alternativeSlugs = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly class EditMultipleChapters
|
||||
* @param array<ChapterEditData> $chapters
|
||||
*/
|
||||
public function __construct(
|
||||
public array $chapters
|
||||
public array $chapters,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
|
||||
readonly class FetchMangaChapters
|
||||
{
|
||||
public function __construct(
|
||||
public MangaId $mangaId
|
||||
public MangaId $mangaId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ readonly class ImportChapter
|
||||
public function __construct(
|
||||
public string $mangaId,
|
||||
public float $chapterNumber,
|
||||
public string $fileBinary
|
||||
public string $fileBinary,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ readonly class ImportVolume
|
||||
public function __construct(
|
||||
public string $mangaId,
|
||||
public int $volumeNumber,
|
||||
public string $fileBinary
|
||||
public string $fileBinary,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
|
||||
readonly class RefreshMangaChapters
|
||||
{
|
||||
public function __construct(
|
||||
public MangaId $mangaId
|
||||
public MangaId $mangaId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly class ToggleMangaMonitoring
|
||||
{
|
||||
public function __construct(
|
||||
public MangaId $mangaId,
|
||||
public bool $enabled
|
||||
public bool $enabled,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ use App\Domain\Manga\Application\Command\CheckMonitoredMangas;
|
||||
use App\Domain\Manga\Application\Command\RefreshMangaChapters;
|
||||
use App\Domain\Manga\Application\Query\MonitoringCriteria;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use DateTimeImmutable;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
readonly class CheckMonitoredMangasHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private MessageBusInterface $commandBus
|
||||
private MessageBusInterface $commandBus,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -21,7 +20,7 @@ readonly class CheckMonitoredMangasHandler
|
||||
{
|
||||
$criteria = new MonitoringCriteria(
|
||||
enabled: true,
|
||||
lastCheckBefore: $command->since ?? new DateTimeImmutable('-1 hour')
|
||||
lastCheckBefore: $command->since ?? new \DateTimeImmutable('-1 hour')
|
||||
);
|
||||
|
||||
$monitoredMangas = $this->mangaRepository->findByMonitoringCriteria($criteria);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Domain\Manga\Application\CommandHandler;
|
||||
|
||||
use App\Domain\Manga\Application\Command\CreateMangaFromMangadex;
|
||||
use App\Domain\Manga\Application\Response\CreateMangaResponse;
|
||||
use App\Domain\Manga\Domain\Contract\Provider\MangaProviderInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Service\ImageProcessorInterface;
|
||||
@@ -19,7 +18,7 @@ readonly class CreateMangaFromMangadexHandler
|
||||
private MangaProviderInterface $mangaProvider,
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private ImageProcessorInterface $imageProcessor,
|
||||
private EventDispatcherInterface $eventDispatcher
|
||||
private EventDispatcherInterface $eventDispatcher,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -27,7 +26,7 @@ readonly class CreateMangaFromMangadexHandler
|
||||
{
|
||||
$manga = $this->mangaProvider->findByExternalId(new ExternalId($command->externalId));
|
||||
|
||||
if ($manga === null) {
|
||||
if (null === $manga) {
|
||||
throw new MangaNotFoundException('Manga not found on Mangadex');
|
||||
}
|
||||
|
||||
@@ -41,7 +40,7 @@ readonly class CreateMangaFromMangadexHandler
|
||||
// Met à jour le manga avec les nouveaux chemins d'images
|
||||
$manga->updateImageUrls(new ImageUrls($fullImagePath, $thumbnailPath));
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException('Erreur lors du traitement de l\'image : ' . $e->getMessage());
|
||||
throw new \RuntimeException('Erreur lors du traitement de l\'image : '.$e->getMessage());
|
||||
}
|
||||
|
||||
$this->mangaRepository->save($manga);
|
||||
|
||||
@@ -20,7 +20,7 @@ readonly class CreateMangaHandler
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private ImageProcessorInterface $imageProcessor,
|
||||
private MessageBusInterface $messageBus
|
||||
private MessageBusInterface $messageBus,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ readonly class CreateMangaHandler
|
||||
$thumbnailPath = $this->imageProcessor->createThumbnail($fullImagePath);
|
||||
$manga->updateImageUrls(new ImageUrls($fullImagePath, $thumbnailPath));
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException('Erreur lors du traitement de l\'image : ' . $e->getMessage());
|
||||
throw new \RuntimeException('Erreur lors du traitement de l\'image : '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace App\Domain\Manga\Application\CommandHandler;
|
||||
use App\Domain\Manga\Application\Command\DeleteCbz;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Service\FileServiceInterface;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\CbzFileNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Shared\Domain\Contract\CommandHandlerInterface;
|
||||
use App\Domain\Shared\Domain\Contract\CommandInterface;
|
||||
|
||||
@@ -14,7 +14,7 @@ readonly class DeleteCbzHandler implements CommandHandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private FileServiceInterface $fileService
|
||||
private FileServiceInterface $fileService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use App\Domain\Shared\Domain\Contract\CommandInterface;
|
||||
readonly class DeleteChapterHandler implements CommandHandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use App\Domain\Shared\Domain\Contract\CommandInterface;
|
||||
readonly class DeleteMangaHandler implements CommandHandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle;
|
||||
readonly class EditMangaHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -23,35 +23,35 @@ readonly class EditMangaHandler
|
||||
}
|
||||
|
||||
// Update only provided fields (partial update)
|
||||
if ($command->title !== null) {
|
||||
if (null !== $command->title) {
|
||||
$manga->updateTitle(new MangaTitle($command->title));
|
||||
}
|
||||
|
||||
if ($command->description !== null) {
|
||||
if (null !== $command->description) {
|
||||
$manga->updateDescription($command->description);
|
||||
}
|
||||
|
||||
if ($command->author !== null) {
|
||||
if (null !== $command->author) {
|
||||
$manga->updateAuthor($command->author);
|
||||
}
|
||||
|
||||
if ($command->publicationYear !== null) {
|
||||
if (null !== $command->publicationYear) {
|
||||
$manga->updatePublicationYear($command->publicationYear);
|
||||
}
|
||||
|
||||
if ($command->genres !== null) {
|
||||
if (null !== $command->genres) {
|
||||
$manga->updateGenres($command->genres);
|
||||
}
|
||||
|
||||
if ($command->status !== null) {
|
||||
if (null !== $command->status) {
|
||||
$manga->updateStatus($command->status);
|
||||
}
|
||||
|
||||
if ($command->rating !== null) {
|
||||
if (null !== $command->rating) {
|
||||
$manga->setRating($command->rating);
|
||||
}
|
||||
|
||||
if ($command->alternativeSlugs !== null) {
|
||||
if (null !== $command->alternativeSlugs) {
|
||||
$manga->updateAlternativeSlugs($command->alternativeSlugs);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
readonly class EditMultipleChaptersHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -24,11 +24,11 @@ readonly class EditMultipleChaptersHandler
|
||||
|
||||
$manga = $this->mangaRepository->findById($chapter->getMangaId()->getValue());
|
||||
|
||||
if ($chapterData->title !== null) {
|
||||
if (null !== $chapterData->title) {
|
||||
$manga->updateChapterTitle($chapter, $chapterData->title);
|
||||
}
|
||||
|
||||
if ($chapterData->volume !== null) {
|
||||
if (null !== $chapterData->volume) {
|
||||
$manga->updateChapterVolume($chapter, $chapterData->volume);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ readonly class FetchMangaChaptersHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private ChapterSynchronizationServiceInterface $chapterSynchronizationService
|
||||
private ChapterSynchronizationServiceInterface $chapterSynchronizationService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ readonly class FetchMangaChaptersHandler
|
||||
{
|
||||
$manga = $this->mangaRepository->findById($command->mangaId->getValue());
|
||||
|
||||
if ($manga === null) {
|
||||
if (null === $manga) {
|
||||
throw new MangaNotFoundException();
|
||||
}
|
||||
|
||||
if ($manga->getExternalId() === null) {
|
||||
throw new MangadexApiException("Manga has no external_id");
|
||||
if (null === $manga->getExternalId()) {
|
||||
throw new MangadexApiException('Manga has no external_id');
|
||||
}
|
||||
|
||||
// Synchronisation initiale (pas d'événements)
|
||||
|
||||
@@ -4,15 +4,15 @@ namespace App\Domain\Manga\Application\CommandHandler;
|
||||
|
||||
use App\Domain\Manga\Application\Command\ImportChapter;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
|
||||
use App\Domain\Shared\Domain\Contract\ImageStorageInterface;
|
||||
|
||||
readonly class ImportChapterHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private ImageStorageInterface $imageStorage
|
||||
private ImageStorageInterface $imageStorage,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -55,6 +55,6 @@ readonly class ImportChapterHandler
|
||||
{
|
||||
$zipMagicNumber = "\x50\x4b\x03\x04"; // PK\x03\x04
|
||||
|
||||
return strpos($fileBinary, $zipMagicNumber) === 0;
|
||||
return 0 === strpos($fileBinary, $zipMagicNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ readonly class ImportVolumeHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private ImageStorageInterface $imageStorage
|
||||
private ImageStorageInterface $imageStorage,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -35,9 +35,7 @@ readonly class ImportVolumeHandler
|
||||
);
|
||||
|
||||
if (empty($chapters)) {
|
||||
throw new \InvalidArgumentException(
|
||||
"No chapters found for manga {$command->mangaId} in volume {$command->volumeNumber}"
|
||||
);
|
||||
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)
|
||||
@@ -56,6 +54,6 @@ readonly class ImportVolumeHandler
|
||||
{
|
||||
$zipMagicNumber = "\x50\x4b\x03\x04"; // PK\x03\x04
|
||||
|
||||
return strpos($fileBinary, $zipMagicNumber) === 0;
|
||||
return 0 === strpos($fileBinary, $zipMagicNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Service\ChapterSynchronizationServiceInterface;
|
||||
use App\Domain\Manga\Domain\Event\ChapterReadyForScraping;
|
||||
use App\Domain\Manga\Domain\Model\ValueObject\ChapterId;
|
||||
use DateTimeImmutable;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
readonly class RefreshMangaChaptersHandler
|
||||
@@ -15,7 +14,7 @@ readonly class RefreshMangaChaptersHandler
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private ChapterSynchronizationServiceInterface $chapterSynchronizationService,
|
||||
private MessageBusInterface $eventBus
|
||||
private MessageBusInterface $eventBus,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -23,7 +22,7 @@ readonly class RefreshMangaChaptersHandler
|
||||
{
|
||||
$manga = $this->mangaRepository->findById($command->mangaId->getValue());
|
||||
|
||||
if ($manga === null) {
|
||||
if (null === $manga) {
|
||||
throw new \RuntimeException('Manga not found');
|
||||
}
|
||||
|
||||
@@ -31,7 +30,7 @@ readonly class RefreshMangaChaptersHandler
|
||||
$newChapterIds = $this->chapterSynchronizationService->synchronizeChapters($manga);
|
||||
|
||||
// Mise à jour de la date de monitoring
|
||||
$manga->updateLastMonitoringCheck(new DateTimeImmutable());
|
||||
$manga->updateLastMonitoringCheck(new \DateTimeImmutable());
|
||||
$this->mangaRepository->save($manga);
|
||||
|
||||
// Événement de scraping pour chaque nouveau chapitre
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
|
||||
readonly class ToggleMangaMonitoringHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
|
||||
readonly class MangaCreatedEventListener
|
||||
{
|
||||
public function __construct(
|
||||
private FetchMangaChaptersHandler $fetchMangaChaptersHandler
|
||||
private FetchMangaChaptersHandler $fetchMangaChaptersHandler,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ readonly class VolumeImportedEventListener
|
||||
}
|
||||
|
||||
$chapters = $this->mangaRepository->findChaptersByMangaIdAndVolume($manga->getId()->getValue(), (int) $event->volume);
|
||||
if ($chapters === []) {
|
||||
if ([] === $chapters) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Domain\Shared\Domain\Contract\QueryInterface;
|
||||
readonly class DownloadCbz implements QueryInterface
|
||||
{
|
||||
public function __construct(
|
||||
public string $chapterId
|
||||
public string $chapterId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly class DownloadVolume implements QueryInterface
|
||||
{
|
||||
public function __construct(
|
||||
public string $mangaId,
|
||||
public int $volume
|
||||
public int $volume,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace App\Domain\Manga\Application\Query;
|
||||
readonly class FindMangaMatchByFilename
|
||||
{
|
||||
public function __construct(
|
||||
public string $filename
|
||||
public string $filename,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Domain\Manga\Application\Query;
|
||||
readonly class GetMangaById
|
||||
{
|
||||
public function __construct(
|
||||
public string $id
|
||||
public string $id,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Domain\Manga\Application\Query;
|
||||
readonly class GetMangaBySlug
|
||||
{
|
||||
public function __construct(
|
||||
public string $slug
|
||||
public string $slug,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly class GetMangaChapters
|
||||
public string $mangaId,
|
||||
public ?int $page = 1,
|
||||
public ?int $limit = 20,
|
||||
public ?string $sortOrder = 'desc'
|
||||
public ?string $sortOrder = 'desc',
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly class GetMangaList
|
||||
public ?int $page = 1,
|
||||
public ?int $limit = 20,
|
||||
public ?string $sortBy = 'title',
|
||||
public ?string $sortOrder = 'asc'
|
||||
public ?string $sortOrder = 'asc',
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
namespace App\Domain\Manga\Application\Query;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
readonly class MonitoringCriteria
|
||||
{
|
||||
public function __construct(
|
||||
public bool $enabled,
|
||||
public ?DateTimeImmutable $lastCheckBefore = null
|
||||
public ?\DateTimeImmutable $lastCheckBefore = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ readonly class SearchLocalManga
|
||||
public function __construct(
|
||||
public string $query,
|
||||
public int $page = 1,
|
||||
public int $limit = 20
|
||||
public int $limit = 20,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Domain\Manga\Application\Query;
|
||||
readonly class SearchManga
|
||||
{
|
||||
public function __construct(
|
||||
public string $title
|
||||
public string $title,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ readonly class DiscoverMangaHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private MangaProviderInterface $mangaProvider
|
||||
private MangaProviderInterface $mangaProvider,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ readonly class DiscoverMangaHandler
|
||||
|
||||
$recommendations = array_values(array_filter(
|
||||
$collection->getItems(),
|
||||
fn (Manga $m) => $m->getExternalId() === null
|
||||
fn (Manga $m) => null === $m->getExternalId()
|
||||
|| !in_array($m->getExternalId()->getValue(), $ownedExternalIds, true)
|
||||
));
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ use App\Domain\Manga\Application\Response\DownloadResponse;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Service\FileServiceInterface;
|
||||
use App\Domain\Manga\Domain\Exception\CbzFileNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotAvailableException;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Shared\Domain\Contract\QueryHandlerInterface;
|
||||
use App\Domain\Shared\Domain\Contract\QueryInterface;
|
||||
use App\Domain\Shared\Domain\Contract\ResponseInterface;
|
||||
@@ -17,7 +17,7 @@ readonly class DownloadCbzHandler implements QueryHandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private FileServiceInterface $fileService
|
||||
private FileServiceInterface $fileService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ readonly class DownloadVolumeHandler implements QueryHandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private FileServiceInterface $fileService
|
||||
private FileServiceInterface $fileService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ readonly class FindMangaMatchByFilenameHandler
|
||||
{
|
||||
public function __construct(
|
||||
private FilenameAnalyzerInterface $filenameAnalyzer,
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ readonly class FindMangaMatchByFilenameHandler
|
||||
|
||||
/**
|
||||
* Calcule un score de correspondance entre le manga et le titre recherché
|
||||
* Score plus élevé = meilleure correspondance
|
||||
* Score plus élevé = meilleure correspondance.
|
||||
*/
|
||||
private function calculateMatchScore(Manga $manga, string $searchedTitle): int
|
||||
{
|
||||
@@ -97,12 +97,12 @@ readonly class FindMangaMatchByFilenameHandler
|
||||
}
|
||||
|
||||
// Le titre du manga contient le terme recherché
|
||||
if (stripos($mangaTitle, $searchedTitle) !== false) {
|
||||
if (false !== stripos($mangaTitle, $searchedTitle)) {
|
||||
$score += 50;
|
||||
}
|
||||
|
||||
// Le terme recherché contient le titre du manga
|
||||
if (stripos($searchedTitle, $mangaTitle) !== false) {
|
||||
if (false !== stripos($searchedTitle, $mangaTitle)) {
|
||||
$score += 40;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
|
||||
readonly class GetMangaByIdHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug;
|
||||
readonly class GetMangaBySlugHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use App\Domain\Manga\Domain\Model\Chapter;
|
||||
readonly class GetMangaChaptersHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ readonly class GetMangaChaptersHandler
|
||||
|
||||
$grouped = $this->groupChapters($allChapters);
|
||||
|
||||
if ($query->sortOrder === 'desc') {
|
||||
if ('desc' === $query->sortOrder) {
|
||||
usort($grouped, fn (ChapterResponse $a, ChapterResponse $b) => $b->number <=> $a->number);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ readonly class GetMangaChaptersHandler
|
||||
$pagesDir = $chapter->getPagesDirectory();
|
||||
$volume = $chapter->getVolume();
|
||||
|
||||
if ($pagesDir !== null && $volume !== null) {
|
||||
if (null !== $pagesDir && null !== $volume) {
|
||||
if ($pagesDir === $currentPagesDir && $volume === $currentVolume) {
|
||||
$currentGroup[] = $chapter;
|
||||
} else {
|
||||
@@ -104,7 +104,7 @@ readonly class GetMangaChaptersHandler
|
||||
$max = max($numbers);
|
||||
|
||||
$fmt = fn (float $n) => $n == (int) $n ? (string) (int) $n : (string) $n;
|
||||
$range = count($group) > 1 ? $fmt($min) . '-' . $fmt($max) : $fmt($min);
|
||||
$range = count($group) > 1 ? $fmt($min).'-'.$fmt($max) : $fmt($min);
|
||||
|
||||
return new ChapterResponse(
|
||||
id: $first->getId(),
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
namespace App\Domain\Manga\Application\QueryHandler;
|
||||
|
||||
use App\Domain\Manga\Application\Query\GetMangaList;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Manga\Application\Response\MangaListResponse;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
|
||||
readonly class GetMangaListHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $mangaRepository
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ readonly class GetMangaListHandler
|
||||
foreach ($mangas as $manga) {
|
||||
$id = $manga->getId()->getValue();
|
||||
$chapterCounts[$id] = [
|
||||
'total' => $this->mangaRepository->countChapters($id),
|
||||
'total' => $this->mangaRepository->countChapters($id),
|
||||
'scraped' => $this->mangaRepository->countAvailableChapters($id),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use App\Domain\Manga\Domain\Model\Manga;
|
||||
readonly class SearchLocalMangaHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaRepositoryInterface $repository
|
||||
private MangaRepositoryInterface $repository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use App\Domain\Manga\Domain\Model\Manga;
|
||||
readonly class SearchMangaHandler
|
||||
{
|
||||
public function __construct(
|
||||
private MangaProviderInterface $mangaProvider
|
||||
private MangaProviderInterface $mangaProvider,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ readonly class SearchMangaHandler
|
||||
{
|
||||
$mangaCollection = $this->mangaProvider->search($query->title);
|
||||
|
||||
|
||||
return new MangaSearchResponse(
|
||||
array_map(
|
||||
fn (Manga $manga, int $index) => new MangaSearchItem(
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly class ChapterListResponse
|
||||
public array $chapters,
|
||||
public int $total,
|
||||
public int $page,
|
||||
public int $limit
|
||||
public int $limit,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
readonly class DownloadResponse implements ResponseInterface
|
||||
{
|
||||
public function __construct(
|
||||
public Response $httpResponse
|
||||
public Response $httpResponse,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ readonly class MangaListResponse
|
||||
public int $total,
|
||||
public int $page,
|
||||
public int $limit,
|
||||
public array $chapterCounts = []
|
||||
public array $chapterCounts = [],
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ readonly class MangaMatchItem
|
||||
public ?string $thumbnailUrl,
|
||||
public int $matchScore,
|
||||
public ?float $chapterNumber = null,
|
||||
public ?float $volumeNumber = null
|
||||
public ?float $volumeNumber = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ readonly class MangaMatchResponse
|
||||
public array $matches,
|
||||
public ?float $chapterNumber,
|
||||
public ?float $volumeNumber,
|
||||
public array $possibleTitles
|
||||
public array $possibleTitles,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ readonly class MangaResponse
|
||||
public ?string $imageUrl,
|
||||
public ?string $thumbnailUrl,
|
||||
public ?float $rating,
|
||||
public bool $monitored
|
||||
public bool $monitored,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ readonly class MangaSearchItem
|
||||
public string $status,
|
||||
public ?string $imageUrl,
|
||||
public ?string $thumbnailUrl,
|
||||
public ?float $rating
|
||||
public ?float $rating,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ readonly class SearchLocalMangaResponse
|
||||
public array $items,
|
||||
public int $total,
|
||||
public int $page,
|
||||
public int $limit
|
||||
public int $limit,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user