*/ class GetMediaInfoFromLibraryHandler implements HandlerInterface { public function __construct( private readonly TmdbClient $tmdb, private readonly MediaFiles $mediaFiles, private readonly LoggerInterface $logger, private readonly MonitorRepository $monitorRepository, ) {} public function handle(C $command): R { $result = new GetMediaFromLibraryResult(); $tmdbResult = $this->fetchTmdbData($command->imdbId, $command->mediaType); if (null === $tmdbResult) { $this->logger->warning('[GetMediaInfoFromLibraryHandler] TMDb result was not found, this may lead to issues in the rest of the library search', (array) $command); } $this->setResultExists($tmdbResult->mediaType, $tmdbResult->title, $result); if ($result->notExists()) { return $result; } $this->parseFromTmdbResult($tmdbResult, $result); if ($command->mediaType === MediaType::TvShow->value) { $this->setEpisodes($tmdbResult, $result); $this->setSeasons($tmdbResult, $result); $this->setMonitors($command->userId, $command->imdbId, $result); } return $result; } private function fetchTmdbData(string $imdbId, string $mediaType): ?TmdbResult { return match($mediaType) { MediaType::Movie->value => $this->tmdb->movieDetails($imdbId), MediaType::TvShow->value => $this->tmdb->tvShowDetails($imdbId), default => null, }; } private function setResultExists(string $mediaType, string $title, GetMediaFromLibraryResult $result): void { $fsResult = match($mediaType) { MediaType::Movie->value => $this->mediaFiles->movieExists($title), MediaType::TvShow->value => $this->mediaFiles->tvShowExists($title), default => false, }; if (false === $fsResult) { $result->setExists(false); } else { $result->setExists(true); } } public function parseFromTmdbResult(TmdbResult $tmdbResult, GetMediaFromLibraryResult $result): void { $result->setTitle($tmdbResult->title); $result->setMediaType($tmdbResult->mediaType); $result->setImdbId($tmdbResult->imdbId); } public function setEpisodes(TmdbResult $tmdbResult, GetMediaFromLibraryResult $result): void { $existingEpisodeFiles = $this->mediaFiles->tvshowExists($tmdbResult->title); $existingEpisodeMap = []; foreach ($existingEpisodeFiles as $file) { /** @var \SplFileInfo $file */ $ptn = (object) new PTN()->parse($file->getBasename()); if (!array_key_exists($ptn->season, $existingEpisodeMap)) { $existingEpisodeMap[$ptn->season] = []; } if (!in_array($ptn->episode, $existingEpisodeMap[$ptn->season])) { $existingEpisodeMap[$ptn->season][] = $ptn->episode; } } $existingEpisodes = []; $missingEpisodes = []; foreach ($tmdbResult->episodes as $season => $episodes) { foreach ($episodes as $episode) { if (array_key_exists($season, $existingEpisodeMap)) { if (in_array($episode->episodeNumber, $existingEpisodeMap[$season])) { $existingEpisodes[] = $episode; } else { $missingEpisodes[] = $episode; } } else { $missingEpisodes[] = $episode; } } } $result->setEpisodes($existingEpisodes); $result->setMissingEpisodes($missingEpisodes); } public function setSeasons(TmdbResult $tmdbResult, GetMediaFromLibraryResult $result): void { $existingEpisodeFiles = $this->mediaFiles->tvshowExists($tmdbResult->title); $existingEpisodeMap = []; foreach ($existingEpisodeFiles as $file) { /** @var \SplFileInfo $file */ $ptn = (object) new PTN()->parse($file->getBasename()); $existingEpisodeMap[$ptn->season][] = $ptn->episode; } $existingFullSeasons = []; $existingPartialSeasons = []; $missingSeasons = []; foreach ($existingEpisodeMap as $season => $episodes) { if (count($tmdbResult->episodes[$season]) === count($episodes)) { $existingFullSeasons[] = $season; } elseif (count($episodes) > 0) { $existingPartialSeasons[] = $season; } } $seasons = array_keys($tmdbResult->episodes); foreach ($seasons as $season) { if (!in_array($season, $existingFullSeasons) && !in_array($season, $existingPartialSeasons)) { $missingSeasons[] = $season; } } $result->setSeasons($existingFullSeasons); $result->setPartialSeasons($existingPartialSeasons); $result->setMissingSeasons($missingSeasons); } public function setMonitors(int $userId, string $imdbId, GetMediaFromLibraryResult $result) { $result->setMonitorCount( $this->monitorRepository->countUserChildrenByParentId($userId, $imdbId) ); $result->setActiveMonitorCount( $this->monitorRepository->countUserActiveChildrenByParentId($userId, $imdbId) ); $result->setCompleteMonitorCount( $this->monitorRepository->countUserCompleteChildrenByParentId($userId, $imdbId) ); } }