Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
39 changed files with 324 additions and 157 deletions
Showing only changes of commit acd3b84b55 - Show all commits

View File

@ -30,7 +30,7 @@ use Psr\Log\LoggerAwareTrait;
/**
* Wrapper around Artax to make it easier to build API requests
*/
class APIRequestBuilder {
abstract class APIRequestBuilder {
use LoggerAwareTrait;
/**

View File

@ -28,6 +28,9 @@ use Aviat\AnimeClient\API\Anilist;
use Aviat\Ion\Json;
use Aviat\Ion\Di\ContainerAware;
use LogicException;
use Throwable;
trait AnilistTrait {
use ContainerAware;
@ -69,10 +72,10 @@ trait AnilistTrait {
/**
* Create a request object
* @param string $url
* @param array $options
* @return Request
* @throws Throwable
*/
public function setUpRequest(string $url, array $options = []): Request
{
@ -123,7 +126,7 @@ trait AnilistTrait {
$file = realpath(__DIR__ . "/GraphQL/Queries/{$name}.graphql");
if ( ! file_exists($file))
{
throw new \LogicException('GraphQL query file does not exist.');
throw new LogicException('GraphQL query file does not exist.');
}
// $query = str_replace(["\t", "\n"], ' ', file_get_contents($file));
@ -146,12 +149,18 @@ trait AnilistTrait {
]);
}
/**
* @param string $name
* @param array $variables
* @return Request
* @throws Throwable
*/
public function mutateRequest (string $name, array $variables = []): Request
{
$file = realpath(__DIR__ . "/GraphQL/Mutations/{$name}.graphql");
if (!file_exists($file))
{
throw new \LogicException('GraphQL mutation file does not exist.');
throw new LogicException('GraphQL mutation file does not exist.');
}
// $query = str_replace(["\t", "\n"], ' ', file_get_contents($file));
@ -174,6 +183,12 @@ trait AnilistTrait {
]);
}
/**
* @param string $name
* @param array $variables
* @return array
* @throws Throwable
*/
public function mutate (string $name, array $variables = []): array
{
$request = $this->mutateRequest($name, $variables);
@ -188,6 +203,7 @@ trait AnilistTrait {
* @param string $url
* @param array $options
* @return Response
* @throws Throwable
*/
private function getResponse(string $url, array $options = []): Response
{
@ -211,6 +227,11 @@ trait AnilistTrait {
return $response;
}
/**
* @param Request $request
* @return Response
* @throws Throwable
*/
private function getResponseFromRequest(Request $request): Response
{
$logger = NULL;
@ -237,6 +258,7 @@ trait AnilistTrait {
*
* @param array $options
* @return array
* @throws Throwable
*/
protected function postRequest(array $options = []): array
{
@ -258,7 +280,7 @@ trait AnilistTrait {
if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE))
{
if ($logger)
if ($logger !== NULL)
{
$logger->warning('Non 200 response for POST api call', (array)$response->getBody());
}

View File

@ -28,6 +28,8 @@ use Aviat\Ion\Json;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Throwable;
/**
* Anilist API Model
*/
@ -59,6 +61,7 @@ final class Model
* @param string $code - The request token
* @param string $redirectUri - The oauth callback url
* @return array
* @throws Throwable
*/
public function authenticate(string $code, string $redirectUri): array
{

View File

@ -144,6 +144,8 @@ final class JsonAPI {
}
}
unset($item);
$data['data']['included'] = $included;
return $data['data'];
@ -193,6 +195,7 @@ final class JsonAPI {
$organized[$type][$id] = $newItem;
}
unset($item);
// Second pass, go through and fill missing relationships in the first pass
foreach($organized as $type => $items)

View File

@ -18,6 +18,7 @@ namespace Aviat\AnimeClient\API\Kitsu;
use Aura\Session\Segment;
use Aviat\Banker\Exception\InvalidArgumentException;
use const Aviat\AnimeClient\SESSION_SEGMENT;
use Aviat\AnimeClient\API\{
@ -25,6 +26,9 @@ use Aviat\AnimeClient\API\{
Kitsu as K
};
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
use Throwable;
/**
* Kitsu API Authentication
@ -51,6 +55,8 @@ final class Auth {
* Constructor
*
* @param ContainerInterface $container
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{
@ -67,6 +73,8 @@ final class Auth {
*
* @param string $password
* @return boolean
* @throws InvalidArgumentException
* @throws Throwable
*/
public function authenticate(string $password): bool
{
@ -110,6 +118,8 @@ final class Auth {
*
* @param string $token
* @return boolean
* @throws InvalidArgumentException
* @throws Throwable
*/
public function reAuthenticate(string $token): bool
{

View File

@ -30,6 +30,8 @@ use Aviat\AnimeClient\API\{
use Aviat\Ion\Json;
use Aviat\Ion\JsonException;
use Throwable;
trait KitsuTrait {
/**
@ -56,7 +58,7 @@ trait KitsuTrait {
* @param string $type
* @param string $url
* @param array $options
* @return \Amp\Artax\Request
* @return Request
*/
public function setUpRequest(string $type, string $url, array $options = []): Request
{
@ -120,6 +122,7 @@ trait KitsuTrait {
* @param string $url
* @param array $options
* @return Response
* @throws Throwable
*/
private function getResponse(string $type, string $url, array $options = []): Response
{
@ -151,8 +154,9 @@ trait KitsuTrait {
* @param string $type
* @param string $url
* @param array $options
* @throws \Aviat\Ion\JsonException
* @throws JsonException
* @throws FailedResponseException
* @throws Throwable
* @return array
*/
private function request(string $type, string $url, array $options = []): array
@ -165,7 +169,7 @@ trait KitsuTrait {
$response = $this->getResponse($type, $url, $options);
if ((int) $response->getStatus() > 299 OR (int) $response->getStatus() < 200)
if ((int) $response->getStatus() > 299 || (int) $response->getStatus() < 200)
{
if ($logger)
{
@ -191,6 +195,7 @@ trait KitsuTrait {
* Remove some boilerplate for get requests
*
* @param mixed ...$args
* @throws Throwable
* @return array
*/
protected function getRequest(...$args): array
@ -202,6 +207,7 @@ trait KitsuTrait {
* Remove some boilerplate for patch requests
*
* @param mixed ...$args
* @throws Throwable
* @return array
*/
protected function patchRequest(...$args): array
@ -213,6 +219,7 @@ trait KitsuTrait {
* Remove some boilerplate for post requests
*
* @param mixed ...$args
* @throws Throwable
* @return array
*/
protected function postRequest(...$args): array
@ -241,6 +248,7 @@ trait KitsuTrait {
* Remove some boilerplate for delete requests
*
* @param mixed ...$args
* @throws Throwable
* @return bool
*/
protected function deleteRequest(...$args): bool

View File

@ -16,6 +16,8 @@
namespace Aviat\AnimeClient\API\Kitsu;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use const Aviat\AnimeClient\SESSION_SEGMENT;
use function Amp\Promise\wait;
@ -27,6 +29,8 @@ use Aviat\AnimeClient\Types\FormItemData;
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Json;
use Throwable;
/**
* CRUD operations for Kitsu list items
*/
@ -34,6 +38,11 @@ final class ListItem implements ListItemInterface {
use ContainerAware;
use KitsuTrait;
/**
* @param array $data
* @return Request
* @throws Throwable
*/
public function create(array $data): Request
{
$body = [
@ -78,6 +87,11 @@ final class ListItem implements ListItemInterface {
->getFullRequest();
}
/**
* @param string $id
* @return Request
* @throws Throwable
*/
public function delete(string $id): Request
{
$authHeader = $this->getAuthHeader();
@ -91,6 +105,11 @@ final class ListItem implements ListItemInterface {
return $request->getFullRequest();
}
/**
* @param string $id
* @return array
* @throws Throwable
*/
public function get(string $id): array
{
$authHeader = $this->getAuthHeader();
@ -115,6 +134,12 @@ final class ListItem implements ListItemInterface {
return $this->update($id, $data);
}
/**
* @param string $id
* @param FormItemData $data
* @return Request
* @throws Throwable
*/
public function update(string $id, FormItemData $data): Request
{
$authHeader = $this->getAuthHeader();
@ -138,7 +163,9 @@ final class ListItem implements ListItemInterface {
}
/**
* @return false|string
* @return bool|string
* @throws ContainerException
* @throws NotFoundException
*/
private function getAuthHeader()
{

View File

@ -41,8 +41,13 @@ use Aviat\AnimeClient\Types\{
FormItem,
MangaPage
};
use Aviat\Banker\Exception\InvalidArgumentException;
use Aviat\Ion\{Di\ContainerAware, Json};
use ReflectionException;
use Throwable;
/**
* Kitsu API Model
*/
@ -103,6 +108,7 @@ final class Model {
* @param string $username
* @param string $password
* @return bool|array
* @throws Throwable
*/
public function authenticate(string $username, string $password)
{
@ -142,6 +148,7 @@ final class Model {
*
* @param string $token
* @return bool|array
* @throws Throwable
*/
public function reAuthenticate(string $token)
{
@ -171,6 +178,7 @@ final class Model {
*
* @param string $username
* @return string
* @throws InvalidArgumentException
*/
public function getUserIdByUsername(string $username = NULL): string
{
@ -206,7 +214,7 @@ final class Model {
*/
public function getCharacter(string $slug): array
{
$data = $this->getRequest('characters', [
return $this->getRequest('characters', [
'query' => [
'filter' => [
'slug' => $slug,
@ -218,8 +226,6 @@ final class Model {
'include' => 'castings.person,castings.media'
]
]);
return $data;
}
/**
@ -227,6 +233,7 @@ final class Model {
*
* @param string $id
* @return array
* @throws InvalidArgumentException
*/
public function getPerson(string $id): array
{
@ -265,8 +272,7 @@ final class Model {
*/
public function getUserData(string $username): array
{
// $userId = $this->getUserIdByUsername($username);
$data = $this->getRequest('users', [
return $this->getRequest('users', [
'query' => [
'filter' => [
'name' => $username,
@ -279,8 +285,6 @@ final class Model {
'include' => 'waifu,favorites.item,stats'
]
]);
return $data;
}
/**
@ -399,6 +403,7 @@ final class Model {
*
* @param string $status - The watching status to filter the list with
* @return array
* @throws InvalidArgumentException
*/
public function getAnimeList(string $status): array
{
@ -421,6 +426,7 @@ final class Model {
{
$item['included'] = $included;
}
unset($item);
$transformed = $this->animeListTransformer->transformCollection($data['data']);
$keyed = [];
@ -441,6 +447,7 @@ final class Model {
*
* @param string $status - Optional status to filter by
* @return int
* @throws InvalidArgumentException
*/
public function getAnimeListCount(string $status = '') : int
{
@ -472,6 +479,8 @@ final class Model {
*
* @param array $options
* @return array
* @throws InvalidArgumentException
* @throws Throwable
*/
public function getFullRawAnimeList(array $options = [
'include' => 'anime.mappings'
@ -507,6 +516,8 @@ final class Model {
* Get all the anime entries, that are organized for output to html
*
* @return array
* @throws ReflectionException
* @throws InvalidArgumentException
*/
public function getFullOrganizedAnimeList(): array
{
@ -564,6 +575,7 @@ final class Model {
* @param int $offset
* @param array $options
* @return Request
* @throws InvalidArgumentException
*/
public function getPagedAnimeList(int $limit, int $offset = 0, array $options = [
'include' => 'anime.mappings'
@ -590,6 +602,8 @@ final class Model {
*
* @param string $status - The watching status to filter the list with
* @return array
* @throws InvalidArgumentException
* @throws Throwable
*/
public function getRawAnimeList(string $status): array
{
@ -647,6 +661,7 @@ final class Model {
* @param int $limit - The number of list items to fetch per page
* @param int $offset - The page offset
* @return array
* @throws InvalidArgumentException
*/
public function getMangaList(string $status, int $limit = 200, int $offset = 0): array
{
@ -685,6 +700,7 @@ final class Model {
{
$item['included'] = $included;
}
unset($item);
$transformed = $this->mangaListTransformer->transformCollection($data['data']);
@ -700,6 +716,7 @@ final class Model {
*
* @param string $status - Optional status to filter by
* @return int
* @throws InvalidArgumentException
*/
public function getMangaListCount(string $status = '') : int
{
@ -731,6 +748,8 @@ final class Model {
*
* @param array $options
* @return array
* @throws InvalidArgumentException
* @throws Throwable
*/
public function getFullRawMangaList(array $options = [
'include' => 'manga.mappings'
@ -766,6 +785,8 @@ final class Model {
* Get all Manga lists
*
* @return array
* @throws ReflectionException
* @throws InvalidArgumentException
*/
public function getFullOrganizedMangaList(): array
{
@ -787,6 +808,7 @@ final class Model {
* @param int $offset
* @param array $options
* @return Request
* @throws InvalidArgumentException
*/
public function getPagedMangaList(int $limit, int $offset = 0, array $options = [
'include' => 'manga.mappings'
@ -845,6 +867,7 @@ final class Model {
*
* @param array $data
* @return Request
* @throws InvalidArgumentException
*/
public function createListItem(array $data): Request
{

View File

@ -44,14 +44,14 @@ final class CharacterTransformer extends AbstractTransformer {
{
if (array_key_exists('anime', $data['included']))
{
uasort($data['included']['anime'], function ($a, $b) {
uasort($data['included']['anime'], static function ($a, $b) {
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
});
}
if (array_key_exists('manga', $data['included']))
{
uasort($data['included']['manga'], function ($a, $b) {
uasort($data['included']['manga'], static function ($a, $b) {
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
});
}

View File

@ -85,7 +85,7 @@ final class MangaListTransformer extends AbstractTransformer {
$titles = Kitsu::filterTitles($manga);
$title = array_shift($titles);
$map = new MangaListItem([
return new MangaListItem([
'id' => $item['id'],
'mal_id' => $MALid,
'chapters' => [
@ -103,7 +103,7 @@ final class MangaListTransformer extends AbstractTransformer {
'slug' => $manga['slug'],
'title' => $title,
'titles' => $titles,
'type' => $this->string($manga['subtype'])->upperCaseFirst()->__toString(),
'type' => (string)$this->string($manga['subtype'])->upperCaseFirst(),
'url' => 'https://kitsu.io/manga/' . $manga['slug'],
]),
'reading_status' => $item['attributes']['status'],
@ -112,8 +112,6 @@ final class MangaListTransformer extends AbstractTransformer {
'reread' => $item['attributes']['reconsumeCount'],
'user_rating' => $rating,
]);
return $map;
}
/**

View File

@ -98,14 +98,14 @@ final class MangaTransformer extends AbstractTransformer {
if ( ! empty($characters['main']))
{
uasort($characters['main'], function ($a, $b) {
uasort($characters['main'], static function ($a, $b) {
return $a['name'] <=> $b['name'];
});
}
if ( ! empty($characters['supporting']))
{
uasort($characters['supporting'], function ($a, $b) {
uasort($characters['supporting'], static function ($a, $b) {
return $a['name'] <=> $b['name'];
});
}
@ -131,12 +131,13 @@ final class MangaTransformer extends AbstractTransformer {
}
/**
* @return int|null|string
* @param int|null $value
* @return string
*/
private function count(int $value = NULL)
private function count(int $value = NULL): string
{
return ((int)$value === 0)
? '-'
: $value;
: (string)$value;
}
}

View File

@ -78,7 +78,7 @@ final class PersonTransformer extends AbstractTransformer {
$includedMedia = array_replace_recursive($existingMedia, $relatedMedia);
uasort($includedMedia, function ($a, $b) {
uasort($includedMedia, static function ($a, $b) {
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
});
@ -103,10 +103,10 @@ final class PersonTransformer extends AbstractTransformer {
}
}
uasort($output['characters']['main'], function ($a, $b) {
uasort($output['characters']['main'], static function ($a, $b) {
return $a['character']['canonicalName'] <=> $b['character']['canonicalName'];
});
uasort($output['characters']['supporting'], function ($a, $b) {
uasort($output['characters']['supporting'], static function ($a, $b) {
return $a['character']['canonicalName'] <=> $b['character']['canonicalName'];
});
ksort($output['staff']);
@ -114,14 +114,14 @@ final class PersonTransformer extends AbstractTransformer {
{
if (array_key_exists('anime', $media))
{
uasort($media['anime'], function ($a, $b) {
uasort($media['anime'], static function ($a, $b) {
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
});
}
if (array_key_exists('manga', $media))
{
uasort($media['manga'], function ($a, $b) {
uasort($media['manga'], static function ($a, $b) {
return $a['canonicalTitle'] <=> $b['canonicalTitle'];
});
}

View File

@ -41,6 +41,7 @@ final class UserTransformer extends AbstractTransformer {
$stats[$key] = $item['attributes']['statsData'];
unset($item);
}
unset($item);
$waifu = [];
if (array_key_exists('waifu', $rels))

View File

@ -21,6 +21,8 @@ use function Amp\call;
use function Amp\Promise\{all, wait};
use function Aviat\AnimeClient\getApiClient;
use Throwable;
/**
* Class to simplify making and validating simultaneous requests
*/
@ -68,7 +70,7 @@ final class ParallelAPIRequest {
* Make the requests, and return the body for each
*
* @return array
* @throws \Throwable
* @throws Throwable
*/
public function makeRequests(): array
{
@ -91,7 +93,7 @@ final class ParallelAPIRequest {
* Make the requests and return the response objects
*
* @return array
* @throws \Throwable
* @throws Throwable
*/
public function getResponses(): array
{

View File

@ -36,7 +36,7 @@ use Zend\Diactoros\{Response, ServerRequestFactory};
/**
* Base class for console command setup
*/
class BaseCommand extends Command {
abstract class BaseCommand extends Command {
use CacheTrait;
use ContainerAware;

View File

@ -28,6 +28,8 @@ use Aviat\AnimeClient\API\Anilist\Transformer\{
};
use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus};
use Aviat\AnimeClient\Types\FormItem;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Json;
use DateTime;
@ -53,8 +55,8 @@ final class SyncLists extends BaseCommand {
*
* @param array $args
* @param array $options
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @throws \Throwable
*/
public function execute(array $args, array $options = []): void
@ -173,8 +175,8 @@ final class SyncLists extends BaseCommand {
* Format an Anilist anime list for comparison
*
* @return array
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
protected function formatAnilistAnimeList(): array
{
@ -206,8 +208,8 @@ final class SyncLists extends BaseCommand {
* Format an Anilist manga list for comparison
*
* @return array
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
protected function formatAnilistMangaList(): array
{

View File

@ -17,6 +17,7 @@
namespace Aviat\AnimeClient\Command;
use Aviat\AnimeClient\API\JsonAPI;
use Aviat\AnimeClient\API\Kitsu\Model;
use Aviat\AnimeClient\Controller\Images;
/**
@ -26,7 +27,7 @@ use Aviat\AnimeClient\Controller\Images;
final class UpdateThumbnails extends ClearThumbnails {
/**
* Model for making requests to Kitsu API
* @var \Aviat\AnimeClient\API\Kitsu\Model
* @var Model
*/
protected $kitsuModel;
@ -63,8 +64,7 @@ final class UpdateThumbnails extends ClearThumbnails {
}
/**
* @return array-key[][]
*
* @return array array-key[][]
* @psalm-return array{anime: list<array-key>, manga: list<array-key>}
*/
public function getImageList(): array

View File

@ -27,6 +27,9 @@ use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Json;
use InvalidArgumentException;
use Throwable;
/**
* Controller for Anime-related pages
*/
@ -65,7 +68,8 @@ final class Anime extends BaseController {
* @param string $view - List or cover view
* @throws ContainerException
* @throws NotFoundException
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @throws Throwable
* @return void
*/
public function index($type = KitsuWatchingStatus::WATCHING, string $view = NULL): void
@ -110,7 +114,8 @@ final class Anime extends BaseController {
* @throws ContainerException
* @throws NotFoundException
* @throws RouteNotFound
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @throws Throwable
* @return void
*/
public function addForm(): void
@ -133,6 +138,7 @@ final class Anime extends BaseController {
*
* @throws ContainerException
* @throws NotFoundException
* @throws Throwable
* @return void
*/
public function add(): void
@ -171,6 +177,7 @@ final class Anime extends BaseController {
*
* @param string $id
* @param string $status
* @throws RouteNotFound
*/
public function edit(string $id, $status = 'all'): void
{
@ -209,6 +216,7 @@ final class Anime extends BaseController {
*
* @throws ContainerException
* @throws NotFoundException
* @throws Throwable
* @return void
*/
public function formUpdate(): void
@ -239,6 +247,7 @@ final class Anime extends BaseController {
/**
* Increase the watched count for an anime item
*
* @throws Throwable
* @return void
*/
public function increment(): void
@ -269,6 +278,7 @@ final class Anime extends BaseController {
/**
* Remove an anime from the list
*
* @throws Throwable
* @return void
*/
public function delete(): void
@ -297,7 +307,7 @@ final class Anime extends BaseController {
* @param string $animeId
* @throws ContainerException
* @throws NotFoundException
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @return void
*/
public function details(string $animeId): void

View File

@ -27,6 +27,8 @@ use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Exception\DoubleRenderException;
use InvalidArgumentException;
/**
* Controller for Anime collection pages
*/
@ -89,7 +91,7 @@ final class AnimeCollection extends BaseController {
* @param string $view
* @throws ContainerException
* @throws NotFoundException
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @return void
*/
public function view($view): void
@ -115,7 +117,7 @@ final class AnimeCollection extends BaseController {
* @throws ContainerException
* @throws NotFoundException
* @throws RouteNotFound
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @return void
*/
public function form($id = NULL): void
@ -144,7 +146,7 @@ final class AnimeCollection extends BaseController {
*
* @throws ContainerException
* @throws NotFoundException
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @return void
*/
public function edit(): void
@ -179,7 +181,7 @@ final class AnimeCollection extends BaseController {
*
* @throws ContainerException
* @throws NotFoundException
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
* @return void
*/
public function add(): void

View File

@ -16,10 +16,13 @@
namespace Aviat\AnimeClient\Controller;
use Aviat\AnimeClient\API\Kitsu\Model;
use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\API\Kitsu\Transformer\CharacterTransformer;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
/**
* Controller for character description pages
@ -27,7 +30,7 @@ use Aviat\Ion\Di\ContainerInterface;
class Character extends BaseController {
/**
* @var \Aviat\AnimeClient\API\Kitsu\Model
* @var Model
*/
private $model;
@ -35,8 +38,8 @@ class Character extends BaseController {
* Character constructor.
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{

View File

@ -24,6 +24,8 @@ use function Aviat\AnimeClient\createPlaceholderImage;
use Aviat\AnimeClient\Controller as BaseController;
use Throwable;
/**
* Controller for handling routes that don't fit elsewhere
*/
@ -36,7 +38,7 @@ final class Images extends BaseController {
* @param bool $display Whether to output the image to the server
* @return void
* @throws NotFoundException
* @throws \Throwable
* @throws Throwable
* @throws ContainerException
*/
public function cache(string $type, string $file, $display = TRUE): void

View File

@ -16,13 +16,18 @@
namespace Aviat\AnimeClient\Controller;
use Aura\Router\Exception\RouteNotFound;
use Aviat\AnimeClient\Controller;
use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer;
use Aviat\AnimeClient\API\Mapping\MangaReadingStatus;
use Aviat\AnimeClient\Model\Manga as MangaModel;
use Aviat\AnimeClient\Types\FormItem;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\{Json, StringWrapper};
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
use Aviat\Ion\Json;
use InvalidArgumentException;
use Throwable;
/**
* Controller for manga list
@ -39,8 +44,8 @@ final class Manga extends Controller {
* Constructor
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{
@ -59,9 +64,9 @@ final class Manga extends Controller {
*
* @param string $status
* @param string $view
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws InvalidArgumentException
* @return void
*/
public function index($status = 'all', $view = ''): void
@ -103,10 +108,10 @@ final class Manga extends Controller {
/**
* Form to add an manga
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \Aura\Router\Exception\RouteNotFound
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws RouteNotFound
* @throws InvalidArgumentException
* @return void
*/
public function addForm(): void
@ -129,9 +134,10 @@ final class Manga extends Controller {
/**
* Add an manga to the list
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @return void
* @throws NotFoundException
* @throws Throwable
* @throws ContainerException
*/
public function add(): void
{
@ -168,10 +174,10 @@ final class Manga extends Controller {
*
* @param string $id
* @param string $status
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \Aura\Router\Exception\RouteNotFound
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws RouteNotFound
* @throws InvalidArgumentException
* @return void
*/
public function edit($id, $status = 'All'): void
@ -210,9 +216,10 @@ final class Manga extends Controller {
/**
* Update an manga item via a form submission
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @return void
* @throws Throwable
* @throws NotFoundException
* @throws ContainerException
*/
public function formUpdate(): void
{
@ -228,7 +235,7 @@ final class Manga extends Controller {
if ($full_result['statusCode'] === 200)
{
$this->setFlashMessage("Successfully updated manga.", 'success');
$this->setFlashMessage('Successfully updated manga.', 'success');
$this->cache->clear();
}
else
@ -242,6 +249,7 @@ final class Manga extends Controller {
/**
* Increment the progress of a manga item
* @throws Throwable
*/
public function increment(): void
{
@ -265,8 +273,9 @@ final class Manga extends Controller {
/**
* Remove an manga from the list
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @throws Throwable
* @return void
*/
public function delete(): void
@ -293,9 +302,10 @@ final class Manga extends Controller {
* View details of an manga
*
* @param string $manga_id
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws InvalidArgumentException
* @throws Throwable
* @return void
*/
public function details($manga_id): void

View File

@ -16,13 +16,19 @@
namespace Aviat\AnimeClient\Controller;
use Aura\Router\Exception\RouteNotFound;
use Aviat\AnimeClient\Controller as BaseController;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Exception\DoubleRenderException;
use Aviat\AnimeClient\Model\{
Manga as MangaModel,
MangaCollection as MangaCollectionModel
};
use Aviat\Ion\Di\ContainerInterface;
use InvalidArgumentException;
/**
* Controller for manga collection pages
*/
@ -44,8 +50,8 @@ final class MangaCollection extends BaseController {
* Constructor
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @throws \InvalidArgumentException
*/
public function __construct(ContainerInterface $container)
@ -65,7 +71,7 @@ final class MangaCollection extends BaseController {
/**
* Search for manga
*
* @throws \Aviat\Ion\Exception\DoubleRenderException
* @throws DoubleRenderException
* @return void
*/
public function search(): void
@ -79,9 +85,9 @@ final class MangaCollection extends BaseController {
* Show the manga collection page
*
* @param string $view
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws InvalidArgumentException
* @return void
*/
public function index($view): void
@ -104,10 +110,10 @@ final class MangaCollection extends BaseController {
* Show the manga collection add/edit form
*
* @param integer|null $id
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \Aura\Router\Exception\RouteNotFound
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws RouteNotFound
* @throws InvalidArgumentException
* @return void
*/
public function form($id = NULL): void
@ -132,9 +138,9 @@ final class MangaCollection extends BaseController {
/**
* Update a collection item
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws InvalidArgumentException
* @return void
*/
public function edit(): void
@ -156,9 +162,9 @@ final class MangaCollection extends BaseController {
/**
* Add a collection item
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @throws ContainerException
* @throws NotFoundException
* @throws InvalidArgumentException
* @return void
*/
public function add(): void

View File

@ -16,10 +16,13 @@
namespace Aviat\AnimeClient\Controller;
use Aviat\AnimeClient\API\Kitsu\Model;
use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\API\Kitsu\Transformer\PersonTransformer;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
/**
* Controller for People pages
@ -27,7 +30,7 @@ use Aviat\Ion\Di\ContainerInterface;
final class People extends BaseController {
/**
* @var \Aviat\AnimeClient\API\Kitsu\Model
* @var Model
*/
private $model;
@ -35,8 +38,8 @@ final class People extends BaseController {
* People constructor.
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{

View File

@ -16,8 +16,12 @@
namespace Aviat\AnimeClient\Controller;
use Aura\Router\Exception\RouteNotFound;
use Aviat\AnimeClient\API\Anilist\Model;
use Aviat\AnimeClient\Controller as BaseController;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
/**
* Controller for user settings
@ -25,7 +29,7 @@ use Aviat\Ion\Di\ContainerInterface;
final class Settings extends BaseController {
/**
* @var \Aviat\AnimeClient\API\Anilist\Model
* @var Model
*/
private $anilistModel;
@ -38,8 +42,8 @@ final class Settings extends BaseController {
* Settings constructor.
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{
@ -75,7 +79,7 @@ final class Settings extends BaseController {
/**
* Attempt to save the user's settings
*
* @throws \Aura\Router\Exception\RouteNotFound
* @throws RouteNotFound
*/
public function update(): void
{

View File

@ -16,10 +16,13 @@
namespace Aviat\AnimeClient\Controller;
use Aviat\AnimeClient\API\Kitsu\Model;
use Aviat\AnimeClient\API\Kitsu\Transformer\UserTransformer;
use Aviat\AnimeClient\Controller as BaseController;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
/**
* Controller for handling routes that don't fit elsewhere
@ -27,7 +30,7 @@ use Aviat\Ion\Di\ContainerInterface;
final class User extends BaseController {
/**
* @var \Aviat\AnimeClient\API\Kitsu\Model
* @var Model
*/
private $kitsuModel;
@ -35,8 +38,8 @@ final class User extends BaseController {
* User constructor.
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{

View File

@ -18,13 +18,16 @@ namespace Aviat\AnimeClient;
use function Aviat\Ion\_dir;
use Aura\Router\{Matcher, Rule};
use Aura\Router\{Matcher, Route, Rule};
use Aviat\AnimeClient\API\FailedResponseException;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Friend;
use Aviat\Ion\StringWrapper;
use LogicException;
use ReflectionException;
/**
* Basic routing/ dispatch
*/
@ -74,7 +77,7 @@ final class Dispatcher extends RoutingBase {
/**
* Get the current route object, if one matches
*
* @return \Aura\Router\Route|false
* @return Route|false
*/
public function getRoute()
{
@ -109,6 +112,7 @@ final class Dispatcher extends RoutingBase {
*
* @param object|null $route
* @return void
* @throws ReflectionException
*/
public function __invoke($route = NULL): void
{
@ -149,8 +153,8 @@ final class Dispatcher extends RoutingBase {
* Parse out the arguments for the appropriate controller for
* the current route
*
* @param \Aura\Router\Route $route
* @throws \LogicException
* @param Route $route
* @throws LogicException
* @return array
*/
protected function processRoute($route): array
@ -161,7 +165,7 @@ final class Dispatcher extends RoutingBase {
}
else
{
throw new \LogicException('Missing controller');
throw new LogicException('Missing controller');
}
// Get the full namespace for a controller if a short name is given
@ -249,7 +253,7 @@ final class Dispatcher extends RoutingBase {
foreach ($classFiles as $file)
{
$rawClassName = basename(str_replace('.php', '', $file));
$path = $this->string($rawClassName)->dasherize()->__toString();
$path = (string)$this->string($rawClassName)->dasherize();
$className = trim($defaultNamespace . '\\' . $rawClassName, '\\');
$controllers[$path] = $className;
@ -296,7 +300,7 @@ final class Dispatcher extends RoutingBase {
/**
* Get the appropriate params for the error page
* pased on the failed route
* passed on the failed route
*
* @return array|false
*/

View File

@ -16,7 +16,10 @@
namespace Aviat\AnimeClient;
use Aura\Html\HelperLocator;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
/**
* Helper object to manage form generation, especially for config editing
@ -25,7 +28,7 @@ final class FormGenerator {
/**
* Html generation helper
*
* @var \Aura\Html\HelperLocator
* @var HelperLocator
*/
private $helper;
@ -33,8 +36,8 @@ final class FormGenerator {
* FormGenerator constructor.
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{

View File

@ -16,11 +16,12 @@
namespace Aviat\AnimeClient;
use Aviat\Ion\{
ArrayWrapper, StringWrapper
};
use Aviat\Ion\{ArrayWrapper, StringWrapper};
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
use Aura\Html\HelperLocator;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Exception\ConfigException;
use Psr\Http\Message\RequestInterface;
/**
* Helper object to manage menu creation and selection
@ -33,14 +34,14 @@ final class MenuGenerator extends UrlGenerator {
/**
* Html generation helper
*
* @var \Aura\Html\HelperLocator
* @var HelperLocator
*/
protected $helper;
/**
* Request object
*
* @var \Psr\Http\Message\RequestInterface
* @var RequestInterface
*/
protected $request;
@ -48,8 +49,8 @@ final class MenuGenerator extends UrlGenerator {
* MenuGenerator constructor.
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{

View File

@ -28,6 +28,8 @@ use Aviat\AnimeClient\Types\{
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
use Throwable;
/**
* Model for handling requests dealing with the anime list
*/
@ -162,6 +164,7 @@ class Anime extends API {
*
* @param array $data
* @return bool
* @throws Throwable
*/
public function createLibraryItem(array $data): bool
{
@ -183,6 +186,7 @@ class Anime extends API {
*
* @param FormItem $data
* @return array
* @throws Throwable
*/
public function incrementLibraryItem(FormItem $data): array
{
@ -210,6 +214,7 @@ class Anime extends API {
*
* @param FormItem $data
* @return array
* @throws Throwable
*/
public function updateLibraryItem(FormItem $data): array
{
@ -238,6 +243,7 @@ class Anime extends API {
* @param string $id
* @param string|null $malId
* @return bool
* @throws Throwable
*/
public function deleteLibraryItem(string $id, string $malId = NULL): bool
{

View File

@ -21,7 +21,7 @@ use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
/**
* Base model for database interaction
*/
class DB {
abstract class DB {
use ContainerAware;
/**

View File

@ -29,6 +29,8 @@ use Aviat\AnimeClient\Types\{
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
use Throwable;
/**
* Model for handling requests dealing with the manga list
*/
@ -130,6 +132,7 @@ class Manga extends API {
*
* @param array $data
* @return bool
* @throws Throwable
*/
public function createLibraryItem(array $data): bool
{
@ -151,6 +154,7 @@ class Manga extends API {
*
* @param FormItem $data
* @return array
* @throws Throwable
*/
public function updateLibraryItem(FormItem $data): array
{
@ -179,6 +183,7 @@ class Manga extends API {
*
* @param FormItem $data
* @return array
* @throws Throwable
*/
public function incrementLibraryItem(FormItem $data): array
{
@ -208,6 +213,7 @@ class Manga extends API {
* @param string $id
* @param string|null $malId
* @return bool
* @throws Throwable
*/
public function deleteLibraryItem(string $id, string $malId = NULL): bool
{

View File

@ -16,8 +16,13 @@
namespace Aviat\AnimeClient;
use Aviat\Ion\Config;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Exception\ConfigException;
use Aviat\Ion\StringWrapper;
use Psr\Http\Message\ServerRequestInterface;
/**
* Base for routing/url classes
@ -34,13 +39,13 @@ class RoutingBase {
/**
* Config Object
* @var \Aviat\Ion\Config
* @var Config
*/
protected $config;
/**
* Class wrapper for input superglobals
* @var \Psr\Http\Message\ServerRequestInterface
* @var ServerRequestInterface
*/
protected $request;
@ -48,9 +53,9 @@ class RoutingBase {
* Constructor
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \Aviat\Ion\Exception\ConfigException
* @throws ContainerException
* @throws NotFoundException
* @throws ConfigException
*/
public function __construct(ContainerInterface $container)
{
@ -61,8 +66,8 @@ class RoutingBase {
/**
* Get the current url path
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @return string
*/
public function path(): string
@ -79,8 +84,8 @@ class RoutingBase {
/**
* Get the url segments
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @return array
*/
public function segments(): array
@ -93,8 +98,8 @@ class RoutingBase {
* Get a segment of the current url
*
* @param int $num
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @return string|null
*/
public function getSegment($num): ?string
@ -106,8 +111,8 @@ class RoutingBase {
/**
* Retrieve the last url segment
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws ContainerException
* @throws NotFoundException
* @return string
*/
public function lastSegment(): string

View File

@ -17,7 +17,6 @@
namespace Aviat\AnimeClient\Types;
use ArrayAccess;
use ArrayObject;
use Countable;
abstract class AbstractType implements ArrayAccess, Countable {

View File

@ -33,11 +33,4 @@ class Cache extends AbstractType {
* @var array
*/
public $options = [];
/* public function setConnection($data): void
{
$this->connection = new class($data) extends AbstractType {
};
} */
}

View File

@ -59,5 +59,11 @@ class FormItemData extends AbstractType {
* @var string
*/
public $status;
/**
* W3C Format Date string
*
* @var string
*/
public $updatedAt;
}

View File

@ -17,6 +17,8 @@
namespace Aviat\AnimeClient;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use InvalidArgumentException;
/**
@ -34,8 +36,8 @@ class UrlGenerator extends RoutingBase {
* Constructor
*
* @param ContainerInterface $container
* @throws \Aviat\Ion\Di\Exception\ContainerException
* @throws \Aviat\Ion\Di\Exception\NotFoundException
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{
@ -47,7 +49,7 @@ class UrlGenerator extends RoutingBase {
/**
* Get the base url for css/js/images
*
* @param string[] $args
* @param string ...$args
* @return string
*/
public function assetUrl(string ...$args): string

View File

@ -163,12 +163,6 @@ const SETTINGS_MAP = [
'Dark Theme' => 'dark',
]
],
/* 'dark_theme' => [
'type' => 'boolean',
'title' => 'Use Dark Theme',
'default' => FALSE,
'description' => 'Use a darker background theme?',
],*/
'show_anime_collection' => [
'type' => 'boolean',
'title' => 'Show Anime Collection',

View File

@ -20,19 +20,24 @@ use Aviat\AnimeClient\Command\BaseCommand;
use Aviat\AnimeClient\Tests\AnimeClientTestCase;
use Aviat\Ion\Friend;
use ConsoleKit\Console;
use Aviat\Ion\Di\Container;
class Command extends BaseCommand {
}
class BaseCommandTest extends AnimeClientTestCase {
protected $base;
protected $friend;
public function setUp(): void {
$this->base = new BaseCommand(new Console());
$this->base = new Command(new Console());
$this->friend = new Friend($this->base);
}
public function testSetupContainer()
public function testSetupContainer(): void
{
$container = $this->friend->setupContainer();
$this->assertInstanceOf('Aviat\Ion\Di\Container', $container);
$this->assertInstanceOf(Container::class, $container);
}
}