chore: makes better use of symfony denormalizer
This commit is contained in:
19
src/Tmdb/Dto/CastMemberDto.php
Normal file
19
src/Tmdb/Dto/CastMemberDto.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Dto;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\SerializedPath;
|
||||
|
||||
class CastMemberDto
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
#[SerializedPath('[name]')]
|
||||
public string $name,
|
||||
) {}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
18
src/Tmdb/Dto/CrewMemberDto.php
Normal file
18
src/Tmdb/Dto/CrewMemberDto.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Dto;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\SerializedPath;
|
||||
|
||||
class CrewMemberDto
|
||||
{
|
||||
public function __construct(
|
||||
#[SerializedPath('[name]')]
|
||||
public string $name,
|
||||
) {}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
18
src/Tmdb/Dto/GenreDto.php
Normal file
18
src/Tmdb/Dto/GenreDto.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Dto;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\SerializedPath;
|
||||
|
||||
class GenreDto
|
||||
{
|
||||
public function __construct(
|
||||
public int $id,
|
||||
public string $name,
|
||||
) {}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
29
src/Tmdb/Dto/TmdbEpisodeDto.php
Normal file
29
src/Tmdb/Dto/TmdbEpisodeDto.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Dto;
|
||||
|
||||
use App\Base\Enum\MediaType;
|
||||
use Symfony\Component\Serializer\Attribute\SerializedPath;
|
||||
|
||||
class TmdbEpisodeDto
|
||||
{
|
||||
public function __construct(
|
||||
#[SerializedPath('[id]')]
|
||||
public ?int $tmdbId = null,
|
||||
#[SerializedPath('[show_id]')]
|
||||
public ?int $tmdbShowId = null,
|
||||
public ?string $mediaType = MediaType::TvShow->value,
|
||||
public ?string $imdbId = null,
|
||||
public ?string $name = null,
|
||||
#[SerializedPath('[air_date]')]
|
||||
public ?string $airDate = null,
|
||||
#[SerializedPath('[overview]')]
|
||||
public ?string $description = null,
|
||||
public ?string $poster = null,
|
||||
public ?int $runtime = 0,
|
||||
#[SerializedPath('[season_number]')]
|
||||
public ?int $seasonNumber = 0,
|
||||
#[SerializedPath('[episode_number]')]
|
||||
public ?int $episodeNumber = 0,
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Framework\Serializer;
|
||||
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class TmdbMovieResultDenormalizer extends TmdbResultDenormalizer implements DenormalizerInterface
|
||||
{
|
||||
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(service: 'serializer.normalizer.object')]
|
||||
private readonly NormalizerInterface $normalizer,
|
||||
) {
|
||||
parent::__construct($normalizer);
|
||||
}
|
||||
|
||||
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): TmdbResult|array|null
|
||||
{
|
||||
/** @var TmdbResult $result */
|
||||
$result = $this->normalizer->denormalize($data, TmdbResult::class, $format, $context);
|
||||
|
||||
if (array_key_exists('release_date', $data) && !in_array($data['release_date'], ['', null,])) {
|
||||
$airDate = (new \DateTime($data['release_date']));
|
||||
} else {
|
||||
$airDate = null;
|
||||
}
|
||||
|
||||
if (!array_key_exists('original_title', $data)) {
|
||||
dd($data, $context);
|
||||
}
|
||||
|
||||
$result->title = $data['original_title'];
|
||||
$result->premiereDate = $airDate;
|
||||
$result->poster = (null !== $data['poster_path']) ? self::POSTER_IMG_PATH . $data['poster_path'] : null;
|
||||
$result->year = (null !== $airDate) ? $airDate->format('Y') : null;
|
||||
$result->mediaType = "movies";
|
||||
$result->stars = $this->getStars($data);
|
||||
$result->directors = $this->getDirectors($data);
|
||||
dd($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function supportsDenormalization(
|
||||
mixed $data,
|
||||
string $type,
|
||||
?string $format = null,
|
||||
array $context = []
|
||||
): bool {
|
||||
return array_key_exists('media_type', $context) &&
|
||||
$context['media_type'] === MediaType::Movie->value;
|
||||
}
|
||||
|
||||
public function getSupportedTypes(?string $format): array
|
||||
{
|
||||
return [
|
||||
TmdbResult::class => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
78
src/Tmdb/Framework/Serializer/TmdbResultDenormalizer.php
Normal file
78
src/Tmdb/Framework/Serializer/TmdbResultDenormalizer.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Framework\Serializer;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Tmdb\Dto\CastMemberDto;
|
||||
use App\Tmdb\Dto\CrewMemberDto;
|
||||
use App\Tmdb\Dto\GenreDto;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class TmdbResultDenormalizer implements DenormalizerInterface
|
||||
{
|
||||
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(service: 'serializer.normalizer.object')]
|
||||
private readonly NormalizerInterface $normalizer,
|
||||
) {}
|
||||
|
||||
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): TmdbResult|array|null
|
||||
{
|
||||
return $this->normalizer->denormalize($data, TmdbResult::class, $format, $context);
|
||||
}
|
||||
|
||||
protected function getStars(array $data): ?array
|
||||
{
|
||||
if (!array_key_exists('credits', $data)) {
|
||||
return null;
|
||||
}
|
||||
return Map::from($data['credits']['cast'])
|
||||
->slice(0, 3)
|
||||
->map(fn($item) => $this->normalizer->denormalize($item, CastMemberDto::class))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
protected function getDirectors(array $data): ?array
|
||||
{
|
||||
if (!array_key_exists('credits', $data)) {
|
||||
return null;
|
||||
}
|
||||
return Map::from($data['credits']['crew'])
|
||||
->filter(fn($item) => $item['job'] === 'Director')
|
||||
->slice(0, 3)
|
||||
->map(fn($item) => $this->normalizer->denormalize($item, CrewMemberDto::class))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function getGenres(array $data, MediaType $mediaType): ?array
|
||||
{
|
||||
if (array_key_exists('genres', $data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Map::from($data['genres'])
|
||||
->map(fn($item) => $this->normalizer->denormalize($item, GenreDto::class))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function supportsDenormalization(
|
||||
mixed $data,
|
||||
string $type,
|
||||
?string $format = null,
|
||||
array $context = []
|
||||
): bool {
|
||||
return !array_key_exists('media_type', $context);
|
||||
}
|
||||
|
||||
public function getSupportedTypes(?string $format): array
|
||||
{
|
||||
return [
|
||||
TmdbResult::class => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Framework\Serializer;
|
||||
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Tmdb\Dto\TmdbEpisodeDto;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class TmdbTvEpisodeResultDenormalizer implements DenormalizerInterface
|
||||
{
|
||||
public function __construct(
|
||||
#[Autowire(service: 'serializer.normalizer.object')]
|
||||
private readonly NormalizerInterface $normalizer,
|
||||
) {}
|
||||
|
||||
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): TmdbResult|array|null
|
||||
{
|
||||
/** @var TmdbEpisodeDto $result */
|
||||
$result = $this->normalizer->denormalize($data, TmdbResult::class, $format, $context);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function supportsDenormalization(
|
||||
mixed $data,
|
||||
string $type,
|
||||
?string $format = null,
|
||||
array $context = []
|
||||
): bool {
|
||||
return array_key_exists('media_type', $context) &&
|
||||
$context['media_type'] === MediaType::TvEpisode->value;
|
||||
}
|
||||
|
||||
public function getSupportedTypes(?string $format): array
|
||||
{
|
||||
return [
|
||||
TmdbResult::class => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb\Framework\Serializer;
|
||||
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class TmdbTvShowResultDenormalizer extends TmdbResultDenormalizer implements DenormalizerInterface
|
||||
{
|
||||
public function __construct(
|
||||
#[Autowire(service: 'serializer.normalizer.object')]
|
||||
private readonly NormalizerInterface $normalizer,
|
||||
) {
|
||||
parent::__construct($normalizer);
|
||||
}
|
||||
|
||||
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): TmdbResult|array|null
|
||||
{
|
||||
/** @var TmdbResult $result */
|
||||
$result = $this->normalizer->denormalize($data, TmdbResult::class, $format, $context);
|
||||
|
||||
if (!in_array($data['first_air_date'], ['', null,])) {
|
||||
$airDate = (new \DateTime($data['first_air_date']));
|
||||
} else {
|
||||
$airDate = null;
|
||||
}
|
||||
|
||||
$result->title = $data['original_name'];
|
||||
$result->premiereDate = $airDate;
|
||||
$result->poster = (null !== $data['poster_path']) ? self::POSTER_IMG_PATH . $data['poster_path'] : null;
|
||||
$result->year = (null !== $airDate) ? $airDate->format('Y') : null;
|
||||
$result->mediaType = MediaType::TvShow->value;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function supportsDenormalization(
|
||||
mixed $data,
|
||||
string $type,
|
||||
?string $format = null,
|
||||
array $context = []
|
||||
): bool {
|
||||
return array_key_exists('media_type', $context) &&
|
||||
$context['media_type'] === "tvshows";
|
||||
}
|
||||
|
||||
public function getSupportedTypes(?string $format): array
|
||||
{
|
||||
return [
|
||||
TmdbResult::class => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Tmdb;
|
||||
use Aimeos\Map;
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Base\Util\ImdbMatcher;
|
||||
use App\Tmdb\Dto\TmdbEpisodeDto;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
@@ -37,6 +38,16 @@ class TmdbClient
|
||||
protected TvEpisodeRepository $tvEpisodeRepository;
|
||||
protected SearchRepository $searchRepository;
|
||||
|
||||
protected array $mediaTypeMap = [
|
||||
MediaType::Movie->value => MediaType::Movie->value,
|
||||
MediaType::TvShow->value => MediaType::TvShow->value,
|
||||
MediaType::TvEpisode->value => MediaType::TvEpisode->value,
|
||||
'movie' => 'movies',
|
||||
'tv' => 'tvshows',
|
||||
];
|
||||
|
||||
protected $repos = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly CacheItemPoolInterface $cache,
|
||||
@@ -96,6 +107,11 @@ class TmdbClient
|
||||
$this->tvSeasonRepository = new TvSeasonRepository($this->client);
|
||||
$this->tvEpisodeRepository = new TvEpisodeRepository($this->client);
|
||||
$this->searchRepository = new SearchRepository($this->client);
|
||||
$this->repos = [
|
||||
MediaType::Movie->value => $this->movieRepository,
|
||||
MediaType::TvShow->value => $this->tvRepository,
|
||||
MediaType::TvEpisode->value => $this->tvEpisodeRepository,
|
||||
];
|
||||
}
|
||||
|
||||
public function search(string $term): TmdbResult|Map
|
||||
@@ -109,17 +125,15 @@ class TmdbClient
|
||||
$handler = $handlers[$data['media_type']];
|
||||
return $this->$handler($term);
|
||||
}
|
||||
return $this->parseListOfResults(
|
||||
$this->searchRepository->getApi()->searchMulti($term),
|
||||
"movies"
|
||||
);
|
||||
$results = $this->searchRepository->getApi()->searchMulti($term);
|
||||
return $this->parseListOfResults($results);
|
||||
}
|
||||
|
||||
public function movieDetails(string $imdbId): ?TmdbResult
|
||||
{
|
||||
$tmdbId = $this->findByImdbId($imdbId)['id'];
|
||||
return $this->parseResult(
|
||||
$this->movieRepository->getApi()->getMovie($tmdbId, ['append_to_response' => 'external_ids']),
|
||||
$this->movieRepository->getApi()->getMovie($tmdbId, ['append_to_response' => 'external_ids,credits']),
|
||||
MediaType::Movie->value,
|
||||
$imdbId
|
||||
);
|
||||
@@ -128,7 +142,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']);
|
||||
$media = $this->tvRepository->getApi()->getTvShow($tmdbId, ['append_to_response' => 'external_ids,credits']);
|
||||
$media['seasons'] = Map::from($media['seasons'])->filter(function ($data) {
|
||||
return $data['season_number'] !== 0 &&
|
||||
strtolower($data['name']) !== 'specials';
|
||||
@@ -147,7 +161,7 @@ class TmdbClient
|
||||
|
||||
public function tvSeasonDetails(string $tmdbId, int $season): array
|
||||
{
|
||||
$result = $this->tvSeasonRepository->getApi()->getSeason($tmdbId, $season);
|
||||
$result = $this->tvSeasonRepository->getApi()->getSeason($tmdbId, $season, ['append_to_response' => 'external_ids,credits']);
|
||||
$result['episodes'] = Map::from($result['episodes'])->map(function ($data) {
|
||||
$data['still_path'] = self::POSTER_IMG_PATH . $data['still_path'];
|
||||
$data['poster'] = $data['still_path'];
|
||||
@@ -156,9 +170,9 @@ class TmdbClient
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function tvEpisodeDetails(string $tmdbId, int $season, int $episode): ?TmdbResult
|
||||
public function tvEpisodeDetails(string $tmdbId, int $season, int $episode): TmdbResult|TmdbEpisodeDto|null
|
||||
{
|
||||
$result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => 'external_ids']);
|
||||
$result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => 'external_ids,credits']);
|
||||
return $this->parseResult(
|
||||
$result,
|
||||
MediaType::TvEpisode->value,
|
||||
@@ -168,56 +182,46 @@ class TmdbClient
|
||||
|
||||
public function relatedMedia(string $tmdbId, string $mediaType, int $resultCount = 6): Map
|
||||
{
|
||||
$repos = [
|
||||
'movies' => $this->movieRepository,
|
||||
'tvshows' => $this->tvRepository,
|
||||
];
|
||||
$results = $repos[$mediaType]->getApi()->getRecommendations($tmdbId);
|
||||
|
||||
$results = $this->repos[$mediaType]->getApi()->getRecommendations($tmdbId, ['append_to_response' => 'external_ids']);
|
||||
return $this->parseListOfResults(
|
||||
$results,
|
||||
$mediaType,
|
||||
$resultCount
|
||||
);
|
||||
}
|
||||
|
||||
public function popularMovies(int $resultCount = 6): Map
|
||||
{
|
||||
$results = $this->movieRepository->getApi()->getPopular();
|
||||
$results['results'] = Map::from($results['results'])->map(function ($result) {
|
||||
$result['media_type'] = MediaType::Movie->value;
|
||||
return $result;
|
||||
});
|
||||
return $this->parseListOfResults(
|
||||
$this->movieRepository->getApi()->getPopular(),
|
||||
"movies",
|
||||
$results,
|
||||
$resultCount
|
||||
);
|
||||
}
|
||||
|
||||
public function popularTvShows(int $resultCount = 6): Map
|
||||
{
|
||||
$results = $this->tvRepository->getApi()->getPopular();
|
||||
$results['results'] = Map::from($results['results'])->map(function ($result) {
|
||||
$result['media_type'] = MediaType::TvShow->value;
|
||||
return $result;
|
||||
});
|
||||
return $this->parseListOfResults(
|
||||
$this->tvRepository->getApi()->getPopular(),
|
||||
"tvshows",
|
||||
$results,
|
||||
$resultCount
|
||||
);
|
||||
}
|
||||
|
||||
private function getExternalIds(string $tmdbId, $mediaType): ?array
|
||||
private function getExternalIds(int $tmdbId, string $mediaType): ?array
|
||||
{
|
||||
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) {
|
||||
if (!array_key_exists($mediaType, $this->repos) ||
|
||||
!in_array($mediaType, [MediaType::Movie->value, MediaType::TvShow->value])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $externalIds;
|
||||
return $this->repos[$mediaType]->getApi()->getExternalIds($tmdbId);
|
||||
}
|
||||
|
||||
private function findByImdbId(string $imdbId): array
|
||||
@@ -236,7 +240,7 @@ class TmdbClient
|
||||
throw new \Exception("No results found for $imdbId");
|
||||
}
|
||||
|
||||
private function parseResult(array $data, string $mediaType, string $imdbId): TmdbResult
|
||||
private function parseResult(array $data, string $mediaType, string $imdbId): TmdbResult|TmdbEpisodeDto
|
||||
{
|
||||
if (!array_key_exists('external_ids', $data)) {
|
||||
$data['external_ids'] = ['imdb_id' => $imdbId];
|
||||
@@ -244,20 +248,21 @@ class TmdbClient
|
||||
return $this->serializer->denormalize($data, TmdbResult::class, context: ['media_type' => $mediaType]);
|
||||
}
|
||||
|
||||
private function parseListOfResults(array $data, string $mediaType, ?int $resultCount = null): Map
|
||||
private function parseListOfResults(array $data, ?int $resultCount = null): Map
|
||||
{
|
||||
$results = Map::from($data['results'])->filter(
|
||||
fn ($result) => array_key_exists('id', $result)
|
||||
)->map(function ($result) {
|
||||
$result['external_ids'] = $this->getExternalIds($result['id'], MediaType::Movie->value);
|
||||
$results = Map::from($data['results'])->filter(function ($result) {
|
||||
return array_key_exists('media_type', $result) &&
|
||||
in_array($result['media_type'], array_keys($this->mediaTypeMap));
|
||||
})->map(function ($result) {
|
||||
$result['external_ids'] = $this->getExternalIds($result['id'], $this->mediaTypeMap[$result['media_type']]);
|
||||
return $result;
|
||||
})->filter(function ($result) {
|
||||
return array_key_exists('id', $result) &&
|
||||
array_key_exists('imdb_id', $result['external_ids']) &&
|
||||
$result['external_ids']['imdb_id'] !== null &&
|
||||
$result['external_ids']['imdb_id'] !== "";
|
||||
})->map(function ($result) use ($mediaType) {
|
||||
return $this->serializer->denormalize($result, TmdbResult::class, context: ['media_type' => $mediaType]);
|
||||
})->map(function ($result) {
|
||||
return $this->serializer->denormalize($result, TmdbResult::class, context: ['media_type' => $this->mediaTypeMap[$result['media_type']]]);
|
||||
});
|
||||
|
||||
if (null !== $resultCount) {
|
||||
|
||||
@@ -2,10 +2,32 @@
|
||||
|
||||
namespace App\Tmdb;
|
||||
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Tmdb\Dto\CastMemberDto;
|
||||
use App\Tmdb\Dto\CrewMemberDto;
|
||||
use App\Tmdb\Dto\GenreDto;
|
||||
use App\Tmdb\Dto\TmdbEpisodeDto;
|
||||
use Symfony\Component\Serializer\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\SerializedPath;
|
||||
|
||||
class TmdbResult
|
||||
{
|
||||
/**
|
||||
* @param string|null $imdbId
|
||||
* @param int|null $tmdbId
|
||||
* @param string|null $title
|
||||
* @param string|null $description
|
||||
* @param string|null $poster
|
||||
* @param \DateTimeInterface|null $premiereDate
|
||||
* @param string|null $year
|
||||
* @param string|null $mediaType
|
||||
* @param array<TmdbEpisodeDto[]>|null $episodes
|
||||
* @param string|null $episodeAirDate
|
||||
* @param GenreDto[]|null $genres
|
||||
* @param CastMemberDto[]|null $stars
|
||||
* @param CrewMemberDto[]|null $directors
|
||||
* @param int|null $runtime
|
||||
*/
|
||||
public function __construct(
|
||||
#[SerializedPath('[external_ids][imdb_id]')]
|
||||
public ?string $imdbId = "",
|
||||
@@ -18,8 +40,15 @@ class TmdbResult
|
||||
public ?\DateTimeInterface $premiereDate = null,
|
||||
public ?string $year = null,
|
||||
public ?string $mediaType = "",
|
||||
#[Context(denormalizationContext: [
|
||||
'media_type' => MediaType::TvEpisode->value
|
||||
])]
|
||||
#[SerializedPath('[seasons]')]
|
||||
public ?array $episodes = null,
|
||||
public ?string $episodeAirDate = null,
|
||||
public ?array $genres = null,
|
||||
public ?array $stars = null,
|
||||
public ?array $directors = null,
|
||||
public ?int $runtime = null,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Base\Enum\MediaType;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
class TmdbResultDenormalizer implements DenormalizerInterface
|
||||
{
|
||||
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(service: 'serializer.normalizer.object')]
|
||||
private readonly NormalizerInterface $normalizer,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): TmdbResult|array|null
|
||||
{
|
||||
$parsers = [
|
||||
MediaType::Movie->value => 'parseMovie',
|
||||
MediaType::TvShow->value => 'parseTvShow',
|
||||
'movie' => 'parseMovie',
|
||||
'tv' => 'parseTvShow',
|
||||
'tvepisode' => 'parseEpisode',
|
||||
];
|
||||
|
||||
$denormalized = $this->normalizer->denormalize($data, TmdbResult::class, $format, $context);
|
||||
$parser = array_key_exists('media_type', $data) ? $parsers[$data['media_type']] : $parsers[$context['media_type']];
|
||||
return $this->$parser($data, $denormalized);
|
||||
}
|
||||
|
||||
private function parseTvShow(array $data, TmdbResult $result): TmdbResult
|
||||
{
|
||||
if (!in_array($data['first_air_date'], ['', null,])) {
|
||||
$airDate = (new \DateTime($data['first_air_date']));
|
||||
} else {
|
||||
$airDate = null;
|
||||
}
|
||||
|
||||
$result->title = $data['original_name'];
|
||||
$result->premiereDate = $airDate;
|
||||
$result->poster = (null !== $data['poster_path']) ? self::POSTER_IMG_PATH . $data['poster_path'] : null;
|
||||
$result->year = (null !== $airDate) ? $airDate->format('Y') : null;
|
||||
$result->mediaType = "tvshows";
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function parseMovie(array $data, TmdbResult $result): TmdbResult
|
||||
{
|
||||
if (!in_array($data['release_date'], ['', null,])) {
|
||||
$airDate = (new \DateTime($data['release_date']));
|
||||
} else {
|
||||
$airDate = null;
|
||||
}
|
||||
|
||||
$result->title = $data['original_title'];
|
||||
$result->premiereDate = $airDate;
|
||||
$result->poster = (null !== $data['poster_path']) ? self::POSTER_IMG_PATH . $data['poster_path'] : null;
|
||||
$result->year = (null !== $airDate) ? $airDate->format('Y') : null;
|
||||
$result->mediaType = "movies";
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function parseEpisode(array $data, TmdbResult $result): TmdbResult
|
||||
{
|
||||
if (!in_array($data['air_date'], ['', null,])) {
|
||||
$airDate = (new \DateTime($data['air_date']));
|
||||
} else {
|
||||
$airDate = null;
|
||||
}
|
||||
|
||||
$result->premiereDate = $airDate;
|
||||
$result->episodeAirDate = $airDate->format('m/d/Y');
|
||||
$result->poster = (null !== $data['still_path']) ? self::POSTER_IMG_PATH . $data['still_path'] : null;
|
||||
$result->year = (null !== $airDate) ? $airDate->format('Y') : null;
|
||||
$result->mediaType = "tvshows";
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function supportsDenormalization(
|
||||
mixed $data,
|
||||
string $type,
|
||||
?string $format = null,
|
||||
array $context = []
|
||||
): bool {
|
||||
return $type === TmdbResult::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getSupportedTypes(?string $format): array
|
||||
{
|
||||
return [
|
||||
TmdbResult::class => true,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user