Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
8 changed files with 38 additions and 32 deletions
Showing only changes of commit 461914a929 - Show all commits

View File

@ -32,10 +32,13 @@ use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger; use Monolog\Logger;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\CacheInterface;
use function Aviat\Ion\_dir;
if ( ! defined('APP_DIR')) if ( ! defined('APP_DIR'))
{ {
define('APP_DIR', __DIR__); define('APP_DIR', __DIR__);
define('TEMPLATE_DIR', APP_DIR . '/templates'); define('ROOT_DIR', dirname(APP_DIR));
define('TEMPLATE_DIR', _dir(APP_DIR, 'templates'));
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -47,15 +50,16 @@ return static function (array $configArray = []): Container {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Logging // Logging
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
$LOG_DIR = _dir(APP_DIR, 'logs');
$appLogger = new Logger('animeclient'); $appLogger = new Logger('animeclient');
$appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', 2, Logger::WARNING)); $appLogger->pushHandler(new RotatingFileHandler(_dir($LOG_DIR, 'app.log'), 2, Logger::WARNING));
$container->setLogger($appLogger); $container->setLogger($appLogger);
foreach (['anilist-request', 'kitsu-request', 'kitsu-graphql'] as $channel) foreach (['anilist-request', 'kitsu-request', 'kitsu-graphql'] as $channel)
{ {
$logger = new Logger($channel); $logger = new Logger($channel);
$handler = new RotatingFileHandler(__DIR__ . "/logs/{$channel}.log", 2, Logger::WARNING); $handler = new RotatingFileHandler(_dir($LOG_DIR, "{$channel}.log"), 2, Logger::WARNING);
$handler->setFormatter(new JsonFormatter()); $handler->setFormatter(new JsonFormatter());
$logger->pushHandler($handler); $logger->pushHandler($handler);

View File

@ -18,7 +18,7 @@
</a> </a>
</div> </div>
<div class="table"> <div class="table">
<?php if ($item['private'] || $item['rewatching']): ?> <?php if (isset($item['private']) || isset($item['rewatching'])): ?>
<div class="row"> <div class="row">
<?php foreach (['private', 'rewatching'] as $attr): ?> <?php foreach (['private', 'rewatching'] as $attr): ?>
<?php if ($item[$attr]): ?> <?php if ($item[$attr]): ?>

View File

@ -35,43 +35,36 @@ abstract class APIRequestBuilder {
/** /**
* Where to look for GraphQL request files * Where to look for GraphQL request files
* @var string
*/ */
protected string $filePath = __DIR__; protected string $filePath = '';
/** /**
* Url prefix for making url requests * Url prefix for making url requests
* @var string
*/ */
protected string $baseUrl = ''; protected string $baseUrl = '';
/** /**
* Url path of the request * Url path of the request
* @var string
*/ */
protected string $path = ''; protected string $path = '';
/** /**
* Query string for the request * Query string for the request
* @var string
*/ */
protected string $query = ''; protected string $query = '';
/** /**
* Default request headers * Default request headers
* @var array
*/ */
protected array $defaultHeaders = []; protected array $defaultHeaders = [];
/** /**
* Valid HTTP request methods * Valid HTTP request methods
* @var array
*/ */
protected array $validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']; protected array $validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
/** /**
* The current request * The current request
* @var Request
*/ */
protected Request $request; protected Request $request;
@ -309,7 +302,7 @@ abstract class APIRequestBuilder {
*/ */
public function queryRequest(string $name, array $variables = []): Request public function queryRequest(string $name, array $variables = []): Request
{ {
$file = "{$this->filePath}/Queries/{$name}.graphql"; $file = realpath("{$this->filePath}/Queries/{$name}.graphql");
if ( ! file_exists($file)) if ( ! file_exists($file))
{ {
throw new LogicException('GraphQL query file does not exist.'); throw new LogicException('GraphQL query file does not exist.');

View File

@ -19,7 +19,6 @@ namespace Aviat\AnimeClient;
use Aviat\AnimeClient\Kitsu; use Aviat\AnimeClient\Kitsu;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException; use Psr\SimpleCache\InvalidArgumentException;
use function Amp\Promise\wait;
use Amp\Http\Client\Request; use Amp\Http\Client\Request;
use Amp\Http\Client\Response; use Amp\Http\Client\Response;
@ -31,6 +30,8 @@ use Yosymfony\Toml\{Toml, TomlBuilder};
use Throwable; use Throwable;
use function Amp\Promise\wait;
use function Aviat\Ion\_dir;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
//! TOML Functions //! TOML Functions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -180,9 +181,11 @@ function checkFolderPermissions(ConfigInterface $config): array
$errors = []; $errors = [];
$publicDir = $config->get('asset_dir'); $publicDir = $config->get('asset_dir');
$APP_DIR = _dir(dirname(__DIR__, 2), '/app');
$pathMap = [ $pathMap = [
'app/config' => realpath(__DIR__ . '/../../app/config'), 'app/config' => "{$APP_DIR}/config",
'app/logs' => realpath(__DIR__ . '/../../app/logs'), 'app/logs' => "{$APP_DIR}/logs",
'public/images/avatars' => "{$publicDir}/images/avatars", 'public/images/avatars' => "{$publicDir}/images/avatars",
'public/images/anime' => "{$publicDir}/images/anime", 'public/images/anime' => "{$publicDir}/images/anime",
'public/images/characters' => "{$publicDir}/images/characters", 'public/images/characters' => "{$publicDir}/images/characters",
@ -285,11 +288,11 @@ function getLocalImg (string $kitsuUrl, $webp = TRUE): string
* Create a transparent placeholder image * Create a transparent placeholder image
* *
* @param string $path * @param string $path
* @param int $width * @param int|null $width
* @param int $height * @param int|null $height
* @param string $text * @param string $text
*/ */
function createPlaceholderImage ($path, ?int $width, ?int $height, $text = 'Image Unavailable'): void function createPlaceholderImage (string $path, ?int $width, ?int $height, $text = 'Image Unavailable'): void
{ {
$width = $width ?? 200; $width = $width ?? 200;
$height = $height ?? 200; $height = $height ?? 200;

View File

@ -268,7 +268,7 @@ final class Dispatcher extends RoutingBase {
* @param array $params * @param array $params
* @return void * @return void
*/ */
protected function call($controllerName, $method, array $params): void protected function call(string $controllerName, string $method, array $params): void
{ {
$logger = $this->container->getLogger('default'); $logger = $this->container->getLogger('default');
@ -282,7 +282,7 @@ final class Dispatcher extends RoutingBase {
$logger->debug('Dispatcher - controller arguments', $params); $logger->debug('Dispatcher - controller arguments', $params);
} }
call_user_func_array([$controller, $method], $params); call_user_func_array([$controller, $method], array_values($params));
} }
catch (FailedResponseException $e) catch (FailedResponseException $e)
{ {
@ -388,21 +388,21 @@ final class Dispatcher extends RoutingBase {
$route['controller'] = $controllerClass; $route['controller'] = $controllerClass;
// Select the appropriate router method based on the http verb // Select the appropriate router method based on the http verb
$add = array_key_exists('verb', $route) $verb = array_key_exists('verb', $route)
? strtolower($route['verb']) ? strtolower($route['verb'])
: 'get'; : 'get';
// Add the route to the router object // Add the route to the router object
if ( ! array_key_exists('tokens', $route)) if ( ! array_key_exists('tokens', $route))
{ {
$routes[] = $this->router->$add($name, $path)->defaults($route); $routes[] = $this->router->$verb($name, $path)->defaults($route);
continue; continue;
} }
$tokens = $route['tokens']; $tokens = $route['tokens'];
unset($route['tokens']); unset($route['tokens']);
$routes[] = $this->router->$add($name, $path) $routes[] = $this->router->$verb($name, $path)
->defaults($route) ->defaults($route)
->tokens($tokens); ->tokens($tokens);
} }

View File

@ -418,6 +418,11 @@ final class Kitsu {
*/ */
private static function titleIsUnique(string $title = '', array $existingTitles = []): bool private static function titleIsUnique(string $title = '', array $existingTitles = []): bool
{ {
if (empty($title))
{
return FALSE;
}
foreach($existingTitles as $existing) foreach($existingTitles as $existing)
{ {
$isSubset = mb_substr_count($existing, $title) > 0; $isSubset = mb_substr_count($existing, $title) > 0;

View File

@ -24,7 +24,7 @@ const ERROR_MESSAGE_METHOD = 'errorPage';
const NOT_FOUND_METHOD = 'notFound'; const NOT_FOUND_METHOD = 'notFound';
const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth'; const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth';
const SRC_DIR = __DIR__; const SRC_DIR = __DIR__;
const USER_AGENT = "Tim's Anime Client/5.1"; const USER_AGENT = "Tim's Anime Client/5.2";
// Regex patterns // Regex patterns
const ALPHA_SLUG_PATTERN = '[a-z_]+'; const ALPHA_SLUG_PATTERN = '[a-z_]+';

View File

@ -10,16 +10,17 @@ if ($timezone === '' || $timezone === FALSE)
ini_set('date.timezone', 'GMT'); ini_set('date.timezone', 'GMT');
} }
define('ROOT_DIR', realpath(__DIR__ . '/../') . '/'); define('ROOT_DIR', dirname(__DIR__) . '/');
define('SRC_DIR', ROOT_DIR . 'src/'); define('SRC_DIR', ROOT_DIR . 'src/');
define('TEST_DIR', __DIR__ . '/');
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Autoloading // Autoloading
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
require_once __DIR__ . '/AnimeClient/AnimeClientTestCase.php'; require_once TEST_DIR . 'AnimeClient/AnimeClientTestCase.php';
require_once __DIR__ . '/Ion/IonTestCase.php'; require_once TEST_DIR . '/Ion/IonTestCase.php';
require_once __DIR__ . '/../vendor/autoload.php'; require_once ROOT_DIR . 'vendor/autoload.php';
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Ini Settings // Ini Settings
@ -27,7 +28,7 @@ require_once __DIR__ . '/../vendor/autoload.php';
ini_set('session.use_cookies', '0'); ini_set('session.use_cookies', '0');
ini_set('session.use_only_cookies', '0'); ini_set('session.use_only_cookies', '0');
ini_set('session.use_trans_sid', '1'); ini_set('session.use_trans_sid', '1');
// Start session here to supress error about headers not sent // Start session here to suppress error about headers not sent
session_start(); session_start();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -39,7 +40,7 @@ $_SESSION = [];
$_COOKIE = []; $_COOKIE = [];
// Request base test case and mocks // Request base test case and mocks
require_once __DIR__ . '/AnimeClient/mocks.php'; require_once TEST_DIR . 'AnimeClient/mocks.php';
require_once __DIR__ . '/Ion/mocks.php'; require_once TEST_DIR . 'Ion/mocks.php';
// End of bootstrap.php // End of bootstrap.php