From df861a776ade9d489174b32365d82a7a5d91ad15 Mon Sep 17 00:00:00 2001 From: memleakd <121398829+memleakd@users.noreply.github.com> Date: Wed, 6 May 2026 23:34:09 +0200 Subject: [PATCH 1/2] refactor: remove PHPStan callable signature baseline Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com> --- system/BaseModel.php | 3 +- system/Model.php | 3 + system/Router/RouteCollection.php | 6 +- system/Router/RouteCollectionInterface.php | 2 +- system/Router/Router.php | 2 +- system/View/Parser.php | 2 + system/View/Table.php | 2 +- .../DataConverter/DataConverterTest.php | 4 ++ .../phpstan-baseline/assign.propertyType.neon | 7 +-- utils/phpstan-baseline/loader.neon | 1 - .../missingType.callable.neon | 63 ------------------- 11 files changed, 18 insertions(+), 77 deletions(-) delete mode 100644 utils/phpstan-baseline/missingType.callable.neon diff --git a/system/BaseModel.php b/system/BaseModel.php index d40a662724d9..4d3dcb1adb41 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -49,7 +49,8 @@ * - process various callbacks * - allow intermingling calls to the db connection * - * @phpstan-type row_array array + * @phpstan-type row_array array + * @psalm-type row_array = array * @phpstan-type event_data_beforeinsert array{data: row_array} * @phpstan-type event_data_afterinsert array{id: int|string, data: row_array, result: bool} * @phpstan-type event_data_beforefind array{id?: int|string, method: string, singleton: bool, limit?: int, offset?: int} diff --git a/system/Model.php b/system/Model.php index d23cecad074a..e2f959b8b940 100644 --- a/system/Model.php +++ b/system/Model.php @@ -84,7 +84,10 @@ * @method $this whereIn(?string $key = null, $values = null, ?bool $escape = null) * @method $this whereNotIn(?string $key = null, $values = null, ?bool $escape = null) * + * @phpstan-method $this when($condition, callable(BaseBuilder, mixed): mixed $callback, (callable(BaseBuilder): mixed)|null $defaultCallback = null) + * @phpstan-method $this whenNot($condition, callable(BaseBuilder, mixed): mixed $callback, (callable(BaseBuilder): mixed)|null $defaultCallback = null) * @phpstan-import-type row_array from BaseModel + * @psalm-import-type row_array from BaseModel */ class Model extends BaseModel { diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 91b9f11d5f20..3c08958604d2 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -479,7 +479,7 @@ public function setAutoRoute(bool $value): RouteCollectionInterface * * This setting is passed to the Router class and handled there. * - * @param callable|string|null $callable + * @param (callable(string): (ResponseInterface|string|void))|string|null $callable */ public function set404Override($callable = null): RouteCollectionInterface { @@ -762,8 +762,8 @@ public function getRedirectCode(string $routeKey): int * $route->resource('users'); * }); * - * @param string $name The name to group/prefix the routes with. - * @param array|callable ...$params + * @param string $name The name to group/prefix the routes with. + * @param array|(callable(self): void) ...$params * * @return void */ diff --git a/system/Router/RouteCollectionInterface.php b/system/Router/RouteCollectionInterface.php index 3c34a9be2d8a..10587d81ee4c 100644 --- a/system/Router/RouteCollectionInterface.php +++ b/system/Router/RouteCollectionInterface.php @@ -117,7 +117,7 @@ public function setAutoRoute(bool $value): self; * * This setting is passed to the Router class and handled there. * - * @param callable|null $callable + * @param (callable(string): (ResponseInterface|string|void))|string|null $callable * * @TODO This method is not related to the route collection. So this should * be removed in the future. diff --git a/system/Router/Router.php b/system/Router/Router.php index e6ca63acffdd..063bb5074cbb 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -745,7 +745,7 @@ protected function setDefaultController() } /** - * @param callable|string $handler + * @param (callable(mixed...): (ResponseInterface|string|void))|string $handler */ protected function setMatchedRoute(string $route, $handler): void { diff --git a/system/View/Parser.php b/system/View/Parser.php index e0e53812c046..e9747988a8cb 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -721,6 +721,8 @@ protected function parsePlugins(string $template) /** * Makes a new plugin available during the parsing of the template. * + * @param (callable(array): string)|(callable(string, array): string) $callback + * * @return $this */ public function addPlugin(string $alias, callable $callback, bool $isPair = false) diff --git a/system/View/Table.php b/system/View/Table.php index df4b870b8ba9..a65b582f36c1 100644 --- a/system/View/Table.php +++ b/system/View/Table.php @@ -83,7 +83,7 @@ class Table /** * Callback for custom table layout * - * @var callable|null + * @var (callable(mixed): mixed)|string|null */ public $function; diff --git a/tests/system/DataConverter/DataConverterTest.php b/tests/system/DataConverter/DataConverterTest.php index 220e101ba762..6686618a181b 100644 --- a/tests/system/DataConverter/DataConverterTest.php +++ b/tests/system/DataConverter/DataConverterTest.php @@ -705,6 +705,10 @@ public function testNotNullable(): void $converter->toDataSource($dbData); } + /** + * @param (Closure(array): object)|string|null $reconstructor + * @param (Closure(object, bool, bool): array)|string|null $extractor + */ private function createDataConverter( array $types, array $handlers = [], diff --git a/utils/phpstan-baseline/assign.propertyType.neon b/utils/phpstan-baseline/assign.propertyType.neon index fa10aa1f575f..e0569c49cd73 100644 --- a/utils/phpstan-baseline/assign.propertyType.neon +++ b/utils/phpstan-baseline/assign.propertyType.neon @@ -1,4 +1,4 @@ -# total 29 errors +# total 28 errors parameters: ignoreErrors: @@ -96,8 +96,3 @@ parameters: message: '#^Property CodeIgniter\\View\\ParserPluginTest\:\:\$validator \(CodeIgniter\\Validation\\Validation\) does not accept CodeIgniter\\Validation\\ValidationInterface\.$#' count: 1 path: ../../tests/system/View/ParserPluginTest.php - - - - message: '#^Property CodeIgniter\\View\\Table\:\:\$function \(\(callable\(\)\: mixed\)\|null\) does not accept ''ticklemyfancy''\.$#' - count: 1 - path: ../../tests/system/View/TableTest.php diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 633e4837d6cd..36fd97fe8d7b 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -16,7 +16,6 @@ includes: - method.childParameterType.neon - method.childReturnType.neon - method.notFound.neon - - missingType.callable.neon - missingType.iterableValue.neon - missingType.parameter.neon - missingType.property.neon diff --git a/utils/phpstan-baseline/missingType.callable.neon b/utils/phpstan-baseline/missingType.callable.neon deleted file mode 100644 index 5d0d90d58d56..000000000000 --- a/utils/phpstan-baseline/missingType.callable.neon +++ /dev/null @@ -1,63 +0,0 @@ -# total 12 errors - -parameters: - ignoreErrors: - - - message: '#^Class CodeIgniter\\Model has PHPDoc tag @method for method whenNot\(\) parameter \#2 \$callback with no signature specified for callable\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Class CodeIgniter\\Model has PHPDoc tag @method for method whenNot\(\) parameter \#3 \$defaultCallback with no signature specified for callable\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Class CodeIgniter\\Model has PHPDoc tag @method for method when\(\) parameter \#2 \$callback with no signature specified for callable\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Class CodeIgniter\\Model has PHPDoc tag @method for method when\(\) parameter \#3 \$defaultCallback with no signature specified for callable\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Router\\RouteCollection\:\:group\(\) has parameter \$params with no signature specified for callable\.$#' - count: 1 - path: ../../system/Router/RouteCollection.php - - - - message: '#^Method CodeIgniter\\Router\\RouteCollection\:\:set404Override\(\) has parameter \$callable with no signature specified for callable\.$#' - count: 1 - path: ../../system/Router/RouteCollection.php - - - - message: '#^Method CodeIgniter\\Router\\RouteCollectionInterface\:\:set404Override\(\) has parameter \$callable with no signature specified for callable\.$#' - count: 1 - path: ../../system/Router/RouteCollectionInterface.php - - - - message: '#^Method CodeIgniter\\Router\\Router\:\:setMatchedRoute\(\) has parameter \$handler with no signature specified for callable\.$#' - count: 1 - path: ../../system/Router/Router.php - - - - message: '#^Method CodeIgniter\\View\\Parser\:\:addPlugin\(\) has parameter \$callback with no signature specified for callable\.$#' - count: 1 - path: ../../system/View/Parser.php - - - - message: '#^Property CodeIgniter\\View\\Table\:\:\$function type has no signature specified for callable\.$#' - count: 1 - path: ../../system/View/Table.php - - - - message: '#^Method CodeIgniter\\DataConverter\\DataConverterTest\:\:createDataConverter\(\) has parameter \$extractor with no signature specified for Closure\.$#' - count: 1 - path: ../../tests/system/DataConverter/DataConverterTest.php - - - - message: '#^Method CodeIgniter\\DataConverter\\DataConverterTest\:\:createDataConverter\(\) has parameter \$reconstructor with no signature specified for Closure\.$#' - count: 1 - path: ../../tests/system/DataConverter/DataConverterTest.php From b1d993b19fc0d7e74eb194e71bf6d07f7ab5964d Mon Sep 17 00:00:00 2001 From: memleakd <121398829+memleakd@users.noreply.github.com> Date: Sat, 9 May 2026 20:00:46 +0200 Subject: [PATCH 2/2] refactor: address review feedback Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com> --- system/BaseModel.php | 3 +-- system/Model.php | 1 - system/View/Table.php | 2 +- tests/system/View/TableTest.php | 2 +- utils/phpstan-baseline/loader.neon | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/system/BaseModel.php b/system/BaseModel.php index 4d3dcb1adb41..d40a662724d9 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -49,8 +49,7 @@ * - process various callbacks * - allow intermingling calls to the db connection * - * @phpstan-type row_array array - * @psalm-type row_array = array + * @phpstan-type row_array array * @phpstan-type event_data_beforeinsert array{data: row_array} * @phpstan-type event_data_afterinsert array{id: int|string, data: row_array, result: bool} * @phpstan-type event_data_beforefind array{id?: int|string, method: string, singleton: bool, limit?: int, offset?: int} diff --git a/system/Model.php b/system/Model.php index e2f959b8b940..f4ddd75276d3 100644 --- a/system/Model.php +++ b/system/Model.php @@ -87,7 +87,6 @@ * @phpstan-method $this when($condition, callable(BaseBuilder, mixed): mixed $callback, (callable(BaseBuilder): mixed)|null $defaultCallback = null) * @phpstan-method $this whenNot($condition, callable(BaseBuilder, mixed): mixed $callback, (callable(BaseBuilder): mixed)|null $defaultCallback = null) * @phpstan-import-type row_array from BaseModel - * @psalm-import-type row_array from BaseModel */ class Model extends BaseModel { diff --git a/system/View/Table.php b/system/View/Table.php index a65b582f36c1..ee6057811615 100644 --- a/system/View/Table.php +++ b/system/View/Table.php @@ -83,7 +83,7 @@ class Table /** * Callback for custom table layout * - * @var (callable(mixed): mixed)|string|null + * @var (callable(mixed): mixed)|null */ public $function; diff --git a/tests/system/View/TableTest.php b/tests/system/View/TableTest.php index 62df5b02c0b3..b7946b059138 100644 --- a/tests/system/View/TableTest.php +++ b/tests/system/View/TableTest.php @@ -773,7 +773,7 @@ public function testInvalidCallback(): void $this->table->setHeading('Name', 'Color', 'Size'); $this->table->addRow('Fred', 'Blue', 'Small'); - $this->table->function = 'ticklemyfancy'; + $this->table->function = 'ticklemyfancy'; // @phpstan-ignore assign.propertyType (needed for testing) $generated = $this->table->generate(); diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 36fd97fe8d7b..815fa2376cc0 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -1,4 +1,4 @@ -# total 2028 errors +# total 2015 errors includes: - argument.type.neon