Fixes for 4.1 #14
@ -2,52 +2,52 @@
|
||||
<main class="details fixed">
|
||||
<section class="flex">
|
||||
<aside class="info">
|
||||
<?= $helper->picture("images/anime/{$show_data['id']}-original.webp") ?>
|
||||
<?= $helper->picture("images/anime/{$data['id']}-original.webp") ?>
|
||||
|
||||
<br />
|
||||
|
||||
<table class="media-details">
|
||||
<tr>
|
||||
<td class="align-right">Airing Status</td>
|
||||
<td><?= $show_data['status'] ?></td>
|
||||
<td><?= $data['status'] ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Show Type</td>
|
||||
<td><?= $show_data['show_type'] ?></td>
|
||||
<td><?= $data['show_type'] ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Episode Count</td>
|
||||
<td><?= $show_data['episode_count'] ?? '-' ?></td>
|
||||
<td><?= $data['episode_count'] ?? '-' ?></td>
|
||||
</tr>
|
||||
<?php if ( ! empty($show_data['episode_length'])): ?>
|
||||
<?php if ( ! empty($data['episode_length'])): ?>
|
||||
<tr>
|
||||
<td>Episode Length</td>
|
||||
<td><?= $show_data['episode_length'] ?> minutes</td>
|
||||
<td><?= $data['episode_length'] ?> minutes</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<?php if ( ! empty($show_data['age_rating'])): ?>
|
||||
<?php if ( ! empty($data['age_rating'])): ?>
|
||||
<tr>
|
||||
<td>Age Rating</td>
|
||||
<td><abbr title="<?= $show_data['age_rating_guide'] ?>"><?= $show_data['age_rating'] ?></abbr>
|
||||
<td><abbr title="<?= $data['age_rating_guide'] ?>"><?= $data['age_rating'] ?></abbr>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<tr>
|
||||
<td>Genres</td>
|
||||
<td>
|
||||
<?= implode(', ', $show_data['genres']) ?>
|
||||
<?= implode(', ', $data['genres']) ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</aside>
|
||||
<article class="text">
|
||||
<h2 class="toph"><a rel="external" href="<?= $show_data['url'] ?>"><?= $show_data['title'] ?></a></h2>
|
||||
<?php foreach ($show_data['titles'] as $title): ?>
|
||||
<h2 class="toph"><a rel="external" href="<?= $data['url'] ?>"><?= $data['title'] ?></a></h2>
|
||||
<?php foreach ($data['titles'] as $title): ?>
|
||||
<h3><?= $title ?></h3>
|
||||
<?php endforeach ?>
|
||||
<br />
|
||||
<p class="description"><?= nl2br($show_data['synopsis']) ?></p>
|
||||
<?php if (count($show_data['streaming_links']) > 0): ?>
|
||||
<p class="description"><?= nl2br($data['synopsis']) ?></p>
|
||||
<?php if (count($data['streaming_links']) > 0): ?>
|
||||
<hr />
|
||||
<h4>Streaming on:</h4>
|
||||
<table class="full-width invisible streaming-links">
|
||||
@ -59,13 +59,13 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($show_data['streaming_links'] as $link): ?>
|
||||
<?php foreach ($data['streaming_links'] as $link): ?>
|
||||
<tr>
|
||||
<td class="align-left">
|
||||
<?php if ($link['meta']['link'] !== FALSE): ?>
|
||||
<a
|
||||
href="<?= $link['link'] ?>"
|
||||
title="Stream '<?= $show_data['title'] ?>' on <?= $link['meta']['name'] ?>"
|
||||
title="Stream '<?= $data['title'] ?>' on <?= $link['meta']['name'] ?>"
|
||||
>
|
||||
<?= $helper->picture("images/{$link['meta']['image']}", 'svg', [
|
||||
'class' => 'streaming-logo',
|
||||
@ -92,13 +92,13 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif ?>
|
||||
<?php if ( ! empty($show_data['trailer_id'])): ?>
|
||||
<?php if ( ! empty($data['trailer_id'])): ?>
|
||||
<div class="responsive-iframe">
|
||||
<h4>Trailer</h4>
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/<?= $show_data['trailer_id'] ?>"
|
||||
src="https://www.youtube.com/embed/<?= $data['trailer_id'] ?>"
|
||||
frameborder="0"
|
||||
allow="autoplay; encrypted-media"
|
||||
allowfullscreen
|
||||
@ -108,13 +108,13 @@
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<?php if (count($characters) > 0): ?>
|
||||
<?php if (count($data['characters']) > 0): ?>
|
||||
<section>
|
||||
<h2>Characters</h2>
|
||||
|
||||
<div class="tabs">
|
||||
<?php $i = 0 ?>
|
||||
<?php foreach ($characters as $role => $list): ?>
|
||||
<?php foreach ($data['characters'] as $role => $list): ?>
|
||||
<input
|
||||
type="radio" name="character-types"
|
||||
id="character-types-<?= $i ?>" <?= ($i === 0) ? 'checked' : '' ?> />
|
||||
@ -140,14 +140,14 @@
|
||||
</section>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (count($staff) > 0): ?>
|
||||
<?php //dump($staff); ?>
|
||||
<?php if (count($data['staff']) > 0): ?>
|
||||
<?php //dump($data['staff']); ?>
|
||||
<section>
|
||||
<h2>Staff</h2>
|
||||
|
||||
<div class="vertical-tabs">
|
||||
<?php $i = 0; ?>
|
||||
<?php foreach ($staff as $role => $people): ?>
|
||||
<?php foreach ($data['staff'] as $role => $people): ?>
|
||||
<div class="tab">
|
||||
<input type="radio" name="staff-roles" id="staff-role<?= $i ?>" <?= $i === 0 ? 'checked' : '' ?> />
|
||||
<label for="staff-role<?= $i ?>"><?= $role ?></label>
|
||||
|
@ -7,10 +7,10 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
<main class="details fixed">
|
||||
<section class="flex flex-no-wrap">
|
||||
<div>
|
||||
<?= $helper->picture("images/characters/{$data[0]['id']}-original.webp") ?>
|
||||
<?php if ( ! empty($data[0]['attributes']['otherNames'])): ?>
|
||||
<?= $helper->picture("images/characters/{$data['id']}-original.webp") ?>
|
||||
<?php if ( ! empty($data['otherNames'])): ?>
|
||||
<h3>Nicknames / Other names</h3>
|
||||
<?php foreach ($data[0]['attributes']['otherNames'] as $name): ?>
|
||||
<?php foreach ($data['otherNames'] as $name): ?>
|
||||
<h4><?= $name ?></h4>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
@ -23,19 +23,19 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
|
||||
<hr />
|
||||
|
||||
<p class="description"><?= $data[0]['attributes']['description'] ?></p>
|
||||
<p class="description"><?= $data['description'] ?></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php if (array_key_exists('anime', $data['included']) || array_key_exists('manga', $data['included'])): ?>
|
||||
<?php if (array_key_exists('anime', $data['media']) || array_key_exists('manga', $data['media'])): ?>
|
||||
<h3>Media</h3>
|
||||
<div class="tabs">
|
||||
<?php if (array_key_exists('anime', $data['included'])): ?>
|
||||
<?php if (array_key_exists('anime', $data['media'])): ?>
|
||||
<input checked="checked" type="radio" id="media-anime" name="media-tabs" />
|
||||
<label for="media-anime">Anime</label>
|
||||
|
||||
<section class="media-wrap content">
|
||||
<?php foreach ($data['included']['anime'] as $id => $anime): ?>
|
||||
<?php foreach ($data['media']['anime'] as $id => $anime): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('anime.details', ['id' => $anime['attributes']['slug']]);
|
||||
@ -58,12 +58,12 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
</section>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (array_key_exists('manga', $data['included'])): ?>
|
||||
<?php if (array_key_exists('manga', $data['media'])): ?>
|
||||
<input type="radio" id="media-manga" name="media-tabs" />
|
||||
<label for="media-manga">Manga</label>
|
||||
|
||||
<section class="media-wrap content">
|
||||
<?php foreach ($data['included']['manga'] as $id => $manga): ?>
|
||||
<?php foreach ($data['media']['manga'] as $id => $manga): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('manga.details', ['id' => $manga['attributes']['slug']]);
|
||||
@ -89,14 +89,68 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
<?php endif ?>
|
||||
|
||||
<section>
|
||||
<?php if ($castCount > 0): ?>
|
||||
<?php if (count($data['castings']) > 0): ?>
|
||||
<h3>Castings</h3>
|
||||
<?php
|
||||
$vas = $castings['Voice Actor'];
|
||||
unset($castings['Voice Actor']);
|
||||
ksort($vas)
|
||||
$vas = $data['castings']['Voice Actor'];
|
||||
unset($data['castings']['Voice Actor']);
|
||||
ksort($vas)
|
||||
?>
|
||||
|
||||
<?php foreach ($data['castings'] as $role => $entries): ?>
|
||||
<h4><?= $role ?></h4>
|
||||
<?php foreach ($entries as $language => $casting): ?>
|
||||
<h5><?= $language ?></h5>
|
||||
<table class="min-table">
|
||||
<tr>
|
||||
<th>Cast Member</th>
|
||||
<th>Series</th>
|
||||
</tr>
|
||||
<?php foreach ($casting as $cid => $c): ?>
|
||||
<tr>
|
||||
<td style="width:229px">
|
||||
<article class="character">
|
||||
<?php
|
||||
$link = $url->generate('person', ['id' => $c['person']['id']]);
|
||||
?>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($c['person']['image'], TRUE)) ?>
|
||||
<div class="name">
|
||||
<?= $c['person']['name'] ?>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
</td>
|
||||
<td>
|
||||
<section class="align-left media-wrap">
|
||||
<?php foreach ($c['series'] as $series): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('anime.details', ['id' => $series['attributes']['slug']]);
|
||||
$titles = Kitsu::filterTitles($series['attributes']);
|
||||
?>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($series['attributes']['posterImage']['small'], TRUE)) ?>
|
||||
</a>
|
||||
<div class="name">
|
||||
<a href="<?= $link ?>">
|
||||
<?= array_shift($titles) ?>
|
||||
<?php foreach ($titles as $title): ?>
|
||||
<br />
|
||||
<small><?= $title ?></small>
|
||||
<?php endforeach ?>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
|
||||
<?php if ( ! empty($vas)): ?>
|
||||
<h4>Voice Actors</h4>
|
||||
|
||||
@ -161,61 +215,6 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
|
||||
<?php foreach ($castings as $role => $entries): ?>
|
||||
<h4><?= $role ?></h4>
|
||||
<?php foreach ($entries as $language => $casting): ?>
|
||||
<h5><?= $language ?></h5>
|
||||
<table class="min-table">
|
||||
<tr>
|
||||
<th>Cast Member</th>
|
||||
<th>Series</th>
|
||||
</tr>
|
||||
<?php foreach ($casting as $cid => $c): ?>
|
||||
<tr>
|
||||
<td style="width:229px">
|
||||
<article class="character">
|
||||
<?php
|
||||
$link = $url->generate('person', ['id' => $c['person']['id']]);
|
||||
?>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($c['person']['image'], TRUE)) ?>
|
||||
<div class="name">
|
||||
<?= $c['person']['name'] ?>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
</td>
|
||||
<td>
|
||||
<section class="align-left media-wrap">
|
||||
<?php foreach ($c['series'] as $series): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('anime.details', ['id' => $series['attributes']['slug']]);
|
||||
$titles = Kitsu::filterTitles($series['attributes']);
|
||||
?>
|
||||
<a href="<?= $link ?>">
|
||||
<?= $helper->picture(getLocalImg($series['attributes']['posterImage']['small'], TRUE)) ?>
|
||||
</a>
|
||||
<div class="name">
|
||||
<a href="<?= $link ?>">
|
||||
<?= array_shift($titles) ?>
|
||||
<?php foreach ($titles as $title): ?>
|
||||
<br />
|
||||
<small><?= $title ?></small>
|
||||
<?php endforeach ?>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
</section>
|
||||
</main>
|
@ -5,7 +5,7 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
<h3>Voice Acting Roles</h3>
|
||||
<div class="tabs">
|
||||
<?php $i = 0; ?>
|
||||
<?php foreach($characters as $role => $characterList): ?>
|
||||
<?php foreach($data['characters'] as $role => $characterList): ?>
|
||||
<input <?= $i === 0 ? 'checked="checked"' : '' ?> type="radio" name="character-type-tabs" id="character-type-<?= $i ?>" />
|
||||
<label for="character-type-<?= $i ?>"><h5><?= ucfirst($role) ?></h5></label>
|
||||
<section class="content">
|
||||
|
@ -9,16 +9,16 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
<?= $helper->picture("images/people/{$data['id']}-original.webp", 'jpg', ['class' => 'cover' ]) ?>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="toph"><?= $data['attributes']['name'] ?></h2>
|
||||
<h2 class="toph"><?= $data['name'] ?></h2>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php if ( ! empty($staff)): ?>
|
||||
<?php if ( ! empty($data['staff'])): ?>
|
||||
<section>
|
||||
<h3>Castings</h3>
|
||||
<div class="vertical-tabs">
|
||||
<?php $i = 0 ?>
|
||||
<?php foreach ($staff as $role => $entries): ?>
|
||||
<?php foreach ($data['staff'] as $role => $entries): ?>
|
||||
<div class="tab">
|
||||
<input
|
||||
type="radio" name="staff-roles" id="staff-role<?= $i ?>" <?= $i === 0 ? 'checked' : '' ?> />
|
||||
@ -59,7 +59,7 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
</section>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ( ! (empty($characters['main']) || empty($characters['supporting']))): ?>
|
||||
<?php if ( ! (empty($data['characters']['main']) || empty($data['characters']['supporting']))): ?>
|
||||
<section>
|
||||
<?php include 'character-mapping.php' ?>
|
||||
</section>
|
||||
|
@ -1,45 +1,39 @@
|
||||
<?php
|
||||
use function Aviat\AnimeClient\getLocalImg;
|
||||
use Aviat\AnimeClient\API\Kitsu;
|
||||
?>
|
||||
<main class="user-page details">
|
||||
<h2 class="toph">
|
||||
<?= $helper->a(
|
||||
"https://kitsu.io/users/{$attributes['slug']}",
|
||||
$attributes['name'], [
|
||||
"https://kitsu.io/users/{$data['slug']}",
|
||||
$data['name'], [
|
||||
'title' => 'View profile on Kitsu'
|
||||
])
|
||||
?>
|
||||
</h2>
|
||||
|
||||
<p><?= $escape->html($attributes['about']) ?></p>
|
||||
<p><?= $escape->html($data['about']) ?></p>
|
||||
|
||||
<section class="flex flex-no-wrap">
|
||||
<aside class="info">
|
||||
<center>
|
||||
<?php
|
||||
$avatar = $urlGenerator->assetUrl(
|
||||
getLocalImg($attributes['avatar']['original'], FALSE)
|
||||
);
|
||||
echo $helper->img($avatar, ['alt' => '']);
|
||||
?>
|
||||
<?= $helper->img($urlGenerator->assetUrl($data['avatar']), ['alt' => '']); ?>
|
||||
</center>
|
||||
<br />
|
||||
<table class="media-details">
|
||||
<tr>
|
||||
<td>Location</td>
|
||||
<td><?= $attributes['location'] ?></td>
|
||||
<td><?= $data['location'] ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Website</td>
|
||||
<td><?= $helper->a($attributes['website'], $attributes['website']) ?></td>
|
||||
<td><?= $helper->a($data['website'], $data['website']) ?></td>
|
||||
</tr>
|
||||
<?php if (array_key_exists('waifu', $relationships)): ?>
|
||||
<?php if ( ! empty($data['waifu'])): ?>
|
||||
<tr>
|
||||
<td><?= $escape->html($attributes['waifuOrHusbando']) ?></td>
|
||||
<td><?= $escape->html($data['waifu']['label']) ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$character = $relationships['waifu']['attributes'];
|
||||
$character = $data['waifu']['character'];
|
||||
echo $helper->a(
|
||||
$url->generate('character', ['slug' => $character['slug']]),
|
||||
$character['canonicalName']
|
||||
@ -52,42 +46,24 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
|
||||
<h3>User Stats</h3><br />
|
||||
<table class="media-details">
|
||||
<?php foreach($data['stats'] as $label => $stat): ?>
|
||||
<tr>
|
||||
<td>Time spent watching anime:</td>
|
||||
<td><?= $timeOnAnime ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td># of Anime episodes watched</td>
|
||||
<td><?= number_format($stats['anime-amount-consumed']['units']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td># of Manga chapters read</td>
|
||||
<td><?= number_format($stats['manga-amount-consumed']['units']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td># of Posts</td>
|
||||
<td><?= number_format($attributes['postsCount']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td># of Comments</td>
|
||||
<td><?= number_format($attributes['commentsCount']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td># of Media Rated</td>
|
||||
<td><?= number_format($attributes['ratingsCount']) ?></td>
|
||||
<td><?= $label ?></td>
|
||||
<td><?= $stat ?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
</aside>
|
||||
<article>
|
||||
<?php if ( ! empty($favorites)): ?>
|
||||
<?php if ( ! empty($data['favorites'])): ?>
|
||||
<h3>Favorites</h3>
|
||||
<div class="tabs">
|
||||
<?php $i = 0 ?>
|
||||
<?php if ( ! empty($favorites['characters'])): ?>
|
||||
<?php if ( ! empty($data['favorites']['characters'])): ?>
|
||||
<input type="radio" name="user-favorites" id="user-fav-chars" <?= $i === 0 ? 'checked' : '' ?> />
|
||||
<label for="user-fav-chars">Characters</label>
|
||||
<section class="content full-width media-wrap">
|
||||
<?php foreach($favorites['characters'] as $id => $char): ?>
|
||||
<?php foreach($data['favorites']['characters'] as $id => $char): ?>
|
||||
<?php if ( ! empty($char['image']['original'])): ?>
|
||||
<article class="character">
|
||||
<?php $link = $url->generate('character', ['slug' => $char['slug']]) ?>
|
||||
@ -101,11 +77,11 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
</section>
|
||||
<?php $i++; ?>
|
||||
<?php endif ?>
|
||||
<?php if ( ! empty($favorites['anime'])): ?>
|
||||
<?php if ( ! empty($data['favorites']['anime'])): ?>
|
||||
<input type="radio" name="user-favorites" id="user-fav-anime" <?= $i === 0 ? 'checked' : '' ?> />
|
||||
<label for="user-fav-anime">Anime</label>
|
||||
<section class="content full-width media-wrap">
|
||||
<?php foreach($favorites['anime'] as $anime): ?>
|
||||
<?php foreach($data['favorites']['anime'] as $anime): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('anime.details', ['id' => $anime['slug']]);
|
||||
@ -127,11 +103,11 @@ use Aviat\AnimeClient\API\Kitsu;
|
||||
</section>
|
||||
<?php $i++; ?>
|
||||
<?php endif ?>
|
||||
<?php if ( ! empty($favorites['manga'])): ?>
|
||||
<?php if ( ! empty($data['favorites']['manga'])): ?>
|
||||
<input type="radio" name="user-favorites" id="user-fav-manga" <?= $i === 0 ? 'checked' : '' ?> />
|
||||
<label for="user-fav-manga">Manga</label>
|
||||
<section class="content full-width media-wrap">
|
||||
<?php foreach($favorites['manga'] as $manga): ?>
|
||||
<?php foreach($data['favorites']['manga'] as $manga): ?>
|
||||
<article class="media">
|
||||
<?php
|
||||
$link = $url->generate('manga.details', ['id' => $manga['slug']]);
|
||||
|
@ -18,7 +18,6 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||
|
||||
use Aviat\AnimeClient\API\Kitsu;
|
||||
use Aviat\AnimeClient\Types\{
|
||||
Anime,
|
||||
FormItem,
|
||||
AnimeListItem
|
||||
};
|
||||
@ -95,7 +94,7 @@ final class AnimeListTransformer extends AbstractTransformer {
|
||||
'started' => $anime['startDate'],
|
||||
'ended' => $anime['endDate']
|
||||
],
|
||||
'anime' => new Anime([
|
||||
'anime' => [
|
||||
'id' => $animeId,
|
||||
'age_rating' => $anime['ageRating'],
|
||||
'title' => $title,
|
||||
@ -105,7 +104,7 @@ final class AnimeListTransformer extends AbstractTransformer {
|
||||
'cover_image' => $anime['posterImage']['small'],
|
||||
'genres' => $genres,
|
||||
'streaming_links' => $streamingLinks,
|
||||
]),
|
||||
],
|
||||
'watching_status' => $item['attributes']['status'],
|
||||
'notes' => $item['attributes']['notes'],
|
||||
'rewatching' => (bool) $item['attributes']['reconsuming'],
|
||||
|
@ -17,7 +17,7 @@
|
||||
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||
|
||||
use Aviat\AnimeClient\API\{JsonAPI, Kitsu};
|
||||
use Aviat\AnimeClient\Types\Anime;
|
||||
use Aviat\AnimeClient\Types\AnimePage;
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
|
||||
/**
|
||||
@ -30,9 +30,9 @@ final class AnimeTransformer extends AbstractTransformer {
|
||||
* logical and workable structure
|
||||
*
|
||||
* @param array $item API library item
|
||||
* @return Anime
|
||||
* @return AnimePage
|
||||
*/
|
||||
public function transform($item): Anime
|
||||
public function transform($item): AnimePage
|
||||
{
|
||||
$item['included'] = JsonAPI::organizeIncludes($item['included']);
|
||||
$genres = $item['included']['categories'] ?? [];
|
||||
@ -40,13 +40,74 @@ final class AnimeTransformer extends AbstractTransformer {
|
||||
sort($item['genres']);
|
||||
|
||||
$title = $item['canonicalTitle'];
|
||||
|
||||
$titles = Kitsu::filterTitles($item);
|
||||
// $titles = array_unique(array_diff($item['titles'], [$title]));
|
||||
|
||||
return new Anime([
|
||||
$characters = [];
|
||||
$staff = [];
|
||||
|
||||
if (array_key_exists('animeCharacters', $item['included']))
|
||||
{
|
||||
$animeCharacters = $item['included']['animeCharacters'];
|
||||
|
||||
foreach ($animeCharacters as $rel)
|
||||
{
|
||||
$charId = $rel['relationships']['character']['data']['id'];
|
||||
$role = $rel['role'];
|
||||
|
||||
if (array_key_exists($charId, $item['included']['characters']))
|
||||
{
|
||||
$characters[$role][$charId] = $item['included']['characters'][$charId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('mediaStaff', $item['included']))
|
||||
{
|
||||
foreach ($item['included']['mediaStaff'] as $id => $staffing)
|
||||
{
|
||||
$personId = $staffing['relationships']['person']['data']['id'];
|
||||
$personDetails = $item['included']['people'][$personId];
|
||||
|
||||
$role = $staffing['role'];
|
||||
|
||||
if ( ! array_key_exists($role, $staff))
|
||||
{
|
||||
$staff[$role] = [];
|
||||
}
|
||||
|
||||
$staff[$role][$personId] = [
|
||||
'id' => $personId,
|
||||
'name' => $personDetails['name'] ?? '??',
|
||||
'image' => $personDetails['image'],
|
||||
];
|
||||
|
||||
usort($staff[$role], function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($characters['main']))
|
||||
{
|
||||
uasort($characters['main'], function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
}
|
||||
|
||||
if ( ! empty($characters['supporting']))
|
||||
{
|
||||
uasort($characters['supporting'], function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
}
|
||||
|
||||
ksort($characters);
|
||||
ksort($staff);
|
||||
|
||||
return new AnimePage([
|
||||
'age_rating' => $item['ageRating'],
|
||||
'age_rating_guide' => $item['ageRatingGuide'],
|
||||
'characters' => $characters,
|
||||
'cover_image' => $item['posterImage']['small'],
|
||||
'episode_count' => $item['episodeCount'],
|
||||
'episode_length' => $item['episodeLength'],
|
||||
@ -55,6 +116,7 @@ final class AnimeTransformer extends AbstractTransformer {
|
||||
'included' => $item['included'],
|
||||
'show_type' => $this->string($item['showType'])->upperCaseFirst()->__toString(),
|
||||
'slug' => $item['slug'],
|
||||
'staff' => $staff,
|
||||
'status' => Kitsu::getAiringStatus($item['startDate'], $item['endDate']),
|
||||
'streaming_links' => Kitsu::parseStreamingLinks($item['included']),
|
||||
'synopsis' => $item['synopsis'],
|
||||
|
173
src/API/Kitsu/Transformer/CharacterTransformer.php
Normal file
173
src/API/Kitsu/Transformer/CharacterTransformer.php
Normal file
@ -0,0 +1,173 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
use Aviat\AnimeClient\Types\Character;
|
||||
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
|
||||
/**
|
||||
* Data transformation class for zippered Hummingbird manga
|
||||
*/
|
||||
final class CharacterTransformer extends AbstractTransformer {
|
||||
|
||||
public function transform($characterData): Character
|
||||
{
|
||||
$data = JsonAPI::organizeData($characterData);
|
||||
$attributes = $data[0]['attributes'];
|
||||
$castings = [];
|
||||
|
||||
$names = array_unique(
|
||||
array_merge(
|
||||
[$attributes['canonicalName']],
|
||||
$attributes['names']
|
||||
)
|
||||
);
|
||||
$name = array_shift($names);
|
||||
|
||||
if (array_key_exists('included', $data))
|
||||
{
|
||||
if (array_key_exists('anime', $data['included']))
|
||||
{
|
||||
uasort($data['included']['anime'], function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
|
||||
if (array_key_exists('manga', $data['included']))
|
||||
{
|
||||
uasort($data['included']['manga'], function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
|
||||
if (array_key_exists('castings', $data['included']))
|
||||
{
|
||||
$castings = $this->organizeCast($data['included']['castings']);
|
||||
}
|
||||
}
|
||||
|
||||
return new Character([
|
||||
'castings' => $castings,
|
||||
'description' => $attributes['description'],
|
||||
'id' => $data[0]['id'],
|
||||
'media' => [
|
||||
'anime' => $data['included']['anime'] ?? [],
|
||||
'manga' => $data['included']['manga'] ?? [],
|
||||
],
|
||||
'name' => $name,
|
||||
'names' => $names,
|
||||
'otherNames' => $attributes['otherNames'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Organize VA => anime relationships
|
||||
*
|
||||
* @param array $cast
|
||||
* @return array
|
||||
*/
|
||||
private function dedupeCast(array $cast): array
|
||||
{
|
||||
$output = [];
|
||||
$people = [];
|
||||
|
||||
$i = 0;
|
||||
foreach ($cast as &$role)
|
||||
{
|
||||
if (empty($role['attributes']['role']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$person = current($role['relationships']['person']['people'])['attributes'];
|
||||
$hasName = array_key_exists($person['name'], $people);
|
||||
|
||||
if ( ! $hasName)
|
||||
{
|
||||
$people[$person['name']] = $i;
|
||||
$role['relationships']['media']['anime'] = [current($role['relationships']['media']['anime'])];
|
||||
$output[$i] = $role;
|
||||
|
||||
$i++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_key_exists('anime', $role['relationships']['media']))
|
||||
{
|
||||
$key = $people[$person['name']];
|
||||
$output[$key]['relationships']['media']['anime'][] = current($role['relationships']['media']['anime']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function organizeCast(array $cast): array
|
||||
{
|
||||
$cast = $this->dedupeCast($cast);
|
||||
$output = [];
|
||||
|
||||
foreach ($cast as $id => $role)
|
||||
{
|
||||
if (empty($role['attributes']['role']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$language = $role['attributes']['language'];
|
||||
$roleName = $role['attributes']['role'];
|
||||
$isVA = $role['attributes']['voiceActor'];
|
||||
|
||||
if ($isVA)
|
||||
{
|
||||
foreach ($role['relationships']['person']['people'] as $pid => $peoples)
|
||||
{
|
||||
$p = $peoples;
|
||||
}
|
||||
|
||||
$person = $p['attributes'];
|
||||
$person['id'] = $pid;
|
||||
$person['image'] = $person['image']['original'];
|
||||
|
||||
uasort($role['relationships']['media']['anime'], function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
|
||||
$item = [
|
||||
'person' => $person,
|
||||
'series' => $role['relationships']['media']['anime']
|
||||
];
|
||||
|
||||
$output[$roleName][$language][] = $item;
|
||||
} else
|
||||
{
|
||||
foreach ($role['relationships']['person']['people'] as $pid => $person)
|
||||
{
|
||||
$person['id'] = $pid;
|
||||
$output[$roleName][$pid] = $person;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
132
src/API/Kitsu/Transformer/PersonTransformer.php
Normal file
132
src/API/Kitsu/Transformer/PersonTransformer.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
use Aviat\AnimeClient\Types\Person;
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
|
||||
/**
|
||||
* Data transformation class for zippered Hummingbird manga
|
||||
*/
|
||||
final class PersonTransformer extends AbstractTransformer {
|
||||
|
||||
public function transform($personData): Person
|
||||
{
|
||||
$data = JsonAPI::organizeData($personData);
|
||||
$included = JsonAPI::organizeIncludes($personData['included']);
|
||||
|
||||
$orgData = $this->organizeData($included);
|
||||
|
||||
return new Person([
|
||||
'id' => $data['id'],
|
||||
'name' => $data['attributes']['name'],
|
||||
'characters' => $orgData['characters'],
|
||||
'staff' => $orgData['staff'],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function organizeData(array $data): array
|
||||
{
|
||||
$output = [
|
||||
'characters' => [
|
||||
'main' => [],
|
||||
'supporting' => [],
|
||||
],
|
||||
'staff' => [],
|
||||
];
|
||||
|
||||
if (array_key_exists('characterVoices', $data))
|
||||
{
|
||||
foreach ($data['characterVoices'] as $cv)
|
||||
{
|
||||
$mcId = $cv['relationships']['mediaCharacter']['data']['id'];
|
||||
|
||||
if ( ! array_key_exists($mcId, $data['mediaCharacters']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$mc = $data['mediaCharacters'][$mcId];
|
||||
|
||||
$role = $mc['role'];
|
||||
|
||||
$charId = $mc['relationships']['character']['data']['id'];
|
||||
$mediaId = $mc['relationships']['media']['data']['id'];
|
||||
|
||||
$existingMedia = array_key_exists($charId, $output['characters'][$role])
|
||||
? $output['characters'][$role][$charId]['media']
|
||||
: [];
|
||||
|
||||
$relatedMedia = [
|
||||
$mediaId => $data['anime'][$mediaId],
|
||||
];
|
||||
|
||||
$includedMedia = array_replace_recursive($existingMedia, $relatedMedia);
|
||||
|
||||
uasort($includedMedia, function ($a, $b) {
|
||||
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
|
||||
});
|
||||
|
||||
$character = $data['characters'][$charId];
|
||||
|
||||
$output['characters'][$role][$charId] = [
|
||||
'character' => $character,
|
||||
'media' => $includedMedia,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('mediaStaff', $data))
|
||||
{
|
||||
foreach ($data['mediaStaff'] as $rid => $role)
|
||||
{
|
||||
$roleName = $role['role'];
|
||||
$mediaType = $role['relationships']['media']['data']['type'];
|
||||
$mediaId = $role['relationships']['media']['data']['id'];
|
||||
$media = $data[$mediaType][$mediaId];
|
||||
$output['staff'][$roleName][$mediaType][$mediaId] = $media;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($output['characters']['main'], function ($a, $b) {
|
||||
return $a['character']['canonicalName'] <=> $b['character']['canonicalName'];
|
||||
});
|
||||
uasort($output['characters']['supporting'], function ($a, $b) {
|
||||
return $a['character']['canonicalName'] <=> $b['character']['canonicalName'];
|
||||
});
|
||||
ksort($output['staff']);
|
||||
foreach ($output['staff'] as $role => &$media)
|
||||
{
|
||||
if (array_key_exists('anime', $media))
|
||||
{
|
||||
uasort($media['anime'], function ($a, $b) {
|
||||
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
|
||||
if (array_key_exists('manga', $media))
|
||||
{
|
||||
uasort($media['manga'], function ($a, $b) {
|
||||
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
147
src/API/Kitsu/Transformer/UserTransformer.php
Normal file
147
src/API/Kitsu/Transformer/UserTransformer.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||
|
||||
use function Aviat\AnimeClient\getLocalImg;
|
||||
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
use Aviat\AnimeClient\Types\User;
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
|
||||
/**
|
||||
* Transform user profile data for display
|
||||
*/
|
||||
final class UserTransformer extends AbstractTransformer {
|
||||
public function transform($profileData): User
|
||||
{
|
||||
$orgData = JsonAPI::organizeData($profileData)[0];
|
||||
$attributes = $orgData['attributes'];
|
||||
|
||||
$rels = $orgData['relationships'] ?? [];
|
||||
$favorites = array_key_exists('favorites', $rels) ? $rels['favorites'] : [];
|
||||
|
||||
$stats = [];
|
||||
foreach ($rels['stats'] as $sid => &$item)
|
||||
{
|
||||
$key = $item['attributes']['kind'];
|
||||
$stats[$key] = $item['attributes']['statsData'];
|
||||
unset($item);
|
||||
}
|
||||
|
||||
$waifu = [];
|
||||
if (array_key_exists('waifu', $rels))
|
||||
{
|
||||
$waifu = [
|
||||
'label' => $attributes['waifuOrHusbando'],
|
||||
'character' => $rels['waifu']['attributes'],
|
||||
];
|
||||
}
|
||||
|
||||
return new User([
|
||||
'about' => $attributes['about'],
|
||||
'avatar' => getLocalImg($attributes['avatar']['original'], FALSE),
|
||||
'favorites' => $this->organizeFavorites($favorites),
|
||||
'location' => $attributes['location'],
|
||||
'name' => $attributes['name'],
|
||||
'slug' => $attributes['slug'],
|
||||
'stats' => $this->organizeStats($stats, $attributes),
|
||||
'waifu' => $waifu,
|
||||
'website' => $attributes['website'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorganize favorites data to be more useful
|
||||
*
|
||||
* @param array $rawFavorites
|
||||
* @return array
|
||||
*/
|
||||
private function organizeFavorites(array $rawFavorites): array
|
||||
{
|
||||
$output = [];
|
||||
|
||||
unset($rawFavorites['data']);
|
||||
|
||||
foreach ($rawFavorites as $item)
|
||||
{
|
||||
$rank = $item['attributes']['favRank'];
|
||||
foreach ($item['relationships']['item'] as $key => $fav)
|
||||
{
|
||||
$output[$key] = $output[$key] ?? [];
|
||||
foreach ($fav as $id => $data)
|
||||
{
|
||||
$output[$key][$rank] = array_merge(['id' => $id], $data['attributes']);
|
||||
}
|
||||
|
||||
ksort($output[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the time spent on anime in a more readable format
|
||||
*
|
||||
* @param int $minutes
|
||||
* @return string
|
||||
*/
|
||||
private function formatAnimeTime(int $minutes): string
|
||||
{
|
||||
$minutesPerDay = 1440;
|
||||
$minutesPerYear = $minutesPerDay * 365;
|
||||
|
||||
// Minutes short of a year
|
||||
$years = (int)floor($minutes / $minutesPerYear);
|
||||
$minutes %= $minutesPerYear;
|
||||
|
||||
// Minutes short of a day
|
||||
$extraMinutes = $minutes % $minutesPerDay;
|
||||
|
||||
$days = ($minutes - $extraMinutes) / $minutesPerDay;
|
||||
|
||||
// Minutes short of an hour
|
||||
$remMinutes = $extraMinutes % 60;
|
||||
|
||||
$hours = ($extraMinutes - $remMinutes) / 60;
|
||||
|
||||
$output = "{$days} days, {$hours} hours, and {$remMinutes} minutes.";
|
||||
|
||||
if ($years > 0)
|
||||
{
|
||||
$output = "{$years} year(s),{$output}";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function organizeStats($stats, $data): array
|
||||
{
|
||||
// $timeOnAnime = $this->formatAnimeTime($orgData['attributes']['lifeSpentOnAnime']);
|
||||
|
||||
return [
|
||||
'Time spent watching anime:' => $this->formatAnimeTime($stats['anime-amount-consumed']['time']),
|
||||
'Anime series watched:' => number_format($stats['anime-amount-consumed']['media']),
|
||||
'Anime episodes watched:' => number_format($stats['anime-amount-consumed']['units']),
|
||||
'Manga series read:' => number_format($stats['manga-amount-consumed']['media']),
|
||||
'Manga chapters read:' => number_format($stats['manga-amount-consumed']['units']),
|
||||
'Posts:' => number_format($data['postsCount']),
|
||||
'Comments:' => number_format($data['commentsCount']),
|
||||
'Media Rated:' => number_format($data['ratingsCount']),
|
||||
];
|
||||
}
|
||||
}
|
@ -23,15 +23,11 @@ use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
|
||||
use Aviat\AnimeClient\Types\FormItem;
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\Ion\StringWrapper;
|
||||
|
||||
/**
|
||||
* Controller for Anime-related pages
|
||||
*/
|
||||
final class Anime extends BaseController {
|
||||
|
||||
use StringWrapper;
|
||||
|
||||
/**
|
||||
* The anime list model
|
||||
* @var \Aviat\AnimeClient\Model\Anime $model
|
||||
@ -276,8 +272,6 @@ final class Anime extends BaseController {
|
||||
public function details(string $animeId): void
|
||||
{
|
||||
$data = $this->model->getAnime($animeId);
|
||||
$characters = [];
|
||||
$staff = [];
|
||||
|
||||
if (empty($data))
|
||||
{
|
||||
@ -291,77 +285,13 @@ final class Anime extends BaseController {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists('animeCharacters', $data['included']))
|
||||
{
|
||||
$animeCharacters = $data['included']['animeCharacters'];
|
||||
|
||||
foreach ($animeCharacters as $rel)
|
||||
{
|
||||
$charId = $rel['relationships']['character']['data']['id'];
|
||||
$role = $rel['role'];
|
||||
|
||||
if (array_key_exists($charId, $data['included']['characters']))
|
||||
{
|
||||
$characters[$role][$charId] = $data['included']['characters'][$charId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('mediaStaff', $data['included']))
|
||||
{
|
||||
foreach ($data['included']['mediaStaff'] as $id => $staffing)
|
||||
{
|
||||
$personId = $staffing['relationships']['person']['data']['id'];
|
||||
$personDetails = $data['included']['people'][$personId];
|
||||
|
||||
$role = $staffing['role'];
|
||||
|
||||
if ( ! array_key_exists($role, $staff))
|
||||
{
|
||||
$staff[$role] = [];
|
||||
}
|
||||
|
||||
$staff[$role][$personId] = [
|
||||
'id' => $personId,
|
||||
'name' => $personDetails['name'] ?? '??',
|
||||
'image' => $personDetails['image'],
|
||||
];
|
||||
|
||||
usort($staff[$role], function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($characters['main']))
|
||||
{
|
||||
uasort($characters['main'], function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
}
|
||||
|
||||
if ( ! empty($characters['supporting']))
|
||||
{
|
||||
uasort($characters['supporting'], function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
}
|
||||
|
||||
ksort($characters);
|
||||
ksort($staff);
|
||||
|
||||
// dump($characters);
|
||||
// dump($staff);
|
||||
|
||||
$this->outputHTML('anime/details', [
|
||||
'title' => $this->formatTitle(
|
||||
$this->config->get('whose_list') . "'s Anime List",
|
||||
'Anime',
|
||||
$data->title
|
||||
),
|
||||
'characters' => $characters,
|
||||
'show_data' => $data,
|
||||
'staff' => $staff,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -17,30 +17,42 @@
|
||||
namespace Aviat\AnimeClient\Controller;
|
||||
|
||||
use Aviat\AnimeClient\Controller as BaseController;
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
use Aviat\Ion\ArrayWrapper;
|
||||
use Aviat\AnimeClient\API\Kitsu\Transformer\CharacterTransformer;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Controller for character description pages
|
||||
*/
|
||||
class Character extends BaseController {
|
||||
|
||||
use ArrayWrapper;
|
||||
/**
|
||||
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* Character constructor.
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->model = $container->get('kitsu-model');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show information about a character
|
||||
*
|
||||
* @param string $slug
|
||||
* @throws \Aviat\Ion\Di\ContainerException
|
||||
* @throws \Aviat\Ion\Di\NotFoundException
|
||||
* @throws \InvalidArgumentException
|
||||
* @return void
|
||||
*/
|
||||
public function index(string $slug): void
|
||||
{
|
||||
$model = $this->container->get('kitsu-model');
|
||||
|
||||
$rawData = $model->getCharacter($slug);
|
||||
$rawData = $this->model->getCharacter($slug);
|
||||
|
||||
if (( ! array_key_exists('data', $rawData)) || empty($rawData['data']))
|
||||
{
|
||||
@ -55,167 +67,14 @@ class Character extends BaseController {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = JsonAPI::organizeData($rawData);
|
||||
$data = (new CharacterTransformer())->transform($rawData)->toArray();
|
||||
|
||||
$data['names'] = array_unique(
|
||||
array_merge(
|
||||
[ $data[0]['attributes']['canonicalName'] ],
|
||||
$data[0]['attributes']['names']
|
||||
)
|
||||
);
|
||||
$data['name'] = array_shift($data['names']);
|
||||
|
||||
if (array_key_exists('included', $data))
|
||||
{
|
||||
if (array_key_exists('anime', $data['included']))
|
||||
{
|
||||
uasort($data['included']['anime'], function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
|
||||
if (array_key_exists('manga', $data['included']))
|
||||
{
|
||||
uasort($data['included']['manga'], function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$viewData = [
|
||||
$this->outputHTML('character/details', [
|
||||
'title' => $this->formatTitle(
|
||||
'Characters',
|
||||
$data[0]['attributes']['name']
|
||||
$data['name']
|
||||
),
|
||||
'data' => $data,
|
||||
'castCount' => 0,
|
||||
'castings' => []
|
||||
];
|
||||
|
||||
if (array_key_exists('included', $data))
|
||||
{
|
||||
if (array_key_exists('castings', $data['included']))
|
||||
{
|
||||
$viewData['castings'] = $this->organizeCast($data['included']['castings']);
|
||||
$viewData['castCount'] = $this->getCastCount($viewData['castings']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->outputHTML('character/details', $viewData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Organize VA => anime relationships
|
||||
*
|
||||
* @param array $cast
|
||||
* @return array
|
||||
*/
|
||||
private function dedupeCast(array $cast): array
|
||||
{
|
||||
$output = [];
|
||||
$people = [];
|
||||
|
||||
$i = 0;
|
||||
foreach ($cast as &$role)
|
||||
{
|
||||
if (empty($role['attributes']['role']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$person = current($role['relationships']['person']['people'])['attributes'];
|
||||
$hasName = array_key_exists($person['name'], $people);
|
||||
|
||||
if ( ! $hasName)
|
||||
{
|
||||
$people[$person['name']] = $i;
|
||||
$role['relationships']['media']['anime'] = [current($role['relationships']['media']['anime'])];
|
||||
$output[$i] = $role;
|
||||
|
||||
$i++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_key_exists('anime', $role['relationships']['media']))
|
||||
{
|
||||
$key = $people[$person['name']];
|
||||
$output[$key]['relationships']['media']['anime'][] = current($role['relationships']['media']['anime']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function getCastCount(array $cast): int
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
foreach($cast as $role)
|
||||
{
|
||||
$count++;
|
||||
/* if (
|
||||
array_key_exists('attributes', $role) &&
|
||||
array_key_exists('role', $role['attributes']) &&
|
||||
$role['attributes']['role'] !== NULL
|
||||
) {
|
||||
$count++;
|
||||
} */
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
protected function organizeCast(array $cast): array
|
||||
{
|
||||
$cast = $this->dedupeCast($cast);
|
||||
$output = [];
|
||||
|
||||
foreach($cast as $id => $role)
|
||||
{
|
||||
if (empty($role['attributes']['role']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$language = $role['attributes']['language'];
|
||||
$roleName = $role['attributes']['role'];
|
||||
$isVA = $role['attributes']['voiceActor'];
|
||||
|
||||
if ($isVA)
|
||||
{
|
||||
foreach($role['relationships']['person']['people'] as $pid => $peoples)
|
||||
{
|
||||
$p = $peoples;
|
||||
}
|
||||
|
||||
$person = $p['attributes'];
|
||||
$person['id'] = $pid;
|
||||
$person['image'] = $person['image']['original'];
|
||||
|
||||
uasort($role['relationships']['media']['anime'], function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
|
||||
$item = [
|
||||
'person' => $person,
|
||||
'series' => $role['relationships']['media']['anime']
|
||||
];
|
||||
|
||||
$output[$roleName][$language][] = $item;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($role['relationships']['person']['people'] as $pid => $person)
|
||||
{
|
||||
$person['id'] = $pid;
|
||||
$output[$roleName][$pid] = $person;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
]);
|
||||
}
|
||||
}
|
@ -17,12 +17,33 @@
|
||||
namespace Aviat\AnimeClient\Controller;
|
||||
|
||||
use Aviat\AnimeClient\Controller as BaseController;
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
use Aviat\AnimeClient\API\Kitsu\Transformer\PersonTransformer;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Controller for People pages
|
||||
*/
|
||||
final class People extends BaseController {
|
||||
|
||||
/**
|
||||
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* People constructor.
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->model = $container->get('kitsu-model');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show information about a person
|
||||
*
|
||||
@ -31,9 +52,8 @@ final class People extends BaseController {
|
||||
*/
|
||||
public function index(string $id): void
|
||||
{
|
||||
$model = $this->container->get('kitsu-model');
|
||||
|
||||
$rawData = $model->getPerson($id);
|
||||
$rawData = $this->model->getPerson($id);
|
||||
$data = (new PersonTransformer())->transform($rawData)->toArray();
|
||||
|
||||
if (( ! array_key_exists('data', $rawData)) || empty($rawData['data']))
|
||||
{
|
||||
@ -48,114 +68,12 @@ final class People extends BaseController {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = JsonAPI::organizeData($rawData);
|
||||
$included = JsonAPI::organizeIncludes($rawData['included']);
|
||||
|
||||
$orgData = $this->organizeData($included);
|
||||
|
||||
$viewData = [
|
||||
'included' => $included,
|
||||
$this->outputHTML('person/details', [
|
||||
'title' => $this->formatTitle(
|
||||
'People',
|
||||
$data['attributes']['name']
|
||||
$data['name']
|
||||
),
|
||||
'data' => $data,
|
||||
'castCount' => 0,
|
||||
'castings' => [],
|
||||
'characters' => $orgData['characters'],
|
||||
'staff' => $orgData['staff'],
|
||||
];
|
||||
|
||||
$this->outputHTML('person/details', $viewData);
|
||||
}
|
||||
|
||||
protected function organizeData(array $data): array
|
||||
{
|
||||
$output = [
|
||||
'characters' => [
|
||||
'main' => [],
|
||||
'supporting' => [],
|
||||
],
|
||||
'staff' => [],
|
||||
];
|
||||
|
||||
if (array_key_exists('characterVoices', $data))
|
||||
{
|
||||
foreach ($data['characterVoices'] as $cv)
|
||||
{
|
||||
$mcId = $cv['relationships']['mediaCharacter']['data']['id'];
|
||||
|
||||
if ( ! array_key_exists($mcId, $data['mediaCharacters']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$mc = $data['mediaCharacters'][$mcId];
|
||||
|
||||
$role = $mc['role'];
|
||||
|
||||
$charId = $mc['relationships']['character']['data']['id'];
|
||||
$mediaId = $mc['relationships']['media']['data']['id'];
|
||||
|
||||
$existingMedia = array_key_exists($charId, $output['characters'][$role])
|
||||
? $output['characters'][$role][$charId]['media']
|
||||
: [];
|
||||
|
||||
$relatedMedia = [
|
||||
$mediaId => $data['anime'][$mediaId],
|
||||
];
|
||||
|
||||
$includedMedia = array_replace_recursive($existingMedia, $relatedMedia);
|
||||
|
||||
uasort($includedMedia, function ($a, $b) {
|
||||
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
|
||||
});
|
||||
|
||||
$character = $data['characters'][$charId];
|
||||
|
||||
$output['characters'][$role][$charId] = [
|
||||
'character' => $character,
|
||||
'media' => $includedMedia,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('mediaStaff', $data))
|
||||
{
|
||||
foreach($data['mediaStaff'] as $rid => $role)
|
||||
{
|
||||
$roleName = $role['role'];
|
||||
$mediaType = $role['relationships']['media']['data']['type'];
|
||||
$mediaId = $role['relationships']['media']['data']['id'];
|
||||
$media = $data[$mediaType][$mediaId];
|
||||
$output['staff'][$roleName][$mediaType][$mediaId] = $media;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($output['characters']['main'], function ($a, $b) {
|
||||
return $a['character']['canonicalName'] <=> $b['character']['canonicalName'];
|
||||
});
|
||||
uasort($output['characters']['supporting'], function ($a, $b) {
|
||||
return $a['character']['canonicalName'] <=> $b['character']['canonicalName'];
|
||||
});
|
||||
ksort($output['staff']);
|
||||
foreach($output['staff'] as $role => &$media)
|
||||
{
|
||||
if (array_key_exists('anime', $media))
|
||||
{
|
||||
uasort($media['anime'], function ($a, $b) {
|
||||
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
|
||||
if (array_key_exists('manga', $media))
|
||||
{
|
||||
uasort($media['manga'], function ($a, $b) {
|
||||
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
]);
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ use Aviat\Ion\Di\ContainerInterface;
|
||||
*/
|
||||
final class Settings extends BaseController {
|
||||
/**
|
||||
* @var \Aviat\API\Anilist\Model
|
||||
* @var \Aviat\AnimeClient\API\Anilist\Model
|
||||
*/
|
||||
private $anilistModel;
|
||||
|
||||
@ -33,6 +33,13 @@ final class Settings extends BaseController {
|
||||
*/
|
||||
private $settingsModel;
|
||||
|
||||
/**
|
||||
* Settings constructor.
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
@ -44,7 +51,7 @@ final class Settings extends BaseController {
|
||||
/**
|
||||
* Show the user settings, if logged in
|
||||
*/
|
||||
public function index()
|
||||
public function index(): void
|
||||
{
|
||||
$auth = $this->container->get('auth');
|
||||
$form = $this->settingsModel->getSettingsForm();
|
||||
@ -66,7 +73,7 @@ final class Settings extends BaseController {
|
||||
*
|
||||
* @throws \Aura\Router\Exception\RouteNotFound
|
||||
*/
|
||||
public function update()
|
||||
public function update(): void
|
||||
{
|
||||
$post = $this->request->getParsedBody();
|
||||
unset($post['settings-tabs']);
|
||||
@ -88,14 +95,15 @@ final class Settings extends BaseController {
|
||||
/**
|
||||
* Redirect to Anilist to start Oauth flow
|
||||
*/
|
||||
public function anilistRedirect()
|
||||
public function anilistRedirect(): void
|
||||
{
|
||||
$redirectUrl = 'https://anilist.co/api/v2/oauth/authorize?' .
|
||||
http_build_query([
|
||||
'client_id' => $this->config->get(['anilist', 'client_id']),
|
||||
'redirect_uri' => $this->urlGenerator->url('/anilist-oauth'),
|
||||
'response_type' => 'code',
|
||||
]);
|
||||
$query = http_build_query([
|
||||
'client_id' => $this->config->get(['anilist', 'client_id']),
|
||||
'redirect_uri' => $this->urlGenerator->url('/anilist-oauth'),
|
||||
'response_type' => 'code',
|
||||
]);
|
||||
|
||||
$redirectUrl = "https://anilist.co/api/v2/oauth/authorize?{$query}";
|
||||
|
||||
$this->redirect($redirectUrl, 303);
|
||||
}
|
||||
@ -103,7 +111,7 @@ final class Settings extends BaseController {
|
||||
/**
|
||||
* Oauth callback for Anilist API
|
||||
*/
|
||||
public function anilistCallback()
|
||||
public function anilistCallback(): void
|
||||
{
|
||||
$query = $this->request->getQueryParams();
|
||||
$authCode = $query['code'];
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
namespace Aviat\AnimeClient\Controller;
|
||||
|
||||
use Aviat\AnimeClient\API\Kitsu\Transformer\UserTransformer;
|
||||
use Aviat\AnimeClient\Controller as BaseController;
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
|
||||
/**
|
||||
@ -25,8 +26,18 @@ use Aviat\Ion\Di\ContainerInterface;
|
||||
*/
|
||||
final class User extends BaseController {
|
||||
|
||||
/**
|
||||
* @var \Aviat\AnimeClient\API\Kitsu\Model
|
||||
*/
|
||||
private $kitsuModel;
|
||||
|
||||
/**
|
||||
* User constructor.
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
@ -56,103 +67,16 @@ final class User extends BaseController {
|
||||
? $this->config->get(['kitsu_username'])
|
||||
: $username;
|
||||
|
||||
$data = $this->kitsuModel->getUserData($username);
|
||||
$orgData = JsonAPI::organizeData($data)[0];
|
||||
$rels = $orgData['relationships'] ?? [];
|
||||
$favorites = array_key_exists('favorites', $rels) ? $rels['favorites'] : [];
|
||||
|
||||
$stats = [];
|
||||
foreach ($rels['stats'] as $sid => &$item)
|
||||
{
|
||||
$key = $item['attributes']['kind'];
|
||||
$stats[$key] = $item['attributes']['statsData'];
|
||||
unset($item);
|
||||
}
|
||||
|
||||
//dump($orgData);
|
||||
// dump($stats);
|
||||
|
||||
// $timeOnAnime = $this->formatAnimeTime($orgData['attributes']['lifeSpentOnAnime']);
|
||||
$timeOnAnime = $this->formatAnimeTime($stats['anime-amount-consumed']['time']);
|
||||
|
||||
|
||||
$whom = $isMainUser
|
||||
? $this->config->get('whose_list')
|
||||
: $username;
|
||||
|
||||
$rawData = $this->kitsuModel->getUserData($username);
|
||||
$data = (new UserTransformer())->transform($rawData)->toArray();
|
||||
|
||||
$this->outputHTML('user/details', [
|
||||
'title' => 'About ' . $whom,
|
||||
'data' => $orgData,
|
||||
'attributes' => $orgData['attributes'],
|
||||
'relationships' => $rels,
|
||||
'favorites' => $this->organizeFavorites($favorites),
|
||||
'stats' => $stats,
|
||||
'timeOnAnime' => $timeOnAnime,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorganize favorites data to be more useful
|
||||
*
|
||||
* @param array $rawFavorites
|
||||
* @return array
|
||||
*/
|
||||
private function organizeFavorites(array $rawFavorites): array
|
||||
{
|
||||
$output = [];
|
||||
|
||||
unset($rawFavorites['data']);
|
||||
|
||||
foreach ($rawFavorites as $item)
|
||||
{
|
||||
$rank = $item['attributes']['favRank'];
|
||||
foreach ($item['relationships']['item'] as $key => $fav)
|
||||
{
|
||||
$output[$key] = $output[$key] ?? [];
|
||||
foreach ($fav as $id => $data)
|
||||
{
|
||||
$output[$key][$rank] = array_merge(['id' => $id], $data['attributes']);
|
||||
}
|
||||
}
|
||||
|
||||
ksort($output[$key]);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the time spent on anime in a more readable format
|
||||
*
|
||||
* @param int $minutes
|
||||
* @return string
|
||||
*/
|
||||
private function formatAnimeTime(int $minutes): string
|
||||
{
|
||||
$minutesPerDay = 1440;
|
||||
$minutesPerYear = $minutesPerDay * 365;
|
||||
|
||||
// Minutes short of a year
|
||||
$years = (int)floor($minutes / $minutesPerYear);
|
||||
$minutes %= $minutesPerYear;
|
||||
|
||||
// Minutes short of a day
|
||||
$extraMinutes = $minutes % $minutesPerDay;
|
||||
|
||||
$days = ($minutes - $extraMinutes) / $minutesPerDay;
|
||||
|
||||
// Minutes short of an hour
|
||||
$remMinutes = $extraMinutes % 60;
|
||||
|
||||
$hours = ($extraMinutes - $remMinutes) / 60;
|
||||
|
||||
$output = "{$days} days, {$hours} hours, and {$remMinutes} minutes.";
|
||||
|
||||
if ($years > 0)
|
||||
{
|
||||
$output = "{$years} year(s),{$output}";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -17,9 +17,9 @@
|
||||
namespace Aviat\AnimeClient\Types;
|
||||
|
||||
/**
|
||||
* Type representing an Anime object for display
|
||||
* Type representing an anime within a watch list
|
||||
*/
|
||||
final class Anime extends AbstractType {
|
||||
class Anime extends AbstractType {
|
||||
public $age_rating;
|
||||
public $age_rating_guide;
|
||||
public $cover_image;
|
||||
|
@ -17,7 +17,7 @@
|
||||
namespace Aviat\AnimeClient\Types;
|
||||
|
||||
/**
|
||||
* Type representing an Anime object for display
|
||||
* Type representing an anime watch list item
|
||||
*/
|
||||
final class AnimeListItem extends AbstractType {
|
||||
public $id;
|
||||
@ -40,4 +40,9 @@ final class AnimeListItem extends AbstractType {
|
||||
public $rewatched;
|
||||
public $user_rating;
|
||||
public $watching_status;
|
||||
|
||||
public function setAnime($anime): void
|
||||
{
|
||||
$this->anime = new Anime($anime);
|
||||
}
|
||||
}
|
||||
|
25
src/Types/AnimePage.php
Normal file
25
src/Types/AnimePage.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Types;
|
||||
|
||||
/**
|
||||
* Type representing an Anime object for a detail page
|
||||
*/
|
||||
final class AnimePage extends Anime {
|
||||
public $characters;
|
||||
public $staff;
|
||||
}
|
39
src/Types/Character.php
Normal file
39
src/Types/Character.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Types;
|
||||
|
||||
/**
|
||||
* Type representing a character for display
|
||||
*/
|
||||
final class Character extends AbstractType {
|
||||
public $castings;
|
||||
public $description;
|
||||
public $id;
|
||||
public $included;
|
||||
public $media;
|
||||
public $name;
|
||||
public $names;
|
||||
public $otherNames;
|
||||
|
||||
public function setMedia ($media): void
|
||||
{
|
||||
$this->media = new class($media) extends AbstractType {
|
||||
public $anime;
|
||||
public $manga;
|
||||
};
|
||||
}
|
||||
}
|
35
src/Types/Person.php
Normal file
35
src/Types/Person.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Types;
|
||||
|
||||
/**
|
||||
* Type representing a person for display
|
||||
*/
|
||||
final class Person extends AbstractType {
|
||||
public $id;
|
||||
public $name;
|
||||
public $characters;
|
||||
public $staff;
|
||||
|
||||
public function setCharacters($characters): void
|
||||
{
|
||||
$this->characters = new class($characters) extends AbstractType {
|
||||
public $main;
|
||||
public $supporting;
|
||||
};
|
||||
}
|
||||
}
|
32
src/Types/User.php
Normal file
32
src/Types/User.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2018 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.1
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Types;
|
||||
|
||||
/**
|
||||
* Type representing a Kitsu user for display
|
||||
*/
|
||||
final class User extends AbstractType {
|
||||
public $about;
|
||||
public $avatar;
|
||||
public $favorites;
|
||||
public $location;
|
||||
public $name;
|
||||
public $slug;
|
||||
public $stats;
|
||||
public $waifu;
|
||||
public $website;
|
||||
}
|
@ -1,4 +1,10 @@
|
||||
<?php return Aviat\AnimeClient\Types\Anime::__set_state(array(
|
||||
<?php return Aviat\AnimeClient\Types\AnimePage::__set_state(array(
|
||||
'characters' =>
|
||||
array (
|
||||
),
|
||||
'staff' =>
|
||||
array (
|
||||
),
|
||||
'age_rating' => 'R',
|
||||
'age_rating_guide' => 'Violence, Profanity',
|
||||
'cover_image' => 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1418580054',
|
||||
|
Loading…
Reference in New Issue
Block a user