From c7cad286cb00b4676c9083a1c6c6e68adc7709ac Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Mon, 24 Aug 2026 20:17:07 +0800 Subject: [PATCH] refactor: fix phpstan errors in `Filters` --- system/Filters/Filters.php | 18 +-- system/Filters/ForceHTTPS.php | 4 +- system/Filters/InvalidChars.php | 8 +- system/Filters/PageCache.php | 4 +- system/Filters/PerformanceMetrics.php | 4 +- tests/system/Filters/CSRFTest.php | 14 ++- tests/system/Filters/DebugToolbarTest.php | 7 +- tests/system/Filters/FiltersTest.php | 22 +++- tests/system/Filters/HoneypotTest.php | 36 ++++-- tests/system/Filters/InvalidCharsTest.php | 6 + .../phpstan-baseline/assign.propertyType.neon | 27 +---- utils/phpstan-baseline/loader.neon | 2 +- .../missingType.iterableValue.neon | 112 +----------------- .../missingType.parameter.neon | 7 +- 14 files changed, 88 insertions(+), 183 deletions(-) diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php index 38bd553249bb..973b9ded7979 100644 --- a/system/Filters/Filters.php +++ b/system/Filters/Filters.php @@ -369,6 +369,8 @@ public function runRequired(string $position = 'before') * * @param 'after'|'before' $position * + * @return array{list, array>} + * * @internal */ public function getRequiredFilters(string $position = 'before'): array @@ -410,7 +412,9 @@ public function getRequiredFilters(string $position = 'before'): array * Set the toolbar filter to the last position to be executed. * * @param list $filters `after` filter array - * @param bool $remove if true, remove `toolbar` filter + * @param bool $remove If true, remove `toolbar` filter + * + * @return list */ private function setToolbarToLast(array $filters, bool $remove = false): array { @@ -853,8 +857,8 @@ protected function processAliasesToClass(string $position) /** * Check paths for match for URI * - * @param string $uri URI to test against - * @param array|string $paths The path patterns to test + * @param string $uri URI to test against + * @param array|string $paths The path patterns to test * * @return bool True if any of the paths apply to the URI */ @@ -876,8 +880,8 @@ private function pathApplies(string $uri, $paths) /** * Check except paths * - * @param string $uri URI path relative to baseURL (all lowercase) - * @param array|string $paths The except path patterns + * @param string $uri URI path relative to baseURL (all lowercase) + * @param array|string $paths The except path patterns * * @return bool True if the URI matches except paths. */ @@ -899,8 +903,8 @@ private function checkExcept(string $uri, $paths): bool /** * Check the URI path as pseudo-regex * - * @param string $uri URI path relative to baseURL (all lowercase, URL-decoded) - * @param array $paths The except path patterns + * @param string $uri URI path relative to baseURL (all lowercase, URL-decoded) + * @param array $paths The except path patterns */ private function checkPseudoRegex(string $uri, array $paths): bool { diff --git a/system/Filters/ForceHTTPS.php b/system/Filters/ForceHTTPS.php index aa9cb3716d08..6f59338d948f 100644 --- a/system/Filters/ForceHTTPS.php +++ b/system/Filters/ForceHTTPS.php @@ -30,7 +30,7 @@ class ForceHTTPS implements FilterInterface * as set the HTTP Strict Transport Security (HSTS) header for those browsers * that support it. * - * @param array|null $arguments + * @param list|null $arguments * * @return ResponseInterface|null */ @@ -56,7 +56,7 @@ public function before(RequestInterface $request, $arguments = null) /** * We don't have anything to do here. * - * @param array|null $arguments + * @param list|null $arguments */ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { diff --git a/system/Filters/InvalidChars.php b/system/Filters/InvalidChars.php index 85e71c5d4f59..5d714b0fdf11 100644 --- a/system/Filters/InvalidChars.php +++ b/system/Filters/InvalidChars.php @@ -84,9 +84,9 @@ public function after(RequestInterface $request, ResponseInterface $response, $a /** * Check the character encoding is valid UTF-8. * - * @param array|string $value + * @param array|string $value * - * @return array|string + * @return array|string * * @throws SecurityException */ @@ -113,9 +113,9 @@ protected function checkEncoding($value) /** * Check for the presence of control characters except line breaks and tabs. * - * @param array|string $value + * @param array|string $value * - * @return array|string + * @return array|string */ protected function checkControl($value) { diff --git a/system/Filters/PageCache.php b/system/Filters/PageCache.php index ff4bd097f84c..d292ff9875c9 100644 --- a/system/Filters/PageCache.php +++ b/system/Filters/PageCache.php @@ -45,7 +45,7 @@ public function __construct(?Cache $config = null) /** * Checks page cache and return if found. * - * @param array|null $arguments + * @param list|null $arguments * * @return ResponseInterface|null */ @@ -61,7 +61,7 @@ public function before(RequestInterface $request, $arguments = null) /** * Cache the page. * - * @param array|null $arguments + * @param list|null $arguments */ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { diff --git a/system/Filters/PerformanceMetrics.php b/system/Filters/PerformanceMetrics.php index 97582ad8dc05..259f7d46e298 100644 --- a/system/Filters/PerformanceMetrics.php +++ b/system/Filters/PerformanceMetrics.php @@ -24,7 +24,7 @@ class PerformanceMetrics implements FilterInterface /** * We don't need to do anything here. * - * @param array|null $arguments + * @param list|null $arguments */ public function before(RequestInterface $request, $arguments = null) { @@ -34,7 +34,7 @@ public function before(RequestInterface $request, $arguments = null) /** * Replaces the performance metrics. * - * @param array|null $arguments + * @param list|null $arguments */ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { diff --git a/tests/system/Filters/CSRFTest.php b/tests/system/Filters/CSRFTest.php index 71a6dfc28e7e..d258755f4870 100644 --- a/tests/system/Filters/CSRFTest.php +++ b/tests/system/Filters/CSRFTest.php @@ -53,8 +53,11 @@ public function testDoNotCheckCliRequest(): void 'after' => [], ]; - $this->request = Services::clirequest(null, false); - $this->response = service('response'); + $this->request = Services::clirequest(null, false); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $filters = new Filters($this->config, $this->request, $this->response); $uri = 'admin/foo/bar'; @@ -71,8 +74,11 @@ public function testPassGetRequest(): void 'after' => [], ]; - $this->request = service('incomingrequest', null, false); - $this->response = service('response'); + $this->request = service('incomingrequest', null, false); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $filters = new Filters($this->config, $this->request, $this->response); $uri = 'admin/foo/bar'; diff --git a/tests/system/Filters/DebugToolbarTest.php b/tests/system/Filters/DebugToolbarTest.php index 905dd46cf15a..fc9f8f179776 100644 --- a/tests/system/Filters/DebugToolbarTest.php +++ b/tests/system/Filters/DebugToolbarTest.php @@ -45,8 +45,11 @@ protected function setUp(): void Services::injectMock('superglobals', new Superglobals()); - $this->request = service('request'); - $this->response = service('response'); + $this->request = service('request'); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; } public function testDebugToolbarFilter(): void diff --git a/tests/system/Filters/FiltersTest.php b/tests/system/Filters/FiltersTest.php index 11567f429c1d..d696498efaa2 100644 --- a/tests/system/Filters/FiltersTest.php +++ b/tests/system/Filters/FiltersTest.php @@ -24,6 +24,7 @@ use CodeIgniter\Filters\fixtures\Multiple2; use CodeIgniter\Filters\fixtures\Role; use CodeIgniter\HTTP\CLIRequest; +use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\Response; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\Superglobals; @@ -70,10 +71,12 @@ protected function setUp(): void Services::injectMock('superglobals', new Superglobals()); - $this->response = service('response'); + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; } - private function createFilters(FiltersConfig $config, $request = null): Filters + private function createFilters(FiltersConfig $config, ?RequestInterface $request = null): Filters { $request ??= service('request'); @@ -213,10 +216,10 @@ public function testProcessMethodProcessGlobals(): void } /** - * @param array|string $except + * @param list|string $except */ #[DataProvider('provideProcessMethodProcessGlobalsWithExcept')] - public function testProcessMethodProcessGlobalsWithExcept($except): void + public function testProcessMethodProcessGlobalsWithExcept(array|string $except): void { service('superglobals')->setServer('REQUEST_METHOD', 'GET'); @@ -249,6 +252,9 @@ public function testProcessMethodProcessGlobalsWithExcept($except): void $this->assertSame($expected, $filters->initialize($uri)->getFilters()); } + /** + * @return iterable|string}> + */ public static function provideProcessMethodProcessGlobalsWithExcept(): iterable { return [ @@ -590,10 +596,11 @@ public function testOtherResult(): void } /** - * @param array|string $except + * @param list|string $except + * @param array{before: list, after: list} $expected */ #[DataProvider('provideBeforeExcept')] - public function testBeforeExcept(string $uri, $except, array $expected): void + public function testBeforeExcept(string $uri, array|string $except, array $expected): void { service('superglobals')->setServer('REQUEST_METHOD', 'GET'); @@ -619,6 +626,9 @@ public function testBeforeExcept(string $uri, $except, array $expected): void $this->assertSame($expected, $filters->initialize($uri)->getFilters()); } + /** + * @return iterable|string, array{before: list, after: list}}> + */ public static function provideBeforeExcept(): iterable { return [ diff --git a/tests/system/Filters/HoneypotTest.php b/tests/system/Filters/HoneypotTest.php index 630a882352ec..8ad3106f1a9f 100644 --- a/tests/system/Filters/HoneypotTest.php +++ b/tests/system/Filters/HoneypotTest.php @@ -65,8 +65,11 @@ public function testBeforeTriggered(): void 'after' => [], ]; - $this->request = service('request', null, false); - $this->response = service('response'); + $this->request = service('request', null, false); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $filters = new Filters($this->config, $this->request, $this->response); $uri = 'admin/foo/bar'; @@ -83,8 +86,11 @@ public function testBeforeClean(): void ]; service('superglobals')->unsetPost($this->honey->name); - $this->request = service('request', null, false); - $this->response = service('response'); + $this->request = service('request', null, false); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $expected = $this->request; @@ -104,14 +110,19 @@ public function testAfter(): void 'after' => ['honeypot'], ]; - $this->request = service('request', null, false); - $this->response = service('response'); + $this->request = service('request', null, false); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $filters = new Filters($this->config, $this->request, $this->response); $uri = 'admin/foo/bar'; $this->response->setBody('
'); - $this->response = $filters->run($uri, 'after'); + $response = $filters->run($uri, 'after'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $this->assertStringContainsString($this->honey->name, (string) $this->response->getBody()); } @@ -124,14 +135,19 @@ public function testAfterNotApplicable(): void 'after' => ['honeypot'], ]; - $this->request = service('request', null, false); - $this->response = service('response'); + $this->request = service('request', null, false); + + $response = service('response'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $filters = new Filters($this->config, $this->request, $this->response); $uri = 'admin/foo/bar'; $this->response->setBody('
'); - $this->response = $filters->run($uri, 'after'); + $response = $filters->run($uri, 'after'); + $this->assertInstanceOf(Response::class, $response); + $this->response = $response; $this->assertStringNotContainsString($this->honey->name, (string) $this->response->getBody()); } } diff --git a/tests/system/Filters/InvalidCharsTest.php b/tests/system/Filters/InvalidCharsTest.php index 4cf112b6da91..66588b5b1a35 100644 --- a/tests/system/Filters/InvalidCharsTest.php +++ b/tests/system/Filters/InvalidCharsTest.php @@ -161,6 +161,9 @@ public function testCheckControlStringWithLineBreakAndTabReturnsTheString(string $this->invalidChars->before($this->request); } + /** + * @return iterable + */ public static function provideCheckControlStringWithLineBreakAndTabReturnsTheString(): iterable { yield from [ @@ -183,6 +186,9 @@ public function testCheckControlStringWithControlCharsCausesException(string $in $this->invalidChars->before($this->request); } + /** + * @return iterable + */ public static function provideCheckControlStringWithControlCharsCausesException(): iterable { yield from [ diff --git a/utils/phpstan-baseline/assign.propertyType.neon b/utils/phpstan-baseline/assign.propertyType.neon index a2a5ca34cc63..89038a5d8ecb 100644 --- a/utils/phpstan-baseline/assign.propertyType.neon +++ b/utils/phpstan-baseline/assign.propertyType.neon @@ -1,4 +1,4 @@ -# total 20 errors +# total 10 errors parameters: ignoreErrors: @@ -17,31 +17,6 @@ parameters: count: 1 path: ../../tests/system/Commands/Utilities/Routes/FilterFinderTest.php - - - message: '#^Property CodeIgniter\\Filters\\CSRFTest\:\:\$response \(CodeIgniter\\HTTP\\Response\|null\) does not accept CodeIgniter\\HTTP\\ResponseInterface\.$#' - count: 2 - path: ../../tests/system/Filters/CSRFTest.php - - - - message: '#^Property CodeIgniter\\Filters\\DebugToolbarTest\:\:\$response \(CodeIgniter\\HTTP\\Response\) does not accept CodeIgniter\\HTTP\\ResponseInterface\.$#' - count: 1 - path: ../../tests/system/Filters/DebugToolbarTest.php - - - - message: '#^Property CodeIgniter\\Filters\\FiltersTest\:\:\$response \(CodeIgniter\\HTTP\\Response\) does not accept CodeIgniter\\HTTP\\ResponseInterface\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - - - message: '#^Property CodeIgniter\\Filters\\HoneypotTest\:\:\$response \(CodeIgniter\\HTTP\\Response\|null\) does not accept CodeIgniter\\HTTP\\RequestInterface\|CodeIgniter\\HTTP\\ResponseInterface\|string\|null\.$#' - count: 2 - path: ../../tests/system/Filters/HoneypotTest.php - - - - message: '#^Property CodeIgniter\\Filters\\HoneypotTest\:\:\$response \(CodeIgniter\\HTTP\\Response\|null\) does not accept CodeIgniter\\HTTP\\ResponseInterface\.$#' - count: 4 - path: ../../tests/system/Filters/HoneypotTest.php - - message: '#^Property CodeIgniter\\Helpers\\CookieHelperTest\:\:\$response \(CodeIgniter\\HTTP\\Response\) does not accept CodeIgniter\\HTTP\\ResponseInterface\.$#' count: 1 diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 61ebc04982b4..9c2635ecfb69 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -1,4 +1,4 @@ -# total 419 errors +# total 386 errors includes: - argument.type.neon diff --git a/utils/phpstan-baseline/missingType.iterableValue.neon b/utils/phpstan-baseline/missingType.iterableValue.neon index 333eaa92ae2e..03aa1374a978 100644 --- a/utils/phpstan-baseline/missingType.iterableValue.neon +++ b/utils/phpstan-baseline/missingType.iterableValue.neon @@ -1,4 +1,4 @@ -# total 282 errors +# total 260 errors parameters: ignoreErrors: @@ -462,81 +462,6 @@ parameters: count: 1 path: ../../system/Exceptions/PageNotFoundException.php - - - message: '#^Method CodeIgniter\\Filters\\Filters\:\:checkExcept\(\) has parameter \$paths with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/Filters.php - - - - message: '#^Method CodeIgniter\\Filters\\Filters\:\:checkPseudoRegex\(\) has parameter \$paths with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/Filters.php - - - - message: '#^Method CodeIgniter\\Filters\\Filters\:\:getRequiredFilters\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/Filters.php - - - - message: '#^Method CodeIgniter\\Filters\\Filters\:\:pathApplies\(\) has parameter \$paths with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/Filters.php - - - - message: '#^Method CodeIgniter\\Filters\\Filters\:\:setToolbarToLast\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/Filters.php - - - - message: '#^Method CodeIgniter\\Filters\\ForceHTTPS\:\:after\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/ForceHTTPS.php - - - - message: '#^Method CodeIgniter\\Filters\\ForceHTTPS\:\:before\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/ForceHTTPS.php - - - - message: '#^Method CodeIgniter\\Filters\\InvalidChars\:\:checkControl\(\) has parameter \$value with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/InvalidChars.php - - - - message: '#^Method CodeIgniter\\Filters\\InvalidChars\:\:checkControl\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/InvalidChars.php - - - - message: '#^Method CodeIgniter\\Filters\\InvalidChars\:\:checkEncoding\(\) has parameter \$value with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/InvalidChars.php - - - - message: '#^Method CodeIgniter\\Filters\\InvalidChars\:\:checkEncoding\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/InvalidChars.php - - - - message: '#^Method CodeIgniter\\Filters\\PageCache\:\:after\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/PageCache.php - - - - message: '#^Method CodeIgniter\\Filters\\PageCache\:\:before\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/PageCache.php - - - - message: '#^Method CodeIgniter\\Filters\\PerformanceMetrics\:\:after\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/PerformanceMetrics.php - - - - message: '#^Method CodeIgniter\\Filters\\PerformanceMetrics\:\:before\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Filters/PerformanceMetrics.php - - message: '#^Method CodeIgniter\\HotReloader\\DirectoryHasher\:\:hashApp\(\) return type has no value type specified in iterable type array\.$#' count: 1 @@ -987,41 +912,6 @@ parameters: count: 1 path: ../../tests/system/Email/EmailTest.php - - - message: '#^Method CodeIgniter\\Filters\\FiltersTest\:\:provideBeforeExcept\(\) return type has no value type specified in iterable type iterable\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - - - message: '#^Method CodeIgniter\\Filters\\FiltersTest\:\:provideProcessMethodProcessGlobalsWithExcept\(\) return type has no value type specified in iterable type iterable\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - - - message: '#^Method CodeIgniter\\Filters\\FiltersTest\:\:testBeforeExcept\(\) has parameter \$except with no value type specified in iterable type array\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - - - message: '#^Method CodeIgniter\\Filters\\FiltersTest\:\:testBeforeExcept\(\) has parameter \$expected with no value type specified in iterable type array\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - - - message: '#^Method CodeIgniter\\Filters\\FiltersTest\:\:testProcessMethodProcessGlobalsWithExcept\(\) has parameter \$except with no value type specified in iterable type array\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - - - message: '#^Method CodeIgniter\\Filters\\InvalidCharsTest\:\:provideCheckControlStringWithControlCharsCausesException\(\) return type has no value type specified in iterable type iterable\.$#' - count: 1 - path: ../../tests/system/Filters/InvalidCharsTest.php - - - - message: '#^Method CodeIgniter\\Filters\\InvalidCharsTest\:\:provideCheckControlStringWithLineBreakAndTabReturnsTheString\(\) return type has no value type specified in iterable type iterable\.$#' - count: 1 - path: ../../tests/system/Filters/InvalidCharsTest.php - - message: '#^Property CodeIgniter\\Helpers\\Array\\ArrayHelperDotKeyExistsTest\:\:\$array type has no value type specified in iterable type array\.$#' count: 1 diff --git a/utils/phpstan-baseline/missingType.parameter.neon b/utils/phpstan-baseline/missingType.parameter.neon index 54d2e4a72c64..8634309cecf9 100644 --- a/utils/phpstan-baseline/missingType.parameter.neon +++ b/utils/phpstan-baseline/missingType.parameter.neon @@ -1,4 +1,4 @@ -# total 12 errors +# total 11 errors parameters: ignoreErrors: @@ -32,11 +32,6 @@ parameters: count: 1 path: ../../tests/system/Entity/EntityTest.php - - - message: '#^Method CodeIgniter\\Filters\\FiltersTest\:\:createFilters\(\) has parameter \$request with no type specified\.$#' - count: 1 - path: ../../tests/system/Filters/FiltersTest.php - - message: '#^Method CodeIgniter\\Helpers\\URLHelper\\CurrentUrlTest\:\:createRequest\(\) has parameter \$body with no type specified\.$#' count: 1