diff --git a/app/bootstrap.php b/app/bootstrap.php
index 55854186..41ec2e38 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -32,10 +32,13 @@ use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
use Psr\SimpleCache\CacheInterface;
+use function Aviat\Ion\_dir;
+
if ( ! defined('APP_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
// -------------------------------------------------------------------------
+ $LOG_DIR = _dir(APP_DIR, 'logs');
$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);
foreach (['anilist-request', 'kitsu-request', 'kitsu-graphql'] as $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());
$logger->pushHandler($handler);
diff --git a/app/templates/anime-cover.php b/app/templates/anime-cover.php
index aef5ec2b..5715d0d2 100644
--- a/app/templates/anime-cover.php
+++ b/app/templates/anime-cover.php
@@ -18,7 +18,7 @@
-
+
diff --git a/src/AnimeClient/API/APIRequestBuilder.php b/src/AnimeClient/API/APIRequestBuilder.php
index 9d2be323..bda3c4e1 100644
--- a/src/AnimeClient/API/APIRequestBuilder.php
+++ b/src/AnimeClient/API/APIRequestBuilder.php
@@ -35,43 +35,36 @@ abstract class APIRequestBuilder {
/**
* Where to look for GraphQL request files
- * @var string
*/
- protected string $filePath = __DIR__;
+ protected string $filePath = '';
/**
* Url prefix for making url requests
- * @var string
*/
protected string $baseUrl = '';
/**
* Url path of the request
- * @var string
*/
protected string $path = '';
/**
* Query string for the request
- * @var string
*/
protected string $query = '';
/**
* Default request headers
- * @var array
*/
protected array $defaultHeaders = [];
/**
* Valid HTTP request methods
- * @var array
*/
protected array $validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
/**
* The current request
- * @var Request
*/
protected Request $request;
@@ -309,7 +302,7 @@ abstract class APIRequestBuilder {
*/
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))
{
throw new LogicException('GraphQL query file does not exist.');
diff --git a/src/AnimeClient/AnimeClient.php b/src/AnimeClient/AnimeClient.php
index a9b9bbf1..72f05bf8 100644
--- a/src/AnimeClient/AnimeClient.php
+++ b/src/AnimeClient/AnimeClient.php
@@ -19,7 +19,6 @@ namespace Aviat\AnimeClient;
use Aviat\AnimeClient\Kitsu;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;
-use function Amp\Promise\wait;
use Amp\Http\Client\Request;
use Amp\Http\Client\Response;
@@ -31,6 +30,8 @@ use Yosymfony\Toml\{Toml, TomlBuilder};
use Throwable;
+use function Amp\Promise\wait;
+use function Aviat\Ion\_dir;
// ----------------------------------------------------------------------------
//! TOML Functions
// ----------------------------------------------------------------------------
@@ -180,9 +181,11 @@ function checkFolderPermissions(ConfigInterface $config): array
$errors = [];
$publicDir = $config->get('asset_dir');
+ $APP_DIR = _dir(dirname(__DIR__, 2), '/app');
+
$pathMap = [
- 'app/config' => realpath(__DIR__ . '/../../app/config'),
- 'app/logs' => realpath(__DIR__ . '/../../app/logs'),
+ 'app/config' => "{$APP_DIR}/config",
+ 'app/logs' => "{$APP_DIR}/logs",
'public/images/avatars' => "{$publicDir}/images/avatars",
'public/images/anime' => "{$publicDir}/images/anime",
'public/images/characters' => "{$publicDir}/images/characters",
@@ -285,11 +288,11 @@ function getLocalImg (string $kitsuUrl, $webp = TRUE): string
* Create a transparent placeholder image
*
* @param string $path
- * @param int $width
- * @param int $height
+ * @param int|null $width
+ * @param int|null $height
* @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;
$height = $height ?? 200;
diff --git a/src/AnimeClient/Dispatcher.php b/src/AnimeClient/Dispatcher.php
index 072e7c5e..d0e67e37 100644
--- a/src/AnimeClient/Dispatcher.php
+++ b/src/AnimeClient/Dispatcher.php
@@ -268,7 +268,7 @@ final class Dispatcher extends RoutingBase {
* @param array $params
* @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');
@@ -282,7 +282,7 @@ final class Dispatcher extends RoutingBase {
$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)
{
@@ -388,21 +388,21 @@ final class Dispatcher extends RoutingBase {
$route['controller'] = $controllerClass;
// 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'])
: 'get';
// Add the route to the router object
if ( ! array_key_exists('tokens', $route))
{
- $routes[] = $this->router->$add($name, $path)->defaults($route);
+ $routes[] = $this->router->$verb($name, $path)->defaults($route);
continue;
}
$tokens = $route['tokens'];
unset($route['tokens']);
- $routes[] = $this->router->$add($name, $path)
+ $routes[] = $this->router->$verb($name, $path)
->defaults($route)
->tokens($tokens);
}
diff --git a/src/AnimeClient/Kitsu.php b/src/AnimeClient/Kitsu.php
index 2f92de9b..48f71c56 100644
--- a/src/AnimeClient/Kitsu.php
+++ b/src/AnimeClient/Kitsu.php
@@ -418,6 +418,11 @@ final class Kitsu {
*/
private static function titleIsUnique(string $title = '', array $existingTitles = []): bool
{
+ if (empty($title))
+ {
+ return FALSE;
+ }
+
foreach($existingTitles as $existing)
{
$isSubset = mb_substr_count($existing, $title) > 0;
diff --git a/src/AnimeClient/constants.php b/src/AnimeClient/constants.php
index 0206d6a6..813a1210 100644
--- a/src/AnimeClient/constants.php
+++ b/src/AnimeClient/constants.php
@@ -24,7 +24,7 @@ const ERROR_MESSAGE_METHOD = 'errorPage';
const NOT_FOUND_METHOD = 'notFound';
const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth';
const SRC_DIR = __DIR__;
-const USER_AGENT = "Tim's Anime Client/5.1";
+const USER_AGENT = "Tim's Anime Client/5.2";
// Regex patterns
const ALPHA_SLUG_PATTERN = '[a-z_]+';
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index f7f942a0..f7e04e67 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -10,16 +10,17 @@ if ($timezone === '' || $timezone === FALSE)
ini_set('date.timezone', 'GMT');
}
-define('ROOT_DIR', realpath(__DIR__ . '/../') . '/');
+define('ROOT_DIR', dirname(__DIR__) . '/');
define('SRC_DIR', ROOT_DIR . 'src/');
+define('TEST_DIR', __DIR__ . '/');
// -----------------------------------------------------------------------------
// Autoloading
// -----------------------------------------------------------------------------
-require_once __DIR__ . '/AnimeClient/AnimeClientTestCase.php';
-require_once __DIR__ . '/Ion/IonTestCase.php';
-require_once __DIR__ . '/../vendor/autoload.php';
+require_once TEST_DIR . 'AnimeClient/AnimeClientTestCase.php';
+require_once TEST_DIR . '/Ion/IonTestCase.php';
+require_once ROOT_DIR . 'vendor/autoload.php';
// -----------------------------------------------------------------------------
// Ini Settings
@@ -27,7 +28,7 @@ require_once __DIR__ . '/../vendor/autoload.php';
ini_set('session.use_cookies', '0');
ini_set('session.use_only_cookies', '0');
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();
// -----------------------------------------------------------------------------
@@ -39,7 +40,7 @@ $_SESSION = [];
$_COOKIE = [];
// Request base test case and mocks
-require_once __DIR__ . '/AnimeClient/mocks.php';
-require_once __DIR__ . '/Ion/mocks.php';
+require_once TEST_DIR . 'AnimeClient/mocks.php';
+require_once TEST_DIR . 'Ion/mocks.php';
// End of bootstrap.php
\ No newline at end of file