Yet more PHPStan fixes
timw4mail/HummingBirdAnimeClient/pipeline/head This commit looks good Details

This commit is contained in:
Timothy Warren 2021-02-11 19:54:22 -05:00
parent 103f95c07b
commit c100105fbc
19 changed files with 126 additions and 86 deletions

View File

@ -64,7 +64,7 @@ if (array_key_exists('timezone', $checkedConfig) && ! empty($checkedConfig['time
{
date_default_timezone_set($checkedConfig['timezone']);
}
else if ($timezone !== '')
else if (is_string($timezone) && $timezone !== '')
{
date_default_timezone_set($timezone);
}

View File

@ -8,6 +8,7 @@ parameters:
- ./console
- index.php
ignoreErrors:
- '#Access to an undefined property Aviat\\Ion\\Friend#'
- "#Offset 'fields' does not exist on array#"
- '#Call to an undefined method Aura\\\Html\\\HelperLocator::[a-zA-Z0-9_]+\(\)#'
- '#Call to an undefined method Query\\QueryBuilderInterface::[a-zA-Z0-9_]+\(\)#'

View File

@ -91,7 +91,7 @@ function loadTomlFile(string $filename): array
return Toml::parseFile($filename);
}
function _iterateToml(TomlBuilder $builder, iterable $data, $parentKey = NULL): void
function _iterateToml(TomlBuilder $builder, iterable $data, mixed $parentKey = NULL): void
{
foreach ($data as $key => $value)
{
@ -359,7 +359,7 @@ function colNotEmpty(array $search, string $key): bool
*
* @param CacheInterface $cache
* @return bool
* @throws InvalidArgumentException
* @throws Throwable
*/
function clearCache(CacheInterface $cache): bool
{

View File

@ -203,7 +203,7 @@ class Controller {
* @throws NotFoundException
* @return string
*/
protected function loadPartial($view, string $template, array $data = []): string
protected function loadPartial(HtmlView $view, string $template, array $data = []): string
{
$router = $this->container->get('dispatcher');
@ -236,7 +236,7 @@ class Controller {
* @throws ContainerException
* @throws NotFoundException
*/
protected function renderFullPage($view, string $template, array $data): HtmlView
protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView
{
$csp = [
"default-src 'self'",
@ -360,7 +360,7 @@ class Controller {
* @throws NotFoundException
* @return string
*/
protected function showMessage($view, string $type, string $message): string
protected function showMessage(HtmlView $view, string $type, string $message): string
{
return $this->loadPartial($view, 'message', [
'message_type' => $type,
@ -399,7 +399,7 @@ class Controller {
* @throws DoubleRenderException
* @return void
*/
protected function outputJSON($data, int $code): void
protected function outputJSON(mixed $data, int $code): void
{
(new JsonView())
->setOutput($data)
@ -420,10 +420,7 @@ class Controller {
{
(new HttpView())->redirect($url, $code)->send();
}
catch (\Throwable $e)
{
}
catch (\Throwable) {}
}
}
// End of BaseController.php

View File

@ -145,7 +145,7 @@ final class Anime extends BaseController {
{
$this->checkAuth();
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
if (empty($data['mal_id']))
{
@ -220,7 +220,7 @@ final class Anime extends BaseController {
{
$this->checkAuth();
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
// Do some minor data manipulation for
// large form-based updates
@ -257,7 +257,7 @@ final class Anime extends BaseController {
}
else
{
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
}
if (empty($data))
@ -282,7 +282,7 @@ final class Anime extends BaseController {
{
$this->checkAuth();
$body = $this->request->getParsedBody();
$body = (array)$this->request->getParsedBody();
$response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']);
if ($response === TRUE)

View File

@ -154,7 +154,7 @@ final class AnimeCollection extends BaseController {
public function edit(): void
{
$this->checkAuth();
$this->update($this->request->getParsedBody());
$this->update((array)$this->request->getParsedBody());
}
/**
@ -169,7 +169,7 @@ final class AnimeCollection extends BaseController {
{
$this->checkAuth();
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
if (array_key_exists('id', $data))
{
// Check for existing entry
@ -218,7 +218,7 @@ final class AnimeCollection extends BaseController {
{
$this->checkAuth();
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
if ( ! array_key_exists('hummingbird_id', $data))
{
$this->setFlashMessage("Can't delete item that doesn't exist", 'error');
@ -238,11 +238,11 @@ final class AnimeCollection extends BaseController {
/**
* Update a collection item
*
* @param $data
* @param array $data
* @throws ContainerException
* @throws NotFoundException
*/
protected function update($data): void
protected function update(array $data): void
{
if (array_key_exists('hummingbird_id', $data))
{

View File

@ -37,9 +37,7 @@ final class Images extends BaseController {
* @param string $file The filename to look for
* @param bool $display Whether to output the image to the server
* @return void
* @throws NotFoundException
* @throws Throwable
* @throws ContainerException
*/
public function cache(string $type, string $file, $display = TRUE): void
{
@ -134,7 +132,16 @@ final class Images extends BaseController {
[$origWidth] = getimagesizefromstring($data);
$gdImg = imagecreatefromstring($data);
if ($gdImg === FALSE)
{
return;
}
$resizedImg = imagescale($gdImg, $width ?? $origWidth);
if ($resizedImg === FALSE)
{
return;
}
if ($ext === 'gif')
{
@ -161,7 +168,7 @@ final class Images extends BaseController {
? 'image/webp'
: $response->getHeader('content-type')[0];
$outputFile = (strpos($file, '-original') !== FALSE)
$outputFile = (str_contains($file, '-original'))
? "{$filePrefix}-original.{$ext}"
: "{$filePrefix}.{$ext}";

View File

@ -135,15 +135,13 @@ final class Manga extends Controller {
* Add an manga to the list
*
* @return void
* @throws NotFoundException
* @throws Throwable
* @throws ContainerException
*/
public function add(): void
{
$this->checkAuth();
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
if ( ! array_key_exists('id', $data))
{
$this->redirect('manga/add', 303);
@ -163,7 +161,7 @@ final class Manga extends Controller {
}
else
{
$this->setFlashMessage('Failed to add new manga to list' . $result['body'], 'error');
$this->setFlashMessage('Failed to add new manga to list:' . print_r($data, TRUE), 'error');
}
$this->sessionRedirect();
@ -180,7 +178,7 @@ final class Manga extends Controller {
* @throws InvalidArgumentException
* @return void
*/
public function edit($id, $status = 'All'): void
public function edit(string $id, string $status = 'All'): void
{
$this->checkAuth();
@ -218,14 +216,12 @@ final class Manga extends Controller {
*
* @return void
* @throws Throwable
* @throws NotFoundException
* @throws ContainerException
*/
public function formUpdate(): void
{
$this->checkAuth();
$data = $this->request->getParsedBody();
$data = (array)$this->request->getParsedBody();
// Do some minor data manipulation for
// large form-based updates
@ -275,8 +271,6 @@ final class Manga extends Controller {
/**
* Remove an manga from the list
*
* @throws ContainerException
* @throws NotFoundException
* @throws Throwable
* @return void
*/
@ -284,7 +278,7 @@ final class Manga extends Controller {
{
$this->checkAuth();
$body = $this->request->getParsedBody();
$body = (array)$this->request->getParsedBody();
$response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']);
if ($response)

View File

@ -74,7 +74,7 @@ final class Misc extends BaseController {
*/
public function loginAction(): void
{
$post = $this->request->getParsedBody();
$post = (array)$this->request->getParsedBody();
if ($this->auth->authenticate($post['password']))
{
@ -83,7 +83,11 @@ final class Misc extends BaseController {
}
$this->setFlashMessage('Invalid username or password.');
$this->redirect($this->url->generate('login'), 303);
$redirectUrl = $this->url->generate('login');
$redirectUrl = ($redirectUrl !== FALSE) ? $redirectUrl : '';
$this->redirect($redirectUrl, 303);
}
/**

View File

@ -84,7 +84,7 @@ final class Settings extends BaseController {
*/
public function update(): void
{
$post = $this->request->getParsedBody();
$post = (array)$this->request->getParsedBody();
unset($post['settings-tabs']);
$saved = $this->settingsModel->saveSettingsFile($post);
@ -93,7 +93,10 @@ final class Settings extends BaseController {
? $this->setFlashMessage('Saved config settings.', 'success')
: $this->setFlashMessage('Failed to save config file.', 'error');
$this->redirect($this->url->generate('settings'), 303);
$redirectUrl = $this->url->generate('settings');
$redirectUrl = ($redirectUrl !== FALSE) ? $redirectUrl : '';
$this->redirect($redirectUrl, 303);
}
/**
@ -152,6 +155,9 @@ final class Settings extends BaseController {
? $this->setFlashMessage('Linked Anilist Account', 'success')
: $this->setFlashMessage('Error Linking Anilist Account', 'error');
$this->redirect($this->url->generate('settings'), 303);
$redirectUrl = $this->url->generate('settings');
$redirectUrl = ($redirectUrl !== FALSE) ? $redirectUrl : '';
$this->redirect($redirectUrl, 303);
}
}

View File

@ -16,19 +16,23 @@
namespace Aviat\AnimeClient;
use Aviat\AnimeClient\Enum\EventType;
use function Aviat\Ion\_dir;
use Aura\Router\{Map, Matcher, Route, Rule};
use Aviat\Ion\Json;
use Aura\Router\{
Map,
Matcher,
Route,
Rule,
};
use Aviat\AnimeClient\API\FailedResponseException;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Event;
use Aviat\Ion\Friend;
use Aviat\Ion\Type\StringType;
use JetBrains\PhpStorm\ArrayShape;
use LogicException;
use ReflectionException;
use function Aviat\Ion\_dir;
/**
* Basic routing/ dispatch
*/
@ -78,7 +82,7 @@ final class Dispatcher extends RoutingBase {
*
* @return Route|false
*/
public function getRoute()
public function getRoute(): Route | false
{
$logger = $this->container->getLogger();
@ -132,7 +136,7 @@ final class Dispatcher extends RoutingBase {
{
// If not route was matched, return an appropriate http
// error message
$errorRoute = $this->getErrorParams();
$errorRoute = (array)$this->getErrorParams();
$controllerName = DEFAULT_CONTROLLER;
$actionMethod = $errorRoute['action_method'];
$params = $errorRoute['params'];
@ -152,11 +156,11 @@ final class Dispatcher extends RoutingBase {
* Parse out the arguments for the appropriate controller for
* the current route
*
* @param Route $route
* @param Friend $route
* @throws LogicException
* @return array
*/
protected function processRoute($route): array
protected function processRoute(Friend $route): array
{
if ( ! array_key_exists('controller', $route->attributes))
{
@ -166,7 +170,7 @@ final class Dispatcher extends RoutingBase {
$controllerName = $route->attributes['controller'];
// Get the full namespace for a controller if a short name is given
if (strpos($controllerName, '\\') === FALSE)
if ( ! str_contains($controllerName, '\\'))
{
$map = $this->getControllerList();
$controllerName = $map[$controllerName];
@ -191,7 +195,7 @@ final class Dispatcher extends RoutingBase {
$logger = $this->container->getLogger();
if ($logger !== NULL)
{
$logger->info(json_encode($params));
$logger->info(Json::encode($params));
}
return [
@ -244,6 +248,10 @@ final class Dispatcher extends RoutingBase {
$path = trim($path, '/');
$actualPath = realpath(_dir(SRC_DIR, $path));
$classFiles = glob("{$actualPath}/*.php");
if ($classFiles === FALSE)
{
return [];
}
$controllers = [];
@ -282,9 +290,10 @@ final class Dispatcher extends RoutingBase {
$logger->debug('Dispatcher - controller arguments', $params);
}
call_user_func_array([$controller, $method], array_values($params));
$params = array_values($params);
$controller->$method(...$params);
}
catch (FailedResponseException $e)
catch (FailedResponseException)
{
$controllerName = DEFAULT_CONTROLLER;
$controller = new $controllerName($this->container);

View File

@ -48,7 +48,7 @@ final class FormGenerator {
* Create a new FormGenerator
*
* @param ContainerInterface $container
* @return $this
* @return self
*/
public static function new(ContainerInterface $container): self
{

View File

@ -22,7 +22,7 @@ use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Exception\ConfigException;
use Aviat\Ion\Type\ArrayType;
use Aviat\Ion\Type\StringType;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Helper object to manage menu creation and selection
@ -39,9 +39,9 @@ final class MenuGenerator extends UrlGenerator {
/**
* Request object
*
* @var RequestInterface
* @var ServerRequestInterface
*/
protected RequestInterface $request;
protected ServerRequestInterface $request;
/**
* @param ContainerInterface $container

View File

@ -85,7 +85,7 @@ trait MediaTrait {
* @param string $itemId
* @return AnimeListItem|MangaListItem
*/
public function getLibraryItem(string $itemId)
public function getLibraryItem(string $itemId): AnimeListItem|MangaListItem
{
return $this->kitsuModel->getListItem($itemId);
}

View File

@ -22,7 +22,7 @@ use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Exception\ConfigException;
use Aviat\Ion\Type\StringType;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Base for routing/url classes
@ -43,9 +43,9 @@ class RoutingBase {
/**
* Class wrapper for input superglobals
* @var RequestInterface
* @var ServerRequestInterface
*/
protected RequestInterface $request;
protected ServerRequestInterface $request;
/**
* Constructor
@ -64,8 +64,7 @@ class RoutingBase {
/**
* Get the current url path
* @throws ContainerException
* @throws NotFoundException
*
* @return string
*/
public function path(): string
@ -82,8 +81,7 @@ class RoutingBase {
/**
* Get the url segments
* @throws ContainerException
* @throws NotFoundException
*
* @return array
*/
public function segments(): array
@ -96,11 +94,10 @@ class RoutingBase {
* Get a segment of the current url
*
* @param int $num
* @throws ContainerException
* @throws NotFoundException
*
* @return string|null
*/
public function getSegment($num): ?string
public function getSegment(int $num): ?string
{
$segments = $this->segments();
return $segments[$num] ?? NULL;
@ -109,8 +106,6 @@ class RoutingBase {
/**
* Retrieve the last url segment
*
* @throws ContainerException
* @throws NotFoundException
* @return string
*/
public function lastSegment(): string

View File

@ -0,0 +1,32 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 8
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2021 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 5.2
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\Ion;
/**
* View Interface abstracting an HTTP Response
*/
interface HttpViewInterface extends ViewInterface {
/**
* Set the status code of the request
*
* @param int $code
* @throws \InvalidArgumentException
* @return self
*/
public function setStatusCode(int $code): self;
}

View File

@ -18,8 +18,6 @@ namespace Aviat\Ion\View;
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
use Laminas\Diactoros\Response\HtmlResponse;
use const EXTR_OVERWRITE;
@ -40,8 +38,6 @@ class HtmlView extends HttpView {
* Create the Html View
*
* @param ContainerInterface $container
* @throws ContainerException
* @throws NotFoundException
*/
public function __construct(ContainerInterface $container)
{
@ -57,6 +53,7 @@ class HtmlView extends HttpView {
* @param string $path
* @param array $data
* @return string
* @throws \Throwable
*/
public function renderTemplate(string $path, array $data): string
{
@ -74,9 +71,7 @@ class HtmlView extends HttpView {
// Very basic html minify, that won't affect content between html tags
$buffer = preg_replace('/>\s+</', '> <', $buffer);
return $buffer;
return preg_replace('/>\s+</', '> <', $buffer);
}
}
// End of HtmlView.php

View File

@ -16,7 +16,7 @@
namespace Aviat\Ion\View;
use Aviat\Ion\ViewInterface;
use Aviat\Ion\HttpViewInterface;
use Laminas\Diactoros\Response;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
@ -26,7 +26,7 @@ use Psr\Http\Message\ResponseInterface;
/**
* Base view class for Http output
*/
class HttpView implements ViewInterface{
class HttpView implements HttpViewInterface{
/**
* HTTP response Object
@ -103,9 +103,9 @@ class HttpView implements ViewInterface{
* Set the output string
*
* @param mixed $string
* @return ViewInterface
* @return HttpViewInterface
*/
public function setOutput($string): ViewInterface
public function setOutput($string): HttpViewInterface
{
$this->response->getBody()->write($string);
@ -117,9 +117,9 @@ class HttpView implements ViewInterface{
* Append additional output.
*
* @param string $string
* @return ViewInterface
* @return HttpViewInterface
*/
public function appendOutput(string $string): ViewInterface
public function appendOutput(string $string): HttpViewInterface
{
return $this->setOutput($string);
}

View File

@ -17,7 +17,7 @@
namespace Aviat\Ion\View;
use Aviat\Ion\Json;
use Aviat\Ion\ViewInterface;
use Aviat\Ion\HttpViewInterface;
/**
* View class to serialize Json
@ -35,9 +35,9 @@ class JsonView extends HttpView {
* Set the output string
*
* @param mixed $string
* @return ViewInterface
* @return HttpViewInterface
*/
public function setOutput($string): ViewInterface
public function setOutput(mixed $string): HttpViewInterface
{
if ( ! is_string($string))
{