Version 5.1 - All the GraphQL #32
@ -50,7 +50,8 @@
|
|||||||
"spatie/phpunit-snapshot-assertions": "^2.2.1",
|
"spatie/phpunit-snapshot-assertions": "^2.2.1",
|
||||||
"squizlabs/php_codesniffer": "^3.2.2",
|
"squizlabs/php_codesniffer": "^3.2.2",
|
||||||
"symfony/var-dumper": "^4.4.1",
|
"symfony/var-dumper": "^4.4.1",
|
||||||
"theseer/phpdox": "*"
|
"theseer/phpdox": "*",
|
||||||
|
"vimeo/psalm": "^3.7"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "vendor/bin/robo build",
|
"build": "vendor/bin/robo build",
|
||||||
@ -58,10 +59,11 @@
|
|||||||
"build:js": "cd public && npm run build:js && cd ..",
|
"build:js": "cd public && npm run build:js && cd ..",
|
||||||
"clean": "vendor/bin/robo clean",
|
"clean": "vendor/bin/robo clean",
|
||||||
"coverage": "phpdbg -qrr -- vendor/bin/phpunit -c build",
|
"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:css": "cd public && npm run watch:css",
|
||||||
"watch:js": "cd public && npm run watch:js",
|
"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": {
|
"scripts-descriptions": {
|
||||||
"build": "Generate the api docs",
|
"build": "Generate the api docs",
|
||||||
|
11
phpstan.neon
11
phpstan.neon
@ -1,9 +1,18 @@
|
|||||||
parameters:
|
parameters:
|
||||||
|
checkGenericClassInNonGenericObjectType: false
|
||||||
|
inferPrivatePropertyTypeFromConstructor: true
|
||||||
|
level: 7
|
||||||
autoload_files:
|
autoload_files:
|
||||||
- %rootDir%/../../../tests/mocks.php
|
- %rootDir%/../../../tests/mocks.php
|
||||||
|
paths:
|
||||||
|
- src
|
||||||
|
- tests
|
||||||
|
- ./console
|
||||||
|
- index.php
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
- '#Access to an undefined property Aviat\\\Ion\\\Friend::\$[a-zA-Z0-9_]+#'
|
- '#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 Aviat\\\Ion\\\Friend::[a-zA-Z0-9_]+\(\)#'
|
||||||
- '#Call to an undefined method Aura\\\Html\\\HelperLocator::[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_]+#'
|
- '#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
|
* The current request
|
||||||
* @var \Amp\Artax\Request
|
* @var Request
|
||||||
*/
|
*/
|
||||||
protected $request;
|
protected $request;
|
||||||
|
|
||||||
@ -219,14 +219,14 @@ class APIRequestBuilder {
|
|||||||
/**
|
/**
|
||||||
* Return the promise for the current request
|
* Return the promise for the current request
|
||||||
*
|
*
|
||||||
|
* @return Request
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
* @return \Amp\Artax\Request
|
|
||||||
*/
|
*/
|
||||||
public function getFullRequest(): Request
|
public function getFullRequest(): Request
|
||||||
{
|
{
|
||||||
$this->buildUri();
|
$this->buildUri();
|
||||||
|
|
||||||
if ($this->logger)
|
if ($this->logger !== NULL)
|
||||||
{
|
{
|
||||||
$this->logger->debug('API Request', [
|
$this->logger->debug('API Request', [
|
||||||
'request_url' => $this->request->getUri(),
|
'request_url' => $this->request->getUri(),
|
||||||
|
@ -25,6 +25,8 @@ use Aviat\AnimeClient\API\Anilist;
|
|||||||
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
|
||||||
use Aviat\AnimeClient\Types\FormItem;
|
use Aviat\AnimeClient\Types\FormItem;
|
||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
|
use Aviat\Ion\Di\Exception\ContainerException;
|
||||||
|
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anilist API Model
|
* Anilist API Model
|
||||||
@ -92,8 +94,8 @@ final class Model
|
|||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Aviat\Ion\Di\Exception\ContainerException
|
* @throws ContainerException
|
||||||
* @throws \Aviat\Ion\Di\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function getSyncList(string $type = 'anime'): array
|
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;
|
namespace Aviat\AnimeClient\API\Kitsu;
|
||||||
|
|
||||||
|
use Aura\Session\Segment;
|
||||||
|
|
||||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\{
|
use Aviat\AnimeClient\API\{
|
||||||
@ -23,7 +25,6 @@ use Aviat\AnimeClient\API\{
|
|||||||
Kitsu as K
|
Kitsu as K
|
||||||
};
|
};
|
||||||
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||||
use Exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kitsu API Authentication
|
* Kitsu API Authentication
|
||||||
@ -42,7 +43,7 @@ final class Auth {
|
|||||||
/**
|
/**
|
||||||
* Session object
|
* Session object
|
||||||
*
|
*
|
||||||
* @var \Aura\Session\Segment
|
* @var Segment
|
||||||
*/
|
*/
|
||||||
private $segment;
|
private $segment;
|
||||||
|
|
||||||
|
@ -137,6 +137,9 @@ final class ListItem implements ListItemInterface {
|
|||||||
return $request->getFullRequest();
|
return $request->getFullRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return false|string
|
||||||
|
*/
|
||||||
private function getAuthHeader()
|
private function getAuthHeader()
|
||||||
{
|
{
|
||||||
$cache = $this->getContainer()->get('cache');
|
$cache = $this->getContainer()->get('cache');
|
||||||
|
@ -142,13 +142,12 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
foreach ($role['relationships']['person']['people'] as $pid => $peoples)
|
foreach ($role['relationships']['person']['people'] as $pid => $peoples)
|
||||||
{
|
{
|
||||||
$p = $peoples;
|
$p = $peoples;
|
||||||
}
|
|
||||||
|
|
||||||
$person = $p['attributes'];
|
$person = $p['attributes'];
|
||||||
$person['id'] = $pid;
|
$person['id'] = $pid;
|
||||||
$person['image'] = $person['image']['original'];
|
$person['image'] = $person['image']['original'];
|
||||||
|
|
||||||
uasort($role['relationships']['media']['anime'], function ($a, $b) {
|
uasort($role['relationships']['media']['anime'], static function ($a, $b) {
|
||||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -158,7 +157,9 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$output[$roleName][$language][] = $item;
|
$output[$roleName][$language][] = $item;
|
||||||
} else
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
foreach ($role['relationships']['person']['people'] as $pid => $person)
|
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)
|
private function count(int $value = NULL)
|
||||||
{
|
{
|
||||||
return ((int)$value === 0)
|
return ((int)$value === 0)
|
||||||
|
@ -62,7 +62,12 @@ final class UpdateThumbnails extends ClearThumbnails {
|
|||||||
$this->echoBox('Finished regenerating all thumbnails');
|
$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();
|
$mangaList = $this->kitsuModel->getFullRawMangaList();
|
||||||
$includes = JsonAPI::organizeIncludes($mangaList['included']);
|
$includes = JsonAPI::organizeIncludes($mangaList['included']);
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Controller;
|
namespace Aviat\AnimeClient\Controller;
|
||||||
|
|
||||||
|
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
||||||
|
|
||||||
use function Amp\Promise\wait;
|
use function Amp\Promise\wait;
|
||||||
use function Aviat\AnimeClient\getResponse;
|
use function Aviat\AnimeClient\getResponse;
|
||||||
use function Aviat\AnimeClient\createPlaceholderImage;
|
use function Aviat\AnimeClient\createPlaceholderImage;
|
||||||
@ -32,17 +34,14 @@ final class Images extends BaseController {
|
|||||||
* @param string $type The category of image
|
* @param string $type The category of image
|
||||||
* @param string $file The filename to look for
|
* @param string $file The filename to look for
|
||||||
* @param bool $display Whether to output the image to the server
|
* @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
|
* @return void
|
||||||
|
* @throws NotFoundException
|
||||||
|
* @throws \Throwable
|
||||||
|
* @throws ContainerException
|
||||||
*/
|
*/
|
||||||
public function cache(string $type, string $file, $display = TRUE): void
|
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/';
|
$kitsuUrl = 'https://media.kitsu.io/';
|
||||||
$fileName = str_replace('-original', '', $file);
|
$fileName = str_replace('-original', '', $file);
|
||||||
|
@ -37,7 +37,7 @@ abstract class AbstractType implements ArrayAccess, Countable {
|
|||||||
*
|
*
|
||||||
* @param mixed $data
|
* @param mixed $data
|
||||||
*/
|
*/
|
||||||
public function __construct($data = [])
|
final public function __construct($data = [])
|
||||||
{
|
{
|
||||||
$typeKeys = array_keys((array)$this);
|
$typeKeys = array_keys((array)$this);
|
||||||
$dataKeys = array_keys((array)$data);
|
$dataKeys = array_keys((array)$data);
|
||||||
@ -187,7 +187,7 @@ abstract class AbstractType implements ArrayAccess, Countable {
|
|||||||
{
|
{
|
||||||
$object = $parent ?? $this;
|
$object = $parent ?? $this;
|
||||||
|
|
||||||
if (is_scalar($object) || empty($object))
|
if (is_scalar($object) || $object === NULL)
|
||||||
{
|
{
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
13
src/Util.php
13
src/Util.php
@ -17,6 +17,7 @@
|
|||||||
namespace Aviat\AnimeClient;
|
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
|
* Utility method class
|
||||||
@ -45,8 +46,8 @@ class Util {
|
|||||||
* Set up the Util class
|
* Set up the Util class
|
||||||
*
|
*
|
||||||
* @param ContainerInterface $container
|
* @param ContainerInterface $container
|
||||||
* @throws \Aviat\Ion\Di\ContainerException
|
* @throws ContainerException
|
||||||
* @throws \Aviat\Ion\Di\NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function __construct(ContainerInterface $container)
|
public function __construct(ContainerInterface $container)
|
||||||
{
|
{
|
||||||
@ -80,8 +81,8 @@ class Util {
|
|||||||
/**
|
/**
|
||||||
* Determine whether to show the sub-menu
|
* Determine whether to show the sub-menu
|
||||||
*
|
*
|
||||||
* @throws \Aviat\Ion\Di\ContainerException
|
* @throws ContainerException
|
||||||
* @throws \Aviat\Ion\Di\NotFoundException
|
* @throws NotFoundException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isViewPage(): bool
|
public function isViewPage(): bool
|
||||||
@ -98,8 +99,8 @@ class Util {
|
|||||||
* Determine whether the page is a page with a form, and
|
* Determine whether the page is a page with a form, and
|
||||||
* not suitable for redirection
|
* not suitable for redirection
|
||||||
*
|
*
|
||||||
* @throws \Aviat\Ion\Di\ContainerException
|
* @throws ContainerException
|
||||||
* @throws \Aviat\Ion\Di\NotFoundException
|
* @throws NotFoundException
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isFormPage(): bool
|
public function isFormPage(): bool
|
||||||
|
@ -36,10 +36,10 @@
|
|||||||
1 => '小林さんちのメイドラゴン',
|
1 => '小林さんちのメイドラゴン',
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
'watching_status' => 'current',
|
|
||||||
'notes' => NULL,
|
'notes' => NULL,
|
||||||
|
'private' => false,
|
||||||
'rewatching' => false,
|
'rewatching' => false,
|
||||||
'rewatched' => 0,
|
'rewatched' => 0,
|
||||||
'user_rating' => '-',
|
'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