Various code cleanup
This commit is contained in:
parent
ec9edff2f3
commit
245e1b4344
@ -50,7 +50,8 @@
|
||||
"spatie/phpunit-snapshot-assertions": "^2.2.1",
|
||||
"squizlabs/php_codesniffer": "^3.2.2",
|
||||
"symfony/var-dumper": "^4.4.1",
|
||||
"theseer/phpdox": "*"
|
||||
"theseer/phpdox": "*",
|
||||
"vimeo/psalm": "^3.7"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vendor/bin/robo build",
|
||||
@ -58,10 +59,11 @@
|
||||
"build:js": "cd public && npm run build:js && cd ..",
|
||||
"clean": "vendor/bin/robo clean",
|
||||
"coverage": "phpdbg -qrr -- vendor/bin/phpunit -c build",
|
||||
"phpstan": "phpstan analyse -l 4 -c phpstan.neon src tests ./console index.php",
|
||||
"phpstan": "phpstan analyse -c phpstan.neon",
|
||||
"watch:css": "cd public && npm run watch:css",
|
||||
"watch:js": "cd public && npm run watch:js",
|
||||
"test": "vendor/bin/phpunit"
|
||||
"test": "vendor/bin/phpunit -c build --no-coverage",
|
||||
"test-update": "vendor/bin/phpunit -c build --no-coverage -d --update-snapshots"
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"build": "Generate the api docs",
|
||||
|
11
phpstan.neon
11
phpstan.neon
@ -1,9 +1,18 @@
|
||||
parameters:
|
||||
checkGenericClassInNonGenericObjectType: false
|
||||
inferPrivatePropertyTypeFromConstructor: true
|
||||
level: 7
|
||||
autoload_files:
|
||||
- %rootDir%/../../../tests/mocks.php
|
||||
paths:
|
||||
- src
|
||||
- tests
|
||||
- ./console
|
||||
- index.php
|
||||
ignoreErrors:
|
||||
- '#Access to an undefined property Aviat\\\Ion\\\Friend::\$[a-zA-Z0-9_]+#'
|
||||
- '#Call to an undefined method Aviat\\\Ion\\\Friend::[a-zA-Z0-9_]+\(\)#'
|
||||
- '#Call to an undefined method Aura\\\Html\\\HelperLocator::[a-zA-Z0-9_]+\(\)#'
|
||||
- '#Undefined variable: \$var#'
|
||||
- '#Property Amp\\Artax\\Internal\\RequestCycle::\$[a-zA-Z0-9_]+#'
|
||||
excludes_analyse:
|
||||
- tests/mocks.php
|
55
psalm.xml
Normal file
55
psalm.xml
Normal file
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
totallyTyped="false"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<LessSpecificReturnType errorLevel="info" />
|
||||
|
||||
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||
|
||||
<DeprecatedMethod errorLevel="info" />
|
||||
<DeprecatedProperty errorLevel="info" />
|
||||
<DeprecatedClass errorLevel="info" />
|
||||
<DeprecatedConstant errorLevel="info" />
|
||||
<DeprecatedFunction errorLevel="info" />
|
||||
<DeprecatedInterface errorLevel="info" />
|
||||
<DeprecatedTrait errorLevel="info" />
|
||||
|
||||
<InternalMethod errorLevel="info" />
|
||||
<InternalProperty errorLevel="info" />
|
||||
<InternalClass errorLevel="info" />
|
||||
|
||||
<MissingClosureReturnType errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
<MissingPropertyType errorLevel="info" />
|
||||
<InvalidDocblock errorLevel="info" />
|
||||
<MisplacedRequiredParam errorLevel="info" />
|
||||
|
||||
<PropertyNotSetInConstructor errorLevel="info" />
|
||||
<MissingConstructor errorLevel="info" />
|
||||
<MissingClosureParamType errorLevel="info" />
|
||||
<MissingParamType errorLevel="info" />
|
||||
|
||||
<RedundantCondition errorLevel="info" />
|
||||
|
||||
<DocblockTypeContradiction errorLevel="info" />
|
||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
||||
|
||||
<UnresolvableInclude errorLevel="info" />
|
||||
|
||||
<RawObjectIteration errorLevel="info" />
|
||||
|
||||
<InvalidStringClass errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
@ -65,7 +65,7 @@ class APIRequestBuilder {
|
||||
|
||||
/**
|
||||
* The current request
|
||||
* @var \Amp\Artax\Request
|
||||
* @var Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
@ -219,14 +219,14 @@ class APIRequestBuilder {
|
||||
/**
|
||||
* Return the promise for the current request
|
||||
*
|
||||
* @return Request
|
||||
* @throws \Throwable
|
||||
* @return \Amp\Artax\Request
|
||||
*/
|
||||
public function getFullRequest(): Request
|
||||
{
|
||||
$this->buildUri();
|
||||
|
||||
if ($this->logger)
|
||||
if ($this->logger !== NULL)
|
||||
{
|
||||
$this->logger->debug('API Request', [
|
||||
'request_url' => $this->request->getUri(),
|
||||
|
@ -25,6 +25,8 @@ use Aviat\AnimeClient\API\Anilist;
|
||||
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
||||
use Aviat\AnimeClient\Types\FormItem;
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\Ion\Di\Exception\ContainerException;
|
||||
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||
|
||||
/**
|
||||
* Anilist API Model
|
||||
@ -92,8 +94,8 @@ final class Model
|
||||
*
|
||||
* @param string $type
|
||||
* @return array
|
||||
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
||||
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getSyncList(string $type = 'anime'): array
|
||||
{
|
||||
@ -144,7 +146,7 @@ final class Model
|
||||
];
|
||||
}
|
||||
|
||||
return $this->listItem->create($createData, $type);
|
||||
return $this->listItem->create($createData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
namespace Aviat\AnimeClient\API\Kitsu;
|
||||
|
||||
use Aura\Session\Segment;
|
||||
|
||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
||||
|
||||
use Aviat\AnimeClient\API\{
|
||||
@ -23,7 +25,6 @@ use Aviat\AnimeClient\API\{
|
||||
Kitsu as K
|
||||
};
|
||||
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Kitsu API Authentication
|
||||
@ -42,7 +43,7 @@ final class Auth {
|
||||
/**
|
||||
* Session object
|
||||
*
|
||||
* @var \Aura\Session\Segment
|
||||
* @var Segment
|
||||
*/
|
||||
private $segment;
|
||||
|
||||
|
@ -137,6 +137,9 @@ final class ListItem implements ListItemInterface {
|
||||
return $request->getFullRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
private function getAuthHeader()
|
||||
{
|
||||
$cache = $this->getContainer()->get('cache');
|
||||
|
@ -142,23 +142,24 @@ final class CharacterTransformer extends AbstractTransformer {
|
||||
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'], static function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
});
|
||||
|
||||
$item = [
|
||||
'person' => $person,
|
||||
'series' => $role['relationships']['media']['anime']
|
||||
];
|
||||
|
||||
$output[$roleName][$language][] = $item;
|
||||
}
|
||||
|
||||
$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
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($role['relationships']['person']['people'] as $pid => $person)
|
||||
{
|
||||
|
@ -130,6 +130,9 @@ final class MangaTransformer extends AbstractTransformer {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null|string
|
||||
*/
|
||||
private function count(int $value = NULL)
|
||||
{
|
||||
return ((int)$value === 0)
|
||||
|
@ -62,7 +62,12 @@ final class UpdateThumbnails extends ClearThumbnails {
|
||||
$this->echoBox('Finished regenerating all thumbnails');
|
||||
}
|
||||
|
||||
public function getImageList()
|
||||
/**
|
||||
* @return array-key[][]
|
||||
*
|
||||
* @psalm-return array{anime: list<array-key>, manga: list<array-key>}
|
||||
*/
|
||||
public function getImageList(): array
|
||||
{
|
||||
$mangaList = $this->kitsuModel->getFullRawMangaList();
|
||||
$includes = JsonAPI::organizeIncludes($mangaList['included']);
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
namespace Aviat\AnimeClient\Controller;
|
||||
|
||||
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
||||
|
||||
use function Amp\Promise\wait;
|
||||
use function Aviat\AnimeClient\getResponse;
|
||||
use function Aviat\AnimeClient\createPlaceholderImage;
|
||||
@ -32,17 +34,14 @@ final class Images extends BaseController {
|
||||
* @param string $type The category of image
|
||||
* @param string $file The filename to look for
|
||||
* @param bool $display Whether to output the image to the server
|
||||
* @throws \Aviat\Ion\Di\ContainerException
|
||||
* @throws \Aviat\Ion\Di\NotFoundException
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \TypeError
|
||||
* @throws \Error
|
||||
* @throws \Throwable
|
||||
* @return void
|
||||
* @throws NotFoundException
|
||||
* @throws \Throwable
|
||||
* @throws ContainerException
|
||||
*/
|
||||
public function cache(string $type, string $file, $display = TRUE): void
|
||||
{
|
||||
$currentUrl = $this->request->getUri()->__toString();
|
||||
$currentUrl = (string)$this->request->getUri();
|
||||
|
||||
$kitsuUrl = 'https://media.kitsu.io/';
|
||||
$fileName = str_replace('-original', '', $file);
|
||||
|
@ -37,7 +37,7 @@ abstract class AbstractType implements ArrayAccess, Countable {
|
||||
*
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function __construct($data = [])
|
||||
final public function __construct($data = [])
|
||||
{
|
||||
$typeKeys = array_keys((array)$this);
|
||||
$dataKeys = array_keys((array)$data);
|
||||
@ -187,7 +187,7 @@ abstract class AbstractType implements ArrayAccess, Countable {
|
||||
{
|
||||
$object = $parent ?? $this;
|
||||
|
||||
if (is_scalar($object) || empty($object))
|
||||
if (is_scalar($object) || $object === NULL)
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
|
15
src/Util.php
15
src/Util.php
@ -16,7 +16,8 @@
|
||||
|
||||
namespace Aviat\AnimeClient;
|
||||
|
||||
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
||||
|
||||
/**
|
||||
* Utility method class
|
||||
@ -45,8 +46,8 @@ class Util {
|
||||
* Set up the Util class
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @throws \Aviat\Ion\Di\ContainerException
|
||||
* @throws \Aviat\Ion\Di\NotFoundException
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
@ -80,8 +81,8 @@ class Util {
|
||||
/**
|
||||
* Determine whether to show the sub-menu
|
||||
*
|
||||
* @throws \Aviat\Ion\Di\ContainerException
|
||||
* @throws \Aviat\Ion\Di\NotFoundException
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
* @return bool
|
||||
*/
|
||||
public function isViewPage(): bool
|
||||
@ -98,8 +99,8 @@ class Util {
|
||||
* Determine whether the page is a page with a form, and
|
||||
* not suitable for redirection
|
||||
*
|
||||
* @throws \Aviat\Ion\Di\ContainerException
|
||||
* @throws \Aviat\Ion\Di\NotFoundException
|
||||
* @throws ContainerException
|
||||
* @throws NotFoundException
|
||||
* @return bool
|
||||
*/
|
||||
public function isFormPage(): bool
|
||||
|
@ -36,10 +36,10 @@
|
||||
1 => '小林さんちのメイドラゴン',
|
||||
),
|
||||
)),
|
||||
'watching_status' => 'current',
|
||||
'notes' => NULL,
|
||||
'private' => false,
|
||||
'rewatching' => false,
|
||||
'rewatched' => 0,
|
||||
'user_rating' => '-',
|
||||
'private' => false,
|
||||
'watching_status' => 'current',
|
||||
));
|
||||
|
@ -1,15 +0,0 @@
|
||||
<?php return Aviat\AnimeClient\Types\FormItem::__set_state(array(
|
||||
'id' => 14047981,
|
||||
'anilist_item_id' => NULL,
|
||||
'mal_id' => NULL,
|
||||
'data' =>
|
||||
Aviat\AnimeClient\Types\FormItemData::__set_state(array(
|
||||
'notes' => 'Very formulaic.',
|
||||
'private' => false,
|
||||
'progress' => 38,
|
||||
'ratingTwenty' => 16,
|
||||
'reconsumeCount' => 0,
|
||||
'reconsuming' => false,
|
||||
'status' => 'current',
|
||||
)),
|
||||
));
|
@ -1,15 +0,0 @@
|
||||
<?php return Aviat\AnimeClient\Types\FormItem::__set_state(array(
|
||||
'id' => 14047981,
|
||||
'anilist_item_id' => NULL,
|
||||
'mal_id' => '12345',
|
||||
'data' =>
|
||||
Aviat\AnimeClient\Types\FormItemData::__set_state(array(
|
||||
'notes' => 'Very formulaic.',
|
||||
'private' => true,
|
||||
'progress' => 38,
|
||||
'ratingTwenty' => 16,
|
||||
'reconsumeCount' => 0,
|
||||
'reconsuming' => true,
|
||||
'status' => 'current',
|
||||
)),
|
||||
));
|
@ -1,14 +0,0 @@
|
||||
<?php return Aviat\AnimeClient\Types\FormItem::__set_state(array(
|
||||
'id' => 14047983,
|
||||
'anilist_item_id' => NULL,
|
||||
'mal_id' => '12347',
|
||||
'data' =>
|
||||
Aviat\AnimeClient\Types\FormItemData::__set_state(array(
|
||||
'notes' => '',
|
||||
'private' => true,
|
||||
'progress' => 12,
|
||||
'reconsumeCount' => 0,
|
||||
'reconsuming' => true,
|
||||
'status' => 'current',
|
||||
)),
|
||||
));
|
@ -1,201 +0,0 @@
|
||||
<?php return array (
|
||||
0 =>
|
||||
Aviat\AnimeClient\Types\MangaListItem::__set_state(array(
|
||||
'id' => '15084773',
|
||||
'mal_id' => '26769',
|
||||
'chapters' =>
|
||||
array (
|
||||
'read' => 67,
|
||||
'total' => '-',
|
||||
),
|
||||
'volumes' =>
|
||||
array (
|
||||
'read' => '-',
|
||||
'total' => '-',
|
||||
),
|
||||
'manga' =>
|
||||
Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array(
|
||||
'genres' =>
|
||||
array (
|
||||
0 => 'Comedy',
|
||||
1 => 'Romance',
|
||||
2 => 'School',
|
||||
3 => 'Slice of Life',
|
||||
4 => 'Thriller',
|
||||
),
|
||||
'id' => '20286',
|
||||
'image' => 'https://media.kitsu.io/manga/poster_images/20286/small.jpg?1434293999',
|
||||
'slug' => 'bokura-wa-minna-kawaisou',
|
||||
'title' => 'Bokura wa Minna Kawaisou',
|
||||
'titles' =>
|
||||
array (
|
||||
),
|
||||
'type' => 'Manga',
|
||||
'url' => 'https://kitsu.io/manga/bokura-wa-minna-kawaisou',
|
||||
)),
|
||||
'reading_status' => 'current',
|
||||
'notes' => '',
|
||||
'rereading' => false,
|
||||
'reread' => 0,
|
||||
'user_rating' => 9,
|
||||
)),
|
||||
1 =>
|
||||
Aviat\AnimeClient\Types\MangaListItem::__set_state(array(
|
||||
'id' => '15085607',
|
||||
'mal_id' => '16',
|
||||
'chapters' =>
|
||||
array (
|
||||
'read' => 17,
|
||||
'total' => 120,
|
||||
),
|
||||
'volumes' =>
|
||||
array (
|
||||
'read' => '-',
|
||||
'total' => 14,
|
||||
),
|
||||
'manga' =>
|
||||
Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array(
|
||||
'genres' =>
|
||||
array (
|
||||
0 => 'Comedy',
|
||||
1 => 'Ecchi',
|
||||
2 => 'Harem',
|
||||
3 => 'Romance',
|
||||
4 => 'Sports',
|
||||
),
|
||||
'id' => '47',
|
||||
'image' => 'https://media.kitsu.io/manga/poster_images/47/small.jpg?1434249493',
|
||||
'slug' => 'love-hina',
|
||||
'title' => 'Love Hina',
|
||||
'titles' =>
|
||||
array (
|
||||
),
|
||||
'type' => 'Manga',
|
||||
'url' => 'https://kitsu.io/manga/love-hina',
|
||||
)),
|
||||
'reading_status' => 'current',
|
||||
'notes' => '',
|
||||
'rereading' => false,
|
||||
'reread' => 0,
|
||||
'user_rating' => 7,
|
||||
)),
|
||||
2 =>
|
||||
Aviat\AnimeClient\Types\MangaListItem::__set_state(array(
|
||||
'id' => '15084529',
|
||||
'mal_id' => '35003',
|
||||
'chapters' =>
|
||||
array (
|
||||
'read' => 16,
|
||||
'total' => '-',
|
||||
),
|
||||
'volumes' =>
|
||||
array (
|
||||
'read' => '-',
|
||||
'total' => '-',
|
||||
),
|
||||
'manga' =>
|
||||
Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array(
|
||||
'genres' =>
|
||||
array (
|
||||
0 => 'Comedy',
|
||||
1 => 'Ecchi',
|
||||
2 => 'Gender Bender',
|
||||
3 => 'Romance',
|
||||
4 => 'School',
|
||||
5 => 'Sports',
|
||||
6 => 'Supernatural',
|
||||
),
|
||||
'id' => '11777',
|
||||
'image' => 'https://media.kitsu.io/manga/poster_images/11777/small.jpg?1438784325',
|
||||
'slug' => 'yamada-kun-to-7-nin-no-majo',
|
||||
'title' => 'Yamada-kun to 7-nin no Majo',
|
||||
'titles' =>
|
||||
array (
|
||||
0 => 'Yamada-kun and the Seven Witches',
|
||||
),
|
||||
'type' => 'Manga',
|
||||
'url' => 'https://kitsu.io/manga/yamada-kun-to-7-nin-no-majo',
|
||||
)),
|
||||
'reading_status' => 'current',
|
||||
'notes' => '',
|
||||
'rereading' => false,
|
||||
'reread' => 0,
|
||||
'user_rating' => 9,
|
||||
)),
|
||||
3 =>
|
||||
Aviat\AnimeClient\Types\MangaListItem::__set_state(array(
|
||||
'id' => '15312827',
|
||||
'mal_id' => '78523',
|
||||
'chapters' =>
|
||||
array (
|
||||
'read' => 68,
|
||||
'total' => '-',
|
||||
),
|
||||
'volumes' =>
|
||||
array (
|
||||
'read' => '-',
|
||||
'total' => '-',
|
||||
),
|
||||
'manga' =>
|
||||
Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array(
|
||||
'genres' =>
|
||||
array (
|
||||
0 => 'Romance',
|
||||
1 => 'School',
|
||||
2 => 'Slice of Life',
|
||||
),
|
||||
'id' => '27175',
|
||||
'image' => 'https://media.kitsu.io/manga/poster_images/27175/small.jpg?1464379411',
|
||||
'slug' => 'relife',
|
||||
'title' => 'ReLIFE',
|
||||
'titles' =>
|
||||
array (
|
||||
),
|
||||
'type' => 'Manga',
|
||||
'url' => 'https://kitsu.io/manga/relife',
|
||||
)),
|
||||
'reading_status' => 'current',
|
||||
'notes' => '',
|
||||
'rereading' => false,
|
||||
'reread' => 0,
|
||||
'user_rating' => '-',
|
||||
)),
|
||||
4 =>
|
||||
Aviat\AnimeClient\Types\MangaListItem::__set_state(array(
|
||||
'id' => '15084769',
|
||||
'mal_id' => '60815',
|
||||
'chapters' =>
|
||||
array (
|
||||
'read' => 43,
|
||||
'total' => '-',
|
||||
),
|
||||
'volumes' =>
|
||||
array (
|
||||
'read' => '-',
|
||||
'total' => '-',
|
||||
),
|
||||
'manga' =>
|
||||
Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array(
|
||||
'genres' =>
|
||||
array (
|
||||
0 => 'Comedy',
|
||||
1 => 'School',
|
||||
2 => 'Slice of Life',
|
||||
),
|
||||
'id' => '25491',
|
||||
'image' => 'https://media.kitsu.io/manga/poster_images/25491/small.jpg?1434305043',
|
||||
'slug' => 'joshikausei',
|
||||
'title' => 'Joshikausei',
|
||||
'titles' =>
|
||||
array (
|
||||
),
|
||||
'type' => 'Manga',
|
||||
'url' => 'https://kitsu.io/manga/joshikausei',
|
||||
)),
|
||||
'reading_status' => 'current',
|
||||
'notes' => '',
|
||||
'rereading' => false,
|
||||
'reread' => 0,
|
||||
'user_rating' => 8,
|
||||
)),
|
||||
);
|
@ -1,5 +0,0 @@
|
||||
- null
|
||||
- null
|
||||
- null
|
||||
- null
|
||||
- null
|
Loading…
Reference in New Issue
Block a user