From a2ec5054d72f622dec4b6ee2b4c665dfa16625d4 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 28 Dec 2024 23:00:15 +0700 Subject: [PATCH 01/11] refactor: enable AddArrowFunctionReturnTypeRector --- app/Views/errors/cli/error_exception.php | 2 +- rector.php | 2 ++ system/CLI/CLI.php | 2 +- system/Commands/Utilities/Routes.php | 2 +- system/Database/BaseBuilder.php | 18 +++++----- system/Database/Forge.php | 2 +- system/Database/MySQLi/Builder.php | 6 ++-- system/Database/OCI8/Builder.php | 34 +++++++++---------- system/Database/OCI8/Result.php | 2 +- system/Database/Postgre/Builder.php | 14 ++++---- system/Database/Postgre/Connection.php | 2 +- system/Database/Query.php | 2 +- system/Database/SQLSRV/Builder.php | 6 ++-- system/Database/SQLSRV/Connection.php | 2 +- system/Database/SQLSRV/Forge.php | 4 +-- system/Database/SQLite3/Builder.php | 10 +++--- system/Database/SQLite3/Table.php | 8 ++--- system/Debug/Toolbar/Collectors/Database.php | 2 +- system/Entity/Entity.php | 2 +- system/Files/FileCollection.php | 2 +- system/HTTP/URI.php | 6 ++-- system/Helpers/Array/ArrayHelper.php | 4 +-- system/Helpers/form_helper.php | 2 +- system/Language/Language.php | 4 +-- system/Router/AutoRouter.php | 2 +- system/Router/AutoRouterImproved.php | 4 +-- system/Router/RouteCollection.php | 2 +- system/Router/Router.php | 2 +- system/Test/ReflectionHelper.php | 2 +- system/Validation/DotArrayFilter.php | 2 +- system/Validation/Validation.php | 8 ++--- system/View/Table.php | 6 ++-- tests/_support/Config/Routes.php | 2 +- tests/system/AutoReview/FrameworkCodeTest.php | 2 +- .../Cache/Handlers/DummyHandlerTest.php | 2 +- .../system/Cache/Handlers/FileHandlerTest.php | 2 +- .../Cache/Handlers/MemcachedHandlerTest.php | 2 +- .../Cache/Handlers/PredisHandlerTest.php | 2 +- .../Cache/Handlers/RedisHandlerTest.php | 2 +- tests/system/CodeIgniterTest.php | 2 +- tests/system/Database/Builder/UnionTest.php | 4 +-- tests/system/Database/Live/ForgeTest.php | 10 +++--- tests/system/Debug/TimerTest.php | 6 ++-- .../system/HTTP/ContentSecurityPolicyTest.php | 4 +-- .../Router/DefinedRouteCollectorTest.php | 4 +-- tests/system/Router/RouterTest.php | 4 +-- tests/system/Test/FeatureTestTraitTest.php | 22 ++++++------ tests/system/Validation/RulesTest.php | 4 +-- .../Validation/StrictRules/RulesTest.php | 2 +- tests/system/Validation/ValidationTest.php | 4 +-- tests/system/View/ParserTest.php | 8 ++--- 51 files changed, 129 insertions(+), 127 deletions(-) diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php index 2bf1459d4094..d551b3317c89 100644 --- a/app/Views/errors/cli/error_exception.php +++ b/app/Views/errors/cli/error_exception.php @@ -50,7 +50,7 @@ $function .= $padClass . $error['function']; } - $args = implode(', ', array_map(static fn ($value) => match (true) { + $args = implode(', ', array_map(static fn ($value): ?string => match (true) { is_object($value) => 'Object(' . $value::class . ')', is_array($value) => $value !== [] ? '[...]' : '[]', $value === null => 'null', // return the lowercased version diff --git a/rector.php b/rector.php index ee8621691862..486685959c70 100644 --- a/rector.php +++ b/rector.php @@ -41,6 +41,7 @@ use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector; use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector; use Rector\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector; +use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector; use Rector\TypeDeclaration\Rector\Closure\AddClosureVoidReturnTypeWhereNoReturnRector; @@ -201,6 +202,7 @@ TypedPropertyFromAssignsRector::class, ClosureReturnTypeRector::class, FlipTypeControlToUseExclusiveTypeRector::class, + AddArrowFunctionReturnTypeRector::class, ]) ->withConfiguredRule(StringClassNameToClassConstantRector::class, [ // keep '\\' prefix string on string '\Foo\Bar' diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index 0b5b01b179aa..9a7e1459e40f 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -339,7 +339,7 @@ public static function promptByMultipleKeys(string $text, array $options): array $pattern = preg_match_all('/^\d+(,\d+)*$/', trim($input)); // separate input by comma and convert all to an int[] - $inputToArray = array_map(static fn ($value) => (int) $value, explode(',', $input)); + $inputToArray = array_map(static fn ($value): int => (int) $value, explode(',', $input)); // find max from key of $options $maxOptions = array_key_last($options); // find max from input diff --git a/system/Commands/Utilities/Routes.php b/system/Commands/Utilities/Routes.php index a0f81f6b42a0..d7a6c0b55744 100644 --- a/system/Commands/Utilities/Routes.php +++ b/system/Commands/Utilities/Routes.php @@ -187,7 +187,7 @@ public function run(array $params) // Sort by Handler. if ($sortByHandler) { - usort($tbody, static fn ($handler1, $handler2) => strcmp($handler1[3], $handler2[3])); + usort($tbody, static fn ($handler1, $handler2): int => strcmp($handler1[3], $handler2[3])); } if ($host !== null) { diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index e738a331d608..54d9a8980f44 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -2018,7 +2018,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ")\n{:_table_:}ON DUPLICATE KEY UPDATE\n" . implode( ",\n", array_map( - static fn ($key, $value) => $table . '.' . $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $table . '.' . $key . ($value instanceof RawSql ? ' = ' . $value : ' = VALUES(' . $value . ')'), array_keys($updateFields), @@ -2108,7 +2108,7 @@ public function onConstraint($set) if (is_string($set)) { $set = explode(',', $set); - $set = array_map(static fn ($key) => trim($key), $set); + $set = array_map(static fn ($key): string => trim($key), $set); } if ($set instanceof RawSql) { @@ -2152,7 +2152,7 @@ public function setQueryAsData($query, ?string $alias = null, $columns = null): if (is_string($query)) { if ($columns !== null && is_string($columns)) { $columns = explode(',', $columns); - $columns = array_map(static fn ($key) => trim($key), $columns); + $columns = array_map(static fn ($key): string => trim($key), $columns); } $columns = (array) $columns; @@ -2190,7 +2190,7 @@ protected function fieldsFromQuery(string $sql): array */ protected function formatValues(array $values): array { - return array_map(static fn ($index) => '(' . implode(',', $index) . ')', $values); + return array_map(static fn ($index): string => '(' . implode(',', $index) . ')', $values); } /** @@ -2649,7 +2649,7 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $key . ($value instanceof RawSql ? ' = ' . $value : ' = ' . $alias . '.' . $value), array_keys($updateFields), @@ -2691,8 +2691,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), @@ -2946,8 +2946,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), diff --git a/system/Database/Forge.php b/system/Database/Forge.php index fc9aa54ec169..b41b8f34f8c8 100644 --- a/system/Database/Forge.php +++ b/system/Database/Forge.php @@ -861,7 +861,7 @@ protected function _alterTable(string $alterType, string $table, $processedField $columnNamesToDrop = explode(',', $columnNamesToDrop); } - $columnNamesToDrop = array_map(fn ($field) => 'DROP COLUMN ' . $this->db->escapeIdentifiers(trim($field)), $columnNamesToDrop); + $columnNamesToDrop = array_map(fn ($field): string => 'DROP COLUMN ' . $this->db->escapeIdentifiers(trim($field)), $columnNamesToDrop); return $sql . implode(', ', $columnNamesToDrop); } diff --git a/system/Database/MySQLi/Builder.php b/system/Database/MySQLi/Builder.php index 81434bc3645d..8c1de9d9f987 100644 --- a/system/Database/MySQLi/Builder.php +++ b/system/Database/MySQLi/Builder.php @@ -115,7 +115,7 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $table . '.' . $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $table . '.' . $key . ($value instanceof RawSql ? ' = ' . $value : ' = ' . $alias . '.' . $value), array_keys($updateFields), @@ -132,8 +132,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), diff --git a/system/Database/OCI8/Builder.php b/system/Database/OCI8/Builder.php index 24a6bb53b07c..5a65ffe9b75d 100644 --- a/system/Database/OCI8/Builder.php +++ b/system/Database/OCI8/Builder.php @@ -89,8 +89,8 @@ protected function _insertBatch(string $table, array $keys, array $values): stri $data = implode( " FROM DUAL UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), @@ -107,7 +107,7 @@ protected function _insertBatch(string $table, array $keys, array $values): stri */ protected function _replace(string $table, array $keys, array $values): string { - $fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys); + $fieldNames = array_map(static fn ($columnName): string => trim($columnName, '"'), $keys); $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); @@ -126,7 +126,7 @@ protected function _replace(string $table, array $keys, array $values): string $sql = 'MERGE INTO ' . $table . "\n USING (SELECT "; - $sql .= implode(', ', array_map(static fn ($columnName, $value) => $value . ' ' . $columnName, $keys, $values)); + $sql .= implode(', ', array_map(static fn ($columnName, $value): string => $value . ' ' . $columnName, $keys, $values)); $sql .= ' FROM DUAL) "_replace" ON ( '; @@ -134,16 +134,16 @@ protected function _replace(string $table, array $keys, array $values): string $onList[] = '1 != 1'; foreach ($uniqueIndexes as $index) { - $onList[] = '(' . implode(' AND ', array_map(static fn ($columnName) => $table . '."' . $columnName . '" = "_replace"."' . $columnName . '"', $index->fields)) . ')'; + $onList[] = '(' . implode(' AND ', array_map(static fn ($columnName): string => $table . '."' . $columnName . '" = "_replace"."' . $columnName . '"', $index->fields)) . ')'; } $sql .= implode(' OR ', $onList) . ') WHEN MATCHED THEN UPDATE SET '; - $sql .= implode(', ', array_map(static fn ($columnName) => $columnName . ' = "_replace".' . $columnName, $replaceableFields)); + $sql .= implode(', ', array_map(static fn ($columnName): string => $columnName . ' = "_replace".' . $columnName, $replaceableFields)); $sql .= ' WHEN NOT MATCHED THEN INSERT (' . implode(', ', $replaceableFields) . ') VALUES '; - return $sql . (' (' . implode(', ', array_map(static fn ($columnName) => '"_replace".' . $columnName, $replaceableFields)) . ')'); + return $sql . (' (' . implode(', ', array_map(static fn ($columnName): string => '"_replace".' . $columnName, $replaceableFields)) . ')'); } /** @@ -298,7 +298,7 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $table . '.' . $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $table . '.' . $key . ($value instanceof RawSql ? ' = ' . $value : ' = ' . $alias . '.' . $value), array_keys($updateFields), @@ -315,8 +315,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )) . ' FROM DUAL', @@ -342,7 +342,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $constraints = $this->QBOptions['constraints'] ?? []; if (empty($constraints)) { - $fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys); + $fieldNames = array_map(static fn ($columnName): string => trim($columnName, '"'), $keys); $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); @@ -401,7 +401,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $key . ($value instanceof RawSql ? " = {$value}" : " = {$alias}.{$value}"), array_keys($updateFields), @@ -412,7 +412,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql .= "\nWHEN NOT MATCHED THEN INSERT (" . implode(', ', $keys) . ")\nVALUES "; $sql .= (' (' - . implode(', ', array_map(static fn ($columnName) => "{$alias}.{$columnName}", $keys)) + . implode(', ', array_map(static fn ($columnName): string => "{$alias}.{$columnName}", $keys)) . ')'); $this->QBOptions['sql'] = $sql; @@ -424,8 +424,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $data = implode( " FROM DUAL UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), @@ -503,8 +503,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri $data = implode( " FROM DUAL UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), diff --git a/system/Database/OCI8/Result.php b/system/Database/OCI8/Result.php index 0039e90ae9b4..1049847b7af0 100644 --- a/system/Database/OCI8/Result.php +++ b/system/Database/OCI8/Result.php @@ -37,7 +37,7 @@ public function getFieldCount(): int */ public function getFieldNames(): array { - return array_map(fn ($fieldIndex) => oci_field_name($this->resultID, $fieldIndex), range(1, $this->getFieldCount())); + return array_map(fn ($fieldIndex): false|string => oci_field_name($this->resultID, $fieldIndex), range(1, $this->getFieldCount())); } /** diff --git a/system/Database/Postgre/Builder.php b/system/Database/Postgre/Builder.php index faae0eda8a9b..21fa222c7544 100644 --- a/system/Database/Postgre/Builder.php +++ b/system/Database/Postgre/Builder.php @@ -353,7 +353,7 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $key . ($value instanceof RawSql ? ' = ' . $value : ' = ' . $that->cast($alias . '.' . $value, $that->getFieldType($table, $key))), array_keys($updateFields), @@ -394,8 +394,8 @@ static function ($key, $value) use ($table, $alias, $that): string|RawSql { $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), @@ -458,7 +458,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri // if this is the first iteration of batch then we need to build skeleton sql if ($sql === '') { - $fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys); + $fieldNames = array_map(static fn ($columnName): string => trim($columnName, '"'), $keys); $constraints = $this->QBOptions['constraints'] ?? []; @@ -524,7 +524,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $key . ($value instanceof RawSql ? " = {$value}" : " = {$alias}.{$value}"), array_keys($updateFields), @@ -617,8 +617,8 @@ static function ($key, $value) use ($table, $alias, $that): RawSql|string { $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php index 4ce2b0763536..ad278145afef 100644 --- a/system/Database/Postgre/Connection.php +++ b/system/Database/Postgre/Connection.php @@ -371,7 +371,7 @@ protected function _indexData(string $table): array $obj = new stdClass(); $obj->name = $row->indexname; $_fields = explode(',', preg_replace('/^.*\((.+?)\)$/', '$1', trim($row->indexdef))); - $obj->fields = array_map(static fn ($v) => trim($v), $_fields); + $obj->fields = array_map(static fn ($v): string => trim($v), $_fields); if (str_starts_with($row->indexdef, 'CREATE UNIQUE INDEX pk')) { $obj->type = 'PRIMARY'; diff --git a/system/Database/Query.php b/system/Database/Query.php index ba8e9066063f..36026817d4d1 100644 --- a/system/Database/Query.php +++ b/system/Database/Query.php @@ -418,7 +418,7 @@ public function debugToolbarDisplay(): string */ $search = '/\b(?:' . implode('|', $highlight) . ')\b(?![^(')]*'(?:(?:[^(')]*'){2})*[^(')]*$)/'; - return preg_replace_callback($search, static fn ($matches) => '' . str_replace(' ', ' ', $matches[0]) . '', $sql); + return preg_replace_callback($search, static fn ($matches): string => '' . str_replace(' ', ' ', $matches[0]) . '', $sql); } /** diff --git a/system/Database/SQLSRV/Builder.php b/system/Database/SQLSRV/Builder.php index c1272cdcf326..e320069e80bf 100644 --- a/system/Database/SQLSRV/Builder.php +++ b/system/Database/SQLSRV/Builder.php @@ -694,7 +694,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $identityInFields = in_array($tableIdentity, $keys, true); - $fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys); + $fieldNames = array_map(static fn ($columnName): string => trim($columnName, '"'), $keys); if (empty($constraints)) { $tableIndexes = $this->db->getIndexData($table); @@ -773,7 +773,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $key . ($value instanceof RawSql ? ' = ' . $value : " = {$alias}.{$value}"), array_keys($updateFields), @@ -787,7 +787,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri '(' . implode( ', ', array_map( - static fn ($columnName) => $columnName === $tableIdentity + static fn ($columnName): string => $columnName === $tableIdentity ? "CASE WHEN {$alias}.{$columnName} IS NULL THEN (SELECT " . 'isnull(IDENT_CURRENT(\'' . $fullTableName . '\')+IDENT_INCR(\'' . $fullTableName . "'),1)) ELSE {$alias}.{$columnName} END" diff --git a/system/Database/SQLSRV/Connection.php b/system/Database/SQLSRV/Connection.php index 8ded4cd02098..6903f42eebac 100644 --- a/system/Database/SQLSRV/Connection.php +++ b/system/Database/SQLSRV/Connection.php @@ -257,7 +257,7 @@ protected function _indexData(string $table): array $obj->name = $row->index_name; $_fields = explode(',', trim($row->index_keys)); - $obj->fields = array_map(static fn ($v) => trim($v), $_fields); + $obj->fields = array_map(static fn ($v): string => trim($v), $_fields); if (str_contains($row->index_description, 'primary key located on')) { $obj->type = 'PRIMARY'; diff --git a/system/Database/SQLSRV/Forge.php b/system/Database/SQLSRV/Forge.php index df3d55c779c4..18d792a6eea8 100644 --- a/system/Database/SQLSRV/Forge.php +++ b/system/Database/SQLSRV/Forge.php @@ -225,7 +225,7 @@ protected function _alterTable(string $alterType, string $table, $processedField $sql = 'ALTER TABLE ' . $fullTable . ' DROP '; - $fields = array_map(static fn ($item) => 'COLUMN [' . trim($item) . ']', (array) $columnNamesToDrop); + $fields = array_map(static fn ($item): string => 'COLUMN [' . trim($item) . ']', (array) $columnNamesToDrop); return $sql . implode(',', $fields); } @@ -380,7 +380,7 @@ protected function _attributeType(array &$attributes) // https://learn.microsoft.com/en-us/sql/t-sql/data-types/char-and-varchar-transact-sql?view=sql-server-ver16#remarks $maxLength = max( array_map( - static fn ($value) => strlen($value), + static fn ($value): int => strlen($value), $attributes['CONSTRAINT'] ) ); diff --git a/system/Database/SQLite3/Builder.php b/system/Database/SQLite3/Builder.php index 15fc2529aa0d..744b64448fc6 100644 --- a/system/Database/SQLite3/Builder.php +++ b/system/Database/SQLite3/Builder.php @@ -143,7 +143,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $constraints = $this->QBOptions['constraints'] ?? []; if (empty($constraints)) { - $fieldNames = array_map(static fn ($columnName) => trim($columnName, '`'), $keys); + $fieldNames = array_map(static fn ($columnName): string => trim($columnName, '`'), $keys); $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); @@ -179,7 +179,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql = 'INSERT INTO ' . $table . ' ('; - $sql .= implode(', ', array_map(static fn ($columnName) => $columnName, $keys)); + $sql .= implode(', ', array_map(static fn ($columnName): string => $columnName, $keys)); $sql .= ")\n"; @@ -192,7 +192,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $sql .= implode( ",\n", array_map( - static fn ($key, $value) => $key . ($value instanceof RawSql ? + static fn ($key, $value): string => $key . ($value instanceof RawSql ? " = {$value}" : " = {$alias}.{$value}"), array_keys($updateFields), @@ -265,8 +265,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri $data = implode( " UNION ALL\n", array_map( - static fn ($value) => 'SELECT ' . implode(', ', array_map( - static fn ($key, $index) => $index . ' ' . $key, + static fn ($value): string => 'SELECT ' . implode(', ', array_map( + static fn ($key, $index): string => $index . ' ' . $key, $keys, $value )), diff --git a/system/Database/SQLite3/Table.php b/system/Database/SQLite3/Table.php index 5db002a1060b..61d4aee7535b 100644 --- a/system/Database/SQLite3/Table.php +++ b/system/Database/SQLite3/Table.php @@ -113,7 +113,7 @@ public function fromTable(string $table) $this->keys = array_merge($this->keys, $this->formatKeys($this->db->getIndexData($table))); // if primary key index exists twice then remove psuedo index name 'primary'. - $primaryIndexes = array_filter($this->keys, static fn ($index) => $index['type'] === 'primary'); + $primaryIndexes = array_filter($this->keys, static fn ($index): bool => $index['type'] === 'primary'); if ($primaryIndexes !== [] && count($primaryIndexes) > 1 && array_key_exists('primary', $this->keys)) { unset($this->keys['primary']); @@ -202,7 +202,7 @@ public function modifyColumn(array $fieldsToModify) */ public function dropPrimaryKey(): Table { - $primaryIndexes = array_filter($this->keys, static fn ($index) => strtolower($index['type']) === 'primary'); + $primaryIndexes = array_filter($this->keys, static fn ($index): bool => strtolower($index['type']) === 'primary'); foreach (array_keys($primaryIndexes) as $key) { unset($this->keys[$key]); @@ -235,7 +235,7 @@ public function dropForeignKey(string $foreignName) */ public function addPrimaryKey(array $fields): Table { - $primaryIndexes = array_filter($this->keys, static fn ($index) => strtolower($index['type']) === 'primary'); + $primaryIndexes = array_filter($this->keys, static fn ($index): bool => strtolower($index['type']) === 'primary'); // if primary key already exists we can't add another one if ($primaryIndexes !== []) { @@ -308,7 +308,7 @@ protected function createTable() $this->keys = array_filter( $this->keys, - static fn ($index) => count(array_intersect($index['fields'], $fieldNames)) === count($index['fields']) + static fn ($index): bool => count(array_intersect($index['fields'], $fieldNames)) === count($index['fields']) ); // Unique/Index keys diff --git a/system/Debug/Toolbar/Collectors/Database.php b/system/Debug/Toolbar/Collectors/Database.php index 1a923a35516b..32f7f07091b3 100644 --- a/system/Debug/Toolbar/Collectors/Database.php +++ b/system/Debug/Toolbar/Collectors/Database.php @@ -218,7 +218,7 @@ public function getTitleDetails(): string $this->getConnections(); $queryCount = count(static::$queries); - $uniqueCount = count(array_filter(static::$queries, static fn ($query) => $query['duplicate'] === false)); + $uniqueCount = count(array_filter(static::$queries, static fn ($query): bool => $query['duplicate'] === false)); $connectionCount = count($this->connections); return sprintf( diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 464992af6251..ff2fba1f7062 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -181,7 +181,7 @@ public function toArray(bool $onlyChanged = false, bool $cast = true, bool $recu { $this->_cast = $cast; - $keys = array_filter(array_keys($this->attributes), static fn ($key) => ! str_starts_with($key, '_')); + $keys = array_filter(array_keys($this->attributes), static fn ($key): bool => ! str_starts_with($key, '_')); if (is_array($this->datamap)) { $keys = array_unique( diff --git a/system/Files/FileCollection.php b/system/Files/FileCollection.php index f1310795867d..179bbc1d4997 100644 --- a/system/Files/FileCollection.php +++ b/system/Files/FileCollection.php @@ -108,7 +108,7 @@ final protected static function matchFiles(array $files, string $pattern): array $pattern = "#\\A{$pattern}\\z#"; } - return array_filter($files, static fn ($value) => (bool) preg_match($pattern, basename($value))); + return array_filter($files, static fn ($value): bool => (bool) preg_match($pattern, basename($value))); } // -------------------------------------------------------------------- diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index d0d23a3d26ee..2b386797fecd 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -1021,7 +1021,7 @@ protected function filterPath(?string $path = null): string // Encode characters $path = preg_replace_callback( '/(?:[^' . static::CHAR_UNRESERVED . ':@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/', - static fn (array $matches) => rawurlencode($matches[0]), + static fn (array $matches): string => rawurlencode($matches[0]), $path ); @@ -1167,9 +1167,9 @@ protected function parseStr(string $query): array $return = []; $query = explode('&', $query); - $params = array_map(static fn (string $chunk) => preg_replace_callback( + $params = array_map(static fn (string $chunk): ?string => preg_replace_callback( '/^(?[^&=]+?)(?:\[[^&=]*\])?=(?[^&=]+)/', - static fn (array $match) => str_replace($match['key'], bin2hex($match['key']), $match[0]), + static fn (array $match): string => str_replace($match['key'], bin2hex($match['key']), $match[0]), urldecode($chunk) ), $query); diff --git a/system/Helpers/Array/ArrayHelper.php b/system/Helpers/Array/ArrayHelper.php index 4bbd34427fa1..fc5bc462956e 100644 --- a/system/Helpers/Array/ArrayHelper.php +++ b/system/Helpers/Array/ArrayHelper.php @@ -58,7 +58,7 @@ private static function convertToArray(string $index): array ); return array_map( - static fn ($key) => str_replace('\.', '.', $key), + static fn ($key): string => str_replace('\.', '.', $key), $segments ); } @@ -96,7 +96,7 @@ private static function arraySearchDot(array $indexes, array $array) $answer[] = self::arraySearchDot($indexes, $value); } - $answer = array_filter($answer, static fn ($value) => $value !== null); + $answer = array_filter($answer, static fn ($value): bool => $value !== null); if ($answer !== []) { // If array only has one element, we return that element for BC. diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php index 7e11388841f4..6e77a1f36b0c 100644 --- a/system/Helpers/form_helper.php +++ b/system/Helpers/form_helper.php @@ -739,7 +739,7 @@ function validation_show_error(string $field, string $template = 'single'): stri $config = config(Validation::class); $view = service('renderer'); - $errors = array_filter(validation_errors(), static fn ($key) => preg_match( + $errors = array_filter(validation_errors(), static fn ($key): false|int => preg_match( '/^' . str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/')) . '$/', $key ), ARRAY_FILTER_USE_KEY); diff --git a/system/Language/Language.php b/system/Language/Language.php index 1ab2c5269195..cbea4a53324e 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -206,11 +206,11 @@ protected function formatMessage($message, array $args = []) $argsString = implode( ', ', - array_map(static fn ($element) => '"' . $element . '"', $args) + array_map(static fn ($element): string => '"' . $element . '"', $args) ); $argsUrlEncoded = implode( ', ', - array_map(static fn ($element) => '"' . rawurlencode($element) . '"', $args) + array_map(static fn ($element): string => '"' . rawurlencode($element) . '"', $args) ); log_message( diff --git a/system/Router/AutoRouter.php b/system/Router/AutoRouter.php index ce40f5cdc406..cad9ecbc1746 100644 --- a/system/Router/AutoRouter.php +++ b/system/Router/AutoRouter.php @@ -184,7 +184,7 @@ public function setTranslateURIDashes(bool $val = false): self */ private function scanControllers(array $segments): array { - $segments = array_filter($segments, static fn ($segment) => $segment !== ''); + $segments = array_filter($segments, static fn ($segment): bool => $segment !== ''); // numerically reindex the array, removing gaps $segments = array_values($segments); diff --git a/system/Router/AutoRouterImproved.php b/system/Router/AutoRouterImproved.php index 63cdd7702635..6160c0555dae 100644 --- a/system/Router/AutoRouterImproved.php +++ b/system/Router/AutoRouterImproved.php @@ -136,7 +136,7 @@ public function __construct( private function createSegments(string $uri): array { $segments = explode('/', $uri); - $segments = array_filter($segments, static fn ($segment) => $segment !== ''); + $segments = array_filter($segments, static fn ($segment): bool => $segment !== ''); // numerically reindex the array, removing gaps return array_values($segments); @@ -209,7 +209,7 @@ private function searchLastDefaultController(): bool } $namespaces = array_map( - fn ($segment) => $this->translateURI($segment), + fn ($segment): string => $this->translateURI($segment), $segments ); diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 13cbba449989..faee291a8213 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -1504,7 +1504,7 @@ protected function create(string $verb, string $from, $to, ?array $options = nul for ($i = (int) $options['offset'] + 1; $i < (int) $options['offset'] + 7; $i++) { $to = preg_replace_callback( '/\$X/', - static fn ($m) => '$' . $i, + static fn ($m): string => '$' . $i, $to, 1 ); diff --git a/system/Router/Router.php b/system/Router/Router.php index 0cd1614991ee..4e8c08852f79 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -590,7 +590,7 @@ protected function validateRequest(array $segments): array */ protected function scanControllers(array $segments): array { - $segments = array_filter($segments, static fn ($segment) => $segment !== ''); + $segments = array_filter($segments, static fn ($segment): bool => $segment !== ''); // numerically reindex the array, removing gaps $segments = array_values($segments); diff --git a/system/Test/ReflectionHelper.php b/system/Test/ReflectionHelper.php index a1b7ee99c67f..988fe949004c 100644 --- a/system/Test/ReflectionHelper.php +++ b/system/Test/ReflectionHelper.php @@ -41,7 +41,7 @@ public static function getPrivateMethodInvoker($obj, $method) $refMethod = new ReflectionMethod($obj, $method); $obj = (gettype($obj) === 'object') ? $obj : null; - return static fn (...$args) => $refMethod->invokeArgs($obj, $args); + return static fn (...$args): mixed => $refMethod->invokeArgs($obj, $args); } /** diff --git a/system/Validation/DotArrayFilter.php b/system/Validation/DotArrayFilter.php index c7a401e1589a..62da95cb61c7 100644 --- a/system/Validation/DotArrayFilter.php +++ b/system/Validation/DotArrayFilter.php @@ -32,7 +32,7 @@ public static function run(array $indexes, array $array): array foreach ($indexes as $index) { $segments = preg_split('/(? str_replace('\.', '.', $key), $segments); + $segments = array_map(static fn ($key): string => str_replace('\.', '.', $key), $segments); $filteredArray = self::filter($segments, $array); diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index c00329d670bb..93524663947e 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -176,7 +176,7 @@ public function run(?array $data = null, ?string $group = null, $dbGroup = null) $values = array_filter( $flattenedArray, - static fn ($key) => preg_match(self::getRegex($field), $key), + static fn ($key): false|int => preg_match(self::getRegex($field), $key), ARRAY_FILTER_USE_KEY ); @@ -413,7 +413,7 @@ private function processIfExist(string $field, array $rules, array $data) } // Otherwise remove the if_exist rule and continue the process - $rules = array_filter($rules, static fn ($rule) => $rule instanceof Closure || $rule !== 'if_exist'); + $rules = array_filter($rules, static fn ($rule): bool => $rule instanceof Closure || $rule !== 'if_exist'); } return $rules; @@ -460,7 +460,7 @@ private function processPermitEmpty($value, array $rules, array $data) } } - $rules = array_filter($rules, static fn ($rule) => $rule instanceof Closure || $rule !== 'permit_empty'); + $rules = array_filter($rules, static fn ($rule): bool => $rule instanceof Closure || $rule !== 'permit_empty'); } return $rules; @@ -867,7 +867,7 @@ public function getError(?string $field = null): string $errors = array_filter( $this->getErrors(), - static fn ($key) => preg_match(self::getRegex($field), $key), + static fn ($key): false|int => preg_match(self::getRegex($field), $key), ARRAY_FILTER_USE_KEY ); diff --git a/system/View/Table.php b/system/View/Table.php index 9eb29578a6da..a063e71c5a85 100644 --- a/system/View/Table.php +++ b/system/View/Table.php @@ -228,13 +228,13 @@ public function addRow() $missingKeys = array_diff_key($keyIndex, $tmpRow); // Remove all keys which don't exist in $keyIndex - $tmpRow = array_filter($tmpRow, static fn ($k) => array_key_exists($k, $keyIndex), ARRAY_FILTER_USE_KEY); + $tmpRow = array_filter($tmpRow, static fn ($k): bool => array_key_exists($k, $keyIndex), ARRAY_FILTER_USE_KEY); // add missing keys to row, but use $this->emptyCells - $tmpRow = array_merge($tmpRow, array_map(fn ($v) => ['data' => $this->emptyCells], $missingKeys)); + $tmpRow = array_merge($tmpRow, array_map(fn ($v): array => ['data' => $this->emptyCells], $missingKeys)); // order keys by $keyIndex values - uksort($tmpRow, static fn ($k1, $k2) => $keyIndex[$k1] <=> $keyIndex[$k2]); + uksort($tmpRow, static fn ($k1, $k2): int => $keyIndex[$k1] <=> $keyIndex[$k2]); } $this->rows[] = $tmpRow; diff --git a/tests/_support/Config/Routes.php b/tests/_support/Config/Routes.php index 9b3ead4fd65f..c6286056e017 100644 --- a/tests/_support/Config/Routes.php +++ b/tests/_support/Config/Routes.php @@ -15,7 +15,7 @@ // This is a simple file to include for testing the RouteCollection class. $routes->add('testing', 'TestController::index', ['as' => 'testing-index']); -$routes->get('closure', static fn () => 'closure test'); +$routes->get('closure', static fn (): string => 'closure test'); $routes->get('/', 'Blog::index', ['hostname' => 'blog.example.com']); $routes->get('/', 'Sub::index', ['subdomain' => 'sub']); $routes->get('/all', 'AllDomain::index', ['subdomain' => '*']); diff --git a/tests/system/AutoReview/FrameworkCodeTest.php b/tests/system/AutoReview/FrameworkCodeTest.php index b8b155bbbf28..7473d26e5880 100644 --- a/tests/system/AutoReview/FrameworkCodeTest.php +++ b/tests/system/AutoReview/FrameworkCodeTest.php @@ -136,7 +136,7 @@ static function (SplFileInfo $file) use ($directory): string { $testClasses = array_filter( $testClasses, - static fn (string $class) => is_subclass_of($class, TestCase::class) + static fn (string $class): bool => is_subclass_of($class, TestCase::class) ); sort($testClasses); diff --git a/tests/system/Cache/Handlers/DummyHandlerTest.php b/tests/system/Cache/Handlers/DummyHandlerTest.php index 1b6fa3aa773a..c9c8a0fa0937 100644 --- a/tests/system/Cache/Handlers/DummyHandlerTest.php +++ b/tests/system/Cache/Handlers/DummyHandlerTest.php @@ -42,7 +42,7 @@ public function testGet(): void public function testRemember(): void { - $dummyHandler = $this->handler->remember('key', 2, static fn () => 'value'); + $dummyHandler = $this->handler->remember('key', 2, static fn (): string => 'value'); $this->assertNull($dummyHandler); } diff --git a/tests/system/Cache/Handlers/FileHandlerTest.php b/tests/system/Cache/Handlers/FileHandlerTest.php index 9a7213374dd2..47223198caad 100644 --- a/tests/system/Cache/Handlers/FileHandlerTest.php +++ b/tests/system/Cache/Handlers/FileHandlerTest.php @@ -135,7 +135,7 @@ public function testGet(): void */ public function testRemember(): void { - $this->handler->remember(self::$key1, 2, static fn () => 'value'); + $this->handler->remember(self::$key1, 2, static fn (): string => 'value'); $this->assertSame('value', $this->handler->get(self::$key1)); $this->assertNull($this->handler->get(self::$dummy)); diff --git a/tests/system/Cache/Handlers/MemcachedHandlerTest.php b/tests/system/Cache/Handlers/MemcachedHandlerTest.php index 45a44b64feff..36c8c220aa31 100644 --- a/tests/system/Cache/Handlers/MemcachedHandlerTest.php +++ b/tests/system/Cache/Handlers/MemcachedHandlerTest.php @@ -86,7 +86,7 @@ public function testGet(): void */ public function testRemember(): void { - $this->handler->remember(self::$key1, 2, static fn () => 'value'); + $this->handler->remember(self::$key1, 2, static fn (): string => 'value'); $this->assertSame('value', $this->handler->get(self::$key1)); $this->assertNull($this->handler->get(self::$dummy)); diff --git a/tests/system/Cache/Handlers/PredisHandlerTest.php b/tests/system/Cache/Handlers/PredisHandlerTest.php index 6d88d6e3f609..9b11c23b0683 100644 --- a/tests/system/Cache/Handlers/PredisHandlerTest.php +++ b/tests/system/Cache/Handlers/PredisHandlerTest.php @@ -91,7 +91,7 @@ public function testGet(): void */ public function testRemember(): void { - $this->handler->remember(self::$key1, 2, static fn () => 'value'); + $this->handler->remember(self::$key1, 2, static fn (): string => 'value'); $this->assertSame('value', $this->handler->get(self::$key1)); $this->assertNull($this->handler->get(self::$dummy)); diff --git a/tests/system/Cache/Handlers/RedisHandlerTest.php b/tests/system/Cache/Handlers/RedisHandlerTest.php index 8aa2339b06f8..0eee45f5704f 100644 --- a/tests/system/Cache/Handlers/RedisHandlerTest.php +++ b/tests/system/Cache/Handlers/RedisHandlerTest.php @@ -97,7 +97,7 @@ public function testGet(): void */ public function testRemember(): void { - $this->handler->remember(self::$key1, 2, static fn () => 'value'); + $this->handler->remember(self::$key1, 2, static fn (): string => 'value'); $this->assertSame('value', $this->handler->get(self::$key1)); $this->assertNull($this->handler->get(self::$dummy)); diff --git a/tests/system/CodeIgniterTest.php b/tests/system/CodeIgniterTest.php index 735aed389552..afddc7dbb30e 100644 --- a/tests/system/CodeIgniterTest.php +++ b/tests/system/CodeIgniterTest.php @@ -214,7 +214,7 @@ public function testControllersCanReturnString(): void $routes = service('routes'); $routes->add( 'pages/(:segment)', - static fn ($segment) => 'You want to see "' . esc($segment) . '" page.' + static fn ($segment): string => 'You want to see "' . esc($segment) . '" page.' ); $router = service('router', $routes, service('incomingrequest')); Services::injectMock('router', $router); diff --git a/tests/system/Database/Builder/UnionTest.php b/tests/system/Database/Builder/UnionTest.php index bd498e2e2cab..5711c6c3cbf7 100644 --- a/tests/system/Database/Builder/UnionTest.php +++ b/tests/system/Database/Builder/UnionTest.php @@ -47,7 +47,7 @@ public function testUnion(): void $builder = $this->db->table('test'); - $builder->union(static fn ($builder) => $builder->from('test')); + $builder->union(static fn ($builder): BaseBuilder => $builder->from('test')); $this->assertSame($expected, $this->buildSelect($builder)); } @@ -85,7 +85,7 @@ public function testUnionSQLSRV(): void $builder = $db->table('users'); - $builder->union(static fn ($builder) => $builder->from('users')); + $builder->union(static fn ($builder): BaseBuilder => $builder->from('users')); $this->assertSame($expected, $this->buildSelect($builder)); } diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index 16ea6b528c89..8f76efd12b42 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -1707,7 +1707,7 @@ public function testProcessIndexes(): void // check that db_actions_name key exists $indexes = array_filter( $allIndexes, - static fn ($index) => ($index->name === 'db_actions_name') + static fn ($index): bool => ($index->name === 'db_actions_name') && ($index->fields === [0 => 'name']) ); $this->assertCount(1, $indexes); @@ -1715,7 +1715,7 @@ public function testProcessIndexes(): void // check that db_actions_category_name key exists $indexes = array_filter( $allIndexes, - static fn ($index) => ($index->name === 'db_actions_category_name') + static fn ($index): bool => ($index->name === 'db_actions_category_name') && ($index->fields === [0 => 'category', 1 => 'name']) ); $this->assertCount(1, $indexes); @@ -1723,7 +1723,7 @@ public function testProcessIndexes(): void // check that the primary key exists $indexes = array_filter( $allIndexes, - static fn ($index) => $index->type === 'PRIMARY' + static fn ($index): bool => $index->type === 'PRIMARY' ); $this->assertCount(1, $indexes); @@ -1755,7 +1755,7 @@ public function testProcessIndexesWithKeyOnly(): void // check that db_actions_name key exists $indexes = array_filter( $allIndexes, - static fn ($index) => ($index->name === 'db_actions_name') + static fn ($index): bool => ($index->name === 'db_actions_name') && ($index->fields === [0 => 'name']) ); $this->assertCount(1, $indexes); @@ -1781,7 +1781,7 @@ public function testProcessIndexesWithPrimaryKeyOnly(): void // check that the primary key exists $indexes = array_filter( $allIndexes, - static fn ($index) => $index->type === 'PRIMARY' + static fn ($index): bool => $index->type === 'PRIMARY' ); $this->assertCount(1, $indexes); diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 09bf0d535bee..c7b02678e4fd 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -157,7 +157,7 @@ public function testRecordFunctionWithReturn(): void public function testRecordArrowFunction(): void { $timer = new Timer(); - $returnValue = $timer->record('longjohn', static fn () => strlen('CI4')); + $returnValue = $timer->record('longjohn', static fn (): int => strlen('CI4')); $this->assertLessThan(0.1, $timer->getElapsedTime('longjohn')); $this->assertSame(3, $returnValue); @@ -196,7 +196,7 @@ public function testCommonWithNameExpectTimer(): void public function testCommonNoNameCallableExpectTimer(): void { - $returnValue = timer(null, static fn () => strlen('CI4')); + $returnValue = timer(null, static fn (): int => strlen('CI4')); $this->assertInstanceOf(Timer::class, $returnValue); } @@ -212,7 +212,7 @@ public function testCommonCallableExpectNoReturn(): void public function testCommonCallableExpectWithReturn(): void { - $returnValue = timer('common', static fn () => strlen('CI4')); + $returnValue = timer('common', static fn (): int => strlen('CI4')); $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertSame(3, $returnValue); diff --git a/tests/system/HTTP/ContentSecurityPolicyTest.php b/tests/system/HTTP/ContentSecurityPolicyTest.php index 596fbfcf0b24..c1d90554fc7c 100644 --- a/tests/system/HTTP/ContentSecurityPolicyTest.php +++ b/tests/system/HTTP/ContentSecurityPolicyTest.php @@ -441,7 +441,7 @@ public function testBodyScriptNonce(): void $result = $this->work($body); $nonceStyle = array_filter( $this->getPrivateProperty($this->csp, 'styleSrc'), - static fn ($value) => str_starts_with($value, 'nonce-') + static fn ($value): bool => str_starts_with($value, 'nonce-') ); $this->assertStringContainsString('nonce=', $this->response->getBody()); @@ -516,7 +516,7 @@ public function testBodyStyleNonce(): void $result = $this->work($body); $nonceScript = array_filter( $this->getPrivateProperty($this->csp, 'scriptSrc'), - static fn ($value) => str_starts_with($value, 'nonce-') + static fn ($value): bool => str_starts_with($value, 'nonce-') ); $this->assertStringContainsString('nonce=', $this->response->getBody()); diff --git a/tests/system/Router/DefinedRouteCollectorTest.php b/tests/system/Router/DefinedRouteCollectorTest.php index 3c1d29abc023..2ec354c88893 100644 --- a/tests/system/Router/DefinedRouteCollectorTest.php +++ b/tests/system/Router/DefinedRouteCollectorTest.php @@ -51,8 +51,8 @@ public function testCollect(): void $routes->get('journals', 'Blogs'); $routes->get('100', 'Home::index'); $routes->get('product/(:num)', 'Catalog::productLookupByID/$1'); - $routes->get('feed', static fn () => 'A Closure route.'); - $routes->get('200', static fn () => 'A Closure route.'); + $routes->get('feed', static fn (): string => 'A Closure route.'); + $routes->get('200', static fn (): string => 'A Closure route.'); $routes->view('about', 'pages/about'); $collector = new DefinedRouteCollector($routes); diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index 5ce347e07f4c..4ad823dda8c3 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -68,8 +68,8 @@ private function createRouteCollection(?Routing $routingConfig = null): void 'posts/(:num)' => 'Blog::show/$1', 'posts/(:num)/edit' => 'Blog::edit/$1', 'books/(:num)/(:alpha)/(:num)' => 'Blog::show/$3/$1', - 'closure/(:num)/(:alpha)' => static fn ($num, $str) => $num . '-' . $str, - 'closure-dash/(:num)/(:alpha)' => static fn ($num, $str) => $num . '-' . $str, + 'closure/(:num)/(:alpha)' => static fn ($num, $str): string => $num . '-' . $str, + 'closure-dash/(:num)/(:alpha)' => static fn ($num, $str): string => $num . '-' . $str, '{locale}/pages' => 'App\Pages::list_all', 'test/(:any)/lang/{locale}' => 'App\Pages::list_all', 'admin/admins' => 'App\Admin\Admins::list_all', diff --git a/tests/system/Test/FeatureTestTraitTest.php b/tests/system/Test/FeatureTestTraitTest.php index 47aaea07d1d6..349d1af233b9 100644 --- a/tests/system/Test/FeatureTestTraitTest.php +++ b/tests/system/Test/FeatureTestTraitTest.php @@ -54,7 +54,7 @@ public function testCallGet(): void [ 'GET', 'home', - static fn () => 'Hello World', + static fn (): string => 'Hello World', ], ]); $response = $this->get('home'); @@ -74,7 +74,7 @@ public function testCallGetAndUriString(): void [ 'GET', 'foo/bar/1/2/3', - static fn () => 'Hello World', + static fn (): string => 'Hello World', ], ]); $response = $this->get('foo/bar/1/2/3'); @@ -90,7 +90,7 @@ public function testCallGetAndFilterReturnsResponse(): void [ 'GET', 'admin', - static fn () => 'Admin Area', + static fn (): string => 'Admin Area', ['filter' => 'test-redirectfilter'], ], ]); @@ -123,7 +123,7 @@ public function testCallPost(): void [ 'POST', 'home', - static fn () => 'Hello Mars', + static fn (): string => 'Hello Mars', ], ]); $response = $this->post('home'); @@ -137,7 +137,7 @@ public function testCallPostWithBody(): void [ 'POST', 'home', - static fn () => 'Hello ' . service('request')->getPost('foo') . '!', + static fn (): string => 'Hello ' . service('request')->getPost('foo') . '!', ], ]); $response = $this->post('home', ['foo' => 'Mars']); @@ -181,7 +181,7 @@ public function testCallPut(): void [ 'PUT', 'home', - static fn () => 'Hello Pluto', + static fn (): string => 'Hello Pluto', ], ]); $response = $this->put('home'); @@ -195,7 +195,7 @@ public function testCallPatch(): void [ 'PATCH', 'home', - static fn () => 'Hello Jupiter', + static fn (): string => 'Hello Jupiter', ], ]); $response = $this->patch('home'); @@ -209,7 +209,7 @@ public function testCallOptions(): void [ 'OPTIONS', 'home', - static fn () => 'Hello George', + static fn (): string => 'Hello George', ], ]); $response = $this->options('home'); @@ -223,7 +223,7 @@ public function testCallDelete(): void [ 'DELETE', 'home', - static fn () => 'Hello Wonka', + static fn (): string => 'Hello Wonka', ], ]); $response = $this->delete('home'); @@ -237,7 +237,7 @@ public function testSession(): void [ 'GET', 'home', - static fn () => 'Home', + static fn (): string => 'Home', ], ])->withSession([ 'fruit' => 'apple', @@ -259,7 +259,7 @@ public function testWithSessionNull(): void [ 'GET', 'home', - static fn () => 'Home', + static fn (): string => 'Home', ], ])->withSession()->get('home'); diff --git a/tests/system/Validation/RulesTest.php b/tests/system/Validation/RulesTest.php index a7e3e985de87..b0b23c00f686 100644 --- a/tests/system/Validation/RulesTest.php +++ b/tests/system/Validation/RulesTest.php @@ -119,7 +119,7 @@ public static function provideIfExist(): iterable ], // Testing with closure [ - ['foo' => ['if_exist', static fn ($value) => true]], + ['foo' => ['if_exist', static fn ($value): bool => true]], ['foo' => []], true, ], @@ -299,7 +299,7 @@ public static function providePermitEmpty(): iterable ], [ // Testing with closure - ['foo' => ['permit_empty', static fn ($value) => true]], + ['foo' => ['permit_empty', static fn ($value): bool => true]], ['foo' => ''], true, ], diff --git a/tests/system/Validation/StrictRules/RulesTest.php b/tests/system/Validation/StrictRules/RulesTest.php index 7589360d0efe..de06bfe576ec 100644 --- a/tests/system/Validation/StrictRules/RulesTest.php +++ b/tests/system/Validation/StrictRules/RulesTest.php @@ -91,7 +91,7 @@ public static function providePermitEmptyStrict(): iterable ], // Testing with closure [ - ['foo' => ['permit_empty', static fn ($value) => true]], + ['foo' => ['permit_empty', static fn ($value): bool => true]], ['foo' => ''], true, ], diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index 5906e2ac5465..f6d7252dc1ff 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -284,7 +284,7 @@ public function testClosureRule(): void { $this->validation->setRules( [ - 'foo' => ['required', static fn ($value) => $value === 'abc'], + 'foo' => ['required', static fn ($value): bool => $value === 'abc'], ], [ // Errors @@ -339,7 +339,7 @@ public function testClosureRuleWithLabel(): void $this->validation->setRules([ 'secret' => [ 'label' => 'シークレット', - 'rules' => ['required', static fn ($value) => $value === 'abc'], + 'rules' => ['required', static fn ($value): bool => $value === 'abc'], 'errors' => [ // Specify the array key for the closure rule. 1 => 'The {field} is invalid', diff --git a/tests/system/View/ParserTest.php b/tests/system/View/ParserTest.php index 33ff7880f893..27a3100ce862 100644 --- a/tests/system/View/ParserTest.php +++ b/tests/system/View/ParserTest.php @@ -797,7 +797,7 @@ public function testParserPluginNoParams(): void public function testParserPluginClosure(): void { $config = $this->config; - $config->plugins['hello'] = static fn (array $params = []) => 'Hello, ' . trim($params[0]); + $config->plugins['hello'] = static fn (array $params = []): string => 'Hello, ' . trim($params[0]); $this->parser = new Parser($config, $this->viewsDir, $this->loader); @@ -828,7 +828,7 @@ public function testParserPluginParams(): void public function testParserSingleTag(): void { - $this->parser->addPlugin('hit:it', static fn () => 'Hip to the Hop', false); + $this->parser->addPlugin('hit:it', static fn (): string => 'Hip to the Hop', false); $template = '{+ hit:it +}'; @@ -837,7 +837,7 @@ public function testParserSingleTag(): void public function testParserSingleTagWithParams(): void { - $this->parser->addPlugin('hit:it', static fn (array $params = []) => "{$params['first']} to the {$params['last']}", false); + $this->parser->addPlugin('hit:it', static fn (array $params = []): string => "{$params['first']} to the {$params['last']}", false); $template = '{+ hit:it first=foo last=bar +}'; @@ -846,7 +846,7 @@ public function testParserSingleTagWithParams(): void public function testParserSingleTagWithSingleParams(): void { - $this->parser->addPlugin('hit:it', static fn (array $params = []) => "{$params[0]} to the {$params[1]}", false); + $this->parser->addPlugin('hit:it', static fn (array $params = []): string => "{$params[0]} to the {$params[1]}", false); $template = '{+ hit:it foo bar +}'; From f29210c0f0ef4c4096d4ac937f1e422ef769673f Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 29 Dec 2024 01:13:34 +0700 Subject: [PATCH 02/11] refactor: use compare equals 1 for preg_match() return on array_filter --- system/Helpers/form_helper.php | 4 ++-- system/Validation/Validation.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php index 6e77a1f36b0c..679008c9731a 100644 --- a/system/Helpers/form_helper.php +++ b/system/Helpers/form_helper.php @@ -739,10 +739,10 @@ function validation_show_error(string $field, string $template = 'single'): stri $config = config(Validation::class); $view = service('renderer'); - $errors = array_filter(validation_errors(), static fn ($key): false|int => preg_match( + $errors = array_filter(validation_errors(), static fn ($key): bool => preg_match( '/^' . str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/')) . '$/', $key - ), ARRAY_FILTER_USE_KEY); + ) === 1, ARRAY_FILTER_USE_KEY); if ($errors === []) { return ''; diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index 93524663947e..5b51b403fef9 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -176,7 +176,7 @@ public function run(?array $data = null, ?string $group = null, $dbGroup = null) $values = array_filter( $flattenedArray, - static fn ($key): false|int => preg_match(self::getRegex($field), $key), + static fn ($key): bool => preg_match(self::getRegex($field), $key) === 1, ARRAY_FILTER_USE_KEY ); @@ -867,7 +867,7 @@ public function getError(?string $field = null): string $errors = array_filter( $this->getErrors(), - static fn ($key): false|int => preg_match(self::getRegex($field), $key), + static fn ($key): bool => preg_match(self::getRegex($field), $key) === 1, ARRAY_FILTER_USE_KEY ); From 47d69b6080d565847e8e1c0353934fee31a55615 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 29 Dec 2024 01:15:51 +0700 Subject: [PATCH 03/11] refactor: update var_export() return --- app/Views/errors/cli/error_exception.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php index d551b3317c89..624f3b5b0600 100644 --- a/app/Views/errors/cli/error_exception.php +++ b/app/Views/errors/cli/error_exception.php @@ -50,7 +50,7 @@ $function .= $padClass . $error['function']; } - $args = implode(', ', array_map(static fn ($value): ?string => match (true) { + $args = implode(', ', array_map(static fn ($value): string => match (true) { is_object($value) => 'Object(' . $value::class . ')', is_array($value) => $value !== [] ? '[...]' : '[]', $value === null => 'null', // return the lowercased version From 0bc67dbb21ee54dff7db871f70684f32f392600d Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Sun, 29 Dec 2024 15:53:24 +0800 Subject: [PATCH 04/11] docs: add changelog and upgrade for v4.5.7 (#9347) --- user_guide_src/source/changelogs/index.rst | 1 + user_guide_src/source/changelogs/v4.5.7.rst | 35 ++++++++++++ .../source/installation/upgrade_457.rst | 55 +++++++++++++++++++ .../source/installation/upgrading.rst | 1 + 4 files changed, 92 insertions(+) create mode 100644 user_guide_src/source/changelogs/v4.5.7.rst create mode 100644 user_guide_src/source/installation/upgrade_457.rst diff --git a/user_guide_src/source/changelogs/index.rst b/user_guide_src/source/changelogs/index.rst index a4d102ada233..e4185217c9c6 100644 --- a/user_guide_src/source/changelogs/index.rst +++ b/user_guide_src/source/changelogs/index.rst @@ -12,6 +12,7 @@ See all the changes. .. toctree:: :titlesonly: + v4.5.7 v4.5.6 v4.5.5 v4.5.4 diff --git a/user_guide_src/source/changelogs/v4.5.7.rst b/user_guide_src/source/changelogs/v4.5.7.rst new file mode 100644 index 000000000000..27a12a74f07d --- /dev/null +++ b/user_guide_src/source/changelogs/v4.5.7.rst @@ -0,0 +1,35 @@ +############# +Version 4.5.7 +############# + +Release Date: Unreleased + +**4.5.7 release of CodeIgniter4** + +.. contents:: + :local: + :depth: 3 + +******** +BREAKING +******** + +*************** +Message Changes +*************** + +******* +Changes +******* + +************ +Deprecations +************ + +********** +Bugs Fixed +********** + +See the repo's +`CHANGELOG.md `_ +for a complete list of bugs fixed. diff --git a/user_guide_src/source/installation/upgrade_457.rst b/user_guide_src/source/installation/upgrade_457.rst new file mode 100644 index 000000000000..9503867f1cd2 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_457.rst @@ -0,0 +1,55 @@ +############################# +Upgrading from 4.5.6 to 4.5.7 +############################# + +Please refer to the upgrade instructions corresponding to your installation method. + +- :ref:`Composer Installation App Starter Upgrading ` +- :ref:`Composer Installation Adding CodeIgniter4 to an Existing Project Upgrading ` +- :ref:`Manual Installation Upgrading ` + +.. contents:: + :local: + :depth: 2 + +********************** +Mandatory File Changes +********************** + +**************** +Breaking Changes +**************** + +********************* +Breaking Enhancements +********************* + +************* +Project Files +************* + +Some files in the **project space** (root, app, public, writable) received updates. Due to +these files being outside of the **system** scope they will not be changed without your intervention. + +.. note:: There are some third-party CodeIgniter modules available to assist + with merging changes to the project space: + `Explore on Packagist `_. + +Content Changes +=============== + +The following files received significant changes (including deprecations or visual adjustments) +and it is recommended that you merge the updated versions with your application: + +Config +------ + +- @TODO + +All Changes +=========== + +This is a list of all files in the **project space** that received changes; +many will be simple comments or formatting that have no effect on the runtime: + +- @TODO diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst index 0b489abb9101..a8dffd3660dd 100644 --- a/user_guide_src/source/installation/upgrading.rst +++ b/user_guide_src/source/installation/upgrading.rst @@ -16,6 +16,7 @@ See also :doc:`./backward_compatibility_notes`. backward_compatibility_notes + upgrade_457 upgrade_456 upgrade_455 upgrade_454 From 65219d74d0169f9f5018e692129910530ba5a9b3 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Mon, 30 Dec 2024 21:06:37 +0800 Subject: [PATCH 05/11] style: bump to php-cs-fixer v3.66 --- user_guide_src/source/database/queries/016.php | 12 +++++------- user_guide_src/source/database/queries/019.php | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/user_guide_src/source/database/queries/016.php b/user_guide_src/source/database/queries/016.php index f674f7c7ccce..61c743fdfd06 100644 --- a/user_guide_src/source/database/queries/016.php +++ b/user_guide_src/source/database/queries/016.php @@ -1,9 +1,7 @@ prepare(static function ($db) { - return $db->table('user')->insert([ - 'name' => 'x', - 'email' => 'y', - 'country' => 'US', - ]); -}); +$pQuery = $db->prepare(static fn ($db) => $db->table('user')->insert([ + 'name' => 'x', + 'email' => 'y', + 'country' => 'US', +])); diff --git a/user_guide_src/source/database/queries/019.php b/user_guide_src/source/database/queries/019.php index 28729f2e484a..8157a5d0f4a9 100644 --- a/user_guide_src/source/database/queries/019.php +++ b/user_guide_src/source/database/queries/019.php @@ -1,13 +1,11 @@ prepare(static function ($db) { - return $db->table('user')->insert([ - 'name' => 'x', - 'email' => 'y', - 'country' => 'US', - ]); -}); +$pQuery = $db->prepare(static fn ($db) => $db->table('user')->insert([ + 'name' => 'x', + 'email' => 'y', + 'country' => 'US', +])); // Collect the Data $name = 'John Doe'; From f551dbd0adc34f94d0131c095497242dfdec5b7c Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 30 Dec 2024 20:59:00 +0700 Subject: [PATCH 06/11] fix: handle namespaced helper found on Common helper --- system/Common.php | 2 +- tests/system/CommonHelperTest.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/system/Common.php b/system/Common.php index b647c9d247ad..d5880acf0363 100644 --- a/system/Common.php +++ b/system/Common.php @@ -598,7 +598,7 @@ function helper($filenames): void if (str_contains($filename, '\\')) { $path = $loader->locateFile($filename, 'Helpers'); - if ($path !== '') { + if ($path === false) { throw FileNotFoundException::forFileNotFound($filename); } diff --git a/tests/system/CommonHelperTest.php b/tests/system/CommonHelperTest.php index db304ecfdb70..8a41f7972a9e 100644 --- a/tests/system/CommonHelperTest.php +++ b/tests/system/CommonHelperTest.php @@ -13,7 +13,9 @@ namespace CodeIgniter; +use CodeIgniter\Autoloader\Autoloader; use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Files\Exceptions\FileNotFoundException; use CodeIgniter\Test\CIUnitTestCase; use Config\Services; use PHPUnit\Framework\Attributes\CoversFunction; @@ -148,4 +150,33 @@ function foo_bar_baz(): string $this->assertSame($this->dummyHelpers[0], foo_bar_baz()); } + + public function testNamespacedHelperNotFound(): void + { + $this->expectException(FileNotFoundException::class); + + $locator = $this->getMockLocator(); + Services::injectMock('locator', $locator); + + helper('foo\barbaz'); + } + + public function testNamespacedHelperFound(): void + { + $autoloader = new Autoloader(); + $autoloader->addNamespace('Tests\Support\Helpers', TESTPATH . '_support/Helpers'); + $locator = new FileLocator($autoloader); + + Services::injectMock('locator', $locator); + + $found = true; + + try { + helper('Tests\Support\Helpers\baguette'); + } catch (FileNotFoundException) { + $found = false; + } + + $this->assertTrue($found); + } } From c61cb4a839bc8dafbc5c72575a086adc53d89b40 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 30 Dec 2024 21:29:32 +0700 Subject: [PATCH 07/11] chore: add changelog for bug fix helper() throw FileNotFoundException on valid namespaced helper --- user_guide_src/source/changelogs/v4.5.7.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_guide_src/source/changelogs/v4.5.7.rst b/user_guide_src/source/changelogs/v4.5.7.rst index 27a12a74f07d..f396510b1366 100644 --- a/user_guide_src/source/changelogs/v4.5.7.rst +++ b/user_guide_src/source/changelogs/v4.5.7.rst @@ -30,6 +30,8 @@ Deprecations Bugs Fixed ********** +- **Common:** Fixed a bug where the ``helper()`` method throw `FileNotFoundException` on valid namespaced helper. + See the repo's `CHANGELOG.md `_ for a complete list of bugs fixed. From c942fd9e0b4b37bc9df81b46cac2a22b1c1e9d26 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 30 Dec 2024 21:33:16 +0700 Subject: [PATCH 08/11] Update user_guide_src/source/changelogs/v4.5.7.rst Co-authored-by: John Paul E. Balandan, CPA --- user_guide_src/source/changelogs/v4.5.7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/changelogs/v4.5.7.rst b/user_guide_src/source/changelogs/v4.5.7.rst index f396510b1366..b196c5f5fffe 100644 --- a/user_guide_src/source/changelogs/v4.5.7.rst +++ b/user_guide_src/source/changelogs/v4.5.7.rst @@ -30,7 +30,7 @@ Deprecations Bugs Fixed ********** -- **Common:** Fixed a bug where the ``helper()`` method throw `FileNotFoundException` on valid namespaced helper. +- **Common:** Fixed a bug where the ``helper()`` method may throw `FileNotFoundException` on valid namespaced helper. See the repo's `CHANGELOG.md `_ From 0fe4bd0ca24125c79976ce4f305070d7d231c9b7 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Tue, 31 Dec 2024 16:49:06 +0800 Subject: [PATCH 09/11] chore: clean up issue templates (#9355) --- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 11 ------ .github/ISSUE_TEMPLATE/planned-work.md | 4 +-- .github/mergeable.yml | 41 +++++++++++++++++++++++ 4 files changed, 44 insertions(+), 14 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/mergeable.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 9bec3b2d3431..d399e41dca3e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,7 @@ blank_issues_enabled: false contact_links: - name: CodeIgniter Forum url: https://forum.codeigniter.com/forum-30.html - about: Please ask your support questions in the forums. Thanks! + about: Please ask your support questions and/or feature requests in the forums. Thanks! - name: CodeIgniter Slack channel url: https://codeigniterchat.slack.com diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 3bd2d0a6c44f..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: Feature request -about: How to submit a feature request -title: '' -labels: '' -assignees: '' - ---- - -Please submit feature requests to our [forum](https://forum.codeigniter.com/forum-29.html). -We use github issues to track bugs and planned work. diff --git a/.github/ISSUE_TEMPLATE/planned-work.md b/.github/ISSUE_TEMPLATE/planned-work.md index 4faa45ed874e..3da11a7dbc58 100644 --- a/.github/ISSUE_TEMPLATE/planned-work.md +++ b/.github/ISSUE_TEMPLATE/planned-work.md @@ -1,10 +1,10 @@ --- name: Planned work -about: Approved work planning +about: Maintainers' space. DO NOT use this for your bug reports! title: 'Dev: ' labels: dev assignees: '' --- -Repo maintainers will create "issues" for planned work, so it can be tracked. +Maintainers will create "issues" for planned work, so it can be tracked. diff --git a/.github/mergeable.yml b/.github/mergeable.yml new file mode 100644 index 000000000000..d23053efa3e2 --- /dev/null +++ b/.github/mergeable.yml @@ -0,0 +1,41 @@ +# https://mergeable.readthedocs.io/en/latest/configuration.html + +version: 2 +mergeable: + - when: issues.opened + validate: + - do: description + and: + - must_include: + regex: '^### PHP Version' + - must_include: + regex: '^### CodeIgniter4 Version' + - do: author + and: + - must_exclude: + regex: 'kenjis' + - must_exclude: + regex: 'lonnieezell' + - must_exclude: + regex: 'MGatner' + - must_exclude: + regex: 'michalsn' + - must_exclude: + regex: 'paulbalandan' + - must_exclude: + regex: 'samsonasik' + fail: + - do: comment + payload: | + Hi there! :wave: + + It looks like you opened an issue without following the bug report template: + + Bug report ([open an issue](https://github.com/codeigniter4/CodeIgniter4/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=Bug%3A+)) + + If you are opening a feature request or support question, please do so in the [forums](https://forum.codeigniter.com/forum-30.html). + + The current issue will be closed. This is a precaution to save maintainers' time, I hope you'll understand. + + Sincerely, the mergeable bot 🤖 + - do: close From d7ce2ba7d304f5cb84148c68174d5251581009d7 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Tue, 31 Dec 2024 18:41:07 +0800 Subject: [PATCH 10/11] fix: `Forge::dropColumn()` always returns `false` on SQLite3 driver (#9351) --- system/Database/Forge.php | 2 +- system/Database/SQLite3/Forge.php | 36 +++++++++++++------ tests/system/Database/Live/ForgeTest.php | 3 +- user_guide_src/source/changelogs/v4.5.7.rst | 1 + .../missingType.iterableValue.neon | 7 +--- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/system/Database/Forge.php b/system/Database/Forge.php index b41b8f34f8c8..974c45848d1c 100644 --- a/system/Database/Forge.php +++ b/system/Database/Forge.php @@ -778,7 +778,7 @@ public function addColumn(string $table, $fields): bool } /** - * @param array|string $columnNames column names to DROP + * @param list|string $columnNames column names to DROP * * @return bool * diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php index 48e9abcc425c..03120dd7a0da 100644 --- a/system/Database/SQLite3/Forge.php +++ b/system/Database/SQLite3/Forge.php @@ -110,6 +110,31 @@ public function dropDatabase(string $dbName): bool return true; } + /** + * @param list|string $columnNames + * + * @throws DatabaseException + */ + public function dropColumn(string $table, $columnNames): bool + { + $columns = is_array($columnNames) ? $columnNames : array_map(trim(...), explode(',', $columnNames)); + $result = (new Table($this->db, $this)) + ->fromTable($this->db->DBPrefix . $table) + ->dropColumn($columns) + ->run(); + + if (! $result && $this->db->DBDebug) { + throw new DatabaseException(sprintf( + 'Failed to drop column%s "%s" on "%s" table.', + count($columns) > 1 ? 's' : '', + implode('", "', $columns), + $table, + )); + } + + return $result; + } + /** * @param array|string $processedFields Processed column definitions * or column names to DROP @@ -121,17 +146,6 @@ public function dropDatabase(string $dbName): bool protected function _alterTable(string $alterType, string $table, $processedFields) { switch ($alterType) { - case 'DROP': - $columnNamesToDrop = $processedFields; - - $sqlTable = new Table($this->db, $this); - - $sqlTable->fromTable($table) - ->dropColumn($columnNamesToDrop) - ->run(); - - return ''; // Why empty string? - case 'CHANGE': $fieldsToModify = []; diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index 8f76efd12b42..0ab672e72067 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -1319,8 +1319,7 @@ public function testDropColumn(): void $this->forge->createTable('forge_test_two'); $this->assertTrue($this->db->fieldExists('name', 'forge_test_two')); - - $this->forge->dropColumn('forge_test_two', 'name'); + $this->assertTrue($this->forge->dropColumn('forge_test_two', 'name')); $this->db->resetDataCache(); diff --git a/user_guide_src/source/changelogs/v4.5.7.rst b/user_guide_src/source/changelogs/v4.5.7.rst index b196c5f5fffe..fc36acf3b314 100644 --- a/user_guide_src/source/changelogs/v4.5.7.rst +++ b/user_guide_src/source/changelogs/v4.5.7.rst @@ -31,6 +31,7 @@ Bugs Fixed ********** - **Common:** Fixed a bug where the ``helper()`` method may throw `FileNotFoundException` on valid namespaced helper. +- **Forge:** Fixed an issue where `SQLite3`'s Forge always returns `false` when calling ``dropColumn()``. See the repo's `CHANGELOG.md `_ diff --git a/utils/phpstan-baseline/missingType.iterableValue.neon b/utils/phpstan-baseline/missingType.iterableValue.neon index 812228800d8f..6abf970718c7 100644 --- a/utils/phpstan-baseline/missingType.iterableValue.neon +++ b/utils/phpstan-baseline/missingType.iterableValue.neon @@ -1,4 +1,4 @@ -# total 1686 errors +# total 1685 errors parameters: ignoreErrors: @@ -1697,11 +1697,6 @@ parameters: count: 1 path: ../../system/Database/Forge.php - - - message: '#^Method CodeIgniter\\Database\\Forge\:\:dropColumn\(\) has parameter \$columnNames with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Database/Forge.php - - message: '#^Method CodeIgniter\\Database\\Forge\:\:modifyColumn\(\) has parameter \$fields with no value type specified in iterable type array\.$#' count: 1 From e8cd894fdf9ea51ea7373611aac039d4b545c6fd Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Tue, 31 Dec 2024 19:56:33 +0800 Subject: [PATCH 11/11] Prep for 4.5.7 release (#9357) --- CHANGELOG.md | 12 +++++++++ phpdoc.dist.xml | 2 +- system/CodeIgniter.php | 2 +- user_guide_src/source/changelogs/v4.5.7.rst | 18 +------------ user_guide_src/source/conf.py | 2 +- .../source/installation/upgrade_457.rst | 25 +------------------ 6 files changed, 17 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e423ad54d961..d31f829aec39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [v4.5.7](https://github.com/codeigniter4/CodeIgniter4/tree/v4.5.7) (2024-12-31) +[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.5.6...v4.5.7) + +### Fixed Bugs + +* fix: handle namespaced helper found on Common helper by @samsonasik in https://github.com/codeigniter4/CodeIgniter4/pull/9354 +* fix: `Forge::dropColumn()` always returns `false` on SQLite3 driver by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/9351 + +### Refactoring + +* refactor: enable AddArrowFunctionReturnTypeRector by @samsonasik in https://github.com/codeigniter4/CodeIgniter4/pull/9343 + ## [v4.5.6](https://github.com/codeigniter4/CodeIgniter4/tree/v4.5.6) (2024-12-28) [Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.5.5...v4.5.6) diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml index 686c89010971..5a287a06f294 100644 --- a/phpdoc.dist.xml +++ b/phpdoc.dist.xml @@ -10,7 +10,7 @@ api/build/ api/cache/ - + system diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index af1ef4ed1e25..e92a6a10ae8c 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -56,7 +56,7 @@ class CodeIgniter /** * The current version of CodeIgniter Framework */ - public const CI_VERSION = '4.5.6'; + public const CI_VERSION = '4.5.7'; /** * App startup time. diff --git a/user_guide_src/source/changelogs/v4.5.7.rst b/user_guide_src/source/changelogs/v4.5.7.rst index fc36acf3b314..b57dea4abca4 100644 --- a/user_guide_src/source/changelogs/v4.5.7.rst +++ b/user_guide_src/source/changelogs/v4.5.7.rst @@ -2,7 +2,7 @@ Version 4.5.7 ############# -Release Date: Unreleased +Release Date: December 31, 2024 **4.5.7 release of CodeIgniter4** @@ -10,22 +10,6 @@ Release Date: Unreleased :local: :depth: 3 -******** -BREAKING -******** - -*************** -Message Changes -*************** - -******* -Changes -******* - -************ -Deprecations -************ - ********** Bugs Fixed ********** diff --git a/user_guide_src/source/conf.py b/user_guide_src/source/conf.py index c5960c23a320..4effd4c7b822 100644 --- a/user_guide_src/source/conf.py +++ b/user_guide_src/source/conf.py @@ -26,7 +26,7 @@ version = '4.5' # The full version, including alpha/beta/rc tags. -release = '4.5.6' +release = '4.5.7' # -- General configuration --------------------------------------------------- diff --git a/user_guide_src/source/installation/upgrade_457.rst b/user_guide_src/source/installation/upgrade_457.rst index 9503867f1cd2..d919c81871f2 100644 --- a/user_guide_src/source/installation/upgrade_457.rst +++ b/user_guide_src/source/installation/upgrade_457.rst @@ -12,18 +12,6 @@ Please refer to the upgrade instructions corresponding to your installation meth :local: :depth: 2 -********************** -Mandatory File Changes -********************** - -**************** -Breaking Changes -**************** - -********************* -Breaking Enhancements -********************* - ************* Project Files ************* @@ -35,21 +23,10 @@ these files being outside of the **system** scope they will not be changed witho with merging changes to the project space: `Explore on Packagist `_. -Content Changes -=============== - -The following files received significant changes (including deprecations or visual adjustments) -and it is recommended that you merge the updated versions with your application: - -Config ------- - -- @TODO - All Changes =========== This is a list of all files in the **project space** that received changes; many will be simple comments or formatting that have no effect on the runtime: -- @TODO +- app/Views/errors/cli/error_exception.php