Version 5.1 - All the GraphQL #32
@ -115,21 +115,9 @@ final class ListItem extends AbstractListItem {
|
|||||||
*/
|
*/
|
||||||
public function get(string $id): array
|
public function get(string $id): array
|
||||||
{
|
{
|
||||||
$authHeader = $this->getAuthHeader();
|
return $this->requestBuilder->runQuery('GetLibraryItem', [
|
||||||
|
'id' => $id,
|
||||||
$request = $this->requestBuilder->newRequest('GET', "library-entries/{$id}")
|
]);
|
||||||
->setQuery([
|
|
||||||
'include' => 'media,media.categories,media.mappings'
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($authHeader !== NULL)
|
|
||||||
{
|
|
||||||
$request = $request->setHeader('Authorization', $authHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
$request = $request->getFullRequest();
|
|
||||||
$response = getResponse($request);
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +59,6 @@ trait MangaTrait {
|
|||||||
$baseData = $this->requestBuilder->runQuery('MangaDetails', [
|
$baseData = $this->requestBuilder->runQuery('MangaDetails', [
|
||||||
'slug' => $slug
|
'slug' => $slug
|
||||||
]);
|
]);
|
||||||
// $baseData = $this->getRawMediaData('manga', $slug);
|
|
||||||
|
|
||||||
if (empty($baseData))
|
if (empty($baseData))
|
||||||
{
|
{
|
||||||
@ -80,7 +79,6 @@ trait MangaTrait {
|
|||||||
$baseData = $this->requestBuilder->runQuery('MangaDetailsById', [
|
$baseData = $this->requestBuilder->runQuery('MangaDetailsById', [
|
||||||
'id' => $mangaId,
|
'id' => $mangaId,
|
||||||
]);
|
]);
|
||||||
// $baseData = $this->getRawMediaDataById('manga', $mangaId);
|
|
||||||
return $this->mangaTransformer->transform($baseData);
|
return $this->mangaTransformer->transform($baseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ use Aviat\AnimeClient\API\{
|
|||||||
use Aviat\AnimeClient\API\Kitsu\Transformer\{
|
use Aviat\AnimeClient\API\Kitsu\Transformer\{
|
||||||
AnimeTransformer,
|
AnimeTransformer,
|
||||||
AnimeListTransformer,
|
AnimeListTransformer,
|
||||||
|
LibraryEntryTransformer,
|
||||||
MangaTransformer,
|
MangaTransformer,
|
||||||
MangaListTransformer
|
MangaListTransformer
|
||||||
};
|
};
|
||||||
@ -331,24 +332,12 @@ final class Model {
|
|||||||
public function getListItem(string $listId)
|
public function getListItem(string $listId)
|
||||||
{
|
{
|
||||||
$baseData = $this->listItem->get($listId);
|
$baseData = $this->listItem->get($listId);
|
||||||
$included = JsonAPI::organizeIncludes($baseData['included']);
|
if ( ! isset($baseData['data']['findLibraryEntryById']))
|
||||||
|
|
||||||
if (array_key_exists('anime', $included))
|
|
||||||
{
|
{
|
||||||
$included = JsonAPI::inlineIncludedRelationships($included, 'anime');
|
return [];
|
||||||
$baseData['data']['included'] = $included;
|
|
||||||
return $this->animeListTransformer->transform($baseData['data']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('manga', $included))
|
return (new LibraryEntryTransformer())->transform($baseData['data']['findLibraryEntryById']);
|
||||||
{
|
|
||||||
$included = JsonAPI::inlineIncludedRelationships($included, 'manga');
|
|
||||||
$baseData['data']['included'] = $included;
|
|
||||||
$baseData['data']['manga'] = $baseData['included'][0];
|
|
||||||
return $this->mangaListTransformer->transform($baseData['data']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $baseData['data'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -464,76 +453,6 @@ final class Model {
|
|||||||
->get(['kitsu_username']);
|
->get(['kitsu_username']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the raw data for the anime/manga id
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @param string $id
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function getRawMediaDataById(string $type, string $id): array
|
|
||||||
{
|
|
||||||
$options = [
|
|
||||||
'query' => [
|
|
||||||
'include' => ($type === 'anime')
|
|
||||||
? 'categories,mappings,streamingLinks'
|
|
||||||
: 'categories,mappings',
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$data = $this->requestBuilder->getRequest("{$type}/{$id}", $options);
|
|
||||||
|
|
||||||
if (empty($data['data']))
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$baseData = $data['data']['attributes'];
|
|
||||||
$baseData['id'] = $id;
|
|
||||||
$baseData['included'] = $data['included'];
|
|
||||||
return $baseData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get media item by slug
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @param string $slug
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function getRawMediaData(string $type, string $slug): array
|
|
||||||
{
|
|
||||||
$options = [
|
|
||||||
'query' => [
|
|
||||||
'filter' => [
|
|
||||||
'slug' => $slug
|
|
||||||
],
|
|
||||||
'fields' => [
|
|
||||||
'categories' => 'slug,title',
|
|
||||||
'characters' => 'slug,name,image',
|
|
||||||
'mappings' => 'externalSite,externalId',
|
|
||||||
'animeCharacters' => 'character,role',
|
|
||||||
'mediaCharacters' => 'character,role',
|
|
||||||
],
|
|
||||||
'include' => ($type === 'anime')
|
|
||||||
? 'staff,staff.person,categories,mappings,streamingLinks,animeCharacters.character,characters.character'
|
|
||||||
: 'staff,staff.person,categories,mappings,characters.character',
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$data = $this->requestBuilder->getRequest($type, $options);
|
|
||||||
|
|
||||||
if (empty($data['data']))
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$baseData = $data['data'][0]['attributes'];
|
|
||||||
$baseData['id'] = $data['data'][0]['id'];
|
|
||||||
$baseData['included'] = $data['included'];
|
|
||||||
return $baseData;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getListCount(string $type, string $status = ''): int
|
private function getListCount(string $type, string $status = ''): int
|
||||||
{
|
{
|
||||||
$options = [
|
$options = [
|
||||||
|
@ -13,17 +13,6 @@ query ($slug: String!) {
|
|||||||
canonicalLocale
|
canonicalLocale
|
||||||
localized
|
localized
|
||||||
},
|
},
|
||||||
primaryMedia {
|
|
||||||
posterImage {
|
|
||||||
original {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
titles {
|
|
||||||
canonical
|
|
||||||
}
|
|
||||||
type
|
|
||||||
},
|
|
||||||
media {
|
media {
|
||||||
nodes {
|
nodes {
|
||||||
media {
|
media {
|
||||||
|
73
src/AnimeClient/API/Kitsu/Queries/GetLibraryItem.graphql
Normal file
73
src/AnimeClient/API/Kitsu/Queries/GetLibraryItem.graphql
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
query($id: ID!) {
|
||||||
|
findLibraryEntryById(id: $id) {
|
||||||
|
id
|
||||||
|
updatedAt
|
||||||
|
notes
|
||||||
|
nsfw
|
||||||
|
private
|
||||||
|
progress
|
||||||
|
reconsumeCount
|
||||||
|
reconsuming
|
||||||
|
status
|
||||||
|
rating
|
||||||
|
media {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
ageRating
|
||||||
|
categories {
|
||||||
|
nodes {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mappings {
|
||||||
|
nodes {
|
||||||
|
externalId
|
||||||
|
externalSite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
posterImage {
|
||||||
|
views {
|
||||||
|
width
|
||||||
|
height
|
||||||
|
url
|
||||||
|
}
|
||||||
|
original {
|
||||||
|
width
|
||||||
|
height
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startDate
|
||||||
|
endDate
|
||||||
|
titles {
|
||||||
|
canonical
|
||||||
|
localized
|
||||||
|
canonicalLocale
|
||||||
|
}
|
||||||
|
type
|
||||||
|
...on Anime {
|
||||||
|
episodeCount
|
||||||
|
episodeLength
|
||||||
|
streamingLinks {
|
||||||
|
nodes {
|
||||||
|
dubs
|
||||||
|
subs
|
||||||
|
regions
|
||||||
|
streamer {
|
||||||
|
id
|
||||||
|
siteName
|
||||||
|
}
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subtype
|
||||||
|
}
|
||||||
|
...on Manga {
|
||||||
|
chapterCount
|
||||||
|
volumeCount
|
||||||
|
subtype
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -255,7 +255,7 @@ final class RequestBuilder extends APIRequestBuilder {
|
|||||||
public function mutate(string $name, array $variables = []): array
|
public function mutate(string $name, array $variables = []): array
|
||||||
{
|
{
|
||||||
$request = $this->mutateRequest($name, $variables);
|
$request = $this->mutateRequest($name, $variables);
|
||||||
$response = $this->getResponseFromRequest($request);
|
$response = getResponse($request);
|
||||||
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
return Json::decode(wait($response->getBody()->buffer()));
|
||||||
}
|
}
|
||||||
@ -267,7 +267,7 @@ final class RequestBuilder extends APIRequestBuilder {
|
|||||||
* @param string $url
|
* @param string $url
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function getResponse(string $type, string $url, array $options = []): Response
|
public function getResponse(string $type, string $url, array $options = []): Response
|
||||||
{
|
{
|
||||||
@ -286,27 +286,6 @@ final class RequestBuilder extends APIRequestBuilder {
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
* @throws Throwable
|
|
||||||
*/
|
|
||||||
private function getResponseFromRequest(Request $request): Response
|
|
||||||
{
|
|
||||||
$logger = $this->container->getLogger('kitsu-request');
|
|
||||||
$response = getResponse($request);
|
|
||||||
|
|
||||||
$logger->debug('Kitsu GraphQL response', [
|
|
||||||
'status' => $response->getStatus(),
|
|
||||||
'reason' => $response->getReason(),
|
|
||||||
'body' => $response->getBody(),
|
|
||||||
'headers' => $response->getHeaders(),
|
|
||||||
'requestHeaders' => $request->getHeaders(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove some boilerplate for GraphQL requests
|
* Remove some boilerplate for GraphQL requests
|
||||||
*
|
*
|
||||||
|
@ -34,9 +34,6 @@ final class AnimeTransformer extends AbstractTransformer {
|
|||||||
*/
|
*/
|
||||||
public function transform($item): AnimePage
|
public function transform($item): AnimePage
|
||||||
{
|
{
|
||||||
// TODO: missing GraphQL data:
|
|
||||||
// * streaming links
|
|
||||||
|
|
||||||
$base = array_key_exists('findAnimeBySlug', $item['data'])
|
$base = array_key_exists('findAnimeBySlug', $item['data'])
|
||||||
? $item['data']['findAnimeBySlug']
|
? $item['data']['findAnimeBySlug']
|
||||||
: $item['data']['findAnimeById'];
|
: $item['data']['findAnimeById'];
|
||||||
@ -52,12 +49,14 @@ final class AnimeTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
if (count($base['characters']['nodes']) > 0)
|
if (count($base['characters']['nodes']) > 0)
|
||||||
{
|
{
|
||||||
$characters['main'] = [];
|
|
||||||
$characters['supporting'] = [];
|
|
||||||
|
|
||||||
foreach ($base['characters']['nodes'] as $rawCharacter)
|
foreach ($base['characters']['nodes'] as $rawCharacter)
|
||||||
{
|
{
|
||||||
$type = $rawCharacter['role'] === 'MAIN' ? 'main' : 'supporting';
|
$type = mb_strtolower($rawCharacter['role']);
|
||||||
|
if ( ! isset($characters[$type]))
|
||||||
|
{
|
||||||
|
$characters[$type] = [];
|
||||||
|
}
|
||||||
|
|
||||||
$details = $rawCharacter['character'];
|
$details = $rawCharacter['character'];
|
||||||
$characters[$type][$details['id']] = [
|
$characters[$type][$details['id']] = [
|
||||||
'image' => $details['image'],
|
'image' => $details['image'],
|
||||||
@ -66,13 +65,19 @@ final class AnimeTransformer extends AbstractTransformer {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
uasort($characters['main'], fn($a, $b) => $a['name'] <=> $b['name']);
|
foreach (array_keys($characters) as $type)
|
||||||
uasort($characters['supporting'], fn($a, $b) => $a['name'] <=> $b['name']);
|
|
||||||
|
|
||||||
if (empty($characters['supporting']))
|
|
||||||
{
|
{
|
||||||
unset($characters['supporting']);
|
if (empty($characters[$type]))
|
||||||
|
{
|
||||||
|
unset($characters[$type]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uasort($characters[$type], fn($a, $b) => $a['name'] <=> $b['name']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krsort($characters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($base['staff']['nodes']) > 0)
|
if (count($base['staff']['nodes']) > 0)
|
||||||
|
@ -0,0 +1,188 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 7.4
|
||||||
|
*
|
||||||
|
* @package HummingbirdAnimeClient
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2015 - 2020 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.1
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
|
use Aviat\AnimeClient\Types\{FormItem, AnimeListItem, MangaListItem, MangaListItemDetail};
|
||||||
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
|
use Aviat\Ion\Type\StringType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transformer for anime list
|
||||||
|
*/
|
||||||
|
final class LibraryEntryTransformer extends AbstractTransformer
|
||||||
|
{
|
||||||
|
public function transform($item)
|
||||||
|
{
|
||||||
|
$type = $item['media']['type'] ?? '';
|
||||||
|
|
||||||
|
$genres = [];
|
||||||
|
if ($type !== '')
|
||||||
|
{
|
||||||
|
$genres = array_column($item['media']['categories']['nodes'], 'title');
|
||||||
|
sort($genres);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (strtolower($type))
|
||||||
|
{
|
||||||
|
case 'anime':
|
||||||
|
return $this->animeTransform($item, $genres);
|
||||||
|
|
||||||
|
case 'manga':
|
||||||
|
return $this->mangaTransform($item, $genres);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function animeTransform($item, array $genres): AnimeListItem
|
||||||
|
{
|
||||||
|
$animeId = $item['media']['id'];
|
||||||
|
$anime = $item['media'];
|
||||||
|
|
||||||
|
$rating = (int) $item['rating'] !== 0
|
||||||
|
? $item['rating'] / 2
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
$total_episodes = array_key_exists('episodeCount', $anime) && (int) $anime['episodeCount'] !== 0
|
||||||
|
? (int) $anime['episodeCount']
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
$MALid = NULL;
|
||||||
|
|
||||||
|
if (isset($anime['mappings']['nodes']))
|
||||||
|
{
|
||||||
|
foreach ($anime['mappings']['nodes'] as $mapping)
|
||||||
|
{
|
||||||
|
if ($mapping['externalSite'] === 'MYANIMELIST_ANIME')
|
||||||
|
{
|
||||||
|
$MALid = $mapping['externalId'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$streamingLinks = array_key_exists('nodes', $anime['streamingLinks'])
|
||||||
|
? Kitsu::parseStreamingLinks($anime['streamingLinks']['nodes'])
|
||||||
|
: [];
|
||||||
|
|
||||||
|
$titles = Kitsu::getFilteredTitles($anime['titles']);
|
||||||
|
$title = $anime['titles']['canonical'];
|
||||||
|
|
||||||
|
return AnimeListItem::from([
|
||||||
|
'id' => $item['id'],
|
||||||
|
'mal_id' => $MALid,
|
||||||
|
'episodes' => [
|
||||||
|
'watched' => (int) $item['progress'] !== 0
|
||||||
|
? (int) $item['progress']
|
||||||
|
: '-',
|
||||||
|
'total' => $total_episodes,
|
||||||
|
'length' => $anime['episodeLength'],
|
||||||
|
],
|
||||||
|
'airing' => [
|
||||||
|
'status' => Kitsu::getAiringStatus($anime['startDate'], $anime['endDate']),
|
||||||
|
'started' => $anime['startDate'],
|
||||||
|
'ended' => $anime['endDate']
|
||||||
|
],
|
||||||
|
'anime' => [
|
||||||
|
'id' => $animeId,
|
||||||
|
'age_rating' => $anime['ageRating'],
|
||||||
|
'title' => $title,
|
||||||
|
'titles' => $titles,
|
||||||
|
'slug' => $anime['slug'],
|
||||||
|
'show_type' => (string)StringType::from($anime['subtype'])->upperCaseFirst(),
|
||||||
|
'cover_image' => $anime['posterImage']['views'][1]['url'],
|
||||||
|
'genres' => $genres,
|
||||||
|
'streaming_links' => $streamingLinks,
|
||||||
|
],
|
||||||
|
'watching_status' => $item['status'],
|
||||||
|
'notes' => $item['notes'],
|
||||||
|
'rewatching' => (bool) $item['reconsuming'],
|
||||||
|
'rewatched' => (int) $item['reconsumeCount'],
|
||||||
|
'user_rating' => $rating,
|
||||||
|
'private' => $item['private'] ?? FALSE,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function mangaTransform($item, array $genres): MangaListItem
|
||||||
|
{
|
||||||
|
$mangaId = $item['media']['id'];
|
||||||
|
$manga = $item['media'];
|
||||||
|
|
||||||
|
$rating = (int) $item['rating'] !== 0
|
||||||
|
? $item['rating'] / 2
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
$totalChapters = ((int) $manga['chapterCount'] !== 0)
|
||||||
|
? $manga['chapterCount']
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
$totalVolumes = ((int) $manga['volumeCount'] !== 0)
|
||||||
|
? $manga['volumeCount']
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
$readChapters = ((int) $item['progress'] !== 0)
|
||||||
|
? $item['progress']
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
$MALid = NULL;
|
||||||
|
|
||||||
|
if (isset($manga['mappings']['nodes']))
|
||||||
|
{
|
||||||
|
foreach ($manga['mappings']['nodes'] as $mapping)
|
||||||
|
{
|
||||||
|
if ($mapping['externalSite'] === 'MYANIMELIST_MANGA')
|
||||||
|
{
|
||||||
|
$MALid = $mapping['externalId'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$titles = Kitsu::getFilteredTitles($manga['titles']);
|
||||||
|
$title = $manga['titles']['canonical'];
|
||||||
|
|
||||||
|
return MangaListItem::from([
|
||||||
|
'id' => $item['id'],
|
||||||
|
'mal_id' => $MALid,
|
||||||
|
'chapters' => [
|
||||||
|
'read' => $readChapters,
|
||||||
|
'total' => $totalChapters
|
||||||
|
],
|
||||||
|
'volumes' => [
|
||||||
|
'read' => '-', //$item['attributes']['volumes_read'],
|
||||||
|
'total' => $totalVolumes
|
||||||
|
],
|
||||||
|
'manga' => MangaListItemDetail::from([
|
||||||
|
'genres' => $genres,
|
||||||
|
'id' => $mangaId,
|
||||||
|
'image' => $manga['posterImage']['views'][1]['url'],
|
||||||
|
'slug' => $manga['slug'],
|
||||||
|
'title' => $title,
|
||||||
|
'titles' => $titles,
|
||||||
|
'type' => (string)StringType::from($manga['subtype'])->upperCaseFirst(),
|
||||||
|
'url' => 'https://kitsu.io/manga/' . $manga['slug'],
|
||||||
|
]),
|
||||||
|
'reading_status' => strtolower($item['status']),
|
||||||
|
'notes' => $item['notes'],
|
||||||
|
'rereading' => (bool)$item['reconsuming'],
|
||||||
|
'reread' => $item['reconsumeCount'],
|
||||||
|
'user_rating' => $rating,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -49,12 +49,14 @@ final class MangaTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
if (count($base['characters']['nodes']) > 0)
|
if (count($base['characters']['nodes']) > 0)
|
||||||
{
|
{
|
||||||
$characters['main'] = [];
|
|
||||||
$characters['supporting'] = [];
|
|
||||||
|
|
||||||
foreach ($base['characters']['nodes'] as $rawCharacter)
|
foreach ($base['characters']['nodes'] as $rawCharacter)
|
||||||
{
|
{
|
||||||
$type = $rawCharacter['role'] === 'MAIN' ? 'main' : 'supporting';
|
$type = mb_strtolower($rawCharacter['role']);
|
||||||
|
if ( ! isset($characters[$type]))
|
||||||
|
{
|
||||||
|
$characters[$type] = [];
|
||||||
|
}
|
||||||
|
|
||||||
$details = $rawCharacter['character'];
|
$details = $rawCharacter['character'];
|
||||||
$characters[$type][$details['id']] = [
|
$characters[$type][$details['id']] = [
|
||||||
'image' => $details['image'],
|
'image' => $details['image'],
|
||||||
@ -63,13 +65,19 @@ final class MangaTransformer extends AbstractTransformer {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
uasort($characters['main'], fn($a, $b) => $a['name'] <=> $b['name']);
|
foreach (array_keys($characters) as $type)
|
||||||
uasort($characters['supporting'], fn($a, $b) => $a['name'] <=> $b['name']);
|
|
||||||
|
|
||||||
if (empty($characters['supporting']))
|
|
||||||
{
|
{
|
||||||
unset($characters['supporting']);
|
if (empty($characters[$type]))
|
||||||
|
{
|
||||||
|
unset($characters[$type]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uasort($characters[$type], fn($a, $b) => $a['name'] <=> $b['name']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krsort($characters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($base['staff']['nodes']) > 0)
|
if (count($base['staff']['nodes']) > 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user