All in GraphQL #34
@ -43,15 +43,14 @@ use Aviat\AnimeClient\API\Kitsu;
|
|||||||
<article class="media">
|
<article class="media">
|
||||||
<?php
|
<?php
|
||||||
$link = $url->generate('anime.details', ['id' => $anime['slug']]);
|
$link = $url->generate('anime.details', ['id' => $anime['slug']]);
|
||||||
$titles = Kitsu::getTitles($anime['titles']);
|
|
||||||
?>
|
?>
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= $helper->picture("images/anime/{$anime['id']}.webp") ?>
|
<?= $helper->picture("images/anime/{$anime['id']}.webp") ?>
|
||||||
</a>
|
</a>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= $anime['titles']['canonical'] ?>
|
<?= $anime['title'] ?>
|
||||||
<?php foreach ($titles as $title): ?>
|
<?php foreach ($anime['titles'] as $title): ?>
|
||||||
<br />
|
<br />
|
||||||
<small><?= $title ?></small>
|
<small><?= $title ?></small>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
@ -71,15 +70,14 @@ use Aviat\AnimeClient\API\Kitsu;
|
|||||||
<article class="media">
|
<article class="media">
|
||||||
<?php
|
<?php
|
||||||
$link = $url->generate('manga.details', ['id' => $manga['slug']]);
|
$link = $url->generate('manga.details', ['id' => $manga['slug']]);
|
||||||
$titles = Kitsu::getTitles($manga['titles']);
|
|
||||||
?>
|
?>
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= $helper->picture("images/manga/{$manga['id']}.webp") ?>
|
<?= $helper->picture("images/manga/{$manga['id']}.webp") ?>
|
||||||
</a>
|
</a>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= $manga['titles']['canonical'] ?>
|
<?= $manga['title'] ?>
|
||||||
<?php foreach ($titles as $title): ?>
|
<?php foreach ($manga['titles'] as $title): ?>
|
||||||
<br />
|
<br />
|
||||||
<small><?= $title ?></small>
|
<small><?= $title ?></small>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
@ -172,12 +170,12 @@ use Aviat\AnimeClient\API\Kitsu;
|
|||||||
<th>Cast Member</th>
|
<th>Cast Member</th>
|
||||||
<th>Series</th>
|
<th>Series</th>
|
||||||
</tr>
|
</tr>
|
||||||
<?php foreach ($casting as $cid => $c): ?>
|
<?php foreach ($casting as $c): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<article class="character">
|
<article class="character">
|
||||||
<?php
|
<?php
|
||||||
$link = $url->generate('person', ['id' => $c['person']['id']]);
|
$link = $url->generate('person', ['id' => $c['person']['id'], 'slug' => $c['person']['slug']]);
|
||||||
?>
|
?>
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= $helper->picture(getLocalImg($c['person']['image'])) ?>
|
<?= $helper->picture(getLocalImg($c['person']['image'])) ?>
|
||||||
@ -192,16 +190,15 @@ use Aviat\AnimeClient\API\Kitsu;
|
|||||||
<?php foreach ($c['series'] as $series): ?>
|
<?php foreach ($c['series'] as $series): ?>
|
||||||
<article class="media">
|
<article class="media">
|
||||||
<?php
|
<?php
|
||||||
$link = $url->generate('anime.details', ['id' => $series['attributes']['slug']]);
|
$link = $url->generate('anime.details', ['id' => $series['slug']]);
|
||||||
$titles = Kitsu::filterTitles($series['attributes']);
|
|
||||||
?>
|
?>
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= $helper->picture(getLocalImg($series['attributes']['posterImage']['small'], TRUE)) ?>
|
<?= $helper->picture(getLocalImg($series['posterImage'], TRUE)) ?>
|
||||||
</a>
|
</a>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<a href="<?= $link ?>">
|
<a href="<?= $link ?>">
|
||||||
<?= array_shift($titles) ?>
|
<?= $series['title'] ?>
|
||||||
<?php foreach ($titles as $title): ?>
|
<?php foreach ($series['titles'] as $title): ?>
|
||||||
<br />
|
<br />
|
||||||
<small><?= $title ?></small>
|
<small><?= $title ?></small>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
"danielstjules/stringy": "^3.1.0",
|
"danielstjules/stringy": "^3.1.0",
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
|
"ext-intl": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-gd": "*",
|
"ext-gd": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
@ -292,6 +292,34 @@ final class Kitsu {
|
|||||||
return $valid;
|
return $valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter out duplicate and very similar titles from a GraphQL response
|
||||||
|
*
|
||||||
|
* @param array $titles
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getFilteredTitles(array $titles): array
|
||||||
|
{
|
||||||
|
// The 'canonical' title is always considered
|
||||||
|
$valid = [$titles['canonical']];
|
||||||
|
|
||||||
|
if (array_key_exists('localized', $titles) && is_array($titles['localized']))
|
||||||
|
{
|
||||||
|
foreach($titles['localized'] as $alternateTitle)
|
||||||
|
{
|
||||||
|
if (self::titleIsUnique($alternateTitle, $valid))
|
||||||
|
{
|
||||||
|
$valid[] = $alternateTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't return the canonical titles
|
||||||
|
array_shift($valid);
|
||||||
|
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name and logo for the streaming service of the current link
|
* Get the name and logo for the streaming service of the current link
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
query ($id: ID!) {
|
query ($id: ID!) {
|
||||||
findPersonById(id: $id) {
|
findPersonById(id: $id) {
|
||||||
id
|
id
|
||||||
|
description
|
||||||
birthday
|
birthday
|
||||||
image {
|
image {
|
||||||
original {
|
original {
|
||||||
@ -22,46 +23,45 @@ query ($id: ID!) {
|
|||||||
localized
|
localized
|
||||||
}
|
}
|
||||||
voices {
|
voices {
|
||||||
licensor {
|
nodes {
|
||||||
name
|
locale
|
||||||
}
|
mediaCharacter {
|
||||||
locale
|
role
|
||||||
mediaCharacter {
|
character {
|
||||||
role
|
id
|
||||||
character {
|
image {
|
||||||
id
|
original {
|
||||||
image {
|
height
|
||||||
original {
|
name
|
||||||
height
|
url
|
||||||
name
|
width
|
||||||
url
|
}
|
||||||
width
|
}
|
||||||
|
names {
|
||||||
|
canonical
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
names {
|
media {
|
||||||
canonical
|
id
|
||||||
}
|
posterImage {
|
||||||
}
|
original {
|
||||||
media {
|
height
|
||||||
id
|
name
|
||||||
posterImage {
|
url
|
||||||
original {
|
width
|
||||||
height
|
}
|
||||||
name
|
views {
|
||||||
url
|
height
|
||||||
width
|
name
|
||||||
|
url
|
||||||
|
width
|
||||||
|
}
|
||||||
}
|
}
|
||||||
views {
|
titles {
|
||||||
height
|
canonical
|
||||||
name
|
localized
|
||||||
url
|
|
||||||
width
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
titles {
|
|
||||||
canonical
|
|
||||||
localized
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\JsonAPI;
|
use Aviat\AnimeClient\API\JsonAPI;
|
||||||
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\AnimeClient\Types\Character;
|
use Aviat\AnimeClient\Types\Character;
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||||
|
use Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data transformation class for character pages
|
* Data transformation class for character pages
|
||||||
@ -70,19 +72,88 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
return [[], []];
|
return [[], []];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$titleSort = fn ($a, $b) => $a['title'] <=> $b['title'];
|
||||||
|
|
||||||
$rawMedia = array_column($data, 'media');
|
$rawMedia = array_column($data, 'media');
|
||||||
$rawAnime = array_filter($rawMedia, fn ($item) => $item['type'] === 'Anime');
|
$rawAnime = array_filter($rawMedia, fn ($item) => $item['type'] === 'Anime');
|
||||||
$rawManga = array_filter($rawMedia, fn ($item) => $item['type'] === 'Manga');
|
$rawManga = array_filter($rawMedia, fn ($item) => $item['type'] === 'Manga');
|
||||||
|
|
||||||
uasort($rawAnime, fn ($a, $b) => $a['titles']['canonical'] <=> $b['titles']['canonical']);
|
$anime = array_map(static function ($item) {
|
||||||
uasort($rawManga, fn ($a, $b) => $a['titles']['canonical'] <=> $b['titles']['canonical']);
|
$output = $item;
|
||||||
|
unset($output['titles']);
|
||||||
|
$output['title'] = $item['titles']['canonical'];
|
||||||
|
$output['titles'] = Kitsu::getFilteredTitles($item['titles']);
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}, $rawAnime);
|
||||||
|
$manga = array_map(static function ($item) {
|
||||||
|
$output = $item;
|
||||||
|
unset($output['titles']);
|
||||||
|
$output['title'] = $item['titles']['canonical'];
|
||||||
|
$output['titles'] = Kitsu::getFilteredTitles($item['titles']);
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}, $rawManga);
|
||||||
|
|
||||||
|
uasort($anime, $titleSort);
|
||||||
|
uasort($manga, $titleSort);
|
||||||
|
|
||||||
$media = [
|
$media = [
|
||||||
'anime' => $rawAnime,
|
'anime' => $anime,
|
||||||
'manga' => $rawManga,
|
'manga' => $manga,
|
||||||
];
|
];
|
||||||
|
|
||||||
return [$media, []];
|
$rawVoices = array_filter($data, fn($item) => count((array)$item['voices']['nodes']) > 0);
|
||||||
|
|
||||||
|
if (empty($rawVoices))
|
||||||
|
{
|
||||||
|
return [$media, []];
|
||||||
|
}
|
||||||
|
|
||||||
|
$castings = [
|
||||||
|
'Voice Actor' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($rawVoices as $voiceMap)
|
||||||
|
{
|
||||||
|
foreach ($voiceMap['voices']['nodes'] as $voice)
|
||||||
|
{
|
||||||
|
$lang = Locale::getDisplayLanguage($voice['locale'], 'en');
|
||||||
|
$id = $voice['person']['name'];
|
||||||
|
$seriesId = $voiceMap['media']['id'];
|
||||||
|
|
||||||
|
if ( ! array_key_exists($lang, $castings['Voice Actor']))
|
||||||
|
{
|
||||||
|
$castings['Voice Actor'][$lang] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! array_key_exists($id, $castings['Voice Actor'][$lang]))
|
||||||
|
{
|
||||||
|
$castings['Voice Actor'][$lang][$id] = [
|
||||||
|
'person' => [
|
||||||
|
'id' => $voice['person']['id'],
|
||||||
|
'slug' => $voice['person']['slug'],
|
||||||
|
'image' => $voice['person']['image']['original']['url'],
|
||||||
|
'name' => $voice['person']['name'],
|
||||||
|
],
|
||||||
|
'series' => []
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$castings['Voice Actor'][$lang][$id]['series'][$seriesId] = [
|
||||||
|
'id' => $seriesId,
|
||||||
|
'slug' => $voiceMap['media']['slug'],
|
||||||
|
'title' => $voiceMap['media']['titles']['canonical'],
|
||||||
|
'titles' => Kitsu::getFilteredTitles($voiceMap['media']['titles']),
|
||||||
|
'posterImage' => $voiceMap['media']['posterImage']['views'][1]['url'],
|
||||||
|
];
|
||||||
|
|
||||||
|
uasort($castings['Voice Actor'][$lang][$id]['series'], $titleSort);
|
||||||
|
ksort($castings['Voice Actor'][$lang]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$media, $castings];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user