From 5b28a35003a015e29770094932157f13a3f7f5c0 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 9 Jun 2024 20:32:12 +0200 Subject: Pass PHPStan level 9 (#6544) * More PHPStan * More, passing * 4 more files * Update to PHPStan 1.11.4 Needed for fixed bug: Consider numeric-string types after string concat https://github.com/phpstan/phpstan/releases/tag/1.11.4 * Pass PHPStan level 9 Start tracking booleansInConditions * Fix mark as read * Fix doctype * ctype_digit --- lib/Minz/Helper.php | 14 ++++++++------ lib/Minz/Model.php | 2 +- lib/Minz/Request.php | 41 ++++++++++++++++++++--------------------- lib/Minz/Url.php | 37 ++++++++++++++++--------------------- lib/favicons.php | 2 +- lib/lib_rss.php | 8 +++++--- 6 files changed, 51 insertions(+), 53 deletions(-) (limited to 'lib') diff --git a/lib/Minz/Helper.php b/lib/Minz/Helper.php index 04539ec40..50243ded0 100644 --- a/lib/Minz/Helper.php +++ b/lib/Minz/Helper.php @@ -9,23 +9,25 @@ declare(strict_types=1); /** * The Minz_Helper class contains some misc. help functions */ -class Minz_Helper { +final class Minz_Helper { /** * Wrapper for htmlspecialchars. - * Force UTf-8 value and can be used on array too. + * Force UTF-8 value and can be used on array too. * - * @phpstan-template T of string|array + * @phpstan-template T of mixed * @phpstan-param T $var * @phpstan-return T * - * @param string|array $var - * @return string|array + * @param mixed $var + * @return mixed */ public static function htmlspecialchars_utf8($var) { if (is_array($var)) { - return array_map(['Minz_Helper', 'htmlspecialchars_utf8'], $var); + // @phpstan-ignore argument.type, return.type + return array_map([self::class, 'htmlspecialchars_utf8'], $var); } elseif (is_string($var)) { + // @phpstan-ignore return.type return htmlspecialchars($var, ENT_COMPAT, 'UTF-8'); } else { return $var; diff --git a/lib/Minz/Model.php b/lib/Minz/Model.php index ee65d7d9c..c744b5a52 100644 --- a/lib/Minz/Model.php +++ b/lib/Minz/Model.php @@ -9,6 +9,6 @@ declare(strict_types=1); /** * The Minz_Model class represents a model in the MVC paradigm. */ -class Minz_Model { +abstract class Minz_Model { } diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 6d099a555..301bd5623 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -19,7 +19,7 @@ class Minz_Request { private static string $default_controller_name = 'index'; private static string $default_action_name = 'index'; - /** @var array{'c'?:string,'a'?:string,'params'?:array} */ + /** @var array{c?:string,a?:string,params?:array} */ private static array $originalRequest = []; /** @@ -35,6 +35,7 @@ class Minz_Request { public static function params(): array { return self::$params; } + /** * Read the URL parameter * @param string $key Key name @@ -46,10 +47,8 @@ class Minz_Request { public static function param(string $key, $default = false, bool $specialchars = false) { if (isset(self::$params[$key])) { $p = self::$params[$key]; - if (is_object($p) || $specialchars) { - return $p; - } elseif (is_string($p) || is_array($p)) { - return Minz_Helper::htmlspecialchars_utf8($p); + if (is_string($p) || is_array($p)) { + return $specialchars ? $p : Minz_Helper::htmlspecialchars_utf8($p); } else { return $p; } @@ -58,12 +57,15 @@ class Minz_Request { } } - /** @return array> */ + public static function hasParam(string $key): bool { + return isset(self::$params[$key]); + } + + /** @return array> */ public static function paramArray(string $key, bool $specialchars = false): array { if (empty(self::$params[$key]) || !is_array(self::$params[$key])) { return []; } - return $specialchars ? Minz_Helper::htmlspecialchars_utf8(self::$params[$key]) : self::$params[$key]; } @@ -131,7 +133,7 @@ class Minz_Request { public static function defaultActionName(): string { return self::$default_action_name; } - /** @return array{'c':string,'a':string,'params':array} */ + /** @return array{c:string,a:string,params:array} */ public static function currentRequest(): array { return [ 'c' => self::$controller_name, @@ -140,14 +142,14 @@ class Minz_Request { ]; } - /** @return array{'c'?:string,'a'?:string,'params'?:array} */ + /** @return array{c?:string,a?:string,params?:array} */ public static function originalRequest() { return self::$originalRequest; } /** * @param array|null $extraParams - * @return array{'c':string,'a':string,'params':array} + * @return array{c:string,a:string,params:array} */ public static function modifiedCurrentRequest(?array $extraParams = null): array { unset(self::$params['ajax']); @@ -169,14 +171,13 @@ class Minz_Request { self::$action_name = ctype_alnum($action_name) ? $action_name : ''; } - /** @param array $params */ + /** @param array $params */ public static function _params(array $params): void { self::$params = $params; } - /** @param array|mixed $value */ - public static function _param(string $key, $value = false): void { - if ($value === false) { + public static function _param(string $key, ?string $value = null): void { + if ($value === null) { unset(self::$params[$key]); } else { self::$params[$key] = $value; @@ -382,7 +383,7 @@ class Minz_Request { /** * Restart a request - * @param array{'c'?:string,'a'?:string,'params'?:array} $url an array presentation of the URL to route to + * @param array{c?:string,a?:string,params?:array} $url an array presentation of the URL to route to * @param bool $redirect If true, uses an HTTP redirection, and if false (default), performs an internal dispatcher redirection. * @throws Minz_ConfigurationException */ @@ -400,10 +401,8 @@ class Minz_Request { } else { self::_controllerName($url['c']); self::_actionName($url['a']); - self::_params(array_merge( - self::$params, - $url['params'] - )); + $merge = array_merge(self::$params, $url['params']); + self::_params($merge); Minz_Dispatcher::reset(); } } @@ -411,7 +410,7 @@ class Minz_Request { /** * Wrappers good notifications + redirection * @param string $msg notification content - * @param array{'c'?:string,'a'?:string,'params'?:array} $url url array to where we should be forwarded + * @param array{c?:string,a?:string,params?:array} $url url array to where we should be forwarded */ public static function good(string $msg, array $url = []): void { Minz_Request::setGoodNotification($msg); @@ -421,7 +420,7 @@ class Minz_Request { /** * Wrappers bad notifications + redirection * @param string $msg notification content - * @param array{'c'?:string,'a'?:string,'params'?:array} $url url array to where we should be forwarded + * @param array{c?:string,a?:string,params?:array} $url url array to where we should be forwarded */ public static function bad(string $msg, array $url = []): void { Minz_Request::setBadNotification($msg); diff --git a/lib/Minz/Url.php b/lib/Minz/Url.php index 67b927f05..73edcf76d 100644 --- a/lib/Minz/Url.php +++ b/lib/Minz/Url.php @@ -7,7 +7,7 @@ declare(strict_types=1); class Minz_Url { /** * Display a formatted URL - * @param string|array> $url The URL to format, defined as an array: + * @param string|array{c?:string,a?:string,params?:array} $url The URL to format, defined as an array: * $url['c'] = controller * $url['a'] = action * $url['params'] = array of additional parameters @@ -26,7 +26,7 @@ class Minz_Url { $url_string = ''; - if ($absolute) { + if ($absolute !== false) { $url_string = Minz_Request::getBaseUrl(); if (strlen($url_string) < strlen('http://a.bc')) { $url_string = Minz_Request::guessBaseUrl(); @@ -58,7 +58,7 @@ class Minz_Url { /** * Construit l'URI d'une URL - * @param array $url l'url sous forme de tableau + * @param array{c:string,a:string,params:array} $url URL as array definition * @param string $encodage pour indiquer comment encoder les & (& ou & pour html) * @return string uri sous la forme ?key=value&key2=value2 */ @@ -74,17 +74,19 @@ class Minz_Url { } if (!empty($url['params']) && is_array($url['params']) && !empty($url['params']['#'])) { - $anchor = '#' . ($encodage === 'html' ? htmlspecialchars($url['params']['#'], ENT_QUOTES, 'UTF-8') : $url['params']['#']); + if (is_string($url['params']['#'])) { + $anchor = '#' . ($encodage === 'html' ? htmlspecialchars($url['params']['#'], ENT_QUOTES, 'UTF-8') : $url['params']['#']); + } unset($url['params']['#']); } - if (isset($url['c']) + if (isset($url['c']) && is_string($url['c']) && $url['c'] != Minz_Request::defaultControllerName()) { $uri .= $separator . 'c=' . $url['c']; $separator = $and; } - if (isset($url['a']) + if (isset($url['a']) && is_string($url['a']) && $url['a'] != Minz_Request::defaultActionName()) { $uri .= $separator . 'a=' . $url['a']; $separator = $and; @@ -94,7 +96,7 @@ class Minz_Url { unset($url['params']['c']); unset($url['params']['a']); foreach ($url['params'] as $key => $param) { - if (!is_string($key) || (!is_string($param) && !is_int($param))) { + if (!is_string($key) || (!is_string($param) && !is_int($param) && !is_bool($param))) { continue; } $uri .= $separator . urlencode($key) . '=' . urlencode((string)$param); @@ -102,10 +104,6 @@ class Minz_Url { } } - if (!empty($url['#']) && is_string($url['#'])) { - $uri .= '#' . ($encodage === 'html' ? htmlspecialchars($url['#'], ENT_QUOTES, 'UTF-8') : $url['#']); - } - $uri .= $anchor; return $uri; @@ -113,8 +111,8 @@ class Minz_Url { /** * Check that all array elements representing the controller URL are OK - * @param array> $url controller URL as array - * @return array{'c':string,'a':string,'params':array} Verified controller URL as array + * @param array{c?:string,a?:string,params?:array} $url controller URL as array + * @return array{c:string,a:string,params:array} Verified controller URL as array */ public static function checkControllerUrl(array $url): array { return [ @@ -124,7 +122,7 @@ class Minz_Url { ]; } - /** @param array{'c'?:string,'a'?:string,'params'?:array} $url */ + /** @param array{c?:string,a?:string,params?:array} $url */ public static function serialize(?array $url = []): string { if (empty($url)) { return ''; @@ -136,19 +134,16 @@ class Minz_Url { } } - /** - * @phpstan-return array{'c'?:string,'a'?:string,'params'?:array} - * @return array> - */ + /** @return array{c?:string,a?:string,params?:array} */ public static function unserialize(string $url = ''): array { $result = json_decode(base64_decode($url, true) ?: '', true, JSON_THROW_ON_ERROR) ?? []; - /** @var array{'c'?:string,'a'?:string,'params'?:array} $result */ + /** @var array{c?:string,a?:string,params?:array} $result */ return $result; } /** * Returns an array representing the URL as passed in the address bar - * @return array{'c'?:string,'a'?:string,'params'?:array} URL representation + * @return array{c?:string,a?:string,params?:array} URL representation */ public static function build(): array { $url = [ @@ -184,5 +179,5 @@ function _url(string $controller, string $action, ...$args) { $params[$arg] = '' . $args[$i + 1]; } - return Minz_Url::display (array ('c' => $controller, 'a' => $action, 'params' => $params)); + return Minz_Url::display(['c' => $controller, 'a' => $action, 'params' => $params]); } diff --git a/lib/favicons.php b/lib/favicons.php index 53cc9f759..a9ebf9f30 100644 --- a/lib/favicons.php +++ b/lib/favicons.php @@ -75,7 +75,7 @@ function searchFavicon(string &$url): string { $links = $xpath->query('//link[@href][translate(@rel, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")="shortcut icon"' . ' or translate(@rel, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")="icon"]'); - if (!$links) { + if (!($links instanceof DOMNodeList)) { return ''; } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 6bceccc86..ae8744841 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -41,8 +41,7 @@ if (!function_exists('syslog')) { define('STDERR', fopen('php://stderr', 'w')); } function syslog(int $priority, string $message): bool { - // @phpstan-ignore booleanAnd.rightAlwaysTrue - if (COPY_SYSLOG_TO_STDERR && defined('STDERR') && STDERR) { + if (COPY_SYSLOG_TO_STDERR && defined('STDERR') && is_resource(STDERR)) { return fwrite(STDERR, $message . "\n") != false; } return false; @@ -619,9 +618,12 @@ function lazyimg(string $content): string { ) ?? ''; } +/** @return numeric-string */ function uTimeString(): string { $t = @gettimeofday(); - return $t['sec'] . str_pad('' . $t['usec'], 6, '0', STR_PAD_LEFT); + $result = $t['sec'] . str_pad('' . $t['usec'], 6, '0', STR_PAD_LEFT); + /** @var numeric-string @result */ + return $result; } function invalidateHttpCache(string $username = ''): bool { -- cgit v1.2.3