*/ readonly class MonitorTvSeasonHandler implements HandlerInterface { public function __construct( private MonitorRepository $monitorRepository, private EntityManagerInterface $entityManager, private MediaFiles $mediaFiles, private MessageBusInterface $bus, private LoggerInterface $logger, private Tmdb $tmdb, private MonitorTvEpisodeHandler $monitorTvEpisodeHandler, ) {} public function handle(CommandInterface $command): ResultInterface { $this->logger->info('> [MonitorTvSeasonHandler] Executing MonitorTvSeasonHandler'); $monitor = $this->monitorRepository->find($command->monitorId); // Check current episodes $downloadedEpisodes = $this->mediaFiles ->getEpisodes($monitor->getTitle()) ->map(fn($episode) => (object) (new PTN())->parse($episode)) ->rekey(fn($episode) => $episode->episode); $this->logger->info('> [MonitorTvSeasonHandler] Found ' . count($downloadedEpisodes) . ' downloaded episodes for title: ' . $monitor->getTitle()); // Compare against list from TMDB $episodesInSeason = Map::from( $this->tmdb->tvDetails($monitor->getTmdbId()) ->episodes[$monitor->getSeason()] )->rekey(fn($episode) => $episode['episode_number']); $this->logger->info('> [MonitorTvSeasonHandler] Found ' . count($episodesInSeason) . ' episodes in season ' . $monitor->getSeason() . ' for title: ' . $monitor->getTitle()); // Dispatch Episode commands for each missing Episode foreach ($episodesInSeason as $episode) { $monitorCheck = $this->monitorRepository->findOneBy([ 'imdbId' => $monitor->getImdbId(), 'title' => $monitor->getTitle(), 'monitorType' => 'tvepisode', 'season' => $monitor->getSeason(), 'episode' => $episode['episode_number'], 'status' => ['New', 'Active', 'In Progress'] ]); $this->logger->info('> [MonitorTvSeasonHandler] Monitor exists for season ' . $monitor->getSeason() . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (null !== $monitorCheck ? 'YES' : 'NO')); if (!array_key_exists($episode['episode_number'], $downloadedEpisodes->toArray()) && null === $monitorCheck ) { $episodeMonitor = (new Monitor()) ->setUser($monitor->getUser()) ->setTmdbId($monitor->getTmdbId()) ->setImdbId($monitor->getImdbId()) ->setTitle($monitor->getTitle()) ->setMonitorType('tvepisode') ->setSeason($monitor->getSeason()) ->setEpisode($episode['episode_number']) ->setCreatedAt(new DateTimeImmutable()) ->setSearchCount(0) ->setStatus('New'); $this->monitorRepository->getEntityManager()->persist($episodeMonitor); $this->monitorRepository->getEntityManager()->flush(); $command = new MonitorTvEpisodeCommand($episodeMonitor->getId()); $this->monitorTvEpisodeHandler->handle($command); $this->logger->info('> [MonitorTvSeasonHandler] Dispatching MonitorTvEpisodeCommand for season ' . $episodeMonitor->getSeason() . ' episode ' . $episodeMonitor->getEpisode() . ' for title: ' . $monitor->getTitle()); } } $monitor->setLastSearch(new DateTimeImmutable()); $monitor->setSearchCount($monitor->getSearchCount() + 1); $monitor->setStatus('Complete'); $this->entityManager->flush(); return new MonitorMovieResult( status: 'OK', result: [ 'monitor' => $monitor, ] ); } }