*/ readonly class MonitorTvShowHandler implements HandlerInterface { public function __construct( private MonitorRepository $monitorRepository, private EntityManagerInterface $entityManager, private MediaFiles $mediaFiles, private MessageBusInterface $bus, private LoggerInterface $logger, private Tmdb $tmdb, ) {} public function handle(CommandInterface $command): ResultInterface { $this->logger->info('> [MonitorTvShowHandler] Executing MonitorTvShowHandler'); $monitor = $this->monitorRepository->find($command->monitorId); // Check current episodes $downloadedEpisodes = $this->mediaFiles ->getEpisodes($monitor->getTitle()) ->map(fn($episode) => (object) (new PTN())->parse($episode)); $this->logger->info('> [MonitorTvShowHandler] Found ' . count($downloadedEpisodes) . ' downloaded episodes for title: ' . $monitor->getTitle()); // Compare against list from TMDB $episodesInShow = Map::from( $this->tmdb->tvDetails($monitor->getTmdbId()) ->episodes )->flat(1); $this->logger->info('> [MonitorTvShowHandler] Found ' . count($episodesInShow) . ' episodes in season ' . $monitor->getSeason() . ' for title: ' . $monitor->getTitle()); // Dispatch Episode commands for each missing Episode foreach ($episodesInShow as $episode) { $episodeAlreadyDownloaded = $downloadedEpisodes->find( fn($ep) => $ep->episode === $episode['episode_number'] && $ep->season === $episode['season_number'] ); $episodeAlreadyDownloaded = !is_null($episodeAlreadyDownloaded); if (false === $episodeAlreadyDownloaded) { $monitor = (new Monitor()) ->setUser($monitor->getUser()) ->setTmdbId($monitor->getTmdbId()) ->setImdbId($monitor->getImdbId()) ->setTitle($monitor->getTitle()) ->setMonitorType('tvshow') ->setSeason($episode['season_number']) ->setEpisode($episode['episode_number']) ->setCreatedAt(new DateTimeImmutable()) ->setSearchCount(0) ->setStatus('New'); $this->monitorRepository->getEntityManager()->persist($monitor); $this->monitorRepository->getEntityManager()->flush(); $command = new MonitorTvEpisodeCommand($monitor->getId()); $this->bus->dispatch($command); $this->logger->info('> [MonitorTvShowHandler] Dispatching MonitorTvEpisodeCommand for season ' . $monitor->getSeason() . ' episode ' . $monitor->getEpisode() . ' for title: ' . $monitor->getTitle()); } } $monitor->setLastSearch(new DateTimeImmutable()); $monitor->setSearchCount($monitor->getSearchCount() + 1); $monitor->setStatus('Complete'); $this->entityManager->flush(); return new MonitorTvEpisodeResult( status: 'OK', result: [ 'monitor' => $monitor, ] ); } }