Do you wish to register an account?
API client for Kitsu.io, with optional Anime collection, and optional Anilist syncing.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
3.6KB

  1. <?php declare(strict_types=1);
  2. /**
  3. * Hummingbird Anime List Client
  4. *
  5. * An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
  6. *
  7. * PHP version 7
  8. *
  9. * @package HummingbirdAnimeClient
  10. * @author Timothy J. Warren <tim@timshomepage.net>
  11. * @copyright 2015 - 2017 Timothy J. Warren
  12. * @license http://www.opensource.org/licenses/mit-license.html MIT License
  13. * @version 4.0
  14. * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
  15. */
  16. namespace Aviat\AnimeClient\Controller;
  17. use Aviat\AnimeClient\Controller as BaseController;
  18. use Aviat\AnimeClient\API\JsonAPI;
  19. use Aviat\Ion\ArrayWrapper;
  20. /**
  21. * Controller for character description pages
  22. */
  23. class Character extends BaseController {
  24. use ArrayWrapper;
  25. public function index(string $slug)
  26. {
  27. $model = $this->container->get('kitsu-model');
  28. $rawData = $model->getCharacter($slug);
  29. if (( ! array_key_exists('data', $rawData)) || empty($rawData['data']))
  30. {
  31. return $this->notFound(
  32. $this->formatTitle(
  33. 'Characters',
  34. 'Character not found'
  35. ),
  36. 'Character Not Found'
  37. );
  38. }
  39. $data = JsonAPI::organizeData($rawData);
  40. $viewData = [
  41. 'title' => $this->formatTitle(
  42. 'Characters',
  43. $data[0]['attributes']['name']
  44. ),
  45. 'data' => $data,
  46. 'castCount' => 0,
  47. 'castings' => []
  48. ];
  49. if (array_key_exists('included', $data) && array_key_exists('castings', $data['included']))
  50. {
  51. $viewData['castings'] = $this->organizeCast($data['included']['castings']);
  52. $viewData['castCount'] = $this->getCastCount($viewData['castings']);
  53. }
  54. $this->outputHTML('character', $viewData);
  55. }
  56. /**
  57. * Organize VA => anime relationships
  58. *
  59. * @param array $cast
  60. * @return array
  61. */
  62. private function dedupeCast(array $cast): array
  63. {
  64. $output = [];
  65. $people = [];
  66. $i = 0;
  67. foreach ($cast as &$role)
  68. {
  69. if (empty($role['attributes']['role']))
  70. {
  71. continue;
  72. }
  73. $person = current($role['relationships']['person']['people'])['attributes'];
  74. if ( ! array_key_exists($person['name'], $people))
  75. {
  76. $people[$person['name']] = $i;
  77. $role['relationships']['media']['anime'] = [current($role['relationships']['media']['anime'])];
  78. $output[$i] = $role;
  79. $i++;
  80. continue;
  81. }
  82. else if(array_key_exists($person['name'], $people))
  83. {
  84. if (array_key_exists('anime', $role['relationships']['media']))
  85. {
  86. $key = $people[$person['name']];
  87. $output[$key]['relationships']['media']['anime'][] = current($role['relationships']['media']['anime']);
  88. }
  89. continue;
  90. }
  91. }
  92. return $output;
  93. }
  94. private function getCastCount(array $cast): int
  95. {
  96. $count = 0;
  97. foreach($cast as $role)
  98. {
  99. if (
  100. array_key_exists('attributes', $role) &&
  101. array_key_exists('role', $role['attributes']) &&
  102. ( ! is_null($role['attributes']['role']))
  103. ) {
  104. $count++;
  105. }
  106. }
  107. return $count;
  108. }
  109. private function organizeCast(array $cast): array
  110. {
  111. $cast = $this->dedupeCast($cast);
  112. $output = [];
  113. foreach($cast as $id => $role)
  114. {
  115. if (empty($role['attributes']['role']))
  116. {
  117. continue;
  118. }
  119. $language = $role['attributes']['language'];
  120. $roleName = $role['attributes']['role'];
  121. $isVA = $role['attributes']['voiceActor'];
  122. if ($isVA)
  123. {
  124. $person = current($role['relationships']['person']['people'])['attributes'];
  125. $name = $person['name'];
  126. $item = [
  127. 'person' => $person,
  128. 'series' => $role['relationships']['media']['anime']
  129. ];
  130. $output[$roleName][$language][] = $item;
  131. }
  132. else
  133. {
  134. $output[$roleName][] = $role['relationships']['person']['people'];
  135. }
  136. }
  137. return $output;
  138. }
  139. }