fix: uses symfony de-normalizer to map tmdb data to objects
This commit is contained in:
166
src/Tmdb/TmdbClient.php
Normal file
166
src/Tmdb/TmdbClient.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Base\Enum\MediaType;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\ObjectMapper\ObjectMapper;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Tmdb\Client;
|
||||
use Tmdb\Event\BeforeRequestEvent;
|
||||
use Tmdb\Event\HydrationEvent;
|
||||
use Tmdb\Event\Listener\Psr6CachedRequestListener;
|
||||
use Tmdb\Event\Listener\Request\AcceptJsonRequestListener;
|
||||
use Tmdb\Event\Listener\Request\ApiTokenRequestListener;
|
||||
use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener;
|
||||
use Tmdb\Event\Listener\Request\UserAgentRequestListener;
|
||||
use Tmdb\Event\RequestEvent;
|
||||
use Tmdb\Model\Movie;
|
||||
use Tmdb\Model\Tv;
|
||||
use Tmdb\Repository\MovieRepository;
|
||||
use Tmdb\Repository\TvRepository;
|
||||
use Tmdb\Token\Api\ApiToken;
|
||||
use Tmdb\Token\Api\BearerToken;
|
||||
|
||||
class TmdbClient
|
||||
{
|
||||
protected Client $client;
|
||||
|
||||
protected MovieRepository $movieRepository;
|
||||
|
||||
protected TvRepository $tvRepository;
|
||||
|
||||
protected ObjectMapper $objectMapper;
|
||||
|
||||
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
||||
|
||||
public function __construct(
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly CacheItemPoolInterface $cache,
|
||||
private readonly EventDispatcherInterface $eventDispatcher,
|
||||
#[Autowire(env: 'TMDB_API')] string $apiKey,
|
||||
) {
|
||||
$this->client = new Client(
|
||||
[
|
||||
/** @var ApiToken|BearerToken */
|
||||
'api_token' => new BearerToken($apiKey),
|
||||
'secure' => true,
|
||||
'base_uri' => Client::TMDB_URI,
|
||||
'event_dispatcher' => [
|
||||
'adapter' => $this->eventDispatcher,
|
||||
],
|
||||
// We make use of PSR-17 and PSR-18 auto discovery to automatically guess these, but preferably set these explicitly.
|
||||
'http' => [
|
||||
'client' => null,
|
||||
'request_factory' => null,
|
||||
'response_factory' => null,
|
||||
'stream_factory' => null,
|
||||
'uri_factory' => null,
|
||||
],
|
||||
'hydration' => [
|
||||
'event_listener_handles_hydration' => true,
|
||||
'only_for_specified_models' => [
|
||||
Movie::class,
|
||||
Tv::class,
|
||||
Tv\Episode::class,
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
/**
|
||||
* Required event listeners and events to be registered with the PSR-14 Event Dispatcher.
|
||||
*/
|
||||
$requestListener = new Psr6CachedRequestListener(
|
||||
$this->client->getHttpClient(),
|
||||
$this->eventDispatcher,
|
||||
$cache,
|
||||
$this->client->getHttpClient()->getPsr17StreamFactory(),
|
||||
[]
|
||||
);
|
||||
$this->eventDispatcher->addListener(RequestEvent::class, $requestListener);
|
||||
|
||||
$apiTokenListener = new ApiTokenRequestListener($this->client->getToken());
|
||||
$this->eventDispatcher->addListener(BeforeRequestEvent::class, $apiTokenListener);
|
||||
|
||||
$acceptJsonListener = new AcceptJsonRequestListener();
|
||||
$this->eventDispatcher->addListener(BeforeRequestEvent::class, $acceptJsonListener);
|
||||
|
||||
$jsonContentTypeListener = new ContentTypeJsonRequestListener();
|
||||
$this->eventDispatcher->addListener(BeforeRequestEvent::class, $jsonContentTypeListener);
|
||||
|
||||
$userAgentListener = new UserAgentRequestListener();
|
||||
$this->eventDispatcher->addListener(BeforeRequestEvent::class, $userAgentListener);
|
||||
|
||||
// $hydrationListener = new HydrationListener($this->eventDispatcher);
|
||||
// $this->eventDispatcher->addListener(HydrationEvent::class, $hydrationListener);
|
||||
|
||||
$this->movieRepository = new MovieRepository($this->client);
|
||||
$this->tvRepository = new TvRepository($this->client);
|
||||
}
|
||||
|
||||
public function search() {}
|
||||
|
||||
public function find() {}
|
||||
|
||||
public function movieDetails() {}
|
||||
|
||||
public function tvshowDetails() {}
|
||||
|
||||
public function tvEpisodeDetails() {}
|
||||
|
||||
public function relatedMedia() {}
|
||||
|
||||
public function popularMovies(int $resultCount = 6): Map
|
||||
{
|
||||
$results = $this->movieRepository->getApi()->getPopular();
|
||||
return Map::from($results['results'])->map(function ($result) {
|
||||
$result['external_ids'] = $this->getExternalIds($result['id'], MediaType::Movie->value);
|
||||
return $result;
|
||||
})->filter(function ($result) {
|
||||
return array_key_exists('imdb_id', $result['external_ids']);
|
||||
})->map(function ($result) {
|
||||
$result = $this->serializer->denormalize($result, TmdbResult::class, context: ['media_type' => MediaType::Movie->value]);
|
||||
return $result;
|
||||
})->slice(0, $resultCount);
|
||||
}
|
||||
|
||||
public function popularTvShows(int $resultCount = 6): Map
|
||||
{
|
||||
$results = $this->tvRepository->getApi()->getPopular();
|
||||
return Map::from($results['results'])->map(function ($result) {
|
||||
$result['external_ids'] = $this->getExternalIds($result['id'], MediaType::Movie->value);
|
||||
return $result;
|
||||
})->filter(function ($result) {
|
||||
return array_key_exists('imdb_id', $result['external_ids']) && $result['external_ids']['imdb_id'] !== null && $result['external_ids']['imdb_id'] !== "";
|
||||
})->map(function ($result) {
|
||||
$result = $this->serializer->denormalize($result, TmdbResult::class, context: ['media_type' => MediaType::TvShow->value]);
|
||||
return $result;
|
||||
})->slice(0, $resultCount);
|
||||
}
|
||||
|
||||
public function getExternalIds(string $tmdbId, $mediaType)
|
||||
{
|
||||
try {
|
||||
switch (MediaType::tryFrom($mediaType)->value) {
|
||||
case MediaType::Movie->value:
|
||||
$externalIds = $this->movieRepository->getApi()->getExternalIds($tmdbId);
|
||||
break;
|
||||
case MediaType::TvShow->value:
|
||||
$externalIds = $this->tvRepository->getApi()->getExternalIds($tmdbId);
|
||||
break;
|
||||
default:
|
||||
$externalIds = null;
|
||||
break;
|
||||
}
|
||||
} catch (\throwable $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $externalIds;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user