From 50bcb4e1dfa02d956d51ab6c7dfbcefe89ec4cf5 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sat, 8 Nov 2025 12:34:53 -0600 Subject: [PATCH] feat(Tmdb): adds pre-filter option to filter by media language --- .env | 5 +++++ src/Tmdb/TmdbClient.php | 30 +++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/.env b/.env index f4c685c..23f3406 100644 --- a/.env +++ b/.env @@ -62,3 +62,8 @@ NTFY_DSN= ###> sentry/sentry-symfony ### SENTRY_DSN= ###< sentry/sentry-symfony ### + +# TMDB 'with_original_language' option +# - only include media originally +# produced in this language +TMDB_ORIGINAL_LANGUAGE=en diff --git a/src/Tmdb/TmdbClient.php b/src/Tmdb/TmdbClient.php index c80752a..626d39b 100644 --- a/src/Tmdb/TmdbClient.php +++ b/src/Tmdb/TmdbClient.php @@ -19,6 +19,7 @@ use Tmdb\Event\Listener\Request\ApiTokenRequestListener; use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener; use Tmdb\Event\Listener\Request\UserAgentRequestListener; use Tmdb\Event\RequestEvent; +use Tmdb\Repository\DiscoverRepository; use Tmdb\Repository\MovieRepository; use Tmdb\Repository\SearchRepository; use Tmdb\Repository\TvEpisodeRepository; @@ -30,6 +31,7 @@ use Tmdb\Token\Api\BearerToken; class TmdbClient { const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500"; + const APPEND_TO_RESPONSE = 'external_ids,credits,watch/providers'; protected Client $client; protected MovieRepository $movieRepository; @@ -38,6 +40,8 @@ class TmdbClient protected TvEpisodeRepository $tvEpisodeRepository; protected SearchRepository $searchRepository; + protected DiscoverRepository $discoverRepository; + protected array $mediaTypeMap = [ MediaType::Movie->value => MediaType::Movie->value, MediaType::TvShow->value => MediaType::TvShow->value, @@ -48,11 +52,14 @@ class TmdbClient protected $repos = []; + private ?string $originalLanguage = 'en'; + public function __construct( private readonly SerializerInterface $serializer, private readonly CacheItemPoolInterface $cache, private readonly EventDispatcherInterface $eventDispatcher, #[Autowire(env: 'TMDB_API')] string $apiKey, + #[Autowire(env: 'TMDB_ORIGINAL_LANGUAGE')] ?string $originalLanguage = null, ) { $this->client = new Client( [ @@ -74,7 +81,7 @@ class TmdbClient 'hydration' => [ 'event_listener_handles_hydration' => false, 'only_for_specified_models' => [] - ] + ], ] ); @@ -107,11 +114,14 @@ class TmdbClient $this->tvSeasonRepository = new TvSeasonRepository($this->client); $this->tvEpisodeRepository = new TvEpisodeRepository($this->client); $this->searchRepository = new SearchRepository($this->client); + $this->discoverRepository = new DiscoverRepository($this->client); + $this->repos = [ MediaType::Movie->value => $this->movieRepository, MediaType::TvShow->value => $this->tvRepository, MediaType::TvEpisode->value => $this->tvEpisodeRepository, ]; + $this->originalLanguage = $originalLanguage; } public function search(string $term): TmdbResult|Map @@ -133,7 +143,7 @@ class TmdbClient { $tmdbId = $this->findByImdbId($imdbId)['id']; return $this->parseResult( - $this->movieRepository->getApi()->getMovie($tmdbId, ['append_to_response' => 'external_ids,credits']), + $this->movieRepository->getApi()->getMovie($tmdbId, ['append_to_response' => static::APPEND_TO_RESPONSE]), MediaType::Movie->value, $imdbId ); @@ -142,7 +152,7 @@ class TmdbClient public function tvshowDetails(string $imdbId): ?TmdbResult { $tmdbId = $this->findByImdbId($imdbId)['id']; - $media = $this->tvRepository->getApi()->getTvShow($tmdbId, ['append_to_response' => 'external_ids,credits']); + $media = $this->tvRepository->getApi()->getTvShow($tmdbId, ['append_to_response' => static::APPEND_TO_RESPONSE]); $media['seasons'] = Map::from($media['seasons'])->filter(function ($data) { return $data['season_number'] !== 0 && @@ -163,7 +173,7 @@ class TmdbClient public function tvSeasonDetails(string $tmdbId, int $season): array { - $result = $this->tvSeasonRepository->getApi()->getSeason($tmdbId, $season, ['append_to_response' => 'external_ids,credits']); + $result = $this->tvSeasonRepository->getApi()->getSeason($tmdbId, $season, ['append_to_response' => static::APPEND_TO_RESPONSE]); $result['episodes'] = Map::from($result['episodes'])->map(function ($data) { $data['still_path'] = self::POSTER_IMG_PATH . $data['still_path']; $data['poster'] = $data['still_path']; @@ -174,7 +184,7 @@ class TmdbClient public function tvEpisodeDetails(string $tmdbId, string $showImdbId, int $season, int $episode): TmdbResult|TmdbEpisodeDto|null { - $result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => 'external_ids,credits']); + $result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => static::APPEND_TO_RESPONSE]); return $this->parseResult( $result, MediaType::TvEpisode->value, @@ -193,7 +203,10 @@ class TmdbClient public function popularMovies(int $resultCount = 6): Map { - $results = $this->movieRepository->getApi()->getPopular(); + $results = $this->discoverRepository->getApi()->discoverMovies([ + 'with_original_language' => $this->originalLanguage, + 'append_to_response' => 'external_ids,watch/providers', + ]); $results['results'] = Map::from($results['results'])->map(function ($result) { $result['media_type'] = MediaType::Movie->value; return $result; @@ -206,7 +219,10 @@ class TmdbClient public function popularTvShows(int $resultCount = 6): Map { - $results = $this->tvRepository->getApi()->getPopular(); + $results = $this->discoverRepository->getApi()->discoverTv([ + 'with_original_language' => $this->originalLanguage, + 'append_to_response' => 'external_ids,watch/providers', + ]); $results['results'] = Map::from($results['results'])->map(function ($result) { $result['media_type'] = MediaType::TvShow->value; return $result;