Genres |
@@ -82,16 +94,16 @@
type="radio" name="staff-roles" id="staff-role= $i ?>" = $i === 0 ? 'checked' : '' ?> />
- $person): ?>
+
- generate('person', ['id' => $pid]) ?>
+ generate('person', ['id' => $person['id']]) ?>
- = $helper->picture("images/people/{$pid}.webp") ?>
+ = $helper->picture("images/people/{$person['id']}.webp") ?>
diff --git a/src/AnimeClient/API/Kitsu.php b/src/AnimeClient/API/Kitsu.php
index 1ef7ae97..fb1ece76 100644
--- a/src/AnimeClient/API/Kitsu.php
+++ b/src/AnimeClient/API/Kitsu.php
@@ -17,6 +17,7 @@
namespace Aviat\AnimeClient\API;
use Aviat\AnimeClient\API\Kitsu\Enum\AnimeAiringStatus;
+use Aviat\AnimeClient\API\Kitsu\Enum\MangaPublishingStatus;
use DateTimeImmutable;
/**
@@ -65,6 +66,28 @@ final class Kitsu {
return AnimeAiringStatus::NOT_YET_AIRED;
}
+ public static function getPublishingStatus(string $kitsuStatus, string $startDate = NULL, string $endDate = NULL): string
+ {
+ $startPubDate = new DateTimeImmutable($startDate ?? 'tomorrow');
+ $endPubDate = new DateTimeImmutable($endDate ?? 'next year');
+ $now = new DateTimeImmutable();
+
+ $isDone = $now > $endPubDate;
+ $isCurrent = ($now > $startPubDate) && ! $isDone;
+
+ if ($kitsuStatus === 'CURRENT' || $isCurrent)
+ {
+ return MangaPublishingStatus::CURRENT;
+ }
+
+ if ($kitsuStatus === 'FINISHED' || $isDone)
+ {
+ return MangaPublishingStatus::FINISHED;
+ }
+
+ return MangaPublishingStatus::NOT_YET_PUBLISHED;
+ }
+
/**
* Reorganize streaming links
*
diff --git a/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php b/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php
new file mode 100644
index 00000000..dc0949aa
--- /dev/null
+++ b/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php
@@ -0,0 +1,29 @@
+
+ * @copyright 2015 - 2020 Timothy J. Warren
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @version 5
+ * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
+ */
+
+namespace Aviat\AnimeClient\API\Kitsu\Enum;
+
+use Aviat\Ion\Enum as BaseEnum;
+
+/**
+ * Status of when anime is being/was/will be aired
+ */
+final class MangaPublishingStatus extends BaseEnum {
+ public const NOT_YET_PUBLISHED = 'Not Yet Published';
+ public const FINISHED = 'Completed';
+ public const CURRENT = 'Current';
+}
+// End of MangaPublishingStatus
diff --git a/src/AnimeClient/API/Kitsu/GraphQL/Queries/MangaDetails.graphql b/src/AnimeClient/API/Kitsu/GraphQL/Queries/MangaDetails.graphql
new file mode 100644
index 00000000..14a7a4ab
--- /dev/null
+++ b/src/AnimeClient/API/Kitsu/GraphQL/Queries/MangaDetails.graphql
@@ -0,0 +1,112 @@
+query ($slug: String!) {
+ findMangaBySlug(slug: $slug) {
+ id
+ ageRating
+ ageRatingGuide
+ posterImage {
+ original {
+ height
+ name
+ url
+ width
+ }
+ views {
+ height
+ name
+ url
+ width
+ }
+ }
+ categories {
+ nodes {
+ title
+ }
+ }
+ characters {
+ nodes {
+ character {
+ id
+ names {
+ canonical
+ alternatives
+ }
+ image {
+ original {
+ height
+ name
+ url
+ width
+ }
+ }
+ slug
+ }
+ role
+ }
+ pageInfo {
+ endCursor
+ hasNextPage
+ hasPreviousPage
+ startCursor
+ }
+ }
+ startDate
+ endDate
+ posterImage {
+ original {
+ height
+ name
+ url
+ width
+ }
+ views {
+ height
+ name
+ url
+ width
+ }
+ }
+ sfw
+ slug
+ staff {
+ nodes {
+ person {
+ id
+ birthday
+ image {
+ original {
+ height
+ name
+ url
+ width
+ }
+ views {
+ height
+ name
+ url
+ width
+ }
+ }
+ names {
+ alternatives
+ canonical
+ localized
+ }
+ }
+ role
+ }
+ pageInfo {
+ endCursor
+ hasNextPage
+ hasPreviousPage
+ startCursor
+ }
+ }
+ status
+ synopsis
+ titles {
+ canonical
+ canonicalLocale
+ localized
+ }
+ }
+}
diff --git a/src/AnimeClient/API/Kitsu/GraphQL/Queries/MangaDetailsById.graphql b/src/AnimeClient/API/Kitsu/GraphQL/Queries/MangaDetailsById.graphql
new file mode 100644
index 00000000..68bfb31b
--- /dev/null
+++ b/src/AnimeClient/API/Kitsu/GraphQL/Queries/MangaDetailsById.graphql
@@ -0,0 +1,112 @@
+query ($id: ID!) {
+ findMangaById(id: $id) {
+ id
+ ageRating
+ ageRatingGuide
+ posterImage {
+ original {
+ height
+ name
+ url
+ width
+ }
+ views {
+ height
+ name
+ url
+ width
+ }
+ }
+ categories {
+ nodes {
+ title
+ }
+ }
+ characters {
+ nodes {
+ character {
+ id
+ names {
+ canonical
+ alternatives
+ }
+ image {
+ original {
+ height
+ name
+ url
+ width
+ }
+ }
+ slug
+ }
+ role
+ }
+ pageInfo {
+ endCursor
+ hasNextPage
+ hasPreviousPage
+ startCursor
+ }
+ }
+ startDate
+ endDate
+ posterImage {
+ original {
+ height
+ name
+ url
+ width
+ }
+ views {
+ height
+ name
+ url
+ width
+ }
+ }
+ sfw
+ slug
+ staff {
+ nodes {
+ person {
+ id
+ birthday
+ image {
+ original {
+ height
+ name
+ url
+ width
+ }
+ views {
+ height
+ name
+ url
+ width
+ }
+ }
+ names {
+ alternatives
+ canonical
+ localized
+ }
+ }
+ role
+ }
+ pageInfo {
+ endCursor
+ hasNextPage
+ hasPreviousPage
+ startCursor
+ }
+ }
+ status
+ synopsis
+ titles {
+ canonical
+ canonicalLocale
+ localized
+ }
+ }
+}
diff --git a/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php b/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php
index 9c844bd0..cf01f9e7 100644
--- a/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php
+++ b/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php
@@ -56,7 +56,10 @@ trait KitsuMangaTrait {
*/
public function getManga(string $slug): MangaPage
{
- $baseData = $this->getRawMediaData('manga', $slug);
+ $baseData = $this->requestBuilder->runQuery('MangaDetails', [
+ 'slug' => $slug
+ ]);
+ // $baseData = $this->getRawMediaData('manga', $slug);
if (empty($baseData))
{
@@ -66,6 +69,21 @@ trait KitsuMangaTrait {
return $this->mangaTransformer->transform($baseData);
}
+ /**
+ * Get information about a particular manga
+ *
+ * @param string $mangaId
+ * @return MangaPage
+ */
+ public function getMangaById(string $mangaId): MangaPage
+ {
+ $baseData = $this->requestBuilder->runQuery('MangaDetailsById', [
+ 'id' => $mangaId,
+ ]);
+ // $baseData = $this->getRawMediaDataById('manga', $mangaId);
+ return $this->mangaTransformer->transform($baseData);
+ }
+
/**
* Retrieve the data for the manga read history page
*
@@ -92,18 +110,6 @@ trait KitsuMangaTrait {
return $list;
}
- /**
- * Get information about a particular manga
- *
- * @param string $mangaId
- * @return MangaPage
- */
- public function getMangaById(string $mangaId): MangaPage
- {
- $baseData = $this->getRawMediaDataById('manga', $mangaId);
- return $this->mangaTransformer->transform($baseData);
- }
-
/**
* Get the manga list for the configured user
*
diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php
index 2d428537..9882abb8 100644
--- a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php
+++ b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php
@@ -16,7 +16,7 @@
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
-use Aviat\AnimeClient\API\JsonAPI;
+use Aviat\AnimeClient\API\Kitsu;
use Aviat\AnimeClient\Types\MangaPage;
use Aviat\Ion\Transformer\AbstractTransformer;
@@ -34,106 +34,90 @@ final class MangaTransformer extends AbstractTransformer {
*/
public function transform($item): MangaPage
{
- $genres = [];
+ // TODO: missing GraphQL data:
+ // * chapter count
+ // * volume count
+ // * manga type
- $item['included'] = JsonAPI::organizeIncluded($item['included']);
-
- if (array_key_exists('categories', $item['included']))
- {
- foreach ($item['included']['categories'] as $cat)
- {
- $genres[] = $cat['attributes']['title'];
- }
- sort($genres);
- }
-
- $title = $item['canonicalTitle'];
- $rawTitles = array_values($item['titles']);
- $titles = array_unique(array_diff($rawTitles, [$title]));
+ $base = array_key_exists('findMangaBySlug', $item['data'])
+ ? $item['data']['findMangaBySlug']
+ : $item['data']['findMangaById'];
$characters = [];
$staff = [];
+ $genres = array_map(fn ($genre) => $genre['title']['en'], $base['categories']['nodes']);
+ sort($genres);
- if (array_key_exists('mediaCharacters', $item['included']))
+ $title = $base['titles']['canonical'];
+ $titles = Kitsu::filterLocalizedTitles($base['titles']);
+
+ if (count($base['characters']['nodes']) > 0)
{
- $mediaCharacters = $item['included']['mediaCharacters'];
+ $characters['main'] = [];
+ $characters['supporting'] = [];
- foreach ($mediaCharacters as $rel)
+ foreach ($base['characters']['nodes'] as $rawCharacter)
{
- // dd($rel);
- // $charId = $rel['relationships']['character']['data']['id'];
- $role = $rel['attributes']['role'];
+ $type = $rawCharacter['role'] === 'MAIN' ? 'main' : 'supporting';
+ $details = $rawCharacter['character'];
+ $characters[$type][$details['id']] = [
+ 'image' => $details['image'],
+ 'name' => $details['names']['canonical'],
+ 'slug' => $details['slug'],
+ ];
+ }
- foreach ($rel['relationships']['character']['characters'] as $charId => $char)
- {
- if (array_key_exists($charId, $item['included']['characters']))
- {
- $characters[$role][$charId] = $char['attributes'];
- }
- }
+ uasort($characters['main'], fn($a, $b) => $a['name'] <=> $b['name']);
+ uasort($characters['supporting'], fn($a, $b) => $a['name'] <=> $b['name']);
+
+ if (empty($characters['supporting']))
+ {
+ unset($characters['supporting']);
}
}
- if (array_key_exists('mediaStaff', $item['included']))
+ if (count($base['staff']['nodes']) > 0)
{
- foreach ($item['included']['mediaStaff'] as $id => $staffing)
+ foreach ($base['staff']['nodes'] as $staffing)
{
- $role = $staffing['attributes']['role'];
+ $person = $staffing['person'];
+ $role = $staffing['role'];
+ $name = $person['names']['localized'][$person['names']['canonical']];
- foreach ($staffing['relationships']['person']['people'] as $personId => $personDetails)
+ if ( ! array_key_exists($role, $staff))
{
- if ( ! array_key_exists($role, $staff))
- {
- $staff[$role] = [];
- }
-
- $staff[$role][$personId] = [
- 'id' => $personId,
- 'name' => $personDetails['attributes']['name'] ?? '??',
- 'image' => $personDetails['attributes']['image'],
- ];
+ $staff[$role] = [];
}
+
+ $staff[$role][$person['id']] = [
+ 'id' => $person['id'],
+ 'name' => $name,
+ 'image' => [
+ 'original' => $person['image']['original']['url'],
+ ],
+ ];
+
+ usort($staff[$role], fn ($a, $b) => $a['name'] <=> $b['name']);
}
+
+ ksort($staff);
}
- if ( ! empty($characters['main']))
- {
- uasort($characters['main'], fn ($a, $b) => $a['name'] <=> $b['name']);
- }
-
- if ( ! empty($characters['supporting']))
- {
- uasort($characters['supporting'], fn ($a, $b) => $a['name'] <=> $b['name']);
- }
-
- ksort($characters);
- ksort($staff);
-
- return MangaPage::from([
+ $data = [
+ 'age_rating' => $base['ageRating'],
+ 'age_rating_guide' => $base['ageRatingGuide'],
'characters' => $characters,
- 'chapter_count' => $this->count($item['chapterCount']),
- 'cover_image' => $item['posterImage']['small'],
+ 'cover_image' => $base['posterImage']['views'][1]['url'],
'genres' => $genres,
- 'id' => $item['id'],
- 'included' => $item['included'],
- 'manga_type' => $item['mangaType'],
+ 'id' => $base['id'],
'staff' => $staff,
- 'synopsis' => $item['synopsis'],
+ 'status' => Kitsu::getPublishingStatus($base['status'], $base['startDate'], $base['endDate']),
+ 'synopsis' => $base['synopsis']['en'],
'title' => $title,
'titles' => $titles,
- 'url' => "https://kitsu.io/manga/{$item['slug']}",
- 'volume_count' => $this->count($item['volumeCount']),
- ]);
- }
+ 'url' => "https://kitsu.io/manga/{$base['slug']}",
+ ];
- /**
- * @param int|null $value
- * @return string
- */
- private function count(int $value = NULL): string
- {
- return ((int)$value === 0)
- ? '-'
- : (string)$value;
+ return MangaPage::from($data);
}
}
\ No newline at end of file
diff --git a/src/AnimeClient/Types/MangaPage.php b/src/AnimeClient/Types/MangaPage.php
index 3db6679c..18eb2d2f 100644
--- a/src/AnimeClient/Types/MangaPage.php
+++ b/src/AnimeClient/Types/MangaPage.php
@@ -16,10 +16,22 @@
namespace Aviat\AnimeClient\Types;
+use Aviat\AnimeClient\API\Kitsu\Enum\MangaPublishingStatus;
+
/**
* Type representing an Anime object for display
*/
final class MangaPage extends AbstractType {
+ /**
+ * @var string
+ */
+ public ?string $age_rating;
+
+ /**
+ * @var string
+ */
+ public ?string $age_rating_guide;
+
/**
* @var array
*/
@@ -45,43 +57,43 @@ final class MangaPage extends AbstractType {
*/
public $id;
- /**
- * @var array
- */
- public $included;
-
/**
* @var string
*/
public $manga_type;
/**
- * @var array
+ * @var MangaPublishingStatus
*/
- public $staff;
-
- /**
- * @var string
- */
- public $synopsis;
-
- /**
- * @var string
- */
- public $title;
+ public string $status = MangaPublishingStatus::FINISHED;
/**
* @var array
*/
- public $titles;
+ public array $staff;
/**
* @var string
*/
- public $url;
+ public string $synopsis;
+
+ /**
+ * @var string
+ */
+ public string $title;
+
+ /**
+ * @var array
+ */
+ public array $titles;
+
+ /**
+ * @var string
+ */
+ public string $url;
/**
* @var int
*/
- public $volume_count;
+ public ?int $volume_count;
}
|