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
@@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user