diff --git a/app/config/config.toml.example b/app/config/config.toml.example index 28f954b7..d70bb34a 100644 --- a/app/config/config.toml.example +++ b/app/config/config.toml.example @@ -10,6 +10,3 @@ whose_list = "Tim" # do you wish to show the anime collection? show_anime_collection = true - -# path to public directory on the server -asset_dir = "/../../public" \ No newline at end of file diff --git a/src/API/Anilist.php b/src/API/Anilist.php index 8b413327..b45ae8d3 100644 --- a/src/API/Anilist.php +++ b/src/API/Anilist.php @@ -29,10 +29,10 @@ use Aviat\AnimeClient\API\Enum\{ * Constants and mappings for the Anilist API */ final class Anilist { - const AUTH_URL = 'https://anilist.co/api/v2/oauth/authorize'; - const BASE_URL = 'https://graphql.anilist.co'; + public const AUTH_URL = 'https://anilist.co/api/v2/oauth/authorize'; + public const BASE_URL = 'https://graphql.anilist.co'; - const KITSU_ANILIST_WATCHING_STATUS_MAP = [ + public const KITSU_ANILIST_WATCHING_STATUS_MAP = [ KAWS::WATCHING => AnimeWatchingStatus::WATCHING, KAWS::COMPLETED => AnimeWatchingStatus::COMPLETED, KAWS::ON_HOLD => AnimeWatchingStatus::ON_HOLD, @@ -40,7 +40,7 @@ final class Anilist { KAWS::PLAN_TO_WATCH => AnimeWatchingStatus::PLAN_TO_WATCH, ]; - const ANILIST_KITSU_WATCHING_STATUS_MAP = [ + public const ANILIST_KITSU_WATCHING_STATUS_MAP = [ AnimeWatchingStatus::WATCHING => KAWS::WATCHING, AnimeWatchingStatus::COMPLETED => KAWS::COMPLETED, AnimeWatchingStatus::ON_HOLD => KAWS::ON_HOLD, @@ -48,7 +48,7 @@ final class Anilist { AnimeWatchingStatus::PLAN_TO_WATCH => KAWS::PLAN_TO_WATCH, ]; - const KITSU_ANILIST_READING_STATUS_MAP = [ + public const KITSU_ANILIST_READING_STATUS_MAP = [ KMRS::READING => MangaReadingStatus::READING, KMRS::COMPLETED => MangaReadingStatus::COMPLETED, KMRS::ON_HOLD => MangaReadingStatus::ON_HOLD, @@ -56,7 +56,7 @@ final class Anilist { KMRS::PLAN_TO_READ => MangaReadingStatus::PLAN_TO_READ, ]; - const ANILIST_KITSU_READING_STATUS_MAP = [ + public const ANILIST_KITSU_READING_STATUS_MAP = [ MangaReadingStatus::READING => KMRS::READING, MangaReadingStatus::COMPLETED => KMRS::COMPLETED, MangaReadingStatus::ON_HOLD => KMRS::ON_HOLD, diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index 634c5462..2edb741b 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -341,9 +341,9 @@ final class Model { * Get information about a particular anime * * @param string $animeId - * @return array + * @return Anime */ - public function getAnimeById(string $animeId): array + public function getAnimeById(string $animeId): Anime { $baseData = $this->getRawMediaDataById('anime', $animeId); return $this->animeTransformer->transform($baseData); @@ -455,7 +455,7 @@ final class Model { } /** - * Get all the anine entries, that are organized for output to html + * Get all the anime entries, that are organized for output to html * * @return array */ diff --git a/src/API/Kitsu/Transformer/AnimeTransformer.php b/src/API/Kitsu/Transformer/AnimeTransformer.php index 40d494c6..3f28919e 100644 --- a/src/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/API/Kitsu/Transformer/AnimeTransformer.php @@ -40,7 +40,7 @@ final class AnimeTransformer extends AbstractTransformer { sort($item['genres']); $title = $item['canonicalTitle']; - $titles = array_diff($item['titles'], [$title]); + $titles = array_unique(array_diff($item['titles'], [$title])); return new Anime([ 'age_rating' => $item['ageRating'], diff --git a/src/API/Kitsu/Transformer/MangaTransformer.php b/src/API/Kitsu/Transformer/MangaTransformer.php index afd468d5..32c5ad9c 100644 --- a/src/API/Kitsu/Transformer/MangaTransformer.php +++ b/src/API/Kitsu/Transformer/MangaTransformer.php @@ -33,7 +33,6 @@ final class MangaTransformer extends AbstractTransformer { */ public function transform($item): MangaPage { - // \dump($item); $genres = []; foreach($item['included'] as $included) @@ -46,11 +45,13 @@ final class MangaTransformer extends AbstractTransformer { sort($genres); + $title = $item['canonicalTitle']; + $titles = array_unique(array_diff($item['titles'], [$title])); + return new MangaPage([ 'id' => $item['id'], - 'title' => $item['canonicalTitle'], - 'en_title' => $item['titles']['en'], - 'jp_title' => $item['titles']['en_jp'], + 'title' => $title, + 'titles' => $titles, 'cover_image' => $item['posterImage']['small'], 'manga_type' => $item['mangaType'], 'chapter_count' => $this->count($item['chapterCount']), diff --git a/src/API/MAL/ListItem.php b/src/API/MAL/ListItem.php index 09405394..e0f9478f 100644 --- a/src/API/MAL/ListItem.php +++ b/src/API/MAL/ListItem.php @@ -85,11 +85,11 @@ final class ListItem { * Update a list item * * @param string $id - * @param AbstractType $data + * @param array $data * @param string $type * @return Request */ - public function update(string $id, AbstractType $data, string $type = 'anime'): Request + public function update(string $id, array $data, string $type = 'anime'): Request { $config = $this->container->get('config'); diff --git a/src/API/MAL/Model.php b/src/API/MAL/Model.php index 0f245d81..ce49b066 100644 --- a/src/API/MAL/Model.php +++ b/src/API/MAL/Model.php @@ -148,11 +148,11 @@ final class Model { /** * Update a list item * - * @param FormItem $data + * @param array $data * @param string $type "anime" or "manga" * @return Request */ - public function updateListItem(FormItem $data, string $type = 'anime'): Request + public function updateListItem($data, string $type = 'anime'): Request { $updateData = []; diff --git a/src/API/MAL/Transformer/AnimeListTransformer.php b/src/API/MAL/Transformer/AnimeListTransformer.php index 5c32c0f6..9e25c9d0 100644 --- a/src/API/MAL/Transformer/AnimeListTransformer.php +++ b/src/API/MAL/Transformer/AnimeListTransformer.php @@ -38,10 +38,10 @@ final class AnimeListTransformer extends AbstractTransformer { /** * Transform Kitsu episode data to MAL episode data * - * @param array $item - * @return AnimeFormItem + * @param mixed $item + * @return array */ - public function untransform(array $item): AnimeFormItem + public function untransform($item): array { $map = [ 'id' => $item['mal_id'], @@ -81,6 +81,6 @@ final class AnimeListTransformer extends AbstractTransformer { } } - return new AnimeFormItem($map); + return $map; } } \ No newline at end of file diff --git a/src/API/MAL/Transformer/MangaListTransformer.php b/src/API/MAL/Transformer/MangaListTransformer.php index b55f91fc..07cf24a7 100644 --- a/src/API/MAL/Transformer/MangaListTransformer.php +++ b/src/API/MAL/Transformer/MangaListTransformer.php @@ -37,18 +37,16 @@ final class MangaListTransformer extends AbstractTransformer { /** * Transform Kitsu data to MAL data * - * @param array $item - * @return array + * @param mixed $item + * @return */ - public function untransform(array $item): array + public function untransform($item): array { $map = [ - 'id' => $item['mal_id'], + 'id' => $item['mal_id'] ?? $item['malId'], 'data' => [] ]; - $data =& $item['data']; - foreach($item['data'] as $key => $value) { switch($key) diff --git a/src/AnimeClient.php b/src/AnimeClient.php index 8b94f169..bdc79eb4 100644 --- a/src/AnimeClient.php +++ b/src/AnimeClient.php @@ -17,7 +17,7 @@ namespace Aviat\AnimeClient; use Aviat\Ion\ConfigInterface; -use Yosymfony\Toml\Toml; +use Yosymfony\Toml\{Toml, TomlBuilder}; /** * Load configuration options from .toml files @@ -51,6 +51,86 @@ function loadToml(string $path): array return $output; } +/** + * Is the array sequential, not associative? + * + * @param mixed $array + * @return bool + */ +function isSequentialArray($array): bool +{ + if ( ! is_array($array)) + { + return FALSE; + } + + $i = 0; + foreach ($array as $k => $v) + { + if ($k !== $i++) + { + return FALSE; + } + } + return TRUE; +} + +function _iterateToml(TomlBuilder $builder, $data, $parentKey = NULL): void +{ + foreach ($data as $key => $value) + { + if ($value === NULL) + { + continue; + } + + + if (is_scalar($value) || isSequentialArray($value)) + { + // $builder->addTable(''); + $builder->addValue($key, $value); + continue; + } + + $newKey = ($parentKey !== NULL) + ? "{$parentKey}.{$key}" + : $key; + + if ( ! isSequentialArray($value)) + { + $builder->addTable($newKey); + } + + _iterateToml($builder, $value, $newKey); + } +} + +/** + * Serialize config data into a Toml file + * + * @param mixed $data + * @return string + */ +function arrayToToml($data): string +{ + $builder = new TomlBuilder(); + + _iterateToml($builder, $data); + + return $builder->getTomlString(); +} + +/** + * Serialize toml back to an array + * + * @param string $toml + * @return array + */ +function tomlToArray(string $toml): array +{ + return Toml::parse($toml); +} + /** * Check that folder permissions are correct for proper operation * @@ -64,7 +144,6 @@ function checkFolderPermissions(ConfigInterface $config): array $pathMap = [ 'app/logs' => realpath(__DIR__ . '/../app/logs'), - 'public/js/cache' => "{$publicDir}/js/cache", 'public/images/avatars' => "{$publicDir}/images/avatars", 'public/images/anime' => "{$publicDir}/images/anime", 'public/images/characters' => "{$publicDir}/images/characters", diff --git a/src/Controller/Index.php b/src/Controller/Index.php index eccb130e..48db67df 100644 --- a/src/Controller/Index.php +++ b/src/Controller/Index.php @@ -170,9 +170,8 @@ final class Index extends BaseController { $auth = $this->container->get('auth'); $this->outputHTML('settings', [ 'auth' => $auth, + 'config' => $this->config, 'title' => $this->config->get('whose_list') . "'s Settings", - 'base_settings' => $this->config->get('default_config'), - 'user_settings' => $this->config->get('user_config_settings'), ]); } diff --git a/src/Model/Anime.php b/src/Model/Anime.php index 34a5b366..28f5351f 100644 --- a/src/Model/Anime.php +++ b/src/Model/Anime.php @@ -109,9 +109,9 @@ class Anime extends API { * Get anime by its kitsu id * * @param string $animeId - * @return array + * @return AnimeType */ - public function getAnimeById(string $animeId): array + public function getAnimeById(string $animeId): AnimeType { return $this->kitsuModel->getAnimeById($animeId); } diff --git a/src/Types/AbstractType.php b/src/Types/AbstractType.php index f4dd427d..2098acca 100644 --- a/src/Types/AbstractType.php +++ b/src/Types/AbstractType.php @@ -19,7 +19,7 @@ namespace Aviat\AnimeClient\Types; use ArrayAccess; use LogicException; -abstract class AbstractType implements ArrayAccess { +class AbstractType implements ArrayAccess { /** * Populate values for unserializing data * diff --git a/src/Types/MangaPage.php b/src/Types/MangaPage.php index 5734d1a5..a2bb3246 100644 --- a/src/Types/MangaPage.php +++ b/src/Types/MangaPage.php @@ -22,14 +22,13 @@ namespace Aviat\AnimeClient\Types; final class MangaPage extends AbstractType { public $chapter_count; public $cover_image; - public $en_title; public $genres; public $id; public $included; - public $jp_title; public $manga_type; public $synopsis; public $title; + public $titles; public $url; public $volume_count; } diff --git a/tests/AnimeClientTest.php b/tests/AnimeClientTest.php new file mode 100644 index 00000000..3414f4f2 --- /dev/null +++ b/tests/AnimeClientTest.php @@ -0,0 +1,60 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Tests; + +use function Aviat\AnimeClient\arrayToToml; +use function Aviat\AnimeClient\tomlToArray; + +class AnimeClientTest extends AnimeClientTestCase +{ + public function testArrayToToml () + { + $arr = [ + 'cat' => false, + 'foo' => 'bar', + 'dateTime' => (array) new \DateTime(), + 'bar' => [ + 'a' => 1, + 'b' => 2, + 'c' => 3, + ], + 'baz' => [ + 'x' => [1, 2, 3], + 'y' => [2, 4, 6], + 'z' => [3, 6, 9], + ], + 'foobar' => [ + 'z' => 22/7, + 'a' => [ + 'aa' => -8, + 'b' => [ + 'aaa' => 4028, + 'c' => [1, 2, 3], + ], + ], + ], + ]; + + $toml = arrayToToml($arr); + + echo $toml . "\n"; + + $parsedArray = tomlToArray($toml); + + $this->assertEquals($arr, $parsedArray); + } +} \ No newline at end of file