diff --git a/.github/workflows/deploy-apidocs.yml b/.github/workflows/deploy-apidocs.yml index b117e3dad72b..5675963ea24f 100644 --- a/.github/workflows/deploy-apidocs.yml +++ b/.github/workflows/deploy-apidocs.yml @@ -43,13 +43,13 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.0' + php-version: '8.1' tools: phive coverage: none - name: Download latest phpDocumentor working-directory: source - run: sudo phive --no-progress install --global --trust-gpg-keys 67F861C3D889C656 phpDocumentor + run: phive --no-progress install --trust-gpg-keys 8AC0BAA79732DD42 phpDocumentor - name: Prepare API repo working-directory: api @@ -61,7 +61,7 @@ jobs: - name: Build API in source repo working-directory: source run: | - phpDocumentor run --ansi --verbose + php tools/phpDocumentor run --ansi --verbose cp -R ${GITHUB_WORKSPACE}/source/api/build/* ${GITHUB_WORKSPACE}/api/docs - name: Deploy to API repo diff --git a/.github/workflows/test-autoreview.yml b/.github/workflows/test-autoreview.yml index dfe4892bdebe..21f885445b63 100644 --- a/.github/workflows/test-autoreview.yml +++ b/.github/workflows/test-autoreview.yml @@ -29,3 +29,79 @@ jobs: php-version: '8.1' job-id: auto-review-tests group-name: AutoReview + + composer-normalize-tests: + name: Check normalized composer.json + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + + - name: Install dependencies + run: composer update + + - name: Run on root composer.json + id: normalize-root-composer + if: ${{ always() }} + run: | + echo "ROOT_COMPOSER_RESULT<> $GITHUB_OUTPUT + echo "$(composer normalize)" >> $GITHUB_OUTPUT + echo "RCR" >> $GITHUB_OUTPUT + + - name: Run on framework composer.json + id: normalize-framework-composer + if: ${{ always() }} + working-directory: admin/framework + run: | + echo "FRAMEWORK_COMPOSER_RESULT<> $GITHUB_OUTPUT + echo "$(composer normalize)" >> $GITHUB_OUTPUT + echo "FCR" >> $GITHUB_OUTPUT + + - name: Run on starter composer.json + id: normalize-starter-composer + if: ${{ always() }} + working-directory: admin/starter + run: | + echo "STARTER_COMPOSER_RESULT<> $GITHUB_OUTPUT + echo "$(composer normalize)" >> $GITHUB_OUTPUT + echo "SCR" >> $GITHUB_OUTPUT + + - name: Analyse normalization results + run: | + if [[ '${{ steps.normalize-root-composer.conclusion }}' == 'failure' ]]; then + echo 'Normalization of root composer.json encountered a problem.'; + echo 'Please run it locally: `composer normalize`'; + exit 1; + fi + + if [[ ${{ contains(steps.normalize-root-composer.outputs.ROOT_COMPOSER_RESULT, 'Successfully normalized') }} == true ]]; then + echo 'Root composer.json is not yet normalized.'; + exit 1; + fi + + if [[ '${{ steps.normalize-framework-composer.conclusion }}' == 'failure' ]]; then + echo 'Normalization of framework composer.json encountered a problem.'; + echo 'Please run it locally: `composer normalize -d admin/framework`'; + exit 1; + fi + + if [[ ${{ contains(steps.normalize-framework-composer.outputs.FRAMEWORK_COMPOSER_RESULT, 'Successfully normalized') }} == true ]]; then + echo 'Framework composer.json is not yet normalized.'; + exit 1; + fi + + if [[ '${{ steps.normalize-starter-composer.conclusion }}' == 'failure' ]]; then + echo 'Normalization of starter composer.json encountered a problem.'; + echo 'Please run it locally: `composer normalize -d admin/starter`'; + exit 1; + fi + + if [[ ${{ contains(steps.normalize-starter-composer.outputs.STARTER_COMPOSER_RESULT, 'Successfully normalized') }} == true ]]; then + echo 'Starter composer.json is not yet normalized.'; + exit 1; + fi diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 3f9a0dd6f254..8c2a6b8b7a52 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -44,6 +44,11 @@ ]); $overrides = [ + 'php_unit_data_provider_name' => [ + 'prefix' => 'provide', + 'suffix' => '', + ], + 'php_unit_data_provider_static' => true, 'php_unit_data_provider_return_type' => true, 'no_extra_blank_lines' => [ 'tokens' => [ diff --git a/.php-cs-fixer.no-header.php b/.php-cs-fixer.no-header.php index 16271f3cb31c..5fb4ce95bfbe 100644 --- a/.php-cs-fixer.no-header.php +++ b/.php-cs-fixer.no-header.php @@ -30,6 +30,11 @@ ]); $overrides = [ + 'php_unit_data_provider_name' => [ + 'prefix' => 'provide', + 'suffix' => '', + ], + 'php_unit_data_provider_static' => true, 'php_unit_data_provider_return_type' => true, 'no_extra_blank_lines' => [ 'tokens' => [ diff --git a/.php-cs-fixer.user-guide.php b/.php-cs-fixer.user-guide.php index ef37d80386bd..cf344d903ad5 100644 --- a/.php-cs-fixer.user-guide.php +++ b/.php-cs-fixer.user-guide.php @@ -53,6 +53,11 @@ 'use', ], ], + 'php_unit_data_provider_static' => true, + 'php_unit_data_provider_name' => [ + 'prefix' => 'provide', + 'suffix' => '', + ], ]; $options = [ diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e1b5b00c029..b86b2969e642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## [v4.3.8](https://github.com/codeigniter4/CodeIgniter4/tree/v4.3.8) (2023-08-25) +[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.3.7...v4.3.8) + +### Fixed Bugs + +* fix: [Pager] knocks down variables for View by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7758 +* fix: Model::insertBatch() causes error to non auto increment table by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7759 +* fix: [Model] updateBatch() may generate invalid SQL statement by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7787 +* fix: Model inserts cast $primaryKey value when using Entity by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7806 +* fix: instances of Validation rules are incremented each time `run()` is executed by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7815 +* fix: filter except empty by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7823 +* fix: `set_checkbox()` checks unchecked checkbox by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7818 + +### Refactoring + +* Normalize data provider names by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/7656 +* refactor: remove Model::$tempPrimaryKeyValue by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/7760 +* Remove unused cast on RedisHandler by @samsonasik in https://github.com/codeigniter4/CodeIgniter4/pull/7786 + ## [v4.3.7](https://github.com/codeigniter4/CodeIgniter4/tree/v4.3.7) (2023-07-30) [Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.3.6...v4.3.7) diff --git a/admin/RELEASE.md b/admin/RELEASE.md index f5059e71b205..b625c743a75b 100644 --- a/admin/RELEASE.md +++ b/admin/RELEASE.md @@ -55,6 +55,7 @@ the existing content. ``` * Vet the **admin/** folders for any removed hidden files (Action deploy scripts *do not remove these*) + * git diff --name-status origin/master admin/ * Merge any Security Advisory PRs in private forks ## Process diff --git a/admin/framework/composer.json b/admin/framework/composer.json index 905e123cd89a..f93daa275b1d 100644 --- a/admin/framework/composer.json +++ b/admin/framework/composer.json @@ -1,9 +1,14 @@ { "name": "codeigniter4/framework", - "type": "project", "description": "The CodeIgniter framework v4", - "homepage": "https://codeigniter.com", "license": "MIT", + "type": "project", + "homepage": "https://codeigniter.com", + "support": { + "forum": "https://forum.codeigniter.com/", + "source": "https://github.com/codeigniter4/CodeIgniter4", + "slack": "https://codeigniterchat.slack.com" + }, "require": { "php": "^7.4 || ^8.0", "ext-intl": "*", @@ -13,10 +18,10 @@ "psr/log": "^1.1" }, "require-dev": { - "kint-php/kint": "^5.0.4", "codeigniter/coding-standard": "^1.5", "fakerphp/faker": "^1.9", "friendsofphp/php-cs-fixer": "3.13.0", + "kint-php/kint": "^5.0.4", "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.6", "phpunit/phpunit": "^9.1", @@ -24,28 +29,23 @@ }, "suggest": { "ext-curl": "If you use CURLRequest class", - "ext-imagick": "If you use Image class ImageMagickHandler", - "ext-gd": "If you use Image class GDHandler", + "ext-dom": "If you use TestResponse", "ext-exif": "If you run Image class tests", - "ext-simplexml": "If you format XML", + "ext-fileinfo": "Improves mime type detection for files", + "ext-gd": "If you use Image class GDHandler", + "ext-imagick": "If you use Image class ImageMagickHandler", + "ext-libxml": "If you use TestResponse", + "ext-memcache": "If you use Cache class MemcachedHandler with Memcache", + "ext-memcached": "If you use Cache class MemcachedHandler with Memcached", "ext-mysqli": "If you use MySQL", "ext-oci8": "If you use Oracle Database", "ext-pgsql": "If you use PostgreSQL", - "ext-sqlsrv": "If you use SQL Server", - "ext-sqlite3": "If you use SQLite3", - "ext-memcache": "If you use Cache class MemcachedHandler with Memcache", - "ext-memcached": "If you use Cache class MemcachedHandler with Memcached", + "ext-readline": "Improves CLI::input() usability", "ext-redis": "If you use Cache class RedisHandler", - "ext-dom": "If you use TestResponse", - "ext-libxml": "If you use TestResponse", - "ext-xdebug": "If you use CIUnitTestCase::assertHeaderEmitted()", - "ext-fileinfo": "Improves mime type detection for files", - "ext-readline": "Improves CLI::input() usability" - }, - "config": { - "optimize-autoloader": true, - "preferred-install": "dist", - "sort-packages": true + "ext-simplexml": "If you format XML", + "ext-sqlite3": "If you use SQLite3", + "ext-sqlsrv": "If you use SQL Server", + "ext-xdebug": "If you use CIUnitTestCase::assertHeaderEmitted()" }, "autoload": { "psr-4": { @@ -55,12 +55,12 @@ "**/Database/Migrations/**" ] }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + }, "scripts": { "test": "phpunit" - }, - "support": { - "forum": "https://forum.codeigniter.com/", - "source": "https://github.com/codeigniter4/CodeIgniter4", - "slack": "https://codeigniterchat.slack.com" } } diff --git a/admin/starter/composer.json b/admin/starter/composer.json index cec23ba1987e..082d7b648c25 100644 --- a/admin/starter/composer.json +++ b/admin/starter/composer.json @@ -1,9 +1,14 @@ { "name": "codeigniter4/appstarter", - "type": "project", "description": "CodeIgniter4 starter app", - "homepage": "https://codeigniter.com", "license": "MIT", + "type": "project", + "homepage": "https://codeigniter.com", + "support": { + "forum": "https://forum.codeigniter.com/", + "source": "https://github.com/codeigniter4/CodeIgniter4", + "slack": "https://codeigniterchat.slack.com" + }, "require": { "php": "^7.4 || ^8.0", "codeigniter4/framework": "^4.0" @@ -13,11 +18,6 @@ "mikey179/vfsstream": "^1.6", "phpunit/phpunit": "^9.1" }, - "config": { - "optimize-autoloader": true, - "preferred-install": "dist", - "sort-packages": true - }, "autoload": { "exclude-from-classmap": [ "**/Database/Migrations/**" @@ -28,12 +28,12 @@ "Tests\\Support\\": "tests/_support" } }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + }, "scripts": { "test": "phpunit" - }, - "support": { - "forum": "https://forum.codeigniter.com/", - "source": "https://github.com/codeigniter4/CodeIgniter4", - "slack": "https://codeigniterchat.slack.com" } } diff --git a/composer.json b/composer.json index 981db0694265..997ca73ebb89 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,14 @@ { "name": "codeigniter4/codeigniter4", - "type": "project", "description": "The CodeIgniter framework v4", - "homepage": "https://codeigniter.com", "license": "MIT", + "type": "project", + "homepage": "https://codeigniter.com", + "support": { + "forum": "https://forum.codeigniter.com/", + "source": "https://github.com/codeigniter4/CodeIgniter4", + "slack": "https://codeigniterchat.slack.com" + }, "require": { "php": "^7.4 || ^8.0", "ext-intl": "*", @@ -13,9 +18,10 @@ "psr/log": "^1.1" }, "require-dev": { - "kint-php/kint": "^5.0.4", "codeigniter/coding-standard": "^1.5", + "ergebnis/composer-normalize": "^2.28", "fakerphp/faker": "^1.9", + "kint-php/kint": "^5.0.4", "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.6", "nexusphp/tachycardia": "^1.0", @@ -24,38 +30,28 @@ "phpunit/phpcov": "^8.2", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1 || ^2.0", - "rector/rector": "0.17.7", + "rector/rector": "0.18.0", "vimeo/psalm": "^5.0" }, "suggest": { "ext-curl": "If you use CURLRequest class", - "ext-imagick": "If you use Image class ImageMagickHandler", - "ext-gd": "If you use Image class GDHandler", + "ext-dom": "If you use TestResponse", "ext-exif": "If you run Image class tests", - "ext-simplexml": "If you format XML", + "ext-fileinfo": "Improves mime type detection for files", + "ext-gd": "If you use Image class GDHandler", + "ext-imagick": "If you use Image class ImageMagickHandler", + "ext-libxml": "If you use TestResponse", + "ext-memcache": "If you use Cache class MemcachedHandler with Memcache", + "ext-memcached": "If you use Cache class MemcachedHandler with Memcached", "ext-mysqli": "If you use MySQL", "ext-oci8": "If you use Oracle Database", "ext-pgsql": "If you use PostgreSQL", - "ext-sqlsrv": "If you use SQL Server", - "ext-sqlite3": "If you use SQLite3", - "ext-memcache": "If you use Cache class MemcachedHandler with Memcache", - "ext-memcached": "If you use Cache class MemcachedHandler with Memcached", + "ext-readline": "Improves CLI::input() usability", "ext-redis": "If you use Cache class RedisHandler", - "ext-dom": "If you use TestResponse", - "ext-libxml": "If you use TestResponse", - "ext-xdebug": "If you use CIUnitTestCase::assertHeaderEmitted()", - "ext-fileinfo": "Improves mime type detection for files", - "ext-readline": "Improves CLI::input() usability" - }, - "config": { - "optimize-autoloader": true, - "preferred-install": "dist", - "sort-packages": true - }, - "extra": { - "branch-alias": { - "dev-develop": "4.x-dev" - } + "ext-simplexml": "If you format XML", + "ext-sqlite3": "If you use SQLite3", + "ext-sqlsrv": "If you use SQL Server", + "ext-xdebug": "If you use CIUnitTestCase::assertHeaderEmitted()" }, "autoload": { "psr-4": { @@ -71,6 +67,19 @@ "Utils\\": "utils/" } }, + "config": { + "allow-plugins": { + "ergebnis/composer-normalize": true + }, + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + }, + "extra": { + "branch-alias": { + "dev-develop": "4.x-dev" + } + }, "scripts": { "post-update-cmd": [ "CodeIgniter\\ComposerScripts::postUpdate", @@ -81,8 +90,6 @@ "bash -c \"XDEBUG_MODE=off phpstan analyse\"", "rector process --dry-run" ], - "sa": "@analyze", - "test": "phpunit", "cs": [ "Composer\\Config::disableProcessTimeout", "php-cs-fixer fix --ansi --verbose --dry-run --diff --config=.php-cs-fixer.user-guide.php", @@ -95,17 +102,14 @@ "php-cs-fixer fix --ansi --verbose --diff --config=.php-cs-fixer.no-header.php", "php-cs-fixer fix --ansi --verbose --diff" ], - "style": "@cs-fix" + "sa": "@analyze", + "style": "@cs-fix", + "test": "phpunit" }, "scripts-descriptions": { "analyze": "Run static analysis", - "test": "Run unit tests", "cs": "Check the coding style", - "cs-fix": "Fix the coding style" - }, - "support": { - "forum": "https://forum.codeigniter.com/", - "source": "https://github.com/codeigniter4/CodeIgniter4", - "slack": "https://codeigniterchat.slack.com" + "cs-fix": "Fix the coding style", + "test": "Run unit tests" } } diff --git a/contributing/documentation.rst b/contributing/documentation.rst index 887ed2d8343e..deedc29ebfc9 100644 --- a/contributing/documentation.rst +++ b/contributing/documentation.rst @@ -171,3 +171,16 @@ As a general rule, we use ``**`` for in-line file paths, and `````` for source c E.g.:: Open the **app/Config/Filters.php** file and update the ``$methods`` property like the following: + +********** +Code Block +********** + +CLI Command +=========== + +:: + + .. code-block:: console + + php spark migrate diff --git a/contributing/pull_request.md b/contributing/pull_request.md index 3acd1f1c6219..0a863fd39746 100644 --- a/contributing/pull_request.md +++ b/contributing/pull_request.md @@ -44,13 +44,13 @@ as the existing code and ensures that the codebase will be as readable as possib You can fix most of the coding style violations by running this command in your terminal: ```console -> composer cs-fix +composer cs-fix ``` You can check the coding style violations: ```console -> composer cs +composer cs ``` ### Unit Testing @@ -213,19 +213,19 @@ so that you can fix whatever errors that pop up with your submission. PHPStan is expected to scan the entire framework by running this command in your terminal: ```console -> vendor/bin/phpstan analyse +vendor/bin/phpstan analyse ``` Rector, on the other hand, can be run on the specific files you modified or added: ```console -> vendor/bin/rector process --dry-run path/to/file +vendor/bin/rector process --dry-run path/to/file ``` If you run it without `--dry-run`, Rector will fix the code: ```console -> vendor/bin/rector process path/to/file +vendor/bin/rector process path/to/file ``` [1]: https://github.com/phpstan/phpstan-src diff --git a/deptrac.yaml b/deptrac.yaml index bf39d4f54734..6b1d0b9818e4 100644 --- a/deptrac.yaml +++ b/deptrac.yaml @@ -189,6 +189,7 @@ parameters: - I18n Model: - Database + - Entity - I18n - Pager - Validation diff --git a/phpstan-baseline.php b/phpstan-baseline.php index 5302862f143a..f09ce499faca 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -2,125 +2,30 @@ $ignoreErrors = []; $ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$callback of function spl_autoload_register expects \\(callable\\(string\\)\\: void\\)\\|null, array\\{\\$this\\(CodeIgniter\\\\Autoloader\\\\Autoloader\\), \'loadClass\'\\} given\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Autoloader/Autoloader.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$callback of function spl_autoload_register expects \\(callable\\(string\\)\\: void\\)\\|null, array\\{\\$this\\(CodeIgniter\\\\Autoloader\\\\Autoloader\\), \'loadClassmap\'\\} given\\.$#', + 'message' => '#^PHPDoc type array of property Config\\\\View\\:\\:\\$filters is not covariant with PHPDoc type array\\ of overridden property CodeIgniter\\\\Config\\\\View\\:\\:\\$filters\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Autoloader/Autoloader.php', + 'path' => __DIR__ . '/app/Config/View.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\BaseModel\\:\\:chunk\\(\\) has no return type specified\\.$#', + 'message' => '#^PHPDoc type array of property Config\\\\View\\:\\:\\$plugins is not covariant with PHPDoc type array\\ of overridden property CodeIgniter\\\\Config\\\\View\\:\\:\\$plugins\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/BaseModel.php', + 'path' => __DIR__ . '/app/Config/View.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\BaseModel\\:\\:chunk\\(\\) has parameter \\$userFunc with no signature specified for Closure\\.$#', + 'message' => '#^Parameter \\#1 \\$callback of function spl_autoload_register expects \\(callable\\(string\\)\\: void\\)\\|null, array\\{\\$this\\(CodeIgniter\\\\Autoloader\\\\Autoloader\\), \'loadClass\'\\} given\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/BaseModel.php', + 'path' => __DIR__ . '/system/Autoloader/Autoloader.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\BaseModel\\:\\:doOnlyDeleted\\(\\) has no return type specified\\.$#', + 'message' => '#^Parameter \\#1 \\$callback of function spl_autoload_register expects \\(callable\\(string\\)\\: void\\)\\|null, array\\{\\$this\\(CodeIgniter\\\\Autoloader\\\\Autoloader\\), \'loadClassmap\'\\} given\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/BaseModel.php', + 'path' => __DIR__ . '/system/Autoloader/Autoloader.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\BaseModel\\:\\:initialize\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\BaseModel\\:\\:chunk\\(\\) has parameter \\$userFunc with no signature specified for Closure\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/BaseModel.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\BaseCommand\\:\\:showError\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/BaseCommand.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\BaseCommand\\:\\:showHelp\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/BaseCommand.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:beep\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:clearScreen\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:error\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:fwrite\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:generateDimensions\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:init\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:newLine\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:parseCommandLine\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:print\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:showProgress\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:table\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:wait\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\CLI\\:\\:write\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/CLI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\Commands\\:\\:discoverCommands\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/Commands.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\CLI\\\\Console\\:\\:showHeader\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/CLI/Console.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\CacheInterface\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/CacheInterface.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\BaseHandler\\:\\:deleteMatching\\(\\) has no return type specified\\.$#', 'count' => 1, @@ -136,11 +41,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Cache/Handlers/DummyHandler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\DummyHandler\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/Handlers/DummyHandler.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\DummyHandler\\:\\:remember\\(\\) has parameter \\$callback with no signature specified for Closure\\.$#', 'count' => 1, @@ -151,51 +51,26 @@ 'count' => 1, 'path' => __DIR__ . '/system/Cache/Handlers/FileHandler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\FileHandler\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/Handlers/FileHandler.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\MemcachedHandler\\:\\:deleteMatching\\(\\) has no return type specified\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Cache/Handlers/MemcachedHandler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\MemcachedHandler\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/Handlers/MemcachedHandler.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\PredisHandler\\:\\:deleteMatching\\(\\) has no return type specified\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Cache/Handlers/PredisHandler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\PredisHandler\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/Handlers/PredisHandler.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\RedisHandler\\:\\:deleteMatching\\(\\) has no return type specified\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Cache/Handlers/RedisHandler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\RedisHandler\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/Handlers/RedisHandler.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\WincacheHandler\\:\\:deleteMatching\\(\\) has no return type specified\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Cache/Handlers/WincacheHandler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Cache\\\\Handlers\\\\WincacheHandler\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Cache/Handlers/WincacheHandler.php', -]; $ignoreErrors[] = [ 'message' => '#^Call to an undefined method CodeIgniter\\\\HTTP\\\\Request\\:\\:getPost\\(\\)\\.$#', 'count' => 1, @@ -452,89 +327,24 @@ 'path' => __DIR__ . '/system/ComposerScripts.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\BaseConfig\\:\\:registerProperties\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/BaseConfig.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\BaseService\\:\\:injectMock\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/BaseService.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\BaseService\\:\\:reset\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/BaseService.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\BaseService\\:\\:resetSingle\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/BaseService.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\Config\\:\\:injectMock\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/Config.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\Config\\:\\:reset\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/Config.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\DotEnv\\:\\:setVariable\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/DotEnv.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\Factories\\:\\:injectMock\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/Factories.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\Factories\\:\\:reset\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/Factories.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Config\\\\ForeignCharacters\\:\\:\\$characterList has no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/ForeignCharacters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Config\\\\Publisher\\:\\:registerProperties\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Config/Publisher.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Config\\\\View\\:\\:\\$filters has no type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\Config\\\\View\\:\\:\\$coreFilters type has no signature specified for callable\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Config/View.php', ]; $ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Config\\\\View\\:\\:\\$plugins has no type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\Config\\\\View\\:\\:\\$corePlugins type has no signature specified for callable\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Config/View.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Controller\\:\\:cachePage\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Controller.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Controller\\:\\:forceHTTPS\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Controller.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Controller\\:\\:initController\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\Config\\\\View\\:\\:\\$filters type has no signature specified for callable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Controller.php', + 'path' => __DIR__ . '/system/Config/View.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Controller\\:\\:loadHelpers\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\Config\\\\View\\:\\:\\$plugins type has no signature specified for callable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Controller.php', + 'path' => __DIR__ . '/system/Config/View.php', ]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Database\\\\BaseBuilder\\:\\:_whereIn\\(\\) has parameter \\$values with no signature specified for Closure\\.$#', @@ -814,887 +624,202 @@ $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Database\\\\Postgre\\\\Forge\\:\\:_attributeAutoIncrement\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Database/Postgre/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\Postgre\\\\Forge\\:\\:_attributeType\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/Postgre/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\PreparedQueryInterface\\:\\:execute\\(\\) has parameter \\$data with no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/PreparedQueryInterface.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\Query\\:\\:compileBinds\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/Query.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\QueryInterface\\:\\:setError\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/QueryInterface.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\ResultInterface\\:\\:freeResult\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/ResultInterface.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$schema\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/system/Database/SQLSRV/Builder.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$schema\\.$#', - 'count' => 13, - 'path' => __DIR__ . '/system/Database/SQLSRV/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLSRV\\\\Forge\\:\\:_attributeAutoIncrement\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/SQLSRV/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLSRV\\\\Forge\\:\\:_attributeType\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/SQLSRV/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Forge\\:\\:_attributeAutoIncrement\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/SQLite3/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Forge\\:\\:_attributeType\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/SQLite3/Forge.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Table\\:\\:copyData\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/SQLite3/Table.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Table\\:\\:dropIndexes\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/SQLite3/Table.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Database\\\\Seeder\\:\\:call\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Database/Seeder.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Exceptions\\:\\:exceptionHandler\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Exceptions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Exceptions\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Exceptions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Exceptions\\:\\:render\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Exceptions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Exceptions\\:\\:shutdownHandler\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Exceptions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Iterator\\:\\:add\\(\\) has parameter \\$closure with no signature specified for Closure\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Iterator.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Timer\\:\\:record\\(\\) has parameter \\$callable with no signature specified for callable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Timer.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\:\\:prepare\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\:\\:respond\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\BaseCollector\\:\\:getBadgeValue\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/BaseCollector.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\BaseCollector\\:\\:getVarData\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/BaseCollector.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\Database\\:\\:collect\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Database.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\Database\\:\\:getConnections\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Database.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\History\\:\\:setFiles\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/History.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Debug\\\\Toolbar\\\\Collectors\\\\Logs\\:\\:collectLogs\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Logs.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Log\\\\Logger\\:\\:\\$logCache \\(array\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Logs.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to an undefined method CodeIgniter\\\\View\\\\RendererInterface\\:\\:getData\\(\\)\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Views.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to an undefined method CodeIgniter\\\\View\\\\RendererInterface\\:\\:getPerformanceData\\(\\)\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Views.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:SMTPEnd\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:appendAttachments\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:batchBCCSend\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:buildHeaders\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:buildMessage\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:setErrorMessage\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:unwrapSpecials\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Email\\\\Email\\:\\:writeHeaders\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Static property CodeIgniter\\\\Email\\\\Email\\:\\:\\$func_overload \\(bool\\) in isset\\(\\) is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Email/Email.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Encryption\\\\Handlers\\\\SodiumHandler\\:\\:parseParams\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Encryption/Handlers/SodiumHandler.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Entity\\\\Entity\\:\\:\\$casts has no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Entity/Entity.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Entity\\\\Entity\\:\\:\\$datamap has no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Entity/Entity.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Entity\\\\Entity\\:\\:\\$dates has no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Entity/Entity.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:on\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:on\\(\\) has parameter \\$callback with no signature specified for callable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:removeAllListeners\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:removeListener\\(\\) has parameter \\$listener with no signature specified for callable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:setFiles\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:simulate\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Events/Events.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\CastException\\:\\:forInvalidJsonFormatException\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/CastException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\ConfigException\\:\\:forDisabledMigrations\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/ConfigException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\DownloadException\\:\\:forCannotSetBinary\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/DownloadException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\DownloadException\\:\\:forCannotSetCache\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/DownloadException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\DownloadException\\:\\:forCannotSetFilePath\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/DownloadException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\DownloadException\\:\\:forCannotSetStatusCode\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/DownloadException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\DownloadException\\:\\:forNotFoundDownloadSource\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/DownloadException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\FrameworkException\\:\\:forCopyError\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/FrameworkException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\FrameworkException\\:\\:forEnabledZlibOutputCompression\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/FrameworkException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\FrameworkException\\:\\:forFabricatorCreateFailed\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/FrameworkException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\FrameworkException\\:\\:forInvalidFile\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/FrameworkException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\FrameworkException\\:\\:forMissingExtension\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/FrameworkException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\FrameworkException\\:\\:forNoHandlers\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/FrameworkException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\ModelException\\:\\:forMethodNotAvailable\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/ModelException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\ModelException\\:\\:forNoDateFormat\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/ModelException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\ModelException\\:\\:forNoPrimaryKey\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/ModelException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\PageNotFoundException\\:\\:forControllerNotFound\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/PageNotFoundException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\PageNotFoundException\\:\\:forEmptyController\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/PageNotFoundException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\PageNotFoundException\\:\\:forLocaleNotSupported\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/PageNotFoundException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\PageNotFoundException\\:\\:forMethodNotFound\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/PageNotFoundException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\PageNotFoundException\\:\\:forPageNotFound\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/PageNotFoundException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Exceptions\\\\TestException\\:\\:forInvalidMockClass\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Exceptions/TestException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Files\\\\Exceptions\\\\FileException\\:\\:forExpectedDirectory\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Files/Exceptions/FileException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Files\\\\Exceptions\\\\FileException\\:\\:forExpectedFile\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Files/Exceptions/FileException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Files\\\\Exceptions\\\\FileException\\:\\:forUnableToMove\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Files/Exceptions/FileException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Files\\\\Exceptions\\\\FileNotFoundException\\:\\:forFileNotFound\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Files/Exceptions/FileNotFoundException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Files\\\\File\\:\\:\\$size \\(int\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Files/File.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Expression on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Filters\\\\Filters\\:\\:discoverFilters\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Filters\\\\Filters\\:\\:processAliasesToClass\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Filters\\\\Filters\\:\\:processFilters\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Filters\\\\Filters\\:\\:processGlobals\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Filters\\\\Filters\\:\\:processMethods\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Filters\\\\Filters\\:\\:setResponse\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Filters/Filters.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Format\\\\XMLFormatter\\:\\:arrayToXML\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Format/XMLFormatter.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\CLIRequest\\:\\:parseCommand\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/CLIRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constructor of class CodeIgniter\\\\HTTP\\\\CURLRequest has an unused parameter \\$config\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/CURLRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:parseOptions\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/CURLRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:resetOptions\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/CURLRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\CURLRequest\\:\\:setResponseHeaders\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/CURLRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\ContentSecurityPolicy\\:\\:addOption\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/ContentSecurityPolicy.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\ContentSecurityPolicy\\:\\:addToHeader\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/ContentSecurityPolicy.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\ContentSecurityPolicy\\:\\:buildHeaders\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/ContentSecurityPolicy.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\ContentSecurityPolicy\\:\\:finalize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/ContentSecurityPolicy.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\ContentSecurityPolicy\\:\\:generateNonces\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/ContentSecurityPolicy.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\DownloadResponse\\:\\:buildHeaders\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/DownloadResponse.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\DownloadResponse\\:\\:setBinary\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/DownloadResponse.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\DownloadResponse\\:\\:setContentTypeByMimeType\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/DownloadResponse.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\DownloadResponse\\:\\:setFilePath\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/DownloadResponse.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\Files\\\\FileCollection\\:\\:populateFiles\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Files/FileCollection.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Expression on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Files/UploadedFile.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\HTTP\\\\Files\\\\UploadedFile\\:\\:\\$error \\(int\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/system/HTTP/Files/UploadedFile.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Return type \\(bool\\) of method CodeIgniter\\\\HTTP\\\\Files\\\\UploadedFile\\:\\:move\\(\\) should be compatible with return type \\(CodeIgniter\\\\Files\\\\File\\) of method CodeIgniter\\\\Files\\\\File\\:\\:move\\(\\)$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Files/UploadedFile.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\Files\\\\UploadedFileInterface\\:\\:move\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Files/UploadedFileInterface.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\IncomingRequest\\:\\:detectLocale\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/IncomingRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\IncomingRequest\\:\\:detectURI\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/IncomingRequest.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\HTTP\\\\Message\\:\\:\\$protocolVersion \\(string\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Message.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Variable \\$_GET on left side of \\?\\? always exists and is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/RedirectResponse.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Variable \\$_POST on left side of \\?\\? always exists and is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/RedirectResponse.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\Request\\:\\:populateGlobals\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Request.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\Response\\:\\:sendCookies\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/Response.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\URI\\:\\:applyParts\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/URI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$fragment \\(string\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/URI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$host \\(string\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/URI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$path \\(string\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/URI.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\UserAgent\\:\\:compileData\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/UserAgent.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\HTTP\\\\UserAgent\\:\\:parse\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/HTTP/UserAgent.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function delete_cookie\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/cookie_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function set_cookie\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/cookie_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Right side of && is always true\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/filesystem_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function d\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/kint_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function d\\(\\) has parameter \\$vars with no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/kint_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function dd\\(\\) has no return type specified\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/system/Helpers/kint_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function dd\\(\\) has parameter \\$vars with no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/kint_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function trace\\(\\) has no return type specified\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/system/Helpers/kint_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Function mock\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Helpers/test_helper.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Honeypot\\\\Exceptions\\\\HoneypotException\\:\\:forNoHiddenValue\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Honeypot/Exceptions/HoneypotException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Honeypot\\\\Exceptions\\\\HoneypotException\\:\\:forNoNameField\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Honeypot/Exceptions/HoneypotException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Honeypot\\\\Exceptions\\\\HoneypotException\\:\\:forNoTemplate\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Honeypot/Exceptions/HoneypotException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Honeypot\\\\Exceptions\\\\HoneypotException\\:\\:isBot\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Honeypot/Exceptions/HoneypotException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Honeypot\\\\Honeypot\\:\\:attachHoneypot\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Honeypot/Honeypot.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Honeypot\\\\Honeypot\\:\\:hasContent\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Honeypot/Honeypot.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\I18n\\\\Time\\:\\:setTestNow\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/I18n/Time.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\I18n\\\\Time\\:\\:toDateTimeString\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/I18n/Time.php', + 'path' => __DIR__ . '/system/Database/Postgre/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\I18n\\\\TimeLegacy\\:\\:setTestNow\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\Postgre\\\\Forge\\:\\:_attributeType\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/I18n/TimeLegacy.php', + 'path' => __DIR__ . '/system/Database/Postgre/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\I18n\\\\TimeLegacy\\:\\:toDateTimeString\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\PreparedQueryInterface\\:\\:execute\\(\\) has parameter \\$data with no type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/I18n/TimeLegacy.php', + 'path' => __DIR__ . '/system/Database/PreparedQueryInterface.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forEXIFUnsupported\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\Query\\:\\:compileBinds\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/Query.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forFileNotSupported\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\QueryInterface\\:\\:setError\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/QueryInterface.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forImageProcessFailed\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\ResultInterface\\:\\:freeResult\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/ResultInterface.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forInvalidDirection\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$schema\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/system/Database/SQLSRV/Builder.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forInvalidImageCreate\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$schema\\.$#', + 'count' => 13, + 'path' => __DIR__ . '/system/Database/SQLSRV/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forInvalidImageLibraryPath\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLSRV\\\\Forge\\:\\:_attributeAutoIncrement\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/SQLSRV/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forInvalidPath\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLSRV\\\\Forge\\:\\:_attributeType\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/SQLSRV/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forMissingAngle\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Forge\\:\\:_attributeAutoIncrement\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/SQLite3/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forMissingImage\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Forge\\:\\:_attributeType\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/SQLite3/Forge.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Exceptions\\\\ImageException\\:\\:forSaveFailed\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Table\\:\\:copyData\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Exceptions/ImageException.php', + 'path' => __DIR__ . '/system/Database/SQLite3/Table.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:_text\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\SQLite3\\\\Table\\:\\:dropIndexes\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/BaseHandler.php', + 'path' => __DIR__ . '/system/Database/SQLite3/Table.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:ensureResource\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Database\\\\Seeder\\:\\:call\\(\\) has no return type specified\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/BaseHandler.php', + 'path' => __DIR__ . '/system/Database/Seeder.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:reproportion\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\Log\\\\Logger\\:\\:\\$logCache \\(array\\) on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/BaseHandler.php', + 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Logs.php', ]; $ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$image \\(CodeIgniter\\\\Images\\\\Image\\) in empty\\(\\) is not falsy\\.$#', + 'message' => '#^Call to an undefined method CodeIgniter\\\\View\\\\RendererInterface\\:\\:getData\\(\\)\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/BaseHandler.php', + 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Views.php', ]; $ignoreErrors[] = [ - 'message' => '#^Comparison operation "\\>\\=" between \\(array\\|float\\|int\\) and 0 results in an error\\.$#', + 'message' => '#^Call to an undefined method CodeIgniter\\\\View\\\\RendererInterface\\:\\:getPerformanceData\\(\\)\\.$#', 'count' => 2, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', + 'path' => __DIR__ . '/system/Debug/Toolbar/Collectors/Views.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Handlers\\\\ImageMagickHandler\\:\\:_text\\(\\) has no return type specified\\.$#', + 'message' => '#^Static property CodeIgniter\\\\Email\\\\Email\\:\\:\\$func_overload \\(bool\\) in isset\\(\\) is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', + 'path' => __DIR__ . '/system/Email/Email.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Handlers\\\\ImageMagickHandler\\:\\:ensureResource\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:on\\(\\) has parameter \\$callback with no signature specified for callable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', + 'path' => __DIR__ . '/system/Events/Events.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Images\\\\Handlers\\\\ImageMagickHandler\\:\\:supportedFormatCheck\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Events\\\\Events\\:\\:removeListener\\(\\) has parameter \\$listener with no signature specified for callable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', + 'path' => __DIR__ . '/system/Events/Events.php', ]; $ignoreErrors[] = [ - 'message' => '#^PHPDoc type string\\|null of property CodeIgniter\\\\Images\\\\Handlers\\\\ImageMagickHandler\\:\\:\\$resource is not covariant with PHPDoc type resource\\|null of overridden property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$resource\\.$#', + 'message' => '#^Property CodeIgniter\\\\Files\\\\File\\:\\:\\$size \\(int\\) on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$height \\(int\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 4, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$width \\(int\\) on left side of \\?\\? is not nullable\\.$#', - 'count' => 4, - 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', + 'path' => __DIR__ . '/system/Files/File.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Log\\\\Exceptions\\\\LogException\\:\\:forInvalidLogLevel\\(\\) has no return type specified\\.$#', + 'message' => '#^Expression on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Log/Exceptions/LogException.php', + 'path' => __DIR__ . '/system/Filters/Filters.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Log\\\\Exceptions\\\\LogException\\:\\:forInvalidMessageType\\(\\) has no return type specified\\.$#', + 'message' => '#^Constructor of class CodeIgniter\\\\HTTP\\\\CURLRequest has an unused parameter \\$config\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Log/Exceptions/LogException.php', + 'path' => __DIR__ . '/system/HTTP/CURLRequest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Log\\\\Handlers\\\\ChromeLoggerHandler\\:\\:sendLogs\\(\\) has no return type specified\\.$#', + 'message' => '#^Expression on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Log/Handlers/ChromeLoggerHandler.php', + 'path' => __DIR__ . '/system/HTTP/Files/UploadedFile.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Model\\:\\:chunk\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Model.php', + 'message' => '#^Property CodeIgniter\\\\HTTP\\\\Files\\\\UploadedFile\\:\\:\\$error \\(int\\) on left side of \\?\\? is not nullable\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/system/HTTP/Files/UploadedFile.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Model\\:\\:chunk\\(\\) has parameter \\$userFunc with no signature specified for Closure\\.$#', + 'message' => '#^Return type \\(bool\\) of method CodeIgniter\\\\HTTP\\\\Files\\\\UploadedFile\\:\\:move\\(\\) should be compatible with return type \\(CodeIgniter\\\\Files\\\\File\\) of method CodeIgniter\\\\Files\\\\File\\:\\:move\\(\\)$#', 'count' => 1, - 'path' => __DIR__ . '/system/Model.php', + 'path' => __DIR__ . '/system/HTTP/Files/UploadedFile.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Model\\:\\:doOnlyDeleted\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\HTTP\\\\Message\\:\\:\\$protocolVersion \\(string\\) on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Model.php', + 'path' => __DIR__ . '/system/HTTP/Message.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Pager\\\\Exceptions\\\\PagerException\\:\\:forInvalidPaginationGroup\\(\\) has no return type specified\\.$#', + 'message' => '#^Variable \\$_GET on left side of \\?\\? always exists and is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Pager/Exceptions/PagerException.php', + 'path' => __DIR__ . '/system/HTTP/RedirectResponse.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Pager\\\\Exceptions\\\\PagerException\\:\\:forInvalidTemplate\\(\\) has no return type specified\\.$#', + 'message' => '#^Variable \\$_POST on left side of \\?\\? always exists and is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Pager/Exceptions/PagerException.php', + 'path' => __DIR__ . '/system/HTTP/RedirectResponse.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Pager\\\\Pager\\:\\:calculateCurrentPage\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$fragment \\(string\\) on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Pager/Pager.php', + 'path' => __DIR__ . '/system/HTTP/URI.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Pager\\\\Pager\\:\\:ensureGroup\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$host \\(string\\) on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Pager/Pager.php', + 'path' => __DIR__ . '/system/HTTP/URI.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Pager\\\\PagerRenderer\\:\\:updatePages\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$path \\(string\\) on left side of \\?\\? is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Pager/PagerRenderer.php', + 'path' => __DIR__ . '/system/HTTP/URI.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Publisher\\\\Exceptions\\\\PublisherException\\:\\:forCollision\\(\\) has no return type specified\\.$#', + 'message' => '#^Right side of && is always true\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Publisher/Exceptions/PublisherException.php', + 'path' => __DIR__ . '/system/Helpers/filesystem_helper.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Publisher\\\\Exceptions\\\\PublisherException\\:\\:forDestinationNotAllowed\\(\\) has no return type specified\\.$#', + 'message' => '#^Property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$image \\(CodeIgniter\\\\Images\\\\Image\\) in empty\\(\\) is not falsy\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Publisher/Exceptions/PublisherException.php', + 'path' => __DIR__ . '/system/Images/Handlers/BaseHandler.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Publisher\\\\Exceptions\\\\PublisherException\\:\\:forFileNotAllowed\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Publisher/Exceptions/PublisherException.php', + 'message' => '#^Comparison operation "\\>\\=" between \\(array\\|float\\|int\\) and 0 results in an error\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Publisher\\\\Publisher\\:\\:verifyAllowed\\(\\) has no return type specified\\.$#', + 'message' => '#^PHPDoc type string\\|null of property CodeIgniter\\\\Images\\\\Handlers\\\\ImageMagickHandler\\:\\:\\$resource is not covariant with PHPDoc type resource\\|null of overridden property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$resource\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Publisher/Publisher.php', + 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\RESTful\\\\BaseResource\\:\\:initController\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/RESTful/BaseResource.php', + 'message' => '#^Property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$height \\(int\\) on left side of \\?\\? is not nullable\\.$#', + 'count' => 4, + 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\RESTful\\\\BaseResource\\:\\:setModel\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/RESTful/BaseResource.php', + 'message' => '#^Property CodeIgniter\\\\Images\\\\Handlers\\\\BaseHandler\\:\\:\\$width \\(int\\) on left side of \\?\\? is not nullable\\.$#', + 'count' => 4, + 'path' => __DIR__ . '/system/Images/Handlers/ImageMagickHandler.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\AutoRouter\\:\\:setDirectory\\(\\) has no return type specified\\.$#', + 'message' => '#^Method CodeIgniter\\\\Model\\:\\:chunk\\(\\) has parameter \\$userFunc with no signature specified for Closure\\.$#', 'count' => 1, - 'path' => __DIR__ . '/system/Router/AutoRouter.php', + 'path' => __DIR__ . '/system/Model.php', ]; $ignoreErrors[] = [ 'message' => '#^Property CodeIgniter\\\\Router\\\\AutoRouter\\:\\:\\$cliRoutes type has no signature specified for Closure\\.$#', @@ -1711,11 +836,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/RouteCollection.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:create\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/RouteCollection.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:create\\(\\) has parameter \\$to with no signature specified for Closure\\.$#', 'count' => 1, @@ -1726,11 +846,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/RouteCollection.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:discoverRoutes\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/RouteCollection.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:environment\\(\\) has parameter \\$callback with no signature specified for Closure\\.$#', 'count' => 1, @@ -1751,11 +866,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/RouteCollection.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:group\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/RouteCollection.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:group\\(\\) has parameter \\$params with no signature specified for callable\\.$#', 'count' => 1, @@ -1791,11 +901,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/RouteCollection.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:resetRoutes\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/RouteCollection.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:set404Override\\(\\) has parameter \\$callable with no signature specified for callable\\.$#', 'count' => 1, @@ -1861,11 +966,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/Router.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:autoRoute\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/Router.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:controllerName\\(\\) return type has no signature specified for Closure\\.$#', 'count' => 1, @@ -1881,26 +981,11 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/Router.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:setDefaultController\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/Router.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:setDirectory\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/Router.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:setMatchedRoute\\(\\) has parameter \\$handler with no signature specified for callable\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Router/Router.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:setRequest\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Router/Router.php', -]; $ignoreErrors[] = [ 'message' => '#^Property CodeIgniter\\\\Router\\\\Router\\:\\:\\$controller type has no signature specified for Closure\\.$#', 'count' => 1, @@ -1916,26 +1001,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Router/RouterInterface.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Security\\\\Exceptions\\\\SecurityException\\:\\:forDisallowedAction\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Security/Exceptions/SecurityException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Security\\\\Exceptions\\\\SecurityException\\:\\:forInvalidControlChars\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Security/Exceptions/SecurityException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Security\\\\Exceptions\\\\SecurityException\\:\\:forInvalidSameSite\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Security/Exceptions/SecurityException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Security\\\\Exceptions\\\\SecurityException\\:\\:forInvalidUTF8Chars\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Security/Exceptions/SecurityException.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Session\\\\Exceptions\\\\SessionException\\:\\:forEmptySavepath\\(\\) has no return type specified\\.$#', 'count' => 1, @@ -2396,11 +1461,6 @@ 'count' => 1, 'path' => __DIR__ . '/system/Test/Mock/MockCache.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Test\\\\Mock\\\\MockCache\\:\\:initialize\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Test/Mock/MockCache.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Test\\\\Mock\\\\MockCache\\:\\:remember\\(\\) has parameter \\$callback with no signature specified for Closure\\.$#', 'count' => 1, @@ -2706,116 +1766,21 @@ 'count' => 1, 'path' => __DIR__ . '/system/Throttle/Throttler.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Exceptions\\\\ValidationException\\:\\:forGroupNotArray\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Exceptions/ValidationException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Exceptions\\\\ValidationException\\:\\:forGroupNotFound\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Exceptions/ValidationException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Exceptions\\\\ValidationException\\:\\:forInvalidTemplate\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Exceptions/ValidationException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Exceptions\\\\ValidationException\\:\\:forNoRuleSets\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Exceptions/ValidationException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Exceptions\\\\ValidationException\\:\\:forRuleNotFound\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Exceptions/ValidationException.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\Validation\\\\Validation\\:\\:isClosure\\(\\) has parameter \\$rule with no signature specified for Closure\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/Validation/Validation.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Validation\\:\\:loadRuleSets\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Validation.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\Validation\\:\\:setRuleGroup\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/Validation.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\Validation\\\\ValidationInterface\\:\\:setRuleGroup\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/Validation/ValidationInterface.php', -]; $ignoreErrors[] = [ 'message' => '#^Call to an undefined static method CodeIgniter\\\\Config\\\\Factories\\:\\:cells\\(\\)\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/View/Cell.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Cell\\:\\:getMethodParams\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Cell.php', -]; $ignoreErrors[] = [ 'message' => '#^Property CodeIgniter\\\\View\\\\Cell\\:\\:\\$cache \\(CodeIgniter\\\\Cache\\\\CacheInterface\\) in empty\\(\\) is not falsy\\.$#', 'count' => 2, 'path' => __DIR__ . '/system/View/Cell.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Cells\\\\Cell\\:\\:setView\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Cells/Cell.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method class@anonymous/system/Traits/PropertiesTrait\\.php\\:47\\:\\:getProperties\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Cells/Cell.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method class@anonymous/system/Traits/PropertiesTrait\\.php\\:47\\:\\:getProperties\\(\\) has parameter \\$obj with no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Cells/Cell.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forInvalidCellClass\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forInvalidCellMethod\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forInvalidCellParameter\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forInvalidDecorator\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forMissingCellParameters\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forNoCellClass\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Exceptions\\\\ViewException\\:\\:forTagSyntaxError\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Exceptions/ViewException.php', -]; $ignoreErrors[] = [ 'message' => '#^Method CodeIgniter\\\\View\\\\Parser\\:\\:addPlugin\\(\\) has parameter \\$callback with no signature specified for callable\\.$#', 'count' => 1, @@ -2826,55 +1791,10 @@ 'count' => 1, 'path' => __DIR__ . '/system/View/Parser.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Table\\:\\:_compileTemplate\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Table.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Table\\:\\:_setFromArray\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Table.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\Table\\:\\:_setFromDBResult\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/Table.php', -]; $ignoreErrors[] = [ 'message' => '#^Property CodeIgniter\\\\View\\\\Table\\:\\:\\$function type has no signature specified for callable\\.$#', 'count' => 1, 'path' => __DIR__ . '/system/View/Table.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\View\\:\\:endSection\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/View.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\View\\:\\:extend\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/View.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\View\\:\\:logPerformance\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/View.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\View\\:\\:renderSection\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/View.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method CodeIgniter\\\\View\\\\View\\:\\:section\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/View.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Property CodeIgniter\\\\View\\\\View\\:\\:\\$tempData has no type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/system/View/View.php', -]; return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; diff --git a/rector.php b/rector.php index c8e18dfd2096..d127556c568c 100644 --- a/rector.php +++ b/rector.php @@ -38,7 +38,6 @@ use Rector\Php71\Rector\FuncCall\CountOnNullRector; use Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector; use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector; -use Rector\PHPUnit\Rector\MethodCall\AssertPropertyExistsRector; use Rector\PHPUnit\Set\PHPUnitSetList; use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector; use Rector\Set\ValueObject\LevelSetList; @@ -78,8 +77,6 @@ __DIR__ . '/tests/_support', JsonThrowOnErrorRector::class, StringifyStrNeedlesRector::class, - // assertObjectHasAttribute() is deprecated - AssertPropertyExistsRector::class, RemoveUnusedPrivateMethodRector::class => [ // private method called via getPrivateMethodInvoker diff --git a/system/BaseModel.php b/system/BaseModel.php index 0f316e6ffa3f..43dcf1c5abe4 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -338,6 +338,8 @@ public function __construct(?ValidationInterface $validation = null) /** * Initializes the instance with any additional steps. * Optionally implemented by child classes. + * + * @return void */ protected function initialize() { @@ -458,6 +460,8 @@ abstract protected function doPurgeDeleted(); * Works with the find* methods to return only the rows that * have been deleted. * This method works only with dbCalls. + * + * @return void */ abstract protected function doOnlyDeleted(); @@ -524,6 +528,8 @@ abstract public function countAllResults(bool $reset = true, bool $test = false) * @param int $size Size * @param Closure $userFunc Callback Function * + * @return void + * * @throws DataException */ abstract public function chunk(int $size, Closure $userFunc); @@ -754,7 +760,7 @@ public function insert($data = null, bool $returnID = true) // Must be called first, so we don't // strip out created_at values. - $data = $this->doProtectFields($data); + $data = $this->doProtectFieldsForInsert($data); // doProtectFields() can further remove elements from // $data so we need to check for empty dataset again @@ -847,7 +853,7 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch // Must be called first so we don't // strip out created_at values. - $row = $this->doProtectFields($row); + $row = $this->doProtectFieldsForInsert($row); // Set created_at and updated_at with same time $date = $this->setDate(); @@ -973,7 +979,9 @@ public function updateBatch(?array $set = null, ?string $index = null, int $batc // properties representing the collection elements, we need to grab // them as an array. if (is_object($row) && ! $row instanceof stdClass) { - $row = $this->objectToArray($row, true, true); + // For updates the index field is needed even if it is not changed. + // So set $onlyChanged to false. + $row = $this->objectToArray($row, false, true); } // If it's still a stdClass, go ahead and convert to @@ -991,6 +999,13 @@ public function updateBatch(?array $set = null, ?string $index = null, int $batc // Save updateIndex for later $updateIndex = $row[$index] ?? null; + if ($updateIndex === null) { + throw new InvalidArgumentException( + 'The index ("' . $index . '") for updateBatch() is missing in the data: ' + . json_encode($row) + ); + } + // Must be called first so we don't // strip out updated_at values. $row = $this->doProtectFields($row); @@ -1222,10 +1237,10 @@ public function protect(bool $protect = true) } /** - * Ensures that only the fields that are allowed to be updated - * are in the data array. + * Ensures that only the fields that are allowed to be updated are + * in the data array. * - * Used by insert() and update() to protect against mass assignment + * Used by update() and updateBatch() to protect against mass assignment * vulnerabilities. * * @param array $data Data @@ -1251,6 +1266,22 @@ protected function doProtectFields(array $data): array return $data; } + /** + * Ensures that only the fields that are allowed to be inserted are in + * the data array. + * + * Used by insert() and insertBatch() to protect against mass assignment + * vulnerabilities. + * + * @param array $data Data + * + * @throws DataException + */ + protected function doProtectFieldsForInsert(array $data): array + { + return $this->doProtectFields($data); + } + /** * Sets the date or current date if null value is passed. * diff --git a/system/CLI/BaseCommand.php b/system/CLI/BaseCommand.php index 0c4abd2cea98..c4448d56b01a 100644 --- a/system/CLI/BaseCommand.php +++ b/system/CLI/BaseCommand.php @@ -117,6 +117,8 @@ protected function call(string $command, array $params = []) /** * A simple method to display an error with line/file, in child commands. + * + * @return void */ protected function showError(Throwable $e) { @@ -129,6 +131,8 @@ protected function showError(Throwable $e) /** * Show Help includes (Usage, Arguments, Description, Options). + * + * @return void */ public function showHelp() { diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index 2798319b057d..044f9dbbc8fd 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -142,6 +142,8 @@ class CLI /** * Static "constructor". + * + * @return void */ public static function init() { @@ -429,6 +431,8 @@ protected static function validate(string $field, string $value, $rules): bool /** * Outputs a string to the CLI without any surrounding newlines. * Useful for showing repeating elements on a single line. + * + * @return void */ public static function print(string $text = '', ?string $foreground = null, ?string $background = null) { @@ -443,6 +447,8 @@ public static function print(string $text = '', ?string $foreground = null, ?str /** * Outputs a string to the cli on it's own line. + * + * @return void */ public static function write(string $text = '', ?string $foreground = null, ?string $background = null) { @@ -460,6 +466,8 @@ public static function write(string $text = '', ?string $foreground = null, ?str /** * Outputs an error to the CLI using STDERR instead of STDOUT + * + * @return void */ public static function error(string $text, string $foreground = 'light_red', ?string $background = null) { @@ -481,6 +489,8 @@ public static function error(string $text, string $foreground = 'light_red', ?st * Beeps a certain number of times. * * @param int $num The number of times to beep + * + * @return void */ public static function beep(int $num = 1) { @@ -493,6 +503,8 @@ public static function beep(int $num = 1) * * @param int $seconds Number of seconds * @param bool $countdown Show a countdown or not + * + * @return void */ public static function wait(int $seconds, bool $countdown = false) { @@ -529,6 +541,8 @@ public static function isWindows(): bool /** * Enter a number of empty lines + * + * @return void */ public static function newLine(int $num = 1) { @@ -542,6 +556,8 @@ public static function newLine(int $num = 1) * Clears the screen of output * * @codeCoverageIgnore + * + * @return void */ public static function clearScreen() { @@ -735,6 +751,8 @@ public static function getHeight(int $default = 32): int * Populates the CLI's dimensions. * * @codeCoverageIgnore + * + * @return void */ public static function generateDimensions() { @@ -778,6 +796,8 @@ public static function generateDimensions() * to update it. Set $thisStep = false to erase the progress bar. * * @param bool|int $thisStep + * + * @return void */ public static function showProgress($thisStep = 1, int $totalSteps = 10) { @@ -859,6 +879,8 @@ public static function wrap(?string $string = null, int $max = 0, int $padLeft = /** * Parses the command line it was called from and collects all * options and valid segments. + * + * @return void */ protected static function parseCommandLine() { @@ -998,6 +1020,8 @@ public static function getOptionString(bool $useLongOpts = false, bool $trim = f * * @param array $tbody List of rows * @param array $thead List of columns + * + * @return void */ public static function table(array $tbody, array $thead = []) { @@ -1096,6 +1120,8 @@ public static function table(array $tbody, array $thead = []) * solution down the road. * * @param resource $handle + * + * @return void */ protected static function fwrite($handle, string $string) { diff --git a/system/CLI/Commands.php b/system/CLI/Commands.php index 0358e8ad2e18..df28e533a354 100644 --- a/system/CLI/Commands.php +++ b/system/CLI/Commands.php @@ -78,6 +78,8 @@ public function getCommands() /** * Discovers all commands in the framework and within user code, * and collects instances of them to work with. + * + * @return void */ public function discoverCommands() { diff --git a/system/CLI/Console.php b/system/CLI/Console.php index 7f396ef2af0c..01c15eea3fad 100644 --- a/system/CLI/Console.php +++ b/system/CLI/Console.php @@ -39,6 +39,8 @@ public function run() /** * Displays basic information about the Console. + * + * @return void */ public function showHeader(bool $suppress = false) { diff --git a/system/Cache/CacheInterface.php b/system/Cache/CacheInterface.php index d50322e778f6..23ea709df482 100644 --- a/system/Cache/CacheInterface.php +++ b/system/Cache/CacheInterface.php @@ -18,6 +18,8 @@ interface CacheInterface { /** * Takes care of any handler-specific setup that must be done. + * + * @return void */ public function initialize(); diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index af3a06f1731a..198602320146 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -48,7 +48,7 @@ class CodeIgniter /** * The current version of CodeIgniter Framework */ - public const CI_VERSION = '4.3.7'; + public const CI_VERSION = '4.3.8'; /** * App startup time. diff --git a/system/Common.php b/system/Common.php index 9be45b3a9c08..af2e558cfa9f 100644 --- a/system/Common.php +++ b/system/Common.php @@ -470,10 +470,8 @@ function esc($data, string $context = 'html', ?string $encoding = null) * * @see https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security * - * @param int $duration How long should the SSL header be set for? (in seconds) - * Defaults to 1 year. - * @param RequestInterface $request - * @param ResponseInterface $response + * @param int $duration How long should the SSL header be set for? (in seconds) + * Defaults to 1 year. * * @throws HTTPException */ diff --git a/system/Config/BaseConfig.php b/system/Config/BaseConfig.php index 80ae268635ef..0958d7ae7f75 100644 --- a/system/Config/BaseConfig.php +++ b/system/Config/BaseConfig.php @@ -169,6 +169,8 @@ protected function getEnvValue(string $property, string $prefix, string $shortPr * Provides external libraries a simple way to register one or more * options into a config file. * + * @return void + * * @throws ReflectionException */ protected function registerProperties() diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index d517691b0c1f..e41c0c0ed06f 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -273,6 +273,8 @@ public static function serviceExists(string $name): ?string /** * Reset shared instances and mocks for testing. + * + * @return void */ public static function reset(bool $initAutoloader = true) { @@ -286,6 +288,8 @@ public static function reset(bool $initAutoloader = true) /** * Resets any mock and shared instances for a single service. + * + * @return void */ public static function resetSingle(string $name) { @@ -297,6 +301,8 @@ public static function resetSingle(string $name) * Inject mock object for testing. * * @param object $mock + * + * @return void */ public static function injectMock(string $name, $mock) { diff --git a/system/Config/Config.php b/system/Config/Config.php index d261fa4d9ae4..3008865b29fa 100644 --- a/system/Config/Config.php +++ b/system/Config/Config.php @@ -34,6 +34,8 @@ public static function get(string $name, bool $getShared = true) * Helper method for injecting mock instances while testing. * * @param object $instance + * + * @return void */ public static function injectMock(string $name, $instance) { @@ -42,6 +44,8 @@ public static function injectMock(string $name, $instance) /** * Resets the static arrays + * + * @return void */ public static function reset() { diff --git a/system/Config/DotEnv.php b/system/Config/DotEnv.php index 724524e2d590..0275b5c4b9c3 100644 --- a/system/Config/DotEnv.php +++ b/system/Config/DotEnv.php @@ -85,6 +85,8 @@ public function parse(): ?array * Sets the variable into the environment. Will parse the string * first to look for {name}={value} pattern, ensure that nested * variables are handled, and strip it of single and double quotes. + * + * @return void */ protected function setVariable(string $name, string $value = '') { diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 222df063196a..f14471c5fda7 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -267,6 +267,8 @@ public static function setOptions(string $component, array $values): array * Resets the static arrays, optionally just for one component * * @param string|null $component Lowercase, plural component name + * + * @return void */ public static function reset(?string $component = null) { @@ -290,6 +292,8 @@ public static function reset(?string $component = null) * * @param string $component Lowercase, plural component name * @param string $name The name of the instance + * + * @return void */ public static function injectMock(string $component, string $name, object $instance) { diff --git a/system/Config/ForeignCharacters.php b/system/Config/ForeignCharacters.php index f2e7cc57cabf..a8569f5419c5 100644 --- a/system/Config/ForeignCharacters.php +++ b/system/Config/ForeignCharacters.php @@ -17,7 +17,9 @@ class ForeignCharacters { /** - * Without further ado, the list of foreign characters. + * The list of foreign characters. + * + * @var array */ public $characterList = [ '/ä|æ|ǽ/' => 'ae', diff --git a/system/Config/Publisher.php b/system/Config/Publisher.php index 608e87afef8e..fa04e24cd28f 100644 --- a/system/Config/Publisher.php +++ b/system/Config/Publisher.php @@ -36,7 +36,7 @@ class Publisher extends BaseConfig /** * Disables Registrars to prevent modules from altering the restrictions. */ - final protected function registerProperties() + final protected function registerProperties(): void { } } diff --git a/system/Config/Services.php b/system/Config/Services.php index 66d0532e5e47..b18b99e91a91 100644 --- a/system/Config/Services.php +++ b/system/Config/Services.php @@ -445,7 +445,7 @@ public static function pager(?PagerConfig $config = null, ?RendererInterface $vi } $config ??= config(PagerConfig::class); - $view ??= AppServices::renderer(); + $view ??= AppServices::renderer(null, null, false); return new Pager($config, $view); } diff --git a/system/Config/View.php b/system/Config/View.php index 42d40faf879e..de4ed62b936a 100644 --- a/system/Config/View.php +++ b/system/Config/View.php @@ -33,6 +33,9 @@ class View extends BaseConfig * * To prevent potential abuse, all filters MUST be defined here * in order for them to be available for use within the Parser. + * + * @var array + * @phpstan-var array */ public $filters = []; @@ -40,13 +43,17 @@ class View extends BaseConfig * Parser Plugins provide a way to extend the functionality provided * by the core Parser by creating aliases that will be replaced with * any callable. Can be single or tag pair. + * + * @var array + * @phpstan-var array */ public $plugins = []; /** * Built-in View filters. * - * @var array + * @var array + * @phpstan-var array */ protected $coreFilters = [ 'abs' => '\abs', @@ -75,7 +82,8 @@ class View extends BaseConfig /** * Built-in View plugins. * - * @var array + * @var array + * @phpstan-var array */ protected $corePlugins = [ 'csp_script_nonce' => '\CodeIgniter\View\Plugins::cspScriptNonce', diff --git a/system/Controller.php b/system/Controller.php index 64de91ab2938..070cc76b88f5 100644 --- a/system/Controller.php +++ b/system/Controller.php @@ -70,6 +70,8 @@ class Controller /** * Constructor. * + * @return void + * * @throws HTTPException */ public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) @@ -96,6 +98,8 @@ public function initController(RequestInterface $request, ResponseInterface $res * considered secure for. Only with HSTS header. * Default value is 1 year. * + * @return void + * * @throws HTTPException */ protected function forceHTTPS(int $duration = 31_536_000) @@ -106,6 +110,8 @@ protected function forceHTTPS(int $duration = 31_536_000) /** * Provides a simple way to tie into the main CodeIgniter class and * tell it how long to cache the current page for. + * + * @return void */ protected function cachePage(int $time) { @@ -118,6 +124,8 @@ protected function cachePage(int $time) * @deprecated Use `helper` function instead of using this method. * * @codeCoverageIgnore + * + * @return void */ protected function loadHelpers() { diff --git a/system/Cookie/Cookie.php b/system/Cookie/Cookie.php index e94d61baee1d..08dfff2c303f 100644 --- a/system/Cookie/Cookie.php +++ b/system/Cookie/Cookie.php @@ -58,7 +58,7 @@ class Cookie implements ArrayAccess, CloneableCookieInterface protected $value; /** - * @var int + * @var int Unix timestamp */ protected $expires; diff --git a/system/Database/OCI8/Forge.php b/system/Database/OCI8/Forge.php index 1eddd4a72888..6e1e85f666a1 100644 --- a/system/Database/OCI8/Forge.php +++ b/system/Database/OCI8/Forge.php @@ -218,19 +218,24 @@ protected function _attributeType(array &$attributes) switch (strtoupper($attributes['TYPE'])) { case 'TINYINT': $attributes['CONSTRAINT'] ??= 3; + // no break case 'SMALLINT': $attributes['CONSTRAINT'] ??= 5; + // no break case 'MEDIUMINT': $attributes['CONSTRAINT'] ??= 7; + // no break case 'INT': case 'INTEGER': $attributes['CONSTRAINT'] ??= 11; + // no break case 'BIGINT': $attributes['CONSTRAINT'] ??= 19; + // no break case 'NUMERIC': $attributes['TYPE'] = 'NUMBER'; @@ -261,6 +266,7 @@ protected function _attributeType(array &$attributes) case 'ENUM': case 'VARCHAR': $attributes['CONSTRAINT'] ??= 255; + // no break case 'TEXT': case 'MEDIUMTEXT': diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php index 6df81c16d5a5..77f5736d28a3 100644 --- a/system/Debug/Exceptions.php +++ b/system/Debug/Exceptions.php @@ -98,6 +98,8 @@ public function __construct(ExceptionsConfig $config, $request, ResponseInterfac * handling of our application. * * @codeCoverageIgnore + * + * @return void */ public function initialize() { @@ -112,6 +114,9 @@ public function initialize() * and fire an event that allows custom actions to be taken at this point. * * @codeCoverageIgnore + * + * @return void + * @phpstan-return never|void */ public function exceptionHandler(Throwable $exception) { @@ -189,6 +194,9 @@ public function errorHandler(int $severity, string $message, ?string $file = nul * need to be caught and handle them. * * @codeCoverageIgnore + * + * @return void + * @phpstan-return never|void */ public function shutdownHandler() { @@ -243,6 +251,9 @@ protected function determineView(Throwable $exception, string $templatePath): st /** * Given an exception and status code will display the error to the client. + * + * @return void + * @phpstan-return never|void */ protected function render(Throwable $exception, int $statusCode) { diff --git a/system/Debug/Iterator.php b/system/Debug/Iterator.php index 62343745b17b..f54335b6dd70 100644 --- a/system/Debug/Iterator.php +++ b/system/Debug/Iterator.php @@ -38,6 +38,8 @@ class Iterator * Tests are simply closures that the user can define any sequence of * things to happen during the test. * + * @phpstan-param Closure(): mixed $closure + * * @return $this */ public function add(string $name, Closure $closure) diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 68a9b7898c64..216b10bab758 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -131,8 +131,8 @@ public function has(string $name): bool * Executes callable and measures its time. * Returns its return value if any. * - * @param string $name The name of the timer - * @param callable $callable callable to be executed + * @param string $name The name of the timer + * @phpstan-param callable(): mixed $callable callable to be executed * * @return array|bool|float|int|object|resource|string|null */ diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php index f00ad09bd122..d20125b9b5bd 100644 --- a/system/Debug/Toolbar.php +++ b/system/Debug/Toolbar.php @@ -348,6 +348,8 @@ protected function roundTo(float $number, int $increments = 5): float * * @param RequestInterface $request * @param ResponseInterface $response + * + * @return void */ public function prepare(?RequestInterface $request = null, ?ResponseInterface $response = null) { @@ -434,6 +436,9 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r * Inject debug toolbar into the response. * * @codeCoverageIgnore + * + * @return void + * @phpstan-return never|void */ public function respond() { diff --git a/system/Debug/Toolbar/Collectors/BaseCollector.php b/system/Debug/Toolbar/Collectors/BaseCollector.php index e8aaad9ba115..4704fcdcaaeb 100644 --- a/system/Debug/Toolbar/Collectors/BaseCollector.php +++ b/system/Debug/Toolbar/Collectors/BaseCollector.php @@ -137,6 +137,8 @@ public function hasVarData(): bool * 'bar' => 'baz' * ], * ]; + * + * @return array|null */ public function getVarData() { @@ -183,6 +185,8 @@ public function cleanPath(string $file): string /** * Gets the "badge" value for the button. + * + * @return int|null */ public function getBadgeValue() { diff --git a/system/Debug/Toolbar/Collectors/Database.php b/system/Debug/Toolbar/Collectors/Database.php index 9d4099f46691..f487af59cef4 100644 --- a/system/Debug/Toolbar/Collectors/Database.php +++ b/system/Debug/Toolbar/Collectors/Database.php @@ -75,7 +75,10 @@ public function __construct() * The static method used during Events to collect * data. * - * @internal param $ array \CodeIgniter\Database\Query + * @internal + * + * @return void + * @phpstan-return never|void */ public static function collect(Query $query) { @@ -247,7 +250,7 @@ public function icon(): string /** * Gets the connections from the database config */ - private function getConnections() + private function getConnections(): void { $this->connections = \Config\Database::getConnections(); } diff --git a/system/Debug/Toolbar/Collectors/History.php b/system/Debug/Toolbar/Collectors/History.php index afc68ee85f2e..9645bd91863a 100644 --- a/system/Debug/Toolbar/Collectors/History.php +++ b/system/Debug/Toolbar/Collectors/History.php @@ -60,6 +60,8 @@ class History extends BaseCollector * * @param string $current Current history time * @param int $limit Max history files + * + * @return void */ public function setFiles(string $current, int $limit = 20) { diff --git a/system/Debug/Toolbar/Collectors/Logs.php b/system/Debug/Toolbar/Collectors/Logs.php index 42d7307ab9d1..d656ca9bcefb 100644 --- a/system/Debug/Toolbar/Collectors/Logs.php +++ b/system/Debug/Toolbar/Collectors/Logs.php @@ -81,6 +81,8 @@ public function icon(): string /** * Ensures the data has been collected. + * + * @return array */ protected function collectLogs() { diff --git a/system/Email/Email.php b/system/Email/Email.php index fe68ff2deda9..d962042d5e7a 100644 --- a/system/Email/Email.php +++ b/system/Email/Email.php @@ -1064,6 +1064,8 @@ public function wordWrap($str, $charlim = null) /** * Build final headers + * + * @return void */ protected function buildHeaders() { @@ -1077,6 +1079,8 @@ protected function buildHeaders() /** * Write Headers as a string + * + * @return void */ protected function writeHeaders() { @@ -1103,6 +1107,8 @@ protected function writeHeaders() /** * Build Final Body and attachments + * + * @return void */ protected function buildMessage() { @@ -1263,6 +1269,8 @@ protected function attachmentsHaveMultipart($type) * @param string $body Message body to append to * @param string $boundary Multipart boundary * @param string|null $multipart When provided, only attachments of this type will be processed + * + * @return void */ protected function appendAttachments(&$body, $boundary, $multipart = null) { @@ -1579,6 +1587,8 @@ public function send($autoClear = true) /** * Batch Bcc Send. Sends groups of BCCs in batches + * + * @return void */ public function batchBCCSend() { @@ -1623,6 +1633,8 @@ public function batchBCCSend() /** * Unwrap special elements + * + * @return void */ protected function unwrapSpecials() { @@ -1837,6 +1849,8 @@ protected function sendWithSmtp() /** * Shortcut to send RSET or QUIT depending on keep-alive + * + * @return void */ protected function SMTPEnd() { @@ -2156,6 +2170,8 @@ private function printDebuggerRaw(): string /** * @param string $msg + * + * @return void */ protected function setErrorMessage($msg) { diff --git a/system/Encryption/Handlers/SodiumHandler.php b/system/Encryption/Handlers/SodiumHandler.php index 9dc4cdbdec44..95dcdfb6c8b0 100644 --- a/system/Encryption/Handlers/SodiumHandler.php +++ b/system/Encryption/Handlers/SodiumHandler.php @@ -112,6 +112,8 @@ public function decrypt($data, $params = null) * * @param array|string|null $params * + * @return void + * * @throws EncryptionException If key is empty */ protected function parseParams($params) diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 07e1e26393c8..a979567d75e7 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -45,9 +45,17 @@ class Entity implements JsonSerializable * $datamap = [ * 'class_property_name' => 'db_column_name' * ]; + * + * @var array */ protected $datamap = []; + /** + * The date fields. + * + * @var array + * @phpstan-var list + */ protected $dates = [ 'created_at', 'updated_at', @@ -57,6 +65,8 @@ class Entity implements JsonSerializable /** * Array of field names and the type of value to cast them as when * they are accessed. + * + * @var array */ protected $casts = []; diff --git a/system/Events/Events.php b/system/Events/Events.php index f90af36c2e57..ff8c92822e52 100644 --- a/system/Events/Events.php +++ b/system/Events/Events.php @@ -63,6 +63,8 @@ class Events /** * Ensures that we have a events file ready. + * + * @return void */ public static function initialize() { @@ -108,6 +110,8 @@ public static function initialize() * @param string $eventName * @param callable $callback * @param int $priority + * + * @return void */ public static function on($eventName, $callback, $priority = self::PRIORITY_NORMAL) { @@ -222,6 +226,8 @@ public static function removeListener($eventName, callable $listener): bool * removed, otherwise all listeners for all events are removed. * * @param string|null $eventName + * + * @return void */ public static function removeAllListeners($eventName = null) { @@ -234,6 +240,8 @@ public static function removeAllListeners($eventName = null) /** * Sets the path to the file that routes are read from. + * + * @return void */ public static function setFiles(array $files) { @@ -254,6 +262,8 @@ public static function getFiles() * Turns simulation on or off. When on, events will not be triggered, * simply logged. Useful during testing when you don't actually want * the tests to run. + * + * @return void */ public static function simulate(bool $choice = true) { diff --git a/system/Exceptions/CastException.php b/system/Exceptions/CastException.php index e1f4e1231eef..8dfb29543a78 100644 --- a/system/Exceptions/CastException.php +++ b/system/Exceptions/CastException.php @@ -27,6 +27,9 @@ public function getExitCode(): int return EXIT_CONFIG; } + /** + * @return static + */ public static function forInvalidJsonFormatException(int $error) { switch ($error) { diff --git a/system/Exceptions/ConfigException.php b/system/Exceptions/ConfigException.php index 0a0a6656362e..6eea2638c5e0 100644 --- a/system/Exceptions/ConfigException.php +++ b/system/Exceptions/ConfigException.php @@ -23,6 +23,9 @@ public function getExitCode(): int return EXIT_CONFIG; } + /** + * @return static + */ public static function forDisabledMigrations() { return new static(lang('Migrations.disabled')); diff --git a/system/Exceptions/DownloadException.php b/system/Exceptions/DownloadException.php index c830891ed5a9..5626cfefa806 100644 --- a/system/Exceptions/DownloadException.php +++ b/system/Exceptions/DownloadException.php @@ -20,26 +20,41 @@ class DownloadException extends RuntimeException implements ExceptionInterface { use DebugTraceableTrait; + /** + * @return static + */ public static function forCannotSetFilePath(string $path) { return new static(lang('HTTP.cannotSetFilepath', [$path])); } + /** + * @return static + */ public static function forCannotSetBinary() { return new static(lang('HTTP.cannotSetBinary')); } + /** + * @return static + */ public static function forNotFoundDownloadSource() { return new static(lang('HTTP.notFoundDownloadSource')); } + /** + * @return static + */ public static function forCannotSetCache() { return new static(lang('HTTP.cannotSetCache')); } + /** + * @return static + */ public static function forCannotSetStatusCode(int $code, string $reason) { return new static(lang('HTTP.cannotSetStatusCode', [$code, $reason])); diff --git a/system/Exceptions/FrameworkException.php b/system/Exceptions/FrameworkException.php index 333f999df84a..7d71147c18de 100644 --- a/system/Exceptions/FrameworkException.php +++ b/system/Exceptions/FrameworkException.php @@ -23,21 +23,33 @@ class FrameworkException extends RuntimeException implements ExceptionInterface { use DebugTraceableTrait; + /** + * @return static + */ public static function forEnabledZlibOutputCompression() { return new static(lang('Core.enabledZlibOutputCompression')); } + /** + * @return static + */ public static function forInvalidFile(string $path) { return new static(lang('Core.invalidFile', [$path])); } + /** + * @return static + */ public static function forCopyError(string $path) { return new static(lang('Core.copyError', [$path])); } + /** + * @return static + */ public static function forMissingExtension(string $extension) { if (strpos($extension, 'intl') !== false) { @@ -54,11 +66,17 @@ public static function forMissingExtension(string $extension) return new static($message); } + /** + * @return static + */ public static function forNoHandlers(string $class) { return new static(lang('Core.noHandlers', [$class])); } + /** + * @return static + */ public static function forFabricatorCreateFailed(string $table, string $reason) { return new static(lang('Fabricator.createFailed', [$table, $reason])); diff --git a/system/Exceptions/ModelException.php b/system/Exceptions/ModelException.php index 3bdc283649ed..39590a60ea13 100644 --- a/system/Exceptions/ModelException.php +++ b/system/Exceptions/ModelException.php @@ -16,16 +16,25 @@ */ class ModelException extends FrameworkException { + /** + * @return static + */ public static function forNoPrimaryKey(string $modelName) { return new static(lang('Database.noPrimaryKey', [$modelName])); } + /** + * @return static + */ public static function forNoDateFormat(string $modelName) { return new static(lang('Database.noDateFormat', [$modelName])); } + /** + * @return static + */ public static function forMethodNotAvailable(string $modelName, string $methodName) { return new static(lang('Database.methodNotAvailable', [$modelName, $methodName])); diff --git a/system/Exceptions/PageNotFoundException.php b/system/Exceptions/PageNotFoundException.php index e41ae6ac868d..69e93f9b9bf1 100644 --- a/system/Exceptions/PageNotFoundException.php +++ b/system/Exceptions/PageNotFoundException.php @@ -25,26 +25,41 @@ class PageNotFoundException extends OutOfBoundsException implements ExceptionInt */ protected $code = 404; + /** + * @return static + */ public static function forPageNotFound(?string $message = null) { return new static($message ?? self::lang('HTTP.pageNotFound')); } + /** + * @return static + */ public static function forEmptyController() { return new static(self::lang('HTTP.emptyController')); } + /** + * @return static + */ public static function forControllerNotFound(string $controller, string $method) { return new static(self::lang('HTTP.controllerNotFound', [$controller, $method])); } + /** + * @return static + */ public static function forMethodNotFound(string $method) { return new static(self::lang('HTTP.methodNotFound', [$method])); } + /** + * @return static + */ public static function forLocaleNotSupported(string $locale) { return new static(self::lang('HTTP.localeNotSupported', [$locale])); diff --git a/system/Exceptions/TestException.php b/system/Exceptions/TestException.php index a1c4c51cf814..dadbbc002b9a 100644 --- a/system/Exceptions/TestException.php +++ b/system/Exceptions/TestException.php @@ -18,6 +18,9 @@ class TestException extends CriticalError { use DebugTraceableTrait; + /** + * @return static + */ public static function forInvalidMockClass(string $name) { return new static(lang('Test.invalidMockClass', [$name])); diff --git a/system/Files/Exceptions/FileException.php b/system/Files/Exceptions/FileException.php index 03af1bc57b08..b877bad2795c 100644 --- a/system/Files/Exceptions/FileException.php +++ b/system/Files/Exceptions/FileException.php @@ -19,6 +19,9 @@ class FileException extends RuntimeException implements ExceptionInterface { use DebugTraceableTrait; + /** + * @return static + */ public static function forUnableToMove(?string $from = null, ?string $to = null, ?string $error = null) { return new static(lang('Files.cannotMove', [$from, $to, $error])); @@ -28,6 +31,8 @@ public static function forUnableToMove(?string $from = null, ?string $to = null, * Throws when an item is expected to be a directory but is not or is missing. * * @param string $caller The method causing the exception + * + * @return static */ public static function forExpectedDirectory(string $caller) { @@ -38,6 +43,8 @@ public static function forExpectedDirectory(string $caller) * Throws when an item is expected to be a file but is not or is missing. * * @param string $caller The method causing the exception + * + * @return static */ public static function forExpectedFile(string $caller) { diff --git a/system/Files/Exceptions/FileNotFoundException.php b/system/Files/Exceptions/FileNotFoundException.php index 1e0a50f0bd3f..1c0f4cfd22eb 100644 --- a/system/Files/Exceptions/FileNotFoundException.php +++ b/system/Files/Exceptions/FileNotFoundException.php @@ -19,6 +19,9 @@ class FileNotFoundException extends RuntimeException implements ExceptionInterfa { use DebugTraceableTrait; + /** + * @return static + */ public static function forFileNotFound(string $path) { return new static(lang('Files.fileNotFound', [$path])); diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php index 784c45c48be6..e4070b9eeccc 100644 --- a/system/Filters/Filters.php +++ b/system/Filters/Filters.php @@ -121,7 +121,7 @@ public function __construct($config, RequestInterface $request, ResponseInterfac * Sample : * $filters->aliases['custom-auth'] = \Acme\Blob\Filters\BlobAuth::class; */ - private function discoverFilters() + private function discoverFilters(): void { $locator = Services::locator(); @@ -144,6 +144,8 @@ private function discoverFilters() /** * Set the response explicitly. + * + * @return void */ public function setResponse(ResponseInterface $response) { @@ -154,7 +156,9 @@ public function setResponse(ResponseInterface $response) * Runs through all of the filters for the specified * uri and position. * - * @return mixed|RequestInterface|ResponseInterface + * @param string $uri URI path relative to baseURL + * + * @return RequestInterface|ResponseInterface|string|null * * @throws FilterException */ @@ -219,6 +223,8 @@ public function run(string $uri, string $position = 'before') * run through both a before and after and don't want to double * process the rows. * + * @param string|null $uri URI path relative to baseURL (all lowercase) + * * @return Filters */ public function initialize(?string $uri = null) @@ -389,7 +395,9 @@ public function getArguments(?string $key = null) /** * Add any applicable (not excluded) global filter settings to the mix. * - * @param string $uri + * @param string|null $uri URI path relative to baseURL (all lowercase) + * + * @return void */ protected function processGlobals(?string $uri = null) { @@ -412,7 +420,7 @@ protected function processGlobals(?string $uri = null) if (isset($rules['except'])) { // grab the exclusion rules $check = $rules['except']; - if ($this->pathApplies($uri, $check)) { + if ($this->checkExcept($uri, $check)) { $keep = false; } } @@ -430,6 +438,8 @@ protected function processGlobals(?string $uri = null) /** * Add any method-specific filters to the mix. + * + * @return void */ protected function processMethods() { @@ -448,7 +458,9 @@ protected function processMethods() /** * Add any applicable configured filters to the mix. * - * @param string $uri + * @param string|null $uri URI path relative to baseURL (all lowercase) + * + * @return void */ protected function processFilters(?string $uri = null) { @@ -480,6 +492,8 @@ protected function processFilters(?string $uri = null) /** * Maps filter aliases to the equivalent filter classes * + * @return void + * * @throws FilterException */ protected function processAliasesToClass(string $position) @@ -526,12 +540,47 @@ private function pathApplies(string $uri, $paths) $paths = [$paths]; } - // treat each paths as pseudo-regex + return $this->checkPseudoRegex($uri, $paths); + } + + /** + * Check except paths + * + * @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. + */ + private function checkExcept(string $uri, $paths): bool + { + // empty array does not match anything + if ($paths === []) { + return false; + } + + // make sure the paths are iterable + if (is_string($paths)) { + $paths = [$paths]; + } + + return $this->checkPseudoRegex($uri, $paths); + } + + /** + * Check the URI path as pseudo-regex + * + * @param string $uri URI path relative to baseURL (all lowercase) + * @param array $paths The except path patterns + */ + private function checkPseudoRegex(string $uri, array $paths): bool + { + // treat each path as pseudo-regex foreach ($paths as $path) { // need to escape path separators $path = str_replace('/', '\/', trim($path, '/ ')); // need to make pseudo wildcard real $path = strtolower(str_replace('*', '.*', $path)); + // Does this rule apply here? if (preg_match('#^' . $path . '$#', $uri, $match) === 1) { return true; diff --git a/system/Format/Exceptions/FormatException.php b/system/Format/Exceptions/FormatException.php index 5fef64eae2a1..cfe39d3b8307 100644 --- a/system/Format/Exceptions/FormatException.php +++ b/system/Format/Exceptions/FormatException.php @@ -25,7 +25,7 @@ class FormatException extends RuntimeException implements ExceptionInterface /** * Thrown when the instantiated class does not exist. * - * @return FormatException + * @return static */ public static function forInvalidFormatter(string $class) { @@ -38,7 +38,7 @@ public static function forInvalidFormatter(string $class) * * @param string $error * - * @return FormatException + * @return static */ public static function forInvalidJSON(?string $error = null) { @@ -49,7 +49,7 @@ public static function forInvalidJSON(?string $error = null) * Thrown when the supplied MIME type has no * defined Formatter class. * - * @return FormatException + * @return static */ public static function forInvalidMime(string $mime) { @@ -60,7 +60,7 @@ public static function forInvalidMime(string $mime) * Thrown on XMLFormatter when the `simplexml` extension * is not installed. * - * @return FormatException + * @return static * * @codeCoverageIgnore */ diff --git a/system/Format/XMLFormatter.php b/system/Format/XMLFormatter.php index 322ac32d2abd..23ed57fadf84 100644 --- a/system/Format/XMLFormatter.php +++ b/system/Format/XMLFormatter.php @@ -53,6 +53,8 @@ public function format($data) * @see http://www.codexworld.com/convert-array-to-xml-in-php/ * * @param SimpleXMLElement $output + * + * @return void */ protected function arrayToXML(array $data, &$output) { diff --git a/system/HTTP/CLIRequest.php b/system/HTTP/CLIRequest.php index 31b0f36f7ff6..ef10d101e05b 100644 --- a/system/HTTP/CLIRequest.php +++ b/system/HTTP/CLIRequest.php @@ -175,6 +175,8 @@ public function getOptionString(bool $useLongOpts = false): string * * NOTE: I tried to use getopt but had it fail occasionally to find * any options, where argv has always had our back. + * + * @return void */ protected function parseCommand() { diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php index 019b12e2b8df..09e65455882a 100644 --- a/system/HTTP/CURLRequest.php +++ b/system/HTTP/CURLRequest.php @@ -151,6 +151,8 @@ public function request($method, string $url, array $options = []): ResponseInte /** * Reset all options to default. + * + * @return void */ protected function resetOptions() { @@ -277,6 +279,8 @@ public function setJSON($data) /** * Sets the correct settings based on the options array * passed in. + * + * @return void */ protected function parseOptions(array $options) { @@ -479,6 +483,8 @@ protected function applyBody(array $curlOptions = []): array /** * Parses the header retrieved from the cURL response into * our Response object. + * + * @return void */ protected function setResponseHeaders(array $headers = []) { diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index deb5093e86a8..2a90c3c6473b 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -298,6 +298,8 @@ public function getScriptNonce(): string * Compiles and sets the appropriate headers in the request. * * Should be called just prior to sending the response to the user agent. + * + * @return void */ public function finalize(ResponseInterface $response) { @@ -641,6 +643,8 @@ public function upgradeInsecureRequests(bool $value = true) * DRY method to add an string or array to a class property. * * @param array|string $options + * + * @return void */ protected function addOption($options, string $target, ?bool $explicitReporting = null) { @@ -662,6 +666,8 @@ protected function addOption($options, string $target, ?bool $explicitReporting * Scans the body of the request message and replaces any nonce * placeholders with actual nonces, that we'll then add to our * headers. + * + * @return void */ protected function generateNonces(ResponseInterface $response) { @@ -688,6 +694,8 @@ protected function generateNonces(ResponseInterface $response) * Based on the current state of the elements, will add the appropriate * Content-Security-Policy and Content-Security-Policy-Report-Only headers * with their values to the response object. + * + * @return void */ protected function buildHeaders(ResponseInterface $response) { @@ -768,6 +776,8 @@ protected function buildHeaders(ResponseInterface $response) * reportOnly header, since it's viable to have both simultaneously. * * @param array|string|null $values + * + * @return void */ protected function addToHeader(string $name, $values = null) { diff --git a/system/HTTP/DownloadResponse.php b/system/HTTP/DownloadResponse.php index d8fb8c035a03..9753ef0239c0 100644 --- a/system/HTTP/DownloadResponse.php +++ b/system/HTTP/DownloadResponse.php @@ -76,6 +76,8 @@ public function __construct(string $filename, bool $setMime) /** * set download for binary string. + * + * @return void */ public function setBinary(string $binary) { @@ -88,6 +90,8 @@ public function setBinary(string $binary) /** * set download for file. + * + * @return void */ public function setFilePath(string $filepath) { @@ -129,7 +133,7 @@ public function getContentLength(): int /** * Set content type by guessing mime type from file extension */ - private function setContentTypeByMimeType() + private function setContentTypeByMimeType(): void { $mime = null; $charset = ''; @@ -262,6 +266,8 @@ public function send() /** * set header for file download. + * + * @return void */ public function buildHeaders() { diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php index 37c44a88d45d..2284cb237aac 100644 --- a/system/HTTP/Files/FileCollection.php +++ b/system/HTTP/Files/FileCollection.php @@ -135,6 +135,8 @@ public function hasFile(string $fileID): bool * of UploadedFile for each one, saving the results to this->files. * * Called by files(), file(), and hasFile() + * + * @return void */ protected function populateFiles() { diff --git a/system/HTTP/Files/UploadedFileInterface.php b/system/HTTP/Files/UploadedFileInterface.php index 37c18554a106..4d3835d301fc 100644 --- a/system/HTTP/Files/UploadedFileInterface.php +++ b/system/HTTP/Files/UploadedFileInterface.php @@ -59,6 +59,8 @@ public function __construct(string $path, string $originalName, ?string $mimeTyp * @param string $targetPath Path to which to move the uploaded file. * @param string $name the name to rename the file to. * + * @return bool + * * @throws InvalidArgumentException if the $path specified is invalid. * @throws RuntimeException on any error during the move operation. * @throws RuntimeException on the second or subsequent call to the method. diff --git a/system/HTTP/IncomingRequest.php b/system/HTTP/IncomingRequest.php index 8eeaefdb0ed8..07c788528a13 100755 --- a/system/HTTP/IncomingRequest.php +++ b/system/HTTP/IncomingRequest.php @@ -208,6 +208,8 @@ private function getPostMaxSize(): int * content negotiation. * * @param App $config + * + * @return void */ public function detectLocale($config) { @@ -226,6 +228,8 @@ public function detectLocale($config) * determined from the environment as needed. * * @deprecated $protocol and $baseURL are deprecated. No longer used. + * + * @return void */ protected function detectURI(string $protocol, string $baseURL) { @@ -796,6 +800,7 @@ public function getPostGet($index = null, $filter = null, $flags = null) if ($index === null) { return array_merge($this->getGet($index, $filter, $flags), $this->getPost($index, $filter, $flags)); } + // Use $_POST directly here, since filter_has_var only // checks the initial POST data, not anything that might // have been added since. @@ -818,6 +823,7 @@ public function getGetPost($index = null, $filter = null, $flags = null) if ($index === null) { return array_merge($this->getPost($index, $filter, $flags), $this->getGet($index, $filter, $flags)); } + // Use $_GET directly here, since filter_has_var only // checks the initial GET data, not anything that might // have been added since. diff --git a/system/HTTP/RequestTrait.php b/system/HTTP/RequestTrait.php index 57f97982dea4..427f7fe354dc 100644 --- a/system/HTTP/RequestTrait.php +++ b/system/HTTP/RequestTrait.php @@ -337,6 +337,8 @@ public function fetchGlobal(string $method, $index = null, ?int $filter = null, /** * Saves a copy of the current state of one of several PHP globals * so we can retrieve them later. + * + * @return void */ protected function populateGlobals(string $method) { diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php index 2ab026c9ba82..7c0741317bc0 100644 --- a/system/HTTP/ResponseTrait.php +++ b/system/HTTP/ResponseTrait.php @@ -718,6 +718,8 @@ public function getCookies() /** * Actually sets the cookies. + * + * @return void */ protected function sendCookies() { diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index b88712e18c76..ab52fa46f5c9 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -946,6 +946,8 @@ protected function filterPath(?string $path = null): string /** * Saves our parts from a parse_url call. + * + * @return void */ protected function applyParts(array $parts) { diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php index ff1c68c4d54c..4b579229d88f 100644 --- a/system/HTTP/UserAgent.php +++ b/system/HTTP/UserAgent.php @@ -247,6 +247,8 @@ public function getReferrer(): string /** * Parse a custom user-agent string + * + * @return void */ public function parse(string $string) { @@ -269,6 +271,8 @@ public function parse(string $string) /** * Compile the User Agent Data + * + * @return void */ protected function compileData() { diff --git a/system/Helpers/cookie_helper.php b/system/Helpers/cookie_helper.php index 9fc004c28b9a..222671694d2b 100755 --- a/system/Helpers/cookie_helper.php +++ b/system/Helpers/cookie_helper.php @@ -9,8 +9,9 @@ * the LICENSE file that was distributed with this source code. */ +use CodeIgniter\Cookie\Cookie; use Config\App; -use Config\Cookie; +use Config\Cookie as CookieConfig; use Config\Services; // ============================================================================= @@ -24,15 +25,17 @@ * Accepts seven parameters, or you can submit an associative * array in the first parameter containing all the values. * - * @param array|string $name Cookie name or array containing binds - * @param string $value The value of the cookie - * @param string $expire The number of seconds until expiration - * @param string $domain For site-wide cookie. Usually: .yourdomain.com - * @param string $path The cookie path - * @param string $prefix The cookie prefix ('': the default prefix) - * @param bool|null $secure True makes the cookie secure - * @param bool|null $httpOnly True makes the cookie accessible via http(s) only (no javascript) - * @param string|null $sameSite The cookie SameSite value + * @param array|Cookie|string $name Cookie name / array containing binds / Cookie object + * @param string $value The value of the cookie + * @param string $expire The number of seconds until expiration + * @param string $domain For site-wide cookie. Usually: .yourdomain.com + * @param string $path The cookie path + * @param string $prefix The cookie prefix ('': the default prefix) + * @param bool|null $secure True makes the cookie secure + * @param bool|null $httpOnly True makes the cookie accessible via http(s) only (no javascript) + * @param string|null $sameSite The cookie SameSite value + * + * @return void * * @see \CodeIgniter\HTTP\Response::setCookie() */ @@ -68,11 +71,11 @@ function set_cookie( function get_cookie($index, bool $xssClean = false, ?string $prefix = '') { if ($prefix === '') { - /** @var Cookie|null $cookie */ - $cookie = config(Cookie::class); + /** @var CookieConfig|null $cookie */ + $cookie = config(CookieConfig::class); // @TODO Remove Config\App fallback when deprecated `App` members are removed. - $prefix = $cookie instanceof Cookie ? $cookie->prefix : config(App::class)->cookiePrefix; + $prefix = $cookie instanceof CookieConfig ? $cookie->prefix : config(App::class)->cookiePrefix; } $request = Services::request(); @@ -91,6 +94,8 @@ function get_cookie($index, bool $xssClean = false, ?string $prefix = '') * @param string $path the cookie path * @param string $prefix the cookie prefix * + * @return void + * * @see \CodeIgniter\HTTP\Response::deleteCookie() */ function delete_cookie($name, string $domain = '', string $path = '/', string $prefix = '') diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php index c553bddee2c3..7f8f191a3a6f 100644 --- a/system/Helpers/form_helper.php +++ b/system/Helpers/form_helper.php @@ -629,8 +629,11 @@ function set_checkbox(string $field, string $value = '', bool $default = false): return ''; } + $session = Services::session(); + $hasOldInput = $session->has('_ci_old_input'); + // Unchecked checkbox and radio inputs are not even submitted by browsers ... - if ((string) $input === '0' || ! empty($request->getPost()) || ! empty(old($field))) { + if ((string) $input === '0' || ! empty($request->getPost()) || $hasOldInput) { return ($input === $value) ? ' checked="checked"' : ''; } diff --git a/system/Helpers/kint_helper.php b/system/Helpers/kint_helper.php index 10c4f34e938d..eaa2e947bc96 100644 --- a/system/Helpers/kint_helper.php +++ b/system/Helpers/kint_helper.php @@ -16,7 +16,9 @@ /** * Prints a Kint debug report and exits. * - * @param array ...$vars + * @param array $vars + * + * @phpstan-return never * * @codeCoverageIgnore Can't be tested ... exits */ @@ -31,6 +33,13 @@ function dd(...$vars) } } else { // In case that Kint is not loaded. + /** + * dd function + * + * @param array $vars + * + * @return int + */ function dd(...$vars) { return 0; @@ -40,6 +49,13 @@ function dd(...$vars) if (! function_exists('d') && ! class_exists(Kint::class)) { // In case that Kint is not loaded. + /** + * d function + * + * @param array $vars + * + * @return int + */ function d(...$vars) { return 0; @@ -51,6 +67,11 @@ function d(...$vars) /** * Provides a backtrace to the current execution point, from Kint. */ + /** + * trace function + * + * @return void + */ function trace() { Kint::$aliases[] = 'trace'; @@ -58,6 +79,11 @@ function trace() } } else { // In case that Kint is not loaded. + /** + * trace function + * + * @return int + */ function trace() { return 0; diff --git a/system/Helpers/number_helper.php b/system/Helpers/number_helper.php index 07d3be942cf5..74173501e177 100644 --- a/system/Helpers/number_helper.php +++ b/system/Helpers/number_helper.php @@ -15,8 +15,7 @@ /** * Formats a numbers as bytes, based on size, and adds the appropriate suffix * - * @param int|string $num Will be cast as int - * @param string $locale + * @param int|string $num Will be cast as int * * @return bool|string */ diff --git a/system/Helpers/test_helper.php b/system/Helpers/test_helper.php index fe6b06794ccd..809a7aabe71b 100644 --- a/system/Helpers/test_helper.php +++ b/system/Helpers/test_helper.php @@ -47,6 +47,8 @@ function fake($model, ?array $overrides = null, $persist = true) * Used within our test suite to mock certain system tools. * * @param string $className Fully qualified class name + * + * @return object */ function mock(string $className) { diff --git a/system/Helpers/text_helper.php b/system/Helpers/text_helper.php index 145515459eba..56cf856fbda7 100755 --- a/system/Helpers/text_helper.php +++ b/system/Helpers/text_helper.php @@ -584,6 +584,7 @@ function random_string(string $type = 'alnum', int $len = 8): string return bin2hex(random_bytes($len / 2)); } + // 'basic' type treated as default return (string) mt_rand(); } diff --git a/system/Honeypot/Exceptions/HoneypotException.php b/system/Honeypot/Exceptions/HoneypotException.php index 8d8510eca8fa..31d13151e980 100644 --- a/system/Honeypot/Exceptions/HoneypotException.php +++ b/system/Honeypot/Exceptions/HoneypotException.php @@ -16,21 +16,41 @@ class HoneypotException extends ConfigException implements ExceptionInterface { + /** + * Thrown when the template value of config is empty. + * + * @return static + */ public static function forNoTemplate() { return new static(lang('Honeypot.noTemplate')); } + /** + * Thrown when the name value of config is empty. + * + * @return static + */ public static function forNoNameField() { return new static(lang('Honeypot.noNameField')); } + /** + * Thrown when the hidden value of config is false. + * + * @return static + */ public static function forNoHiddenValue() { return new static(lang('Honeypot.noHiddenValue')); } + /** + * Thrown when there are no data in the request of honeypot field. + * + * @return static + */ public static function isBot() { return new static(lang('Honeypot.theClientIsABot')); diff --git a/system/Honeypot/Honeypot.php b/system/Honeypot/Honeypot.php index 7ab0cd36737e..6e08c9df8bfe 100644 --- a/system/Honeypot/Honeypot.php +++ b/system/Honeypot/Honeypot.php @@ -59,6 +59,8 @@ public function __construct(HoneypotConfig $config) /** * Checks the request if honeypot field has data. + * + * @return bool */ public function hasContent(RequestInterface $request) { @@ -69,6 +71,8 @@ public function hasContent(RequestInterface $request) /** * Attaches Honeypot template to response. + * + * @return void */ public function attachHoneypot(ResponseInterface $response) { diff --git a/system/I18n/TimeTrait.php b/system/I18n/TimeTrait.php index 5c41618f6861..7f2068b7a30c 100644 --- a/system/I18n/TimeTrait.php +++ b/system/I18n/TimeTrait.php @@ -320,6 +320,8 @@ public function toDateTime() * @param DateTimeInterface|self|string|null $datetime * @param DateTimeZone|string|null $timezone * + * @return void + * * @throws Exception */ public static function setTestNow($datetime = null, $timezone = null, ?string $locale = null) @@ -845,6 +847,8 @@ public function subYears(int $years) /** * Returns the localized value of the date in the format 'Y-m-d H:i:s' * + * @return false|string + * * @throws Exception */ public function toDateTimeString() diff --git a/system/Images/Exceptions/ImageException.php b/system/Images/Exceptions/ImageException.php index 3343f6d0c806..e72a19f8b6d3 100644 --- a/system/Images/Exceptions/ImageException.php +++ b/system/Images/Exceptions/ImageException.php @@ -16,51 +16,101 @@ class ImageException extends FrameworkException implements ExceptionInterface { + /** + * Thrown when the image is not found. + * + * @return static + */ public static function forMissingImage() { return new static(lang('Images.sourceImageRequired')); } + /** + * Thrown when the file specific is not following the role. + * + * @return static + */ public static function forFileNotSupported() { return new static(lang('Images.fileNotSupported')); } + /** + * Thrown when the angle is undefined. + * + * @return static + */ public static function forMissingAngle() { return new static(lang('Images.rotationAngleRequired')); } + /** + * Thrown when the direction property is invalid. + * + * @return static + */ public static function forInvalidDirection(?string $dir = null) { return new static(lang('Images.invalidDirection', [$dir])); } + /** + * Thrown when the path property is invalid. + * + * @return static + */ public static function forInvalidPath() { return new static(lang('Images.invalidPath')); } + /** + * Thrown when the EXIF function is not supported. + * + * @return static + */ public static function forEXIFUnsupported() { return new static(lang('Images.exifNotSupported')); } + /** + * Thrown when the image specific is invalid. + * + * @return static + */ public static function forInvalidImageCreate(?string $extra = null) { return new static(lang('Images.unsupportedImageCreate') . ' ' . $extra); } + /** + * Thrown when the image save failed. + * + * @return static + */ public static function forSaveFailed() { return new static(lang('Images.saveFailed')); } + /** + * Thrown when the image library path is invalid. + * + * @return static + */ public static function forInvalidImageLibraryPath(?string $path = null) { return new static(lang('Images.libPathInvalid', [$path])); } + /** + * Thrown when the image process failed. + * + * @return static + */ public static function forImageProcessFailed() { return new static(lang('Images.imageProcessFailed')); diff --git a/system/Images/Handlers/BaseHandler.php b/system/Images/Handlers/BaseHandler.php index b7d74ae36d15..134c7c6ce1cd 100644 --- a/system/Images/Handlers/BaseHandler.php +++ b/system/Images/Handlers/BaseHandler.php @@ -156,6 +156,8 @@ public function withFile(string $path) /** * Make the image resource object if needed + * + * @return void */ abstract protected function ensureResource(); @@ -422,6 +424,8 @@ public function text(string $text, array $options = []) /** * Handler-specific method for overlaying text on an image. + * + * @return void */ abstract protected function _text(string $text, array $options = []); @@ -722,6 +726,8 @@ public function __call(string $name, array $args = []) * * This function lets us re-proportion the width/height * if users choose to maintain the aspect ratio when resizing. + * + * @return void */ protected function reproportion() { diff --git a/system/Images/Handlers/ImageMagickHandler.php b/system/Images/Handlers/ImageMagickHandler.php index 41274c6a9591..3d7eea0504e6 100644 --- a/system/Images/Handlers/ImageMagickHandler.php +++ b/system/Images/Handlers/ImageMagickHandler.php @@ -290,6 +290,8 @@ protected function getResourcePath() /** * Make the image resource object if needed * + * @return void + * * @throws Exception */ protected function ensureResource() @@ -302,6 +304,8 @@ protected function ensureResource() /** * Check if given image format is supported * + * @return void + * * @throws ImageException */ protected function supportedFormatCheck() @@ -318,6 +322,8 @@ protected function supportedFormatCheck() /** * Handler-specific method for overlaying text on an image. * + * @return void + * * @throws Exception */ protected function _text(string $text, array $options = []) diff --git a/system/Log/Exceptions/LogException.php b/system/Log/Exceptions/LogException.php index f79763622cc7..c5f8b97999af 100644 --- a/system/Log/Exceptions/LogException.php +++ b/system/Log/Exceptions/LogException.php @@ -15,11 +15,17 @@ class LogException extends FrameworkException { + /** + * @return static + */ public static function forInvalidLogLevel(string $level) { return new static(lang('Log.invalidLogLevel', [$level])); } + /** + * @return static + */ public static function forInvalidMessageType(string $messageType) { return new static(lang('Log.invalidMessageType', [$messageType])); diff --git a/system/Log/Handlers/ChromeLoggerHandler.php b/system/Log/Handlers/ChromeLoggerHandler.php index b2c6d28fdfb4..9ce30a822364 100644 --- a/system/Log/Handlers/ChromeLoggerHandler.php +++ b/system/Log/Handlers/ChromeLoggerHandler.php @@ -150,6 +150,8 @@ protected function format($object) * Attaches the header and the content to the passed in request object. * * @param ResponseInterface $response + * + * @return void */ public function sendLogs(?ResponseInterface &$response = null) { diff --git a/system/Model.php b/system/Model.php index a9c8e4f2eba9..e53c0aae4bd1 100644 --- a/system/Model.php +++ b/system/Model.php @@ -20,6 +20,7 @@ use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\Database\Query; +use CodeIgniter\Entity\Entity; use CodeIgniter\Exceptions\ModelException; use CodeIgniter\I18n\Time; use CodeIgniter\Validation\ValidationInterface; @@ -78,6 +79,8 @@ * @method $this selectMax(string $select = '', string $alias = '') * @method $this selectMin(string $select = '', string $alias = '') * @method $this selectSum(string $select = '', string $alias = '') + * @method $this when($condition, callable $callback, ?callable $defaultCallback = null) + * @method $this whenNot($condition, callable $callback, ?callable $defaultCallback = null) * @method $this where($key, $value = null, ?bool $escape = null) * @method $this whereIn(?string $key = null, $values = null, ?bool $escape = null) * @method $this whereNotIn(?string $key = null, $values = null, ?bool $escape = null) @@ -129,13 +132,6 @@ class Model extends BaseModel */ protected $escape = []; - /** - * Primary Key value when inserting and useAutoIncrement is false. - * - * @var int|string|null - */ - private $tempPrimaryKeyValue; - /** * Builder method names that should not be used in the Model. * @@ -281,13 +277,6 @@ protected function doInsert(array $data) $escape = $this->escape; $this->escape = []; - // If $useAutoIncrement is false, add the primary key data. - if ($this->useAutoIncrement === false && $this->tempPrimaryKeyValue !== null) { - $data[$this->primaryKey] = $this->tempPrimaryKeyValue; - - $this->tempPrimaryKeyValue = null; - } - // Require non-empty primaryKey when // not using auto-increment feature if (! $this->useAutoIncrement && empty($data[$this->primaryKey])) { @@ -474,6 +463,8 @@ protected function doPurgeDeleted() * Works with the find* methods to return only the rows that * have been deleted. * This method works only with dbCalls. + * + * @return void */ protected function doOnlyDeleted() { @@ -554,6 +545,8 @@ public function getIdValue($data) * determine the rows to operate on. * This method works only with dbCalls. * + * @return void + * * @throws DataException */ public function chunk(int $size, Closure $userFunc) @@ -716,20 +709,47 @@ public function insert($data = null, bool $returnID = true) } } - if ($this->useAutoIncrement === false) { - if (is_array($data) && isset($data[$this->primaryKey])) { - $this->tempPrimaryKeyValue = $data[$this->primaryKey]; - } elseif (is_object($data) && isset($data->{$this->primaryKey})) { - $this->tempPrimaryKeyValue = $data->{$this->primaryKey}; - } - } - $this->escape = $this->tempData['escape'] ?? []; $this->tempData = []; return parent::insert($data, $returnID); } + /** + * Ensures that only the fields that are allowed to be inserted are in + * the data array. + * + * Used by insert() and insertBatch() to protect against mass assignment + * vulnerabilities. + * + * @param array $data Data + * + * @throws DataException + */ + protected function doProtectFieldsForInsert(array $data): array + { + if (! $this->protectFields) { + return $data; + } + + if (empty($this->allowedFields)) { + throw DataException::forInvalidAllowedFields(static::class); + } + + foreach (array_keys($data) as $key) { + // Do not remove the non-auto-incrementing primary key data. + if ($this->useAutoIncrement === false && $key === $this->primaryKey) { + continue; + } + + if (! in_array($key, $this->allowedFields, true)) { + unset($data[$key]); + } + } + + return $data; + } + /** * Updates a single record in the database. If an object is provided, * it will attempt to convert it into an array. @@ -757,11 +777,11 @@ public function update($id = null, $data = null): bool } /** - * Takes a class an returns an array of it's public and protected + * Takes a class and returns an array of its public and protected * properties as an array with raw values. * * @param object|string $data - * @param bool $recursive If true, inner entities will be casted as array as well + * @param bool $recursive If true, inner entities will be cast as array as well * * @return array|null Array * @@ -771,17 +791,32 @@ protected function objectToRawArray($data, bool $onlyChanged = true, bool $recur { $properties = parent::objectToRawArray($data, $onlyChanged); + $primaryKey = null; + + if ($data instanceof Entity) { + $cast = $data->cast(); + + // Disable Entity casting, because raw primary key data is needed for database. + $data->cast(false); + + $primaryKey = $data->{$this->primaryKey}; + + // Restore Entity casting setting. + $data->cast($cast); + } + // Always grab the primary key otherwise updates will fail. if ( + // @TODO Should use `$data instanceof Entity`. method_exists($data, 'toRawArray') && ( ! empty($properties) && ! empty($this->primaryKey) && ! in_array($this->primaryKey, $properties, true) - && ! empty($data->{$this->primaryKey}) + && ! empty($primaryKey) ) ) { - $properties[$this->primaryKey] = $data->{$this->primaryKey}; + $properties[$this->primaryKey] = $primaryKey; } return $properties; diff --git a/system/Pager/Exceptions/PagerException.php b/system/Pager/Exceptions/PagerException.php index b1cb6072816f..6f1032f7281d 100644 --- a/system/Pager/Exceptions/PagerException.php +++ b/system/Pager/Exceptions/PagerException.php @@ -15,11 +15,21 @@ class PagerException extends FrameworkException { + /** + * Throws when the template is invalid. + * + * @return static + */ public static function forInvalidTemplate(?string $template = null) { return new static(lang('Pager.invalidTemplate', [$template])); } + /** + * Throws when the group is invalid. + * + * @return static + */ public static function forInvalidPaginationGroup(?string $group = null) { return new static(lang('Pager.invalidPaginationGroup', [$group])); diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php index 2c0179a69dc3..2c666e2ce579 100644 --- a/system/Pager/Pager.php +++ b/system/Pager/Pager.php @@ -123,7 +123,7 @@ protected function displayLinks(string $group, string $template): string $pager = new PagerRenderer($this->getDetails($group)); return $this->view->setVar('pager', $pager) - ->render($this->config->templates[$template], null, false); + ->render($this->config->templates[$template]); } /** @@ -388,6 +388,8 @@ public function only(array $queries): self * Ensures that an array exists for the group specified. * * @param int $perPage + * + * @return void */ protected function ensureGroup(string $group, ?int $perPage = null) { @@ -414,6 +416,8 @@ protected function ensureGroup(string $group, ?int $perPage = null) /** * Calculating the current page + * + * @return void */ protected function calculateCurrentPage(string $group) { diff --git a/system/Pager/PagerRenderer.php b/system/Pager/PagerRenderer.php index 9206a482323b..024ffd095673 100644 --- a/system/Pager/PagerRenderer.php +++ b/system/Pager/PagerRenderer.php @@ -289,6 +289,8 @@ public function links(): array * to show. * * @param int|null $count The new "surroundCount" + * + * @return void */ protected function updatePages(?int $count = null) { diff --git a/system/Publisher/Exceptions/PublisherException.php b/system/Publisher/Exceptions/PublisherException.php index 535d3a757d15..5204897c975e 100644 --- a/system/Publisher/Exceptions/PublisherException.php +++ b/system/Publisher/Exceptions/PublisherException.php @@ -25,6 +25,8 @@ class PublisherException extends FrameworkException * * @param string $from The source file * @param string $to The destination file + * + * @return static */ public static function forCollision(string $from, string $to) { @@ -33,6 +35,8 @@ public static function forCollision(string $from, string $to) /** * Throws when given a destination that is not in the list of allowed directories. + * + * @return static */ public static function forDestinationNotAllowed(string $destination) { @@ -41,6 +45,8 @@ public static function forDestinationNotAllowed(string $destination) /** * Throws when a file fails to match the allowed pattern for its destination. + * + * @return static */ public static function forFileNotAllowed(string $file, string $directory, string $pattern) { diff --git a/system/Publisher/Publisher.php b/system/Publisher/Publisher.php index 82948b8378c1..e40a14c88905 100644 --- a/system/Publisher/Publisher.php +++ b/system/Publisher/Publisher.php @@ -466,7 +466,7 @@ public function addLineBefore(string $file, string $line, string $before): bool /** * Verify this is an allowed file for its destination. */ - private function verifyAllowed(string $from, string $to) + private function verifyAllowed(string $from, string $to): void { // Verify this is an allowed file for its destination foreach ($this->restrictions as $directory => $pattern) { diff --git a/system/RESTful/BaseResource.php b/system/RESTful/BaseResource.php index 108c63ce9be6..1c21f65da860 100644 --- a/system/RESTful/BaseResource.php +++ b/system/RESTful/BaseResource.php @@ -39,6 +39,8 @@ abstract class BaseResource extends Controller /** * Constructor. + * + * @return void */ public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { @@ -52,6 +54,8 @@ public function initController(RequestInterface $request, ResponseInterface $res * Given either the name or the object, determine the other. * * @param object|string|null $which + * + * @return void */ public function setModel($which = null) { diff --git a/system/Router/AutoRouter.php b/system/Router/AutoRouter.php index 1475def4fb53..f7cd02a3d329 100644 --- a/system/Router/AutoRouter.php +++ b/system/Router/AutoRouter.php @@ -254,6 +254,8 @@ private function isValidSegment(string $segment): bool * @param bool $validate if true, checks to make sure $dir consists of only PSR4 compliant segments * * @deprecated This method should be removed. + * + * @return void */ public function setDirectory(?string $dir = null, bool $append = false, bool $validate = true) { diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 488315193454..8fa3054edf1d 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -274,6 +274,8 @@ public function loadRoutes(string $routesFile = APPPATH . 'Config/Routes.php') /** * Will attempt to discover any additional routes, either through * the local PSR4 namespaces, or through selected Composer packages. + * + * @return void */ protected function discoverRoutes() { @@ -659,6 +661,8 @@ public function getRedirectCode(string $from): int * * @param string $name The name to group/prefix the routes with. * @param array|callable ...$params + * + * @return void */ public function group(string $name, ...$params) { @@ -1291,6 +1295,8 @@ private function replaceLocale(string $route, ?string $locale = null): string * by a pipe character "|" if there is more than one. * * @param array|Closure|string $to + * + * @return void */ protected function create(string $verb, string $from, $to, ?array $options = null) { @@ -1536,6 +1542,8 @@ private function determineCurrentSubdomain() /** * Reset the routes, so that a test case can provide the * explicit ones needed for it. + * + * @return void */ public function resetRoutes() { diff --git a/system/Router/Router.php b/system/Router/Router.php index f0b9d2c9aab5..5dee59b31c25 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -503,6 +503,8 @@ protected function checkRoutes(string $uri): bool * * Attempts to match a URI path against Controllers and directories * found in APPPATH/Controllers, to find a matching route. + * + * @return void */ public function autoRoute(string $uri) { @@ -579,6 +581,8 @@ protected function scanControllers(array $segments): array * * @param bool $validate if true, checks to make sure $dir consists of only PSR4 compliant segments * + * @return void + * * @deprecated This method should be removed. */ public function setDirectory(?string $dir = null, bool $append = false, bool $validate = true) @@ -611,6 +615,8 @@ private function isValidSegment(string $segment): bool * to be called. * * @param array $segments URI segments + * + * @return void */ protected function setRequest(array $segments = []) { @@ -638,6 +644,8 @@ protected function setRequest(array $segments = []) * Sets the default controller based on the info set in the RouteCollection. * * @deprecated This was an unnecessary method, so it is no longer used. + * + * @return void */ protected function setDefaultController() { diff --git a/system/Security/Exceptions/SecurityException.php b/system/Security/Exceptions/SecurityException.php index 68683c324730..ab2f6adc7f43 100644 --- a/system/Security/Exceptions/SecurityException.php +++ b/system/Security/Exceptions/SecurityException.php @@ -16,11 +16,24 @@ class SecurityException extends FrameworkException implements HTTPExceptionInterface { + /** + * Throws when some specific action is not allowed. + * + * @return static + */ public static function forDisallowedAction() { return new static(lang('Security.disallowedAction'), 403); } + /** + * Throws when the source string contains invalid UTF-8 characters. + * + * @param string $source The source string + * @param string $string The invalid string + * + * @return static + */ public static function forInvalidUTF8Chars(string $source, string $string) { return new static( @@ -29,6 +42,14 @@ public static function forInvalidUTF8Chars(string $source, string $string) ); } + /** + * Throws when the source string contains invalid control characters. + * + * @param string $source The source string + * @param string $string The invalid string + * + * @return static + */ public static function forInvalidControlChars(string $source, string $string) { return new static( @@ -41,6 +62,8 @@ public static function forInvalidControlChars(string $source, string $string) * @deprecated Use `CookieException::forInvalidSameSite()` instead. * * @codeCoverageIgnore + * + * @return static */ public static function forInvalidSameSite(string $samesite) { diff --git a/system/Session/Handlers/RedisHandler.php b/system/Session/Handlers/RedisHandler.php index 56b725327dd7..9d427f381152 100644 --- a/system/Session/Handlers/RedisHandler.php +++ b/system/Session/Handlers/RedisHandler.php @@ -78,14 +78,14 @@ public function __construct(AppConfig $config, string $ipAddress) if ($session instanceof SessionConfig) { $this->sessionExpiration = empty($session->expiration) ? (int) ini_get('session.gc_maxlifetime') - : (int) $session->expiration; + : $session->expiration; // Add sessionCookieName for multiple session cookies. $this->keyPrefix .= $session->cookieName . ':'; } else { // `Config/Session.php` is absence $this->sessionExpiration = empty($config->sessionExpiration) ? (int) ini_get('session.gc_maxlifetime') - : (int) $config->sessionExpiration; + : $config->sessionExpiration; // Add sessionCookieName for multiple session cookies. $this->keyPrefix .= $config->sessionCookieName . ':'; } diff --git a/system/Test/Mock/MockCache.php b/system/Test/Mock/MockCache.php index f0414bb8bf02..73a755802285 100644 --- a/system/Test/Mock/MockCache.php +++ b/system/Test/Mock/MockCache.php @@ -42,6 +42,8 @@ class MockCache extends BaseHandler implements CacheInterface /** * Takes care of any handler-specific setup that must be done. + * + * @return void */ public function initialize() { diff --git a/system/Test/TestResponse.php b/system/Test/TestResponse.php index 62706158617b..d66728c5d0db 100644 --- a/system/Test/TestResponse.php +++ b/system/Test/TestResponse.php @@ -134,6 +134,7 @@ public function isOK(): bool if ($status >= 400 || $status < 200) { return false; } + // Empty bodies are not considered valid, unless in redirects return ! ($status < 300 && empty($this->response->getBody())); } diff --git a/system/Traits/PropertiesTrait.php b/system/Traits/PropertiesTrait.php index d05c36e14115..4983ed68f252 100644 --- a/system/Traits/PropertiesTrait.php +++ b/system/Traits/PropertiesTrait.php @@ -45,7 +45,7 @@ final public function fill(array $params): self final public function getPublicProperties(): array { $worker = new class () { - public function getProperties($obj) + public function getProperties(object $obj): array { return get_object_vars($obj); } diff --git a/system/Validation/Exceptions/ValidationException.php b/system/Validation/Exceptions/ValidationException.php index 2e924fffc937..83772adb5a83 100644 --- a/system/Validation/Exceptions/ValidationException.php +++ b/system/Validation/Exceptions/ValidationException.php @@ -15,26 +15,51 @@ class ValidationException extends FrameworkException { + /** + * Throws when the validation rule is not found. + * + * @return static + */ public static function forRuleNotFound(?string $rule = null) { return new static(lang('Validation.ruleNotFound', [$rule])); } + /** + * Throws when the group value of config is not set. + * + * @return static + */ public static function forGroupNotFound(?string $group = null) { return new static(lang('Validation.groupNotFound', [$group])); } + /** + * Throws when the group value of config is not array type. + * + * @return static + */ public static function forGroupNotArray(?string $group = null) { return new static(lang('Validation.groupNotArray', [$group])); } + /** + * Throws when the template of config is invalid. + * + * @return static + */ public static function forInvalidTemplate(?string $template = null) { return new static(lang('Validation.invalidTemplate', [$template])); } + /** + * Throws when there is no any rule set. + * + * @return static + */ public static function forNoRuleSets() { return new static(lang('Validation.noRuleSets')); diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index 91e441356112..4ed4d089c4cb 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -107,6 +107,8 @@ public function __construct($config, RendererInterface $view) $this->config = $config; $this->view = $view; + + $this->loadRuleSets(); } /** @@ -127,7 +129,6 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup // `DBGroup` is a reserved name. For is_unique and is_not_unique $data['DBGroup'] = $dbGroup; - $this->loadRuleSets(); $this->loadRuleGroup($group); // If no rules exist, we return false to ensure @@ -593,6 +594,8 @@ public function getRuleGroup(string $group): array * * @param string $group Group. * + * @return void + * * @throws ValidationException If group not found. */ public function setRuleGroup(string $group) @@ -645,6 +648,8 @@ public function showError(string $field, string $template = 'single'): string /** * Loads all of the rulesets classes that have been defined in the * Config\Validation and stores them locally so we can use them. + * + * @return void */ protected function loadRuleSets() { diff --git a/system/Validation/ValidationInterface.php b/system/Validation/ValidationInterface.php index 9336c26e7f62..ef4004f43a96 100644 --- a/system/Validation/ValidationInterface.php +++ b/system/Validation/ValidationInterface.php @@ -92,6 +92,8 @@ public function getRuleGroup(string $group): array; * Set rule group. * * @param string $group Group. + * + * @return void */ public function setRuleGroup(string $group); diff --git a/system/View/Cell.php b/system/View/Cell.php index 5c4d0ce2e99f..223d694f6308 100644 --- a/system/View/Cell.php +++ b/system/View/Cell.php @@ -234,7 +234,7 @@ final protected function renderCell(BaseCell $instance, string $method, array $p * for a method, in the order they are defined. This allows * them to be passed directly into the method. */ - private function getMethodParams(BaseCell $instance, string $method, array $params) + private function getMethodParams(BaseCell $instance, string $method, array $params): array { $mountParams = []; diff --git a/system/View/Cells/Cell.php b/system/View/Cells/Cell.php index 962f89217861..dc97fd996544 100644 --- a/system/View/Cells/Cell.php +++ b/system/View/Cells/Cell.php @@ -51,6 +51,8 @@ public function render(): string /** * Sets the view to use when rendered. + * + * @return $this */ public function setView(string $view) { diff --git a/system/View/Exceptions/ViewException.php b/system/View/Exceptions/ViewException.php index 3e07893ffec2..84ab72c54462 100644 --- a/system/View/Exceptions/ViewException.php +++ b/system/View/Exceptions/ViewException.php @@ -15,36 +15,57 @@ class ViewException extends FrameworkException { + /** + * @return static + */ public static function forInvalidCellMethod(string $class, string $method) { return new static(lang('View.invalidCellMethod', ['class' => $class, 'method' => $method])); } + /** + * @return static + */ public static function forMissingCellParameters(string $class, string $method) { return new static(lang('View.missingCellParameters', ['class' => $class, 'method' => $method])); } + /** + * @return static + */ public static function forInvalidCellParameter(string $key) { return new static(lang('View.invalidCellParameter', [$key])); } + /** + * @return static + */ public static function forNoCellClass() { return new static(lang('View.noCellClass')); } + /** + * @return static + */ public static function forInvalidCellClass(?string $class = null) { return new static(lang('View.invalidCellClass', [$class])); } + /** + * @return static + */ public static function forTagSyntaxError(string $output) { return new static(lang('View.tagSyntaxError', [$output])); } + /** + * @return static + */ public static function forInvalidDecorator(string $className) { return new static(lang('View.invalidDecoratorClass', [$className])); diff --git a/system/View/Table.php b/system/View/Table.php index a7ded4fd5cb7..bb1ef5dd858d 100644 --- a/system/View/Table.php +++ b/system/View/Table.php @@ -411,6 +411,8 @@ public function clear() * Set table data from a database result object * * @param BaseResult $object Database result object + * + * @return void */ protected function _setFromDBResult($object) { @@ -428,6 +430,8 @@ protected function _setFromDBResult($object) * Set table data from an array * * @param array $data + * + * @return void */ protected function _setFromArray($data) { @@ -442,6 +446,8 @@ protected function _setFromArray($data) /** * Compile Template + * + * @return void */ protected function _compileTemplate() { diff --git a/system/View/View.php b/system/View/View.php index 164d67642305..63969f3bd184 100644 --- a/system/View/View.php +++ b/system/View/View.php @@ -29,14 +29,16 @@ class View implements RendererInterface use ViewDecoratorTrait; /** - * Data that is made available to the Views. + * Saved Data. * * @var array */ protected $data = []; /** - * Merge savedData and userData + * Data for the variables that are available in the Views. + * + * @var array|null */ protected $tempData; @@ -48,7 +50,7 @@ class View implements RendererInterface protected $viewPath; /** - * The render variables + * Data for rendering including Caching and Debug Toolbar data. * * @var array */ @@ -382,6 +384,8 @@ public function getData(): array /** * Specifies that the current view should extend an existing layout. + * + * @return void */ public function extend(string $layout) { @@ -392,6 +396,8 @@ public function extend(string $layout) * Starts holds content for a section within the layout. * * @param string $name Section name + * + * @return void */ public function section(string $name) { @@ -405,6 +411,8 @@ public function section(string $name) /** * Captures the last section * + * @return void + * * @throws RuntimeException */ public function endSection() @@ -427,6 +435,8 @@ public function endSection() /** * Renders a section's contents. + * + * @return void */ public function renderSection(string $sectionName) { @@ -463,6 +473,8 @@ public function getPerformanceData(): array /** * Logs performance data for rendering a view. + * + * @return void */ protected function logPerformance(float $start, float $end, string $view) { diff --git a/tests/system/AutoReview/ComposerJsonTest.php b/tests/system/AutoReview/ComposerJsonTest.php index dc9ad26b9ef8..ecc57c028cba 100644 --- a/tests/system/AutoReview/ComposerJsonTest.php +++ b/tests/system/AutoReview/ComposerJsonTest.php @@ -13,6 +13,7 @@ namespace CodeIgniter\AutoReview; +use InvalidArgumentException; use JsonException; use PHPUnit\Framework\TestCase; @@ -40,7 +41,7 @@ protected function setUp(): void public function testFrameworkRequireIsTheSameWithDevRequire(): void { - $this->checkFramework('require'); + $this->checkSection('require', 'framework'); } public function testFrameworkRequireDevIsTheSameWithDevRequireDev(): void @@ -68,35 +69,66 @@ public function testFrameworkRequireDevIsTheSameWithDevRequireDev(): void public function testFrameworkSuggestIsTheSameWithDevSuggest(): void { - $this->checkFramework('suggest'); + $this->checkSection('suggest', 'framework'); } public function testFrameworkConfigIsTheSameWithDevSuggest(): void { - $this->checkFramework('config'); + $this->checkConfig( + $this->devComposer['config'], + $this->frameworkComposer['config'], + 'framework' + ); } public function testStarterConfigIsTheSameWithDevSuggest(): void { - $this->checkStarter('config'); + $this->checkConfig( + $this->devComposer['config'], + $this->starterComposer['config'], + 'starter' + ); } - private function checkFramework(string $section): void + private function checkSection(string $section, string $component): void { + switch (strtolower($component)) { + case 'framework': + $sectionContent = $this->frameworkComposer[$section] ?? null; + break; + + case 'starter': + $sectionContent = $this->starterComposer[$section] ?? null; + break; + + default: + throw new InvalidArgumentException(sprintf('Unknown component: %s.', $component)); + } + $this->assertSame( $this->devComposer[$section], - $this->frameworkComposer[$section], - 'The framework\'s "' . $section . '" section is not updated with the main composer.json.' + $sectionContent, + sprintf('The %s\'s "%s" section is not updated with the main composer.json', strtolower($component), $section) ); } - private function checkStarter(string $section): void + private function checkConfig(array $fromMain, array $fromComponent, string $component): void { - $this->assertSame( - $this->devComposer[$section], - $this->starterComposer[$section], - 'The starter\'s "' . $section . '" section is not updated with the main composer.json.' - ); + foreach ($fromMain as $key => $expectedValue) { + if (! isset($fromComponent[$key])) { + $this->addToAssertionCount(1); + + continue; + } + + $actualValue = $fromComponent[$key]; + + $this->assertSame($expectedValue, $actualValue, sprintf( + '%s\'s value for config property "%s" is not same with the main composer.json\'s config.', + ucfirst($component), + $key + )); + } } private function getComposerJson(string $path): array diff --git a/tests/system/AutoReview/FrameworkCodeTest.php b/tests/system/AutoReview/FrameworkCodeTest.php index f72e7ae9987f..e61e0663836b 100644 --- a/tests/system/AutoReview/FrameworkCodeTest.php +++ b/tests/system/AutoReview/FrameworkCodeTest.php @@ -39,7 +39,7 @@ final class FrameworkCodeTest extends TestCase ]; /** - * @dataProvider provideTestClassCases + * @dataProvider provideEachTestClassHasCorrectGroupAnnotation * * @phpstan-param class-string $class */ @@ -73,7 +73,7 @@ public function testEachTestClassHasCorrectGroupAnnotation(string $class): void )); } - public function provideTestClassCases(): iterable + public function provideEachTestClassHasCorrectGroupAnnotation(): iterable { foreach ($this->getTestClasses() as $class) { yield $class => [$class]; diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php index e02db8d97515..e7a9264c8791 100644 --- a/tests/system/CLI/CLITest.php +++ b/tests/system/CLI/CLITest.php @@ -450,7 +450,7 @@ public function testWindow(): void } /** - * @dataProvider tableProvider + * @dataProvider provideTable * * @param array $tbody * @param array $thead @@ -463,7 +463,7 @@ public function testTable($tbody, $thead, $expected): void $this->assertSame($this->getStreamFilterBuffer(), $expected); } - public function tableProvider(): iterable + public static function provideTable(): iterable { $head = [ 'ID', diff --git a/tests/system/Cache/Handlers/BaseHandlerTest.php b/tests/system/Cache/Handlers/BaseHandlerTest.php index 2e835760e9e4..15bb94bfa944 100644 --- a/tests/system/Cache/Handlers/BaseHandlerTest.php +++ b/tests/system/Cache/Handlers/BaseHandlerTest.php @@ -23,7 +23,7 @@ final class BaseHandlerTest extends CIUnitTestCase { /** - * @dataProvider invalidTypeProvider + * @dataProvider provideValidateKeyInvalidType * * @param mixed $input */ @@ -35,7 +35,7 @@ public function testValidateKeyInvalidType($input): void BaseHandler::validateKey($input); } - public function invalidTypeProvider(): iterable + public static function provideValidateKeyInvalidType(): iterable { return [ [true], diff --git a/tests/system/Cache/Handlers/FileHandlerTest.php b/tests/system/Cache/Handlers/FileHandlerTest.php index db8387b8c9cf..11d1c93b9c1c 100644 --- a/tests/system/Cache/Handlers/FileHandlerTest.php +++ b/tests/system/Cache/Handlers/FileHandlerTest.php @@ -273,7 +273,7 @@ public function testIsSupported(): void } /** - * @dataProvider modeProvider + * @dataProvider provideSaveMode * * permissions given on Windows are fixed to `0666` * @@ -296,7 +296,7 @@ public function testSaveMode(int $int, string $string): void $this->assertSame($string, $mode); } - public function modeProvider(): iterable + public static function provideSaveMode(): iterable { return [ [ diff --git a/tests/system/CodeIgniterTest.php b/tests/system/CodeIgniterTest.php index a593fb279db3..4a4b8a2021b2 100644 --- a/tests/system/CodeIgniterTest.php +++ b/tests/system/CodeIgniterTest.php @@ -731,7 +731,7 @@ public function testPageCacheSendSecureHeaders(): void /** * @param array|bool $cacheQueryStringValue * - * @dataProvider cacheQueryStringProvider + * @dataProvider providePageCacheWithCacheQueryString * * @see https://github.com/codeigniter4/CodeIgniter4/pull/6410 */ @@ -789,7 +789,7 @@ public function testPageCacheWithCacheQueryString($cacheQueryStringValue, int $e CITestStreamFilter::removeErrorFilter(); } - public function cacheQueryStringProvider(): iterable + public static function providePageCacheWithCacheQueryString(): iterable { $testingUrls = [ 'test', // URL #1 diff --git a/tests/system/Commands/CommandTest.php b/tests/system/Commands/CommandTest.php index 90da337c11a0..e75b2ddc4503 100644 --- a/tests/system/Commands/CommandTest.php +++ b/tests/system/Commands/CommandTest.php @@ -128,7 +128,7 @@ public function testInexistentCommandsButWithManyAlternatives(): void } /** - * @dataProvider commandArgsProvider + * @dataProvider provideCommandParsesArgsCorrectly */ public function testCommandParsesArgsCorrectly(string $input, array $expected): void { @@ -138,7 +138,7 @@ public function testCommandParsesArgsCorrectly(string $input, array $expected): $this->assertSame($expected, ParamsReveal::$args); } - public function commandArgsProvider(): iterable + public static function provideCommandParsesArgsCorrectly(): iterable { return [ [ diff --git a/tests/system/Commands/Utilities/Routes/SampleURIGeneratorTest.php b/tests/system/Commands/Utilities/Routes/SampleURIGeneratorTest.php index ec4acc47259e..4f7d6221665d 100644 --- a/tests/system/Commands/Utilities/Routes/SampleURIGeneratorTest.php +++ b/tests/system/Commands/Utilities/Routes/SampleURIGeneratorTest.php @@ -22,7 +22,7 @@ final class SampleURIGeneratorTest extends CIUnitTestCase { /** - * @dataProvider routeKeyProvider + * @dataProvider provideGet */ public function testGet(string $routeKey, string $expected): void { @@ -33,7 +33,7 @@ public function testGet(string $routeKey, string $expected): void $this->assertSame($expected, $uri); } - public function routeKeyProvider(): iterable + public static function provideGet(): iterable { yield from [ 'root' => ['/', '/'], diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index 8d4f7199d0e1..4a23d3a923e7 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -594,7 +594,7 @@ public function testForceHttpsNullRequestAndResponse(): void } /** - * @dataProvider dirtyPathsProvider + * @dataProvider provideCleanPathActuallyCleaningThePaths * * @param mixed $input * @param mixed $expected @@ -604,7 +604,7 @@ public function testCleanPathActuallyCleaningThePaths($input, $expected): void $this->assertSame($expected, clean_path($input)); } - public function dirtyPathsProvider(): iterable + public static function provideCleanPathActuallyCleaningThePaths(): iterable { $ds = DIRECTORY_SEPARATOR; diff --git a/tests/system/CommonSingleServiceTest.php b/tests/system/CommonSingleServiceTest.php index 58854f27df68..9a6c094dec35 100644 --- a/tests/system/CommonSingleServiceTest.php +++ b/tests/system/CommonSingleServiceTest.php @@ -27,7 +27,7 @@ final class CommonSingleServiceTest extends CIUnitTestCase { /** - * @dataProvider serviceNamesProvider + * @dataProvider provideServiceNames */ public function testSingleServiceWithNoParamsSupplied(string $service): void { @@ -43,7 +43,7 @@ public function testSingleServiceWithNoParamsSupplied(string $service): void } /** - * @dataProvider serviceNamesProvider + * @dataProvider provideServiceNames */ public function testSingleServiceWithAtLeastOneParamSupplied(string $service): void { @@ -99,7 +99,7 @@ public function testSingleServiceWithGibberishGiven(): void $this->assertNull(single_service('timers')); } - public static function serviceNamesProvider(): iterable + public static function provideServiceNames(): iterable { static $services = []; static $excl = [ diff --git a/tests/system/Config/DotEnvTest.php b/tests/system/Config/DotEnvTest.php index 6bd8b23958f5..0709de51800a 100644 --- a/tests/system/Config/DotEnvTest.php +++ b/tests/system/Config/DotEnvTest.php @@ -56,7 +56,7 @@ public function testReturnsFalseIfCannotFindFile(): void } /** - * @dataProvider provideLoadVars + * @dataProvider provideLoadsVars */ public function testLoadsVars(string $expected, string $varname): void { @@ -66,7 +66,7 @@ public function testLoadsVars(string $expected, string $varname): void $this->assertSame($expected, getenv($varname)); } - public function provideLoadVars(): iterable + public static function provideLoadsVars(): iterable { yield from [ ['bar', 'FOO'], diff --git a/tests/system/Config/MimesTest.php b/tests/system/Config/MimesTest.php index 7e1e78676155..e15b10d436c3 100644 --- a/tests/system/Config/MimesTest.php +++ b/tests/system/Config/MimesTest.php @@ -21,7 +21,7 @@ */ final class MimesTest extends CIUnitTestCase { - public function extensionsList(): iterable + public static function provideGuessExtensionFromType(): iterable { return [ 'null' => [ @@ -48,14 +48,14 @@ public function extensionsList(): iterable } /** - * @dataProvider extensionsList + * @dataProvider provideGuessExtensionFromType */ public function testGuessExtensionFromType(?string $expected, string $mime): void { $this->assertSame($expected, Mimes::guessExtensionFromType($mime)); } - public function mimesList(): iterable + public static function provideGuessTypeFromExtension(): iterable { return [ 'null' => [ @@ -82,7 +82,7 @@ public function mimesList(): iterable } /** - * @dataProvider mimesList + * @dataProvider provideGuessTypeFromExtension */ public function testGuessTypeFromExtension(?string $expected, string $ext): void { diff --git a/tests/system/Cookie/CookieTest.php b/tests/system/Cookie/CookieTest.php index c69fb1b806d2..04a7da830a04 100644 --- a/tests/system/Cookie/CookieTest.php +++ b/tests/system/Cookie/CookieTest.php @@ -79,7 +79,7 @@ public function testConfigInjectionForDefaults(): void } /** - * @dataProvider prefixProvider + * @dataProvider provideConfigPrefix */ public function testConfigPrefix(string $configPrefix, string $optionPrefix, string $expected): void { @@ -98,7 +98,7 @@ public function testConfigPrefix(string $configPrefix, string $optionPrefix, str $this->assertSame($expected, $cookie->getPrefixedName()); } - public function prefixProvider(): iterable + public static function provideConfigPrefix(): iterable { yield from [ ['prefix_', '', 'prefix_test'], @@ -165,7 +165,7 @@ public function testExpirationTime(): void } /** - * @dataProvider invalidExpiresProvider + * @dataProvider provideInvalidExpires * * @param bool|float|string $expires */ @@ -175,7 +175,7 @@ public function testInvalidExpires($expires): void new Cookie('test', 'value', ['expires' => $expires]); } - public static function invalidExpiresProvider(): iterable + public static function provideInvalidExpires(): iterable { $cases = [ 'non-numeric-string' => ['yes'], @@ -189,7 +189,7 @@ public static function invalidExpiresProvider(): iterable } /** - * @dataProvider setCookieHeaderProvider + * @dataProvider provideSetCookieHeaderCreation */ public function testSetCookieHeaderCreation(string $header, array $changed): void { @@ -198,7 +198,7 @@ public function testSetCookieHeaderCreation(string $header, array $changed): voi $this->assertSame(array_merge($cookie, $changed), $cookie); } - public static function setCookieHeaderProvider(): iterable + public static function provideSetCookieHeaderCreation(): iterable { yield 'basic' => [ 'test=value', diff --git a/tests/system/Database/BaseConnectionTest.php b/tests/system/Database/BaseConnectionTest.php index 333a81c87d1f..1d629832bf6c 100644 --- a/tests/system/Database/BaseConnectionTest.php +++ b/tests/system/Database/BaseConnectionTest.php @@ -167,7 +167,7 @@ public function testMagicGetMissing(): void * These tests are intended to confirm the current behavior. * We do not know if all of these are the correct behavior. * - * @dataProvider identifiersProvider + * @dataProvider provideProtectIdentifiers */ public function testProtectIdentifiers( bool $prefixSingle, @@ -183,7 +183,7 @@ public function testProtectIdentifiers( $this->assertSame($expected, $return); } - public function identifiersProvider(): iterable + public static function provideProtectIdentifiers(): iterable { yield from [ // $prefixSingle, $protectIdentifiers, $fieldExists, $item, $expected diff --git a/tests/system/Database/BaseQueryTest.php b/tests/system/Database/BaseQueryTest.php index d52df3899ea6..dde670c107e7 100644 --- a/tests/system/Database/BaseQueryTest.php +++ b/tests/system/Database/BaseQueryTest.php @@ -104,7 +104,7 @@ public function testSwapPrefix(): void $this->assertSame($newSQL, $query->getQuery()); } - public function queryTypes(): iterable + public static function provideIsWriteType(): iterable { return [ 'select' => [ @@ -183,7 +183,7 @@ public function queryTypes(): iterable } /** - * @dataProvider queryTypes + * @dataProvider provideIsWriteType * * @param mixed $expected * @param mixed $sql @@ -577,7 +577,7 @@ public function testSwapPrefixAfterGetQuery(): void $this->assertSame($expected, $query->getQuery()); } - public function queryKeywords(): iterable + public static function provideHighlightQueryKeywords(): iterable { return [ 'highlightKeyWords' => [ @@ -596,7 +596,7 @@ public function queryKeywords(): iterable } /** - * @dataProvider queryKeywords + * @dataProvider provideHighlightQueryKeywords * * @param mixed $expected * @param mixed $sql diff --git a/tests/system/Database/Builder/WhereTest.php b/tests/system/Database/Builder/WhereTest.php index c0ddeb34f329..7882e48e1e23 100644 --- a/tests/system/Database/Builder/WhereTest.php +++ b/tests/system/Database/Builder/WhereTest.php @@ -392,7 +392,7 @@ public function testWhereInSubQuery(): void $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); } - public function provideInvalidKeys(): iterable + public static function provideWhereInvalidKeyThrowInvalidArgumentException(): iterable { return [ 'null' => [null], @@ -401,7 +401,7 @@ public function provideInvalidKeys(): iterable } /** - * @dataProvider provideInvalidKeys + * @dataProvider provideWhereInvalidKeyThrowInvalidArgumentException * * @param mixed $key */ @@ -413,7 +413,7 @@ public function testWhereInvalidKeyThrowInvalidArgumentException($key): void $builder->whereIn($key, ['Politician', 'Accountant']); } - public function provideInvalidValues(): iterable + public static function provideWhereInEmptyValuesThrowInvalidArgumentException(): iterable { return [ 'null' => [null], @@ -423,7 +423,7 @@ public function provideInvalidValues(): iterable } /** - * @dataProvider provideInvalidValues + * @dataProvider provideWhereInEmptyValuesThrowInvalidArgumentException * * @param mixed $values */ diff --git a/tests/system/Database/ConfigTest.php b/tests/system/Database/ConfigTest.php index b401d541b7a8..37ecfeb6f5e2 100644 --- a/tests/system/Database/ConfigTest.php +++ b/tests/system/Database/ConfigTest.php @@ -192,7 +192,7 @@ public function testConnectionGroupWithDSNPostgreNative(): void } /** - * @dataProvider convertDSNProvider + * @dataProvider provideConvertDSN * * @see https://github.com/codeigniter4/CodeIgniter4/issues/7550 */ @@ -208,7 +208,7 @@ public function testConvertDSN(string $input, string $expected): void $this->assertSame($expected, $this->getPrivateProperty($conn, 'DSN')); } - public function convertDSNProvider(): iterable + public static function provideConvertDSN(): iterable { yield from [ [ diff --git a/tests/system/Database/Migrations/MigrationRunnerTest.php b/tests/system/Database/Migrations/MigrationRunnerTest.php index 6d88cd894e0d..a573114c1f94 100644 --- a/tests/system/Database/Migrations/MigrationRunnerTest.php +++ b/tests/system/Database/Migrations/MigrationRunnerTest.php @@ -23,6 +23,8 @@ use Config\Services; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamDirectory; +use Tests\Support\MigrationTestMigrations\Database\Migrations\Migration_another_migration; +use Tests\Support\MigrationTestMigrations\Database\Migrations\Migration_some_migration; /** * @group DatabaseLive @@ -258,7 +260,7 @@ public function testFindMigrationsSuccessTimestamp(): void 'version' => '2018-01-24-102301', 'name' => 'Some_migration', 'path' => realpath(TESTPATH . '_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php'), - 'class' => 'Tests\Support\MigrationTestMigrations\Database\Migrations\Migration_some_migration', + 'class' => Migration_some_migration::class, 'namespace' => 'Tests\Support\MigrationTestMigrations', ]; $mig1->uid = $runner->getObjectUid($mig1); @@ -267,7 +269,7 @@ public function testFindMigrationsSuccessTimestamp(): void 'version' => '2018-01-24-102302', 'name' => 'Another_migration', 'path' => realpath(TESTPATH . '_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102302_Another_migration.php'), - 'class' => 'Tests\Support\MigrationTestMigrations\Database\Migrations\Migration_another_migration', + 'class' => Migration_another_migration::class, 'namespace' => 'Tests\Support\MigrationTestMigrations', 'uid' => '20180124102302Tests\Support\MigrationTestMigrations\Database\Migrations\Migration_another_migration', ]; diff --git a/tests/system/Email/EmailTest.php b/tests/system/Email/EmailTest.php index 2fff192e7295..dfcbedf183cc 100644 --- a/tests/system/Email/EmailTest.php +++ b/tests/system/Email/EmailTest.php @@ -32,7 +32,7 @@ public function testEmailValidation(): void $this->assertStringContainsString('Invalid email address: "invalid"', $email->printDebugger()); } - public function autoClearProvider(): iterable + public static function provideEmailSendWithClearance(): iterable { return [ 'autoclear' => [true], @@ -41,7 +41,7 @@ public function autoClearProvider(): iterable } /** - * @dataProvider autoClearProvider + * @dataProvider provideEmailSendWithClearance * * @param mixed $autoClear */ diff --git a/tests/system/Filters/FiltersTest.php b/tests/system/Filters/FiltersTest.php index a89950c71750..ae75b14af835 100644 --- a/tests/system/Filters/FiltersTest.php +++ b/tests/system/Filters/FiltersTest.php @@ -208,22 +208,30 @@ public function testProcessMethodProcessGlobals(): void $this->assertSame($expected, $filters->initialize()->getFilters()); } - public function provideExcept(): iterable + public static function provideProcessMethodProcessGlobalsWithExcept(): iterable { return [ [ ['admin/*'], ], [ - [], + ['admin/*', 'foo/*'], + ], + [ + ['*'], + ], + [ + 'admin/*', ], ]; } /** - * @dataProvider provideExcept + * @dataProvider provideProcessMethodProcessGlobalsWithExcept + * + * @param array|string $except */ - public function testProcessMethodProcessGlobalsWithExcept(array $except): void + public function testProcessMethodProcessGlobalsWithExcept($except): void { $_SERVER['REQUEST_METHOD'] = 'GET'; @@ -572,7 +580,12 @@ public function testOtherResult(): void $this->assertSame('This is curious', $response); } - public function testBeforeExceptString(): void + /** + * @dataProvider provideBeforeExcept + * + * @param array|string $except + */ + public function testBeforeExcept(string $uri, $except, array $expected): void { $_SERVER['REQUEST_METHOD'] = 'GET'; @@ -584,7 +597,7 @@ public function testBeforeExceptString(): void ], 'globals' => [ 'before' => [ - 'foo' => ['except' => 'admin/*'], + 'foo' => ['except' => $except], 'bar', ], 'after' => [ @@ -595,48 +608,91 @@ public function testBeforeExceptString(): void $filtersConfig = $this->createConfigFromArray(FiltersConfig::class, $config); $filters = $this->createFilters($filtersConfig); - $uri = 'admin/foo/bar'; - $expected = [ - 'before' => [ - 'bar', - ], - 'after' => ['baz'], - ]; $this->assertSame($expected, $filters->initialize($uri)->getFilters()); } - public function testBeforeExceptInapplicable(): void + public static function provideBeforeExcept(): iterable { - $_SERVER['REQUEST_METHOD'] = 'GET'; - - $config = [ - 'aliases' => [ - 'foo' => '', - 'bar' => '', - 'baz' => '', + return [ + 'string exclude' => [ + 'admin/foo/bar', + 'admin/*', + [ + 'before' => [ + 'bar', + ], + 'after' => ['baz'], + ], ], - 'globals' => [ - 'before' => [ - 'foo' => ['except' => 'george/*'], - 'bar', + 'string not exclude' => [ + 'admin/foo/bar', + 'george/*', + [ + 'before' => [ + 'foo', + 'bar', + ], + 'after' => ['baz'], ], - 'after' => [ - 'baz', + ], + 'empty array not exclude' => [ + 'admin/foo/bar', + [], + [ + 'before' => [ + 'foo', + 'bar', + ], + 'after' => ['baz'], ], ], - ]; - $filtersConfig = $this->createConfigFromArray(FiltersConfig::class, $config); - $filters = $this->createFilters($filtersConfig); - - $uri = 'admin/foo/bar'; - $expected = [ - 'before' => [ - 'foo', - 'bar', + 'empty string not exclude' => [ + 'admin/foo/bar', + // The URI path '' means the baseURL. + '', + [ + 'before' => [ + 'foo', + 'bar', + ], + 'after' => ['baz'], + ], + ], + 'empty string exclude' => [ + // The URI path '' means the baseURL. + '', + // So this setting excludes `foo` filter only to the baseURL. + '', + [ + 'before' => [ + 'bar', + ], + 'after' => ['baz'], + ], + ], + 'slash not exclude' => [ + 'admin/foo/bar', + '/', + [ + 'before' => [ + 'foo', + 'bar', + ], + 'after' => ['baz'], + ], + ], + 'slash exclude' => [ + // The URI path '' means the baseURL. + '', + '/', + [ + 'before' => [ + 'bar', + ], + 'after' => ['baz'], + ], ], - 'after' => ['baz'], ]; - $this->assertSame($expected, $filters->initialize($uri)->getFilters()); } public function testAfterExceptString(): void diff --git a/tests/system/Filters/InvalidCharsTest.php b/tests/system/Filters/InvalidCharsTest.php index 7a56746d7bcb..6289ae755ce0 100644 --- a/tests/system/Filters/InvalidCharsTest.php +++ b/tests/system/Filters/InvalidCharsTest.php @@ -115,7 +115,7 @@ public function testBeforeInvalidControlCharCausesException(): void /** * @doesNotPerformAssertions * - * @dataProvider stringWithLineBreakAndTabProvider + * @dataProvider provideCheckControlStringWithLineBreakAndTabReturnsTheString */ public function testCheckControlStringWithLineBreakAndTabReturnsTheString(string $input): void { @@ -124,7 +124,7 @@ public function testCheckControlStringWithLineBreakAndTabReturnsTheString(string $this->invalidChars->before($this->request); } - public function stringWithLineBreakAndTabProvider(): iterable + public static function provideCheckControlStringWithLineBreakAndTabReturnsTheString(): iterable { yield from [ ["String contains \n line break."], @@ -136,7 +136,7 @@ public function stringWithLineBreakAndTabProvider(): iterable } /** - * @dataProvider stringWithControlCharsProvider + * @dataProvider provideCheckControlStringWithControlCharsCausesException */ public function testCheckControlStringWithControlCharsCausesException(string $input): void { @@ -148,7 +148,7 @@ public function testCheckControlStringWithControlCharsCausesException(string $in $this->invalidChars->before($this->request); } - public function stringWithControlCharsProvider(): iterable + public static function provideCheckControlStringWithControlCharsCausesException(): iterable { yield from [ ["String contains null char.\0"], diff --git a/tests/system/Format/XMLFormatterTest.php b/tests/system/Format/XMLFormatterTest.php index b6606c1a3d19..3b1c48a467f5 100644 --- a/tests/system/Format/XMLFormatterTest.php +++ b/tests/system/Format/XMLFormatterTest.php @@ -102,7 +102,7 @@ public function testValidatingXmlTags(): void } /** - * @dataProvider invalidTagsProvider + * @dataProvider provideValidatingInvalidTags */ public function testValidatingInvalidTags(string $expected, array $input): void { @@ -115,7 +115,7 @@ public function testValidatingInvalidTags(string $expected, array $input): void $this->assertSame($expectedXML, $this->xmlFormatter->format($input)); } - public function invalidTagsProvider(): iterable + public static function provideValidatingInvalidTags(): iterable { return [ [ diff --git a/tests/system/HTTP/CLIRequestTest.php b/tests/system/HTTP/CLIRequestTest.php index 40bf2aad3a53..1298df1b9ad3 100644 --- a/tests/system/HTTP/CLIRequestTest.php +++ b/tests/system/HTTP/CLIRequestTest.php @@ -517,7 +517,7 @@ public function testFetchGlobalWithEmptyNotation(): void $this->assertSame($expected, $this->request->fetchGlobal('post', 'clients[]')); } - public function ipAddressChecks(): iterable + public static function provideValidIPAddress(): iterable { return [ 'empty' => [ @@ -564,7 +564,7 @@ public function ipAddressChecks(): iterable } /** - * @dataProvider ipAddressChecks + * @dataProvider provideValidIPAddress * * @param mixed $expected * @param mixed $address diff --git a/tests/system/HTTP/IncomingRequestTest.php b/tests/system/HTTP/IncomingRequestTest.php index b8015fab933e..5224b5f5ea03 100644 --- a/tests/system/HTTP/IncomingRequestTest.php +++ b/tests/system/HTTP/IncomingRequestTest.php @@ -518,7 +518,7 @@ public function testCanGrabGetRawInput(): void $this->assertSame($expected, $request->getRawInput()); } - public function provideRawInputVarChecks(): iterable + public static function provideCanGrabGetRawInputVar(): iterable { return [ [ @@ -598,7 +598,7 @@ public function provideRawInputVarChecks(): iterable } /** - * @dataProvider provideRawInputVarChecks + * @dataProvider provideCanGrabGetRawInputVar * * @param string $rawstring * @param mixed $var @@ -626,7 +626,7 @@ public function testIsHTTPMethodLowerCase(string $value): void $this->assertTrue($request->is(strtolower($value))); } - public function provideIsHTTPMethods(): iterable + public static function provideIsHTTPMethods(): iterable { yield from [ ['GET'], @@ -839,7 +839,7 @@ public function testGetPostIndexNotExists(): void $this->assertNull($this->request->getGetPost('gc')); } - public function providePathChecks(): iterable + public static function provideExtensionPHP(): iterable { return [ 'not /index.php' => [ @@ -854,7 +854,7 @@ public function providePathChecks(): iterable } /** - * @dataProvider providePathChecks + * @dataProvider provideExtensionPHP * * @param mixed $path * @param mixed $detectPath diff --git a/tests/system/HTTP/MessageTest.php b/tests/system/HTTP/MessageTest.php index 67768aa7ea2c..b30984a8c7a6 100644 --- a/tests/system/HTTP/MessageTest.php +++ b/tests/system/HTTP/MessageTest.php @@ -185,7 +185,7 @@ public function testSetHeaderArrayValues(): void $this->assertSame('json, html, xml', $this->message->getHeaderLine('Accept')); } - public function provideArrayHeaderValue(): iterable + public static function provideArrayHeaderValue(): iterable { return [ 'existing for next not append' => [ diff --git a/tests/system/HTTP/RequestTest.php b/tests/system/HTTP/RequestTest.php index 3eaea59ed1c2..0b0714c38a20 100644 --- a/tests/system/HTTP/RequestTest.php +++ b/tests/system/HTTP/RequestTest.php @@ -532,7 +532,7 @@ public function testFetchGlobalFiltersWithArrayChildElement(): void $this->assertSame($expected, $this->request->fetchGlobal('post', 'people[0]', FILTER_VALIDATE_INT)); } - public function ipAddressChecks(): iterable + public static function provideValidIPAddress(): iterable { return [ 'empty' => [ @@ -579,7 +579,7 @@ public function ipAddressChecks(): iterable } /** - * @dataProvider ipAddressChecks + * @dataProvider provideValidIPAddress * * @param mixed $expected * @param mixed $address diff --git a/tests/system/HTTP/ResponseTest.php b/tests/system/HTTP/ResponseTest.php index c9cb68807ac4..a66dc06f9bc4 100644 --- a/tests/system/HTTP/ResponseTest.php +++ b/tests/system/HTTP/ResponseTest.php @@ -270,7 +270,7 @@ public function testRedirectSetsDefaultCodeAndLocationHeader(): void } /** - * @dataProvider provideForRedirect + * @dataProvider provideRedirect */ public function testRedirect( string $server, @@ -291,7 +291,7 @@ public function testRedirect( $this->assertSame($expectedCode, $response->getStatusCode()); } - public function provideForRedirect(): iterable + public static function provideRedirect(): iterable { yield from [ ['Apache/2.4.17', 'HTTP/1.1', 'GET', null, 302], @@ -316,7 +316,7 @@ public function provideForRedirect(): iterable } /** - * @dataProvider provideForRedirectWithIIS + * @dataProvider provideRedirectWithIIS */ public function testRedirectWithIIS( string $protocol, @@ -337,7 +337,7 @@ public function testRedirectWithIIS( unset($_SERVER['SERVER_SOFTWARE']); } - public function provideForRedirectWithIIS(): iterable + public static function provideRedirectWithIIS(): iterable { yield from [ ['HTTP/1.1', 'GET', null, 302], diff --git a/tests/system/HTTP/URITest.php b/tests/system/HTTP/URITest.php index dd802ec5de55..82256ad92549 100644 --- a/tests/system/HTTP/URITest.php +++ b/tests/system/HTTP/URITest.php @@ -126,7 +126,7 @@ public function testCanCastAsString(): void } /** - * @dataProvider provideURLs + * @dataProvider provideSimpleUri */ public function testSimpleUri(string $url, string $expectedURL, string $expectedPath): void { @@ -136,7 +136,7 @@ public function testSimpleUri(string $url, string $expectedURL, string $expected $this->assertSame($expectedPath, $uri->getPath()); } - public function provideURLs(): iterable + public static function provideSimpleUri(): iterable { return [ '' => [ @@ -362,7 +362,7 @@ public function testSetPathSetsValue(): void } /** - * @dataProvider providePaths + * @dataProvider provideSetPath */ public function testSetPath(string $path, string $expectedURL, string $expectedPath): void { @@ -375,7 +375,7 @@ public function testSetPath(string $path, string $expectedURL, string $expectedP $this->assertSame($expectedPath, $uri->getPath()); } - public function providePaths(): iterable + public static function provideSetPath(): iterable { return [ '' => [ @@ -431,7 +431,7 @@ public function providePaths(): iterable ]; } - public function invalidPaths(): iterable + public static function providePathGetsFiltered(): iterable { return [ 'dot-segment' => [ @@ -462,7 +462,7 @@ public function invalidPaths(): iterable } /** - * @dataProvider invalidPaths + * @dataProvider providePathGetsFiltered * * @param string $path * @param string $expected @@ -555,7 +555,7 @@ public function testSetQueryThrowsErrorWhenFragmentPresentSilent(): void $this->assertSame('', $uri->getQuery()); } - public function authorityInfo(): iterable + public static function provideAuthorityReturnsExceptedValues(): iterable { return [ 'host-only' => [ @@ -578,7 +578,7 @@ public function authorityInfo(): iterable } /** - * @dataProvider authorityInfo + * @dataProvider provideAuthorityReturnsExceptedValues * * @param string $url * @param string $expected @@ -590,7 +590,7 @@ public function testAuthorityReturnsExceptedValues($url, $expected): void $this->assertSame($expected, $uri->getAuthority()); } - public function defaultPorts(): iterable + public static function provideAuthorityRemovesDefaultPorts(): iterable { return [ 'http' => [ @@ -605,7 +605,7 @@ public function defaultPorts(): iterable } /** - * @dataProvider defaultPorts + * @dataProvider provideAuthorityRemovesDefaultPorts * * @param string $scheme * @param int $port @@ -629,7 +629,7 @@ public function testSetAuthorityReconstitutes(): void $this->assertSame($authority, $uri->getAuthority()); } - public function defaultDots(): iterable + public static function provideRemoveDotSegments(): iterable { return [ [ @@ -728,7 +728,7 @@ public function defaultDots(): iterable } /** - * @dataProvider defaultDots + * @dataProvider provideRemoveDotSegments * * @param string $path * @param string $expected @@ -738,7 +738,7 @@ public function testRemoveDotSegments($path, $expected): void $this->assertSame($expected, URI::removeDotSegments($path)); } - public function defaultResolutions(): iterable + public static function defaultResolutions(): iterable { return [ [ diff --git a/tests/system/Helpers/ArrayHelperTest.php b/tests/system/Helpers/ArrayHelperTest.php index 53a860c3a4a4..7b5c1e45a145 100644 --- a/tests/system/Helpers/ArrayHelperTest.php +++ b/tests/system/Helpers/ArrayHelperTest.php @@ -209,7 +209,7 @@ public function testArrayDotIgnoresLastWildcard(): void } /** - * @dataProvider deepSearchProvider + * @dataProvider provideArrayDeepSearch * * @param int|string $key * @param array|string|null $expected @@ -248,7 +248,7 @@ public function testArrayDeepSearchReturnNullEmptyArray(): void } /** - * @dataProvider sortByMultipleKeysProvider + * @dataProvider provideSortByMultipleKeys */ public function testArraySortByMultipleKeysWithArray(array $data, array $sortColumns, array $expected): void { @@ -259,7 +259,7 @@ public function testArraySortByMultipleKeysWithArray(array $data, array $sortCol } /** - * @dataProvider sortByMultipleKeysProvider + * @dataProvider provideSortByMultipleKeys */ public function testArraySortByMultipleKeysWithObjects(array $data, array $sortColumns, array $expected): void { @@ -275,7 +275,7 @@ public function testArraySortByMultipleKeysWithObjects(array $data, array $sortC } /** - * @dataProvider sortByMultipleKeysProvider + * @dataProvider provideSortByMultipleKeys */ public function testArraySortByMultipleKeysFailsEmptyParameter(array $data, array $sortColumns, array $expected): void { @@ -297,7 +297,7 @@ public function testArraySortByMultipleKeysFailsEmptyParameter(array $data, arra } /** - * @dataProvider sortByMultipleKeysProvider + * @dataProvider provideSortByMultipleKeys * * @param mixed $data */ @@ -320,7 +320,7 @@ public function testArraySortByMultipleKeysFailsInconsistentArraySizes($data): v array_sort_by_multiple_keys($data, $sortColumns); } - public static function deepSearchProvider(): iterable + public static function provideArrayDeepSearch(): iterable { return [ [ @@ -346,7 +346,7 @@ public static function deepSearchProvider(): iterable ]; } - public static function sortByMultipleKeysProvider(): iterable + public static function provideSortByMultipleKeys(): iterable { $seed = [ 0 => [ @@ -400,14 +400,14 @@ public static function sortByMultipleKeysProvider(): iterable } /** - * @dataProvider arrayFlattenProvider + * @dataProvider provideArrayFlattening */ public function testArrayFlattening(array $input, array $expected): void { $this->assertSame($expected, array_flatten_with_dots($input)); } - public function arrayFlattenProvider(): iterable + public static function provideArrayFlattening(): iterable { yield 'normal' => [ [ diff --git a/tests/system/Helpers/FormHelperTest.php b/tests/system/Helpers/FormHelperTest.php index 639d03c48f47..ca90ce53c12e 100644 --- a/tests/system/Helpers/FormHelperTest.php +++ b/tests/system/Helpers/FormHelperTest.php @@ -867,6 +867,29 @@ public function testSetCheckboxWithValueZero(): void $this->assertSame(' checked="checked"', set_checkbox('foo', '0', true)); } + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/7814 + */ + public function testSetCheckboxWithUnchecked(): void + { + $_SESSION = [ + '_ci_old_input' => [ + 'post' => [ + ], + ], + ]; + + $this->assertSame( + '', + set_checkbox('fruit', 'apple', true) + ); + + $this->assertSame( + '', + set_checkbox('fruit', 'apple') + ); + } + /** * @runInSeparateProcess * @preserveGlobalState disabled diff --git a/tests/system/Helpers/InflectorHelperTest.php b/tests/system/Helpers/InflectorHelperTest.php index 1a0325f4ccaa..cd962c8d3b52 100755 --- a/tests/system/Helpers/InflectorHelperTest.php +++ b/tests/system/Helpers/InflectorHelperTest.php @@ -243,7 +243,7 @@ public function testDasherize(): void } } - public function provideOrdinal(): iterable + public static function provideOrdinal(): iterable { return [ ['st', 1], diff --git a/tests/system/Helpers/URLHelper/CurrentUrlTest.php b/tests/system/Helpers/URLHelper/CurrentUrlTest.php index ec639e104594..6f908053b6a6 100644 --- a/tests/system/Helpers/URLHelper/CurrentUrlTest.php +++ b/tests/system/Helpers/URLHelper/CurrentUrlTest.php @@ -235,7 +235,7 @@ public function testUriStringSubfolderRelative(): void $this->assertSame('assets/image.jpg', uri_string()); } - public function urlIsProvider(): iterable + public static function provideUrlIs(): iterable { return [ [ @@ -277,7 +277,7 @@ public function urlIsProvider(): iterable } /** - * @dataProvider urlIsProvider + * @dataProvider provideUrlIs */ public function testUrlIs(string $currentPath, string $testPath, bool $expected): void { @@ -291,7 +291,7 @@ public function testUrlIs(string $currentPath, string $testPath, bool $expected) } /** - * @dataProvider urlIsProvider + * @dataProvider provideUrlIs */ public function testUrlIsNoIndex(string $currentPath, string $testPath, bool $expected): void { @@ -307,7 +307,7 @@ public function testUrlIsNoIndex(string $currentPath, string $testPath, bool $ex } /** - * @dataProvider urlIsProvider + * @dataProvider provideUrlIs */ public function testUrlIsWithSubfolder(string $currentPath, string $testPath, bool $expected): void { diff --git a/tests/system/Helpers/URLHelper/MiscUrlTest.php b/tests/system/Helpers/URLHelper/MiscUrlTest.php index 6d4daf8d56c1..7af14d169f16 100644 --- a/tests/system/Helpers/URLHelper/MiscUrlTest.php +++ b/tests/system/Helpers/URLHelper/MiscUrlTest.php @@ -112,7 +112,7 @@ public function testIndexPageAlt(): void // Test anchor - public function anchorNormalPatterns(): iterable + public static function provideAnchor(): iterable { return [ 'normal01' => [ @@ -156,7 +156,7 @@ public function anchorNormalPatterns(): iterable } /** - * @dataProvider anchorNormalPatterns + * @dataProvider provideAnchor * * @param mixed $expected * @param mixed $uri @@ -171,7 +171,7 @@ public function testAnchor($expected = '', $uri = '', $title = '', $attributes = $this->assertSame($expected, anchor($uri, $title, $attributes, $this->config)); } - public function anchorNoindexPatterns(): iterable + public static function provideAnchorNoindex(): iterable { return [ 'noindex01' => [ @@ -221,7 +221,7 @@ public function anchorNoindexPatterns(): iterable } /** - * @dataProvider anchorNoindexPatterns + * @dataProvider provideAnchorNoindex * * @param mixed $expected * @param mixed $uri @@ -238,7 +238,7 @@ public function testAnchorNoindex($expected = '', $uri = '', $title = '', $attri $this->assertSame($expected, anchor($uri, $title, $attributes, $this->config)); } - public function anchorSubpagePatterns(): iterable + public static function provideAnchorTargetted(): iterable { return [ 'subpage01' => [ @@ -278,7 +278,7 @@ public function anchorSubpagePatterns(): iterable } /** - * @dataProvider anchorSubpagePatterns + * @dataProvider provideAnchorTargetted * * @param mixed $expected * @param mixed $uri @@ -295,7 +295,7 @@ public function testAnchorTargetted($expected = '', $uri = '', $title = '', $att $this->assertSame($expected, anchor($uri, $title, $attributes, $this->config)); } - public function anchorExamplePatterns(): iterable + public static function provideAnchorExamples(): iterable { return [ 'egpage01' => [ @@ -324,7 +324,7 @@ public function anchorExamplePatterns(): iterable } /** - * @dataProvider anchorExamplePatterns + * @dataProvider provideAnchorExamples * * @param mixed $expected * @param mixed $uri @@ -341,7 +341,7 @@ public function testAnchorExamples($expected = '', $uri = '', $title = '', $attr // Test anchor_popup - public function anchorPopupPatterns(): iterable + public static function provideAnchorPopup(): iterable { return [ 'normal01' => [ @@ -382,7 +382,7 @@ public function anchorPopupPatterns(): iterable } /** - * @dataProvider anchorPopupPatterns + * @dataProvider provideAnchorPopup * * @param mixed $expected * @param mixed $uri @@ -399,7 +399,7 @@ public function testAnchorPopup($expected = '', $uri = '', $title = '', $attribu // Test mailto - public function mailtoPatterns(): iterable + public static function provideMailto(): iterable { return [ 'page01' => [ @@ -421,7 +421,7 @@ public function mailtoPatterns(): iterable } /** - * @dataProvider mailtoPatterns + * @dataProvider provideMailto * * @param mixed $expected * @param mixed $email @@ -438,7 +438,7 @@ public function testMailto($expected = '', $email = '', $title = '', $attributes // Test safe_mailto - public function safeMailtoPatterns(): iterable + public static function provideSafeMailto(): iterable { return [ 'page01' => [ @@ -460,7 +460,7 @@ public function safeMailtoPatterns(): iterable } /** - * @dataProvider safeMailtoPatterns + * @dataProvider provideSafeMailto * * @param mixed $expected * @param mixed $email @@ -487,7 +487,7 @@ public function testSafeMailtoWithCsp(): void // Test auto_link - public function autolinkUrls(): iterable + public static function provideAutoLinkUrl(): iterable { return [ 'test01' => [ @@ -526,7 +526,7 @@ public function autolinkUrls(): iterable } /** - * @dataProvider autolinkUrls + * @dataProvider provideAutoLinkUrl * * @param mixed $in * @param mixed $out @@ -536,7 +536,7 @@ public function testAutoLinkUrl($in, $out): void $this->assertSame($out, auto_link($in, 'url')); } - public function autolinkEmails(): iterable + public static function provideAutoLinkEmail(): iterable { return [ 'test01' => [ @@ -575,7 +575,7 @@ public function autolinkEmails(): iterable } /** - * @dataProvider autolinkEmails + * @dataProvider provideAutoLinkEmail * * @param mixed $in * @param mixed $out @@ -585,7 +585,7 @@ public function testAutoLinkEmail($in, $out): void $this->assertSame($out, auto_link($in, 'email')); } - public function autolinkBoth(): iterable + public static function provideAutolinkBoth(): iterable { return [ 'test01' => [ @@ -624,7 +624,7 @@ public function autolinkBoth(): iterable } /** - * @dataProvider autolinkBoth + * @dataProvider provideAutolinkBoth * * @param mixed $in * @param mixed $out @@ -634,7 +634,7 @@ public function testAutolinkBoth($in, $out): void $this->assertSame($out, auto_link($in)); } - public function autolinkPopup(): iterable + public static function provideAutoLinkPopup(): iterable { return [ 'test01' => [ @@ -673,7 +673,7 @@ public function autolinkPopup(): iterable } /** - * @dataProvider autolinkPopup + * @dataProvider provideAutoLinkPopup * * @param mixed $in * @param mixed $out @@ -685,7 +685,7 @@ public function testAutoLinkPopup($in, $out): void // Test prep_url - public function prepUrlProvider(): iterable + public static function providePrepUrl(): iterable { // input, expected, secure return [ @@ -763,7 +763,7 @@ public function prepUrlProvider(): iterable } /** - * @dataProvider prepUrlProvider + * @dataProvider providePrepUrl */ public function testPrepUrl(string $input, string $expected, bool $secure): void { @@ -829,7 +829,7 @@ public function testMbUrlTitleExtraDashes(): void } /** - * @dataProvider urlToProvider + * @dataProvider provideUrlTo */ public function testUrlTo(string $expected, string $input, ...$args): void { @@ -845,7 +845,7 @@ public function testUrlTo(string $expected, string $input, ...$args): void } /** - * @dataProvider urlToMissingRoutesProvider + * @dataProvider provideUrlToThrowsOnEmptyOrMissingRoute */ public function testUrlToThrowsOnEmptyOrMissingRoute(string $route): void { @@ -854,7 +854,7 @@ public function testUrlToThrowsOnEmptyOrMissingRoute(string $route): void url_to($route); } - public function urlToProvider(): iterable + public static function provideUrlTo(): iterable { $page = config('App')->indexPage !== '' ? config('App')->indexPage . '/' : ''; @@ -874,7 +874,7 @@ public function urlToProvider(): iterable ]; } - public function urlToMissingRoutesProvider(): iterable + public static function provideUrlToThrowsOnEmptyOrMissingRoute(): iterable { return [ [ diff --git a/tests/system/Helpers/URLHelper/SiteUrlTest.php b/tests/system/Helpers/URLHelper/SiteUrlTest.php index 36fe9882c6d6..cafcb2f3ee6a 100644 --- a/tests/system/Helpers/URLHelper/SiteUrlTest.php +++ b/tests/system/Helpers/URLHelper/SiteUrlTest.php @@ -61,7 +61,7 @@ protected function tearDown(): void * @param string $expectedSiteUrl * @param string $expectedBaseUrl * - * @dataProvider configProvider + * @dataProvider provideUrls */ public function testUrls( $baseURL, @@ -81,7 +81,7 @@ public function testUrls( $this->assertSame($expectedBaseUrl, base_url($path, $scheme)); } - public function configProvider(): iterable + public static function provideUrls(): iterable { // baseURL, indexPage, scheme, secure, path, expectedSiteUrl, expectedBaseUrl return [ diff --git a/tests/system/I18n/TimeLegacyTest.php b/tests/system/I18n/TimeLegacyTest.php index f9d081709a7b..36907988349d 100644 --- a/tests/system/I18n/TimeLegacyTest.php +++ b/tests/system/I18n/TimeLegacyTest.php @@ -1123,17 +1123,16 @@ public function testGetter(): void $this->assertNull($time->weekOfWeek); } - // @TODO Uncomment when PHP 8.2.4 Segmentation fault fixed. - // public function testUnserializeTimeObject() - // { - // $time1 = new TimeLegacy('August 28, 2020 10:04:00pm', 'Asia/Manila', 'en'); - // $timeCache = serialize($time1); - // $time2 = unserialize($timeCache); - // - // $this->assertInstanceOf(TimeLegacy::class, $time2); - // $this->assertTrue($time2->equals($time1)); - // $this->assertNotSame($time1, $time2); - // } + public function testUnserializeTimeObject() + { + $time1 = new TimeLegacy('August 28, 2020 10:04:00pm', 'Asia/Manila', 'en'); + $timeCache = serialize($time1); + $time2 = unserialize($timeCache); + + $this->assertInstanceOf(TimeLegacy::class, $time2); + $this->assertTrue($time2->equals($time1)); + $this->assertNotSame($time1, $time2); + } public function testSetTestNowWithFaLocale(): void { @@ -1147,7 +1146,7 @@ public function testSetTestNowWithFaLocale(): void } /** - * @dataProvider provideLocales + * @dataProvider provideToStringDoesNotDependOnLocale */ public function testToStringDoesNotDependOnLocale(string $locale): void { @@ -1158,7 +1157,7 @@ public function testToStringDoesNotDependOnLocale(string $locale): void $this->assertSame('2017-03-10 12:00:00', (string) $time); } - public function provideLocales(): iterable + public static function provideToStringDoesNotDependOnLocale(): iterable { yield from [ ['en'], diff --git a/tests/system/I18n/TimeTest.php b/tests/system/I18n/TimeTest.php index 35a64dad695e..ac2eb4facd61 100644 --- a/tests/system/I18n/TimeTest.php +++ b/tests/system/I18n/TimeTest.php @@ -1126,17 +1126,16 @@ public function testGetter(): void $this->assertNull($time->weekOfWeek); } - // @TODO Uncomment when PHP 8.2.4 Segmentation fault fixed. - // public function testUnserializeTimeObject() - // { - // $time1 = new Time('August 28, 2020 10:04:00pm', 'Asia/Manila', 'en'); - // $timeCache = serialize($time1); - // $time2 = unserialize($timeCache); - // - // $this->assertInstanceOf(Time::class, $time2); - // $this->assertTrue($time2->equals($time1)); - // $this->assertNotSame($time1, $time2); - // } + public function testUnserializeTimeObject() + { + $time1 = new Time('August 28, 2020 10:04:00pm', 'Asia/Manila', 'en'); + $timeCache = serialize($time1); + $time2 = unserialize($timeCache); + + $this->assertInstanceOf(Time::class, $time2); + $this->assertTrue($time2->equals($time1)); + $this->assertNotSame($time1, $time2); + } public function testSetTestNowWithTimeZone(): void { @@ -1159,7 +1158,7 @@ public function testSetTestNowWithFaLocale(): void } /** - * @dataProvider provideLocales + * @dataProvider provideToStringDoesNotDependOnLocale */ public function testToStringDoesNotDependOnLocale(string $locale): void { @@ -1170,7 +1169,7 @@ public function testToStringDoesNotDependOnLocale(string $locale): void $this->assertSame('2017-03-10 12:00:00', (string) $time); } - public function provideLocales(): iterable + public static function provideToStringDoesNotDependOnLocale(): iterable { yield from [ ['en'], diff --git a/tests/system/Language/LanguageTest.php b/tests/system/Language/LanguageTest.php index 27c1b6bee346..34313e8dfac8 100644 --- a/tests/system/Language/LanguageTest.php +++ b/tests/system/Language/LanguageTest.php @@ -213,7 +213,7 @@ public function testPrioritizedLocator(): void $this->assertSame('billions and billions', lang('Core.bazillion', [], 'en')); } - public function MessageBundles(): iterable + public static function provideBundleUniqueKeys(): iterable { return [ ['CLI'], @@ -244,7 +244,7 @@ public function MessageBundles(): iterable * There's not a whole lot that can be done with message bundles, * but we can at least try loading them ... more accurate code coverage? * - * @dataProvider MessageBundles + * @dataProvider provideBundleUniqueKeys * * @param mixed $bundle */ diff --git a/tests/system/Models/FindModelTest.php b/tests/system/Models/FindModelTest.php index bfe3ed0ec182..8b54d09fbbff 100644 --- a/tests/system/Models/FindModelTest.php +++ b/tests/system/Models/FindModelTest.php @@ -157,7 +157,7 @@ public function testFirst(): void } /** - * @dataProvider provideGroupBy + * @dataProvider provideFirstAggregate * * @param mixed $groupBy * @param mixed $total @@ -184,7 +184,7 @@ public function testFirstAggregate($groupBy, $total): void $this->assertSame($total, (int) $user->total); } - public static function provideGroupBy(): iterable + public static function provideFirstAggregate(): iterable { return [ [true, 3], diff --git a/tests/system/Models/InsertModelTest.php b/tests/system/Models/InsertModelTest.php index 141eebdd6307..f538b417c935 100644 --- a/tests/system/Models/InsertModelTest.php +++ b/tests/system/Models/InsertModelTest.php @@ -65,6 +65,26 @@ public function testInsertBatchSuccess(): void $this->seeInDatabase('job', ['name' => 'Cab Driver']); } + public function testInsertBatchUseAutoIncrementSetToFalse(): void + { + $insertData = [ + [ + 'key' => 'key1', + 'value' => 'value1', + ], + [ + 'key' => 'key2', + 'value' => 'value2', + ], + ]; + + $this->createModel(WithoutAutoIncrementModel::class); + $this->model->insertBatch($insertData); + + $this->seeInDatabase('without_auto_increment', ['key' => 'key1']); + $this->seeInDatabase('without_auto_increment', ['key' => 'key2']); + } + public function testInsertBatchValidationFail(): void { $jobData = [ diff --git a/tests/system/Models/UpdateModelTest.php b/tests/system/Models/UpdateModelTest.php index bd57025dc87f..78ee2c945631 100644 --- a/tests/system/Models/UpdateModelTest.php +++ b/tests/system/Models/UpdateModelTest.php @@ -147,6 +147,27 @@ public function testUpdateBatchSuccess(): void ]); } + public function testUpdateBatchInvalidIndex(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage( + 'The index ("not_exist") for updateBatch() is missing in the data: {"name":"Derek Jones","country":"Greece"}' + ); + + $data = [ + [ + 'name' => 'Derek Jones', + 'country' => 'Greece', + ], + [ + 'name' => 'Ahmadinejad', + 'country' => 'Greece', + ], + ]; + + $this->createModel(UserModel::class)->updateBatch($data, 'not_exist'); + } + public function testUpdateBatchValidationFail(): void { $data = [ @@ -208,11 +229,16 @@ public function testUpdateBatchWithEntity(): void $entity1->name = 'Jones Martin'; $entity1->country = 'India'; $entity1->deleted = 0; + $entity1->syncOriginal(); + // Update the entity. + $entity1->country = 'China'; + // This entity is not updated. $entity2->id = 4; $entity2->name = 'Jones Martin'; $entity2->country = 'India'; $entity2->deleted = 0; + $entity2->syncOriginal(); $this->assertSame(2, $this->createModel(UserModel::class)->updateBatch([$entity1, $entity2], 'id')); } @@ -382,7 +408,7 @@ public function testUpdateWithSetAndEscape(): void } /** - * @dataProvider provideInvalidIds + * @dataProvider provideUpdateThrowDatabaseExceptionWithoutWhereClause * * @param false|null $id */ @@ -397,7 +423,7 @@ public function testUpdateThrowDatabaseExceptionWithoutWhereClause($id, string $ $this->model->update($id, ['name' => 'Foo Bar']); } - public function provideInvalidIds(): iterable + public static function provideUpdateThrowDatabaseExceptionWithoutWhereClause(): iterable { yield from [ [ diff --git a/tests/system/Models/WhenWhenNotModelTest.php b/tests/system/Models/WhenWhenNotModelTest.php new file mode 100644 index 000000000000..9f19b9c52d41 --- /dev/null +++ b/tests/system/Models/WhenWhenNotModelTest.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Models; + +use Tests\Support\Models\SecondaryModel; + +/** + * @group DatabaseLive + * + * @internal + */ +final class WhenWhenNotModelTest extends LiveModelTestCase +{ + public function testWhenWithTrueCondition(): void + { + $secondaryData = [ + [ + 'key' => 'foo', + 'value' => 'foobar', + ], + [ + 'key' => 'bar', + 'value' => 'foobar', + ], + [ + 'key' => 'baz', + 'value' => 'foobaz', + ], + ]; + $filter = 'foobar'; + + $this->createModel(SecondaryModel::class)->insertBatch($secondaryData); + + $result = $this->model->when($filter, static function ($query, $filter) { + $query->where('value', $filter); + })->find(); + + $this->assertCount(2, $result); + $this->assertSame('foo', $result[0]->key); + $this->assertSame('bar', $result[1]->key); + } + + public function testWhenWithFalseConditionAndDefaultCallback(): void + { + $secondaryData = [ + [ + 'key' => 'foo', + 'value' => 'foobar', + ], + [ + 'key' => 'bar', + 'value' => 'foobar', + ], + [ + 'key' => 'baz', + 'value' => 'foobaz', + ], + ]; + $filter = ''; + + $this->createModel(SecondaryModel::class)->insertBatch($secondaryData); + + $result = $this->model->when($filter, static function ($query, $filter) { + $query->where('value', $filter); + }, static function ($query) { + $query->where('value', 'foobar'); + })->find(); + + $this->assertCount(2, $result); + $this->assertSame('foo', $result[0]->key); + $this->assertSame('bar', $result[1]->key); + } + + public function testWhenNotWithFalseCondition(): void + { + $secondaryData = [ + [ + 'key' => 'foo', + 'value' => 'foobar', + ], + [ + 'key' => 'bar', + 'value' => 'foobar', + ], + [ + 'key' => 'baz', + 'value' => 'foobaz', + ], + ]; + $filter = ''; + + $this->createModel(SecondaryModel::class)->insertBatch($secondaryData); + + $result = $this->model->whenNot($filter, static function ($query, $filter) { + $query->where('value !=', 'foobar'); + })->find(); + + $this->assertCount(1, $result); + $this->assertSame('baz', $result[0]->key); + $this->assertSame('foobaz', $result[0]->value); + } + + public function testWhenNotWithTrueConditionAndDefaultCallback(): void + { + $secondaryData = [ + [ + 'key' => 'foo', + 'value' => 'foobar', + ], + [ + 'key' => 'bar', + 'value' => 'foobar', + ], + [ + 'key' => 'baz', + 'value' => 'foobaz', + ], + ]; + $filter = 'foobar'; + + $this->createModel(SecondaryModel::class)->insertBatch($secondaryData); + + $result = $this->model->whenNot($filter, static function ($query, $filter) { + $query->where('value !=', 'foobar'); + }, static function ($query) { + $query->where('value', 'foobar'); + })->find(); + + $this->assertCount(2, $result); + $this->assertSame('foo', $result[0]->key); + $this->assertSame('bar', $result[1]->key); + } +} diff --git a/tests/system/Publisher/PublisherRestrictionsTest.php b/tests/system/Publisher/PublisherRestrictionsTest.php index ccecc704cd21..51237d20b4ac 100644 --- a/tests/system/Publisher/PublisherRestrictionsTest.php +++ b/tests/system/Publisher/PublisherRestrictionsTest.php @@ -47,7 +47,7 @@ public function testImmutableRestrictions(): void } /** - * @dataProvider fileProvider + * @dataProvider provideDefaultPublicRestrictions */ public function testDefaultPublicRestrictions(string $path): void { @@ -69,7 +69,7 @@ public function testDefaultPublicRestrictions(string $path): void $this->assertSame($expected, $errors[$file]->getMessage()); } - public function fileProvider(): iterable + public static function provideDefaultPublicRestrictions(): iterable { yield from [ 'php' => ['index.php'], @@ -79,7 +79,7 @@ public function fileProvider(): iterable } /** - * @dataProvider destinationProvider + * @dataProvider provideDestinations */ public function testDestinations(string $destination, bool $allowed): void { @@ -99,7 +99,7 @@ public function testDestinations(string $destination, bool $allowed): void $this->assertInstanceOf(Publisher::class, $publisher); } - public function destinationProvider(): iterable + public static function provideDestinations(): iterable { return [ 'explicit' => [ diff --git a/tests/system/Router/RouteCollectionReverseRouteTest.php b/tests/system/Router/RouteCollectionReverseRouteTest.php index 64ddacd163bb..8335d516f9e8 100644 --- a/tests/system/Router/RouteCollectionReverseRouteTest.php +++ b/tests/system/Router/RouteCollectionReverseRouteTest.php @@ -120,7 +120,7 @@ public function testReverseRoutingWithLocale(): void $this->assertSame('/en/contact', $routes->reverseRoute('myController::goto')); } - public function reverseRoutingHandlerProvider(): iterable + public static function provideReverseRoutingDefaultNamespaceAppController(): iterable { return yield from [ 'Omit namespace' => ['Galleries::showUserGallery'], @@ -130,7 +130,7 @@ public function reverseRoutingHandlerProvider(): iterable } /** - * @dataProvider reverseRoutingHandlerProvider + * @dataProvider provideReverseRoutingDefaultNamespaceAppController */ public function testReverseRoutingDefaultNamespaceAppController(string $controller): void { diff --git a/tests/system/Router/RouteCollectionTest.php b/tests/system/Router/RouteCollectionTest.php index 4143c6a3bd2f..a4e49c9ad4f4 100644 --- a/tests/system/Router/RouteCollectionTest.php +++ b/tests/system/Router/RouteCollectionTest.php @@ -380,7 +380,7 @@ static function ($routes): void { } /** - * @dataProvider groupProvider + * @dataProvider provideNestedGroupingWorksWithRootPrefix */ public function testNestedGroupingWorksWithRootPrefix( string $group, @@ -405,7 +405,7 @@ static function ($routes): void { $this->assertSame($expected, $routes->getRoutes()); } - public function groupProvider(): iterable + public static function provideNestedGroupingWorksWithRootPrefix(): iterable { yield from [ ['admin', '/', [ @@ -1218,7 +1218,7 @@ static function (): void {}, } /** - * @dataProvider optionsProvider + * @dataProvider provideRoutesOptionsWithSameFromTwoRoutes */ public function testRoutesOptionsWithSameFromTwoRoutes(array $options1, array $options2): void { @@ -1242,7 +1242,7 @@ static function (): void {}, $this->assertSame($options, $options1); } - public function optionsProvider(): iterable + public static function provideRoutesOptionsWithSameFromTwoRoutes(): iterable { yield from [ [ @@ -1657,7 +1657,7 @@ public function testZeroAsURIPath(): void $this->assertSame($expects, $router->handle('/0')); } - public function provideRouteDefaultNamespace(): iterable + public static function provideRouteDefaultNamespace(): iterable { return [ 'with \\ prefix' => ['\App\Controllers'], diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index c068569c4576..e863bb5e4baf 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -847,7 +847,7 @@ public function testSetDirectoryInvalid(): void } /** - * @dataProvider provideRedirectCase + * @dataProvider provideRedirectRoute */ public function testRedirectRoute( string $route, @@ -870,7 +870,7 @@ public function testRedirectRoute( $router->handle($url); } - public function provideRedirectCase(): iterable + public static function provideRedirectRoute(): iterable { // [$route, $redirectFrom, $redirectTo, $url, $expectedPath, $alias] return [ diff --git a/tests/system/Test/DOMParserTest.php b/tests/system/Test/DOMParserTest.php index 56c3cc00b31e..f6e33cc32250 100644 --- a/tests/system/Test/DOMParserTest.php +++ b/tests/system/Test/DOMParserTest.php @@ -79,7 +79,7 @@ public function testParseSelectorWithAttribute(): void $this->assertSame(['href' => 'http://example.com'], $selector['attr']); } - public function provideText(): iterable + public static function provideText(): iterable { return [ 'en' => ['Hello World'], diff --git a/tests/system/Test/FeatureTestTraitTest.php b/tests/system/Test/FeatureTestTraitTest.php index dc6fa35a5975..f40817767b6d 100644 --- a/tests/system/Test/FeatureTestTraitTest.php +++ b/tests/system/Test/FeatureTestTraitTest.php @@ -284,7 +284,7 @@ public function testCallZeroAsPathGot404(): void $this->get('0'); } - public function provideRoutesData(): iterable + public static function provideOpenCliRoutesFromHttpGot404(): iterable { return [ 'non parameterized cli' => [ @@ -316,7 +316,7 @@ public function provideRoutesData(): iterable } /** - * @dataProvider provideRoutesData + * @dataProvider provideOpenCliRoutesFromHttpGot404 * * @param mixed $from * @param mixed $to diff --git a/tests/system/Test/TestLoggerTest.php b/tests/system/Test/TestLoggerTest.php index 4240b4c2690b..256359abf81f 100644 --- a/tests/system/Test/TestLoggerTest.php +++ b/tests/system/Test/TestLoggerTest.php @@ -21,7 +21,7 @@ final class TestLoggerTest extends CIUnitTestCase { /** - * @dataProvider provideDidLogCases + * @dataProvider provideDidLogMethod */ public function testDidLogMethod(bool $expected, string $level, string $message, bool $exact): void { @@ -33,7 +33,7 @@ public function testDidLogMethod(bool $expected, string $level, string $message, ); } - public function provideDidLogCases(): iterable + public static function provideDidLogMethod(): iterable { yield 'exact' => [ true, diff --git a/tests/system/Test/TestResponseTest.php b/tests/system/Test/TestResponseTest.php index 48baf0cf4a66..ef10e0cf3506 100644 --- a/tests/system/Test/TestResponseTest.php +++ b/tests/system/Test/TestResponseTest.php @@ -33,7 +33,7 @@ protected function setUp(): void } /** - * @dataProvider statusCodeProvider + * @dataProvider provideHttpStatusCodes */ public function testIsOK(int $code, bool $isOk): void { @@ -46,7 +46,7 @@ public function testIsOK(int $code, bool $isOk): void /** * Provides status codes and their expected "OK" */ - public function statusCodeProvider(): iterable + public static function provideHttpStatusCodes(): iterable { return [ [ @@ -223,7 +223,7 @@ public function testAssertStatus(): void } /** - * @dataProvider statusCodeProvider + * @dataProvider provideHttpStatusCodes */ public function testAssertIsOK(int $code, bool $isOk): void { diff --git a/tests/system/Throttle/ThrottleTest.php b/tests/system/Throttle/ThrottleTest.php index 83a44878cf76..16d58ac506d4 100644 --- a/tests/system/Throttle/ThrottleTest.php +++ b/tests/system/Throttle/ThrottleTest.php @@ -189,7 +189,7 @@ public function testFlooding(): void } /** - * @dataProvider tokenTimeUsecases + * @dataProvider provideTokenTimeCalculationUCs */ public function testTokenTimeCalculationUCs(int $capacity, int $seconds, array $checkInputs): void { @@ -208,7 +208,7 @@ public function testTokenTimeCalculationUCs(int $capacity, int $seconds, array $ } } - public function tokenTimeUsecases(): iterable + public static function provideTokenTimeCalculationUCs(): iterable { return [ '2 capacity / 200 seconds (100s refresh, 0.01 tokens/s) -> 5 checks, 1 cost each' => [ diff --git a/tests/system/Validation/CreditCardRulesTest.php b/tests/system/Validation/CreditCardRulesTest.php index 6ef13c5ecee5..397675270eda 100644 --- a/tests/system/Validation/CreditCardRulesTest.php +++ b/tests/system/Validation/CreditCardRulesTest.php @@ -49,7 +49,7 @@ protected function setUp(): void } /** - * @dataProvider creditCardProvider + * @dataProvider provideValidCCNumber */ public function testValidCCNumber(string $type, ?string $number, bool $expected): void { @@ -63,7 +63,7 @@ public function testValidCCNumber(string $type, ?string $number, bool $expected) * * @see https://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm */ - public function creditCardProvider(): iterable + public function provideValidCCNumber(): iterable { yield from [ 'null_test' => [ diff --git a/tests/system/Validation/FormatRulesTest.php b/tests/system/Validation/FormatRulesTest.php index c04ed0eb22e5..eb25696c4fea 100644 --- a/tests/system/Validation/FormatRulesTest.php +++ b/tests/system/Validation/FormatRulesTest.php @@ -85,7 +85,7 @@ public function testRegexMatchFalse(): void } /** - * @dataProvider urlProvider + * @dataProvider provideValidUrl */ public function testValidURL(?string $url, bool $isLoose, bool $isStrict): void { @@ -101,7 +101,7 @@ public function testValidURL(?string $url, bool $isLoose, bool $isStrict): void } /** - * @dataProvider urlProvider + * @dataProvider provideValidUrl */ public function testValidURLStrict(?string $url, bool $isLoose, bool $isStrict): void { @@ -129,7 +129,7 @@ public function testValidURLStrictWithSchema(): void $this->assertFalse($this->validation->run($data)); } - public function urlProvider(): iterable + public static function provideValidUrl(): iterable { yield from [ [ @@ -229,7 +229,7 @@ public function urlProvider(): iterable } /** - * @dataProvider emailProviderSingle + * @dataProvider provideValidEmail */ public function testValidEmail(?string $email, bool $expected): void { @@ -245,7 +245,7 @@ public function testValidEmail(?string $email, bool $expected): void } /** - * @dataProvider emailsProvider + * @dataProvider provideValidEmails */ public function testValidEmails(?string $email, bool $expected): void { @@ -260,7 +260,7 @@ public function testValidEmails(?string $email, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function emailProviderSingle(): iterable + public static function provideValidEmail(): iterable { yield from [ [ @@ -278,7 +278,7 @@ public function emailProviderSingle(): iterable ]; } - public function emailsProvider(): iterable + public static function provideValidEmails(): iterable { yield from [ [ @@ -309,7 +309,7 @@ public function emailsProvider(): iterable } /** - * @dataProvider ipProvider + * @dataProvider provideValidIP */ public function testValidIP(?string $ip, ?string $which, bool $expected): void { @@ -324,7 +324,7 @@ public function testValidIP(?string $ip, ?string $which, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function ipProvider(): iterable + public static function provideValidIP(): iterable { yield from [ [ @@ -376,7 +376,7 @@ public function ipProvider(): iterable } /** - * @dataProvider stringProvider + * @dataProvider provideString * * @param int|string $str */ @@ -393,7 +393,7 @@ public function testString($str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function stringProvider(): iterable + public static function provideString(): iterable { yield from [ [ @@ -412,7 +412,7 @@ public function stringProvider(): iterable } /** - * @dataProvider alphaProvider + * @dataProvider provideAlpha */ public function testAlpha(?string $str, bool $expected): void { @@ -427,7 +427,7 @@ public function testAlpha(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function alphaProvider(): iterable + public static function provideAlpha(): iterable { yield from [ [ @@ -454,7 +454,7 @@ public function alphaProvider(): iterable } /** - * @dataProvider alphaSpaceProvider + * @dataProvider provideAlphaSpace */ public function testAlphaSpace(?string $value, bool $expected): void { @@ -469,7 +469,7 @@ public function testAlphaSpace(?string $value, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function alphaSpaceProvider(): iterable + public static function provideAlphaSpace(): iterable { yield from [ [ @@ -515,7 +515,7 @@ public function testAlphaNumeric(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function alphaNumericProvider(): iterable + public static function alphaNumericProvider(): iterable { yield from [ [ @@ -538,7 +538,7 @@ public function alphaNumericProvider(): iterable } /** - * @dataProvider alphaNumericPunctProvider + * @dataProvider provideAlphaNumericPunct */ public function testAlphaNumericPunct(?string $str, bool $expected): void { @@ -553,7 +553,7 @@ public function testAlphaNumericPunct(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function alphaNumericPunctProvider(): iterable + public static function provideAlphaNumericPunct(): iterable { yield from [ [ @@ -670,7 +670,7 @@ public function alphaNumericSpaceProvider(): Generator } /** - * @dataProvider alphaDashProvider + * @dataProvider provideAlphaDash */ public function testAlphaDash(?string $str, bool $expected): void { @@ -685,7 +685,7 @@ public function testAlphaDash(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function alphaDashProvider(): iterable + public static function provideAlphaDash(): iterable { yield from [ [ @@ -708,7 +708,7 @@ public function alphaDashProvider(): iterable } /** - * @dataProvider hexProvider + * @dataProvider provideHex */ public function testHex(?string $str, bool $expected): void { @@ -723,7 +723,7 @@ public function testHex(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function hexProvider(): iterable + public static function provideHex(): iterable { yield from [ [ @@ -746,7 +746,7 @@ public function hexProvider(): iterable } /** - * @dataProvider numericProvider + * @dataProvider provideNumeric */ public function testNumeric(?string $str, bool $expected): void { @@ -761,7 +761,7 @@ public function testNumeric(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function numericProvider(): iterable + public static function provideNumeric(): iterable { yield from [ [ @@ -802,7 +802,7 @@ public function numericProvider(): iterable /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/5374 * - * @dataProvider integerInvalidTypeDataProvider + * @dataProvider provideInvalidIntegerType * * @param mixed $value */ @@ -821,7 +821,7 @@ public function testIntegerWithInvalidTypeData($value, bool $expected): void /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/5374 * - * @dataProvider integerInvalidTypeDataProvider + * @dataProvider provideInvalidIntegerType * * @param mixed $value */ @@ -837,7 +837,7 @@ public function testNumericWithInvalidTypeData($value, bool $expected): void $this->assertsame($expected, $this->validation->run($data)); } - public function integerInvalidTypeDataProvider(): iterable + public static function provideInvalidIntegerType(): iterable { // TypeError : CodeIgniter\Validation\FormatRules::integer(): Argument #1 ($str) must be of type ?string, array given // yield 'array with int' => [ @@ -868,7 +868,7 @@ public function integerInvalidTypeDataProvider(): iterable } /** - * @dataProvider integerProvider + * @dataProvider provideInteger */ public function testInteger(?string $str, bool $expected): void { @@ -883,7 +883,7 @@ public function testInteger(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function integerProvider(): iterable + public static function provideInteger(): iterable { yield from [ [ @@ -922,7 +922,7 @@ public function integerProvider(): iterable } /** - * @dataProvider decimalProvider + * @dataProvider provideDecimal */ public function testDecimal(?string $str, bool $expected): void { @@ -937,7 +937,7 @@ public function testDecimal(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function decimalProvider(): iterable + public static function provideDecimal(): iterable { yield from [ [ @@ -980,7 +980,7 @@ public function decimalProvider(): iterable } /** - * @dataProvider naturalProvider + * @dataProvider provideNatural */ public function testNatural(?string $str, bool $expected): void { @@ -995,7 +995,7 @@ public function testNatural(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function naturalProvider(): iterable + public static function provideNatural(): iterable { yield from [ [ @@ -1022,7 +1022,7 @@ public function naturalProvider(): iterable } /** - * @dataProvider naturalZeroProvider + * @dataProvider provideNaturalNoZero */ public function testNaturalNoZero(?string $str, bool $expected): void { @@ -1037,7 +1037,7 @@ public function testNaturalNoZero(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function naturalZeroProvider(): iterable + public static function provideNaturalNoZero(): iterable { yield from [ [ @@ -1064,7 +1064,7 @@ public function naturalZeroProvider(): iterable } /** - * @dataProvider base64Provider + * @dataProvider provideBase64 */ public function testBase64(?string $str, bool $expected): void { @@ -1079,7 +1079,7 @@ public function testBase64(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function base64Provider(): iterable + public static function provideBase64(): iterable { yield from [ [ @@ -1098,7 +1098,7 @@ public function base64Provider(): iterable } /** - * @dataProvider jsonProvider + * @dataProvider provideJson */ public function testJson(?string $str, bool $expected): void { @@ -1113,7 +1113,7 @@ public function testJson(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function jsonProvider(): iterable + public static function provideJson(): iterable { yield from [ [ @@ -1156,7 +1156,7 @@ public function jsonProvider(): iterable } /** - * @dataProvider timezoneProvider + * @dataProvider provideTimeZone */ public function testTimeZone(?string $str, bool $expected): void { @@ -1171,7 +1171,7 @@ public function testTimeZone(?string $str, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function timezoneProvider(): iterable + public static function provideTimeZone(): iterable { yield from [ [ @@ -1194,7 +1194,7 @@ public function timezoneProvider(): iterable } /** - * @dataProvider validDateProvider + * @dataProvider provideValidDate */ public function testValidDate(?string $str, ?string $format, bool $expected): void { @@ -1209,7 +1209,7 @@ public function testValidDate(?string $str, ?string $format, bool $expected): vo $this->assertSame($expected, $this->validation->run($data)); } - public function validDateProvider(): iterable + public static function provideValidDate(): iterable { yield from [ [ diff --git a/tests/system/Validation/RulesTest.php b/tests/system/Validation/RulesTest.php index fe10358e20ce..f031a129a286 100644 --- a/tests/system/Validation/RulesTest.php +++ b/tests/system/Validation/RulesTest.php @@ -52,7 +52,7 @@ protected function setUp(): void } /** - * @dataProvider provideRequiredCases + * @dataProvider provideRequired */ public function testRequired(array $data, bool $expected): void { @@ -60,7 +60,7 @@ public function testRequired(array $data, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function provideRequiredCases(): iterable + public static function provideRequired(): iterable { yield from [ [['foo' => null], false], @@ -73,7 +73,7 @@ public function provideRequiredCases(): iterable } /** - * @dataProvider ifExistProvider + * @dataProvider provideIfExist */ public function testIfExist(array $rules, array $data, bool $expected): void { @@ -81,7 +81,7 @@ public function testIfExist(array $rules, array $data, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function ifExistProvider(): iterable + public static function provideIfExist(): iterable { yield from [ [ @@ -126,7 +126,7 @@ public function ifExistProvider(): iterable } /** - * @dataProvider providePermitEmptyCases + * @dataProvider providePermitEmpty */ public function testPermitEmpty(array $rules, array $data, bool $expected): void { @@ -134,7 +134,7 @@ public function testPermitEmpty(array $rules, array $data, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function providePermitEmptyCases(): iterable + public static function providePermitEmpty(): iterable { yield from [ // If the rule is only `permit_empty`, any value will pass. @@ -298,7 +298,7 @@ public function testMatches(array $data, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function provideMatchesCases(): iterable + public static function provideMatchesCases(): iterable { yield from [ [['foo' => null, 'bar' => null], true], @@ -316,7 +316,7 @@ public function testMatchesNested(array $data, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function provideMatchesNestedCases(): iterable + public static function provideMatchesNestedCases(): iterable { yield from [ [['nested' => ['foo' => 'match', 'bar' => 'match']], true], @@ -343,7 +343,7 @@ public function testDiffersNested(array $data, bool $expected): void } /** - * @dataProvider provideEqualsCases + * @dataProvider provideEquals */ public function testEquals(array $data, string $param, bool $expected): void { @@ -351,7 +351,7 @@ public function testEquals(array $data, string $param, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function provideEqualsCases(): iterable + public static function provideEquals(): iterable { yield from [ 'null' => [['foo' => null], '', false], @@ -371,7 +371,7 @@ public function testMinLength(?string $data, string $length, bool $expected): vo $this->assertSame($expected, $this->validation->run(['foo' => $data])); } - public function provideMinLengthCases(): iterable + public static function provideMinLengthCases(): iterable { yield from [ 'null' => [null, '2', false], @@ -397,7 +397,7 @@ public function testMaxLengthReturnsFalseWithNonNumericVal(): void } /** - * @dataProvider provideExactLengthCases + * @dataProvider provideExactLength */ public function testExactLength(?string $data, bool $expected): void { @@ -405,7 +405,7 @@ public function testExactLength(?string $data, bool $expected): void $this->assertSame($expected, $this->validation->run(['foo' => $data])); } - public function provideExactLengthCases(): iterable + public static function provideExactLength(): iterable { yield from [ 'null' => [null, false], @@ -423,7 +423,7 @@ public function testExactLengthDetectsBadLength(): void } /** - * @dataProvider greaterThanProvider + * @dataProvider provideGreaterThan */ public function testGreaterThan(?string $first, ?string $second, bool $expected): void { @@ -432,7 +432,7 @@ public function testGreaterThan(?string $first, ?string $second, bool $expected) $this->assertSame($expected, $this->validation->run($data)); } - public function greaterThanProvider(): iterable + public static function provideGreaterThan(): iterable { yield from [ ['-10', '-11', true], @@ -448,7 +448,7 @@ public function greaterThanProvider(): iterable } /** - * @dataProvider greaterThanEqualProvider + * @dataProvider provideGreaterThanEqual */ public function testGreaterThanEqual(?string $first, ?string $second, bool $expected): void { @@ -457,7 +457,7 @@ public function testGreaterThanEqual(?string $first, ?string $second, bool $expe $this->assertSame($expected, $this->validation->run($data)); } - public function greaterThanEqualProvider(): iterable + public static function provideGreaterThanEqual(): iterable { yield from [ ['0', '0', true], @@ -474,7 +474,7 @@ public function greaterThanEqualProvider(): iterable } /** - * @dataProvider lessThanProvider + * @dataProvider provideLessThan */ public function testLessThan(?string $first, ?string $second, bool $expected): void { @@ -483,7 +483,7 @@ public function testLessThan(?string $first, ?string $second, bool $expected): v $this->assertSame($expected, $this->validation->run($data)); } - public function lessThanProvider(): iterable + public static function provideLessThan(): iterable { yield from [ ['-10', '-11', false], @@ -500,7 +500,7 @@ public function lessThanProvider(): iterable } /** - * @dataProvider lessThanEqualProvider + * @dataProvider provideLessThanEqual */ public function testLessThanEqual(?string $first, ?string $second, bool $expected): void { @@ -509,7 +509,7 @@ public function testLessThanEqual(?string $first, ?string $second, bool $expecte $this->assertSame($expected, $this->validation->run($data)); } - public function lessThanEqualProvider(): iterable + public static function provideLessThanEqual(): iterable { yield from [ ['0', '0', true], @@ -526,7 +526,7 @@ public function lessThanEqualProvider(): iterable } /** - * @dataProvider inListProvider + * @dataProvider provideInList */ public function testInList(?string $first, ?string $second, bool $expected): void { @@ -536,7 +536,7 @@ public function testInList(?string $first, ?string $second, bool $expected): voi } /** - * @dataProvider inListProvider + * @dataProvider provideInList */ public function testNotInList(?string $first, ?string $second, bool $expected): void { @@ -545,7 +545,7 @@ public function testNotInList(?string $first, ?string $second, bool $expected): $this->assertSame(! $expected, $this->validation->run($data)); } - public function inListProvider(): iterable + public static function provideInList(): iterable { yield from [ ['red', 'red,Blue,123', true], @@ -561,7 +561,7 @@ public function inListProvider(): iterable } /** - * @dataProvider requiredWithProvider + * @dataProvider provideRequiredWith */ public function testRequiredWith(?string $field, ?string $check, bool $expected): void { @@ -581,7 +581,7 @@ public function testRequiredWith(?string $field, ?string $check, bool $expected) $this->assertSame($expected, $this->validation->run($data)); } - public function requiredWithProvider(): iterable + public static function provideRequiredWith(): iterable { yield from [ ['nope', 'bar', false], @@ -616,7 +616,7 @@ public function requiredWithProvider(): iterable /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/7557 * - * @dataProvider RequiredWithAndOtherRulesProvider + * @dataProvider provideRequiredWithAndOtherRules */ public function testRequiredWithAndOtherRules(bool $expected, array $data): void { @@ -629,7 +629,7 @@ public function testRequiredWithAndOtherRules(bool $expected, array $data): void $this->assertSame($expected, $result); } - public function RequiredWithAndOtherRulesProvider(): iterable + public static function provideRequiredWithAndOtherRules(): iterable { yield from [ // `otherField` and `mustBeADate` do not exist @@ -652,7 +652,7 @@ public function RequiredWithAndOtherRulesProvider(): iterable } /** - * @dataProvider RequiredWithAndOtherRuleWithValueZeroProvider + * @dataProvider provideRequiredWithAndOtherRuleWithValueZero */ public function testRequiredWithAndOtherRuleWithValueZero(bool $expected, array $data): void { @@ -666,7 +666,7 @@ public function testRequiredWithAndOtherRuleWithValueZero(bool $expected, array $this->assertSame($expected, $result); } - public function RequiredWithAndOtherRuleWithValueZeroProvider(): iterable + public static function provideRequiredWithAndOtherRuleWithValueZero(): iterable { yield from [ [true, ['married' => '0', 'partner_name' => '']], @@ -676,7 +676,7 @@ public function RequiredWithAndOtherRuleWithValueZeroProvider(): iterable } /** - * @dataProvider requiredWithoutProvider + * @dataProvider provideRequiredWithout */ public function testRequiredWithout(?string $field, ?string $check, bool $expected): void { @@ -696,7 +696,7 @@ public function testRequiredWithout(?string $field, ?string $check, bool $expect $this->assertSame($expected, $this->validation->run($data)); } - public function requiredWithoutProvider(): iterable + public static function provideRequiredWithout(): iterable { yield from [ ['nope', 'bars', false], @@ -728,7 +728,7 @@ public function requiredWithoutProvider(): iterable } /** - * @dataProvider requiredWithoutMultipleProvider + * @dataProvider provideRequiredWithoutMultiple */ public function testRequiredWithoutMultiple(string $foo, string $bar, string $baz, bool $result): void { @@ -742,7 +742,7 @@ public function testRequiredWithoutMultiple(string $foo, string $bar, string $ba $this->assertSame($result, $this->validation->run($data)); } - public function requiredWithoutMultipleProvider(): iterable + public static function provideRequiredWithoutMultiple(): iterable { yield from [ 'all empty' => [ @@ -779,7 +779,7 @@ public function requiredWithoutMultipleProvider(): iterable } /** - * @dataProvider requiredWithoutMultipleWithoutFieldsProvider + * @dataProvider provideRequiredWithoutMultipleWithoutFields */ public function testRequiredWithoutMultipleWithoutFields(array $data, bool $result): void { @@ -788,7 +788,7 @@ public function testRequiredWithoutMultipleWithoutFields(array $data, bool $resu $this->assertSame($result, $this->validation->run($data)); } - public function requiredWithoutMultipleWithoutFieldsProvider(): iterable + public static function provideRequiredWithoutMultipleWithoutFields(): iterable { yield from [ 'baz is missing' => [ diff --git a/tests/system/Validation/StrictRules/CreditCardRulesTest.php b/tests/system/Validation/StrictRules/CreditCardRulesTest.php index f6441c70b7fd..2e685c852e55 100644 --- a/tests/system/Validation/StrictRules/CreditCardRulesTest.php +++ b/tests/system/Validation/StrictRules/CreditCardRulesTest.php @@ -50,7 +50,7 @@ protected function setUp(): void } /** - * @dataProvider creditCardProvider + * @dataProvider provideValidCCNumber */ public function testValidCCNumber(string $type, ?string $number, bool $expected): void { @@ -64,7 +64,7 @@ public function testValidCCNumber(string $type, ?string $number, bool $expected) * * @see https://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm */ - public function creditCardProvider(): iterable + public function provideValidCCNumber(): iterable { yield from [ 'null_test' => [ diff --git a/tests/system/Validation/StrictRules/FormatRulesTest.php b/tests/system/Validation/StrictRules/FormatRulesTest.php index f5dd2e71609a..39a9e72588d8 100644 --- a/tests/system/Validation/StrictRules/FormatRulesTest.php +++ b/tests/system/Validation/StrictRules/FormatRulesTest.php @@ -12,7 +12,6 @@ namespace CodeIgniter\Validation\StrictRules; use CodeIgniter\Validation\FormatRulesTest as TraditionalFormatRulesTest; -use Generator; use Tests\Support\Validation\TestRules; /** @@ -40,7 +39,7 @@ final class FormatRulesTest extends TraditionalFormatRulesTest ], ]; - public function alphaSpaceProvider(): Generator + public static function provideAlphaSpace(): iterable { yield from [ [ @@ -70,7 +69,7 @@ public function alphaSpaceProvider(): Generator ]; } - public function integerInvalidTypeDataProvider(): Generator + public static function provideInvalidIntegerType(): iterable { yield 'array with int' => [ [555], diff --git a/tests/system/Validation/StrictRules/RulesTest.php b/tests/system/Validation/StrictRules/RulesTest.php index 2bbddad70561..495fa02e20e9 100644 --- a/tests/system/Validation/StrictRules/RulesTest.php +++ b/tests/system/Validation/StrictRules/RulesTest.php @@ -42,7 +42,7 @@ final class RulesTest extends TraditionalRulesTest ]; /** - * @dataProvider providePermitEmptyCasesStrict + * @dataProvider providePermitEmptyStrict */ public function testPermitEmptyStrict(array $rules, array $data, bool $expected): void { @@ -50,7 +50,7 @@ public function testPermitEmptyStrict(array $rules, array $data, bool $expected) $this->assertSame($expected, $this->validation->run($data)); } - public function providePermitEmptyCasesStrict(): iterable + public static function providePermitEmptyStrict(): iterable { yield from [ [ @@ -105,7 +105,7 @@ public function testGreaterThanEqualStrict($value, string $param, bool $expected $this->assertSame($expected, $this->validation->run($data)); } - public function provideGreaterThanEqualStrict(): iterable + public static function provideGreaterThanEqualStrict(): iterable { yield from [ [0, '0', true], @@ -131,7 +131,7 @@ public function testGreaterThanStrict($value, string $param, bool $expected): vo $this->assertSame($expected, $this->validation->run($data)); } - public function provideGreaterThanStrict(): iterable + public static function provideGreaterThanStrict(): iterable { yield from [ [-10, '-11', true], @@ -158,7 +158,7 @@ public function testLessThanStrict($value, string $param, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function provideLessThanStrict(): iterable + public static function provideLessThanStrict(): iterable { yield from [ [-10, '-11', false], @@ -174,7 +174,7 @@ public function provideLessThanStrict(): iterable } /** - * @dataProvider provideLessThanEqualStrict + * @dataProvider provideLessEqualThanStrict * * @param int $value */ @@ -186,7 +186,7 @@ public function testLessEqualThanStrict($value, ?string $param, bool $expected): $this->assertSame($expected, $this->validation->run($data)); } - public function provideLessThanEqualStrict(): iterable + public static function provideLessEqualThanStrict(): iterable { yield from [ [0, '0', true], diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index ab09c9d8238a..8f05442c74bb 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -186,7 +186,7 @@ public function testSetRuleOverwritesRuleReverse(): void } /** - * @dataProvider setRuleRulesFormatCaseProvider + * @dataProvider provideSetRuleRulesFormat * * @param mixed $rules */ @@ -201,7 +201,7 @@ public function testSetRuleRulesFormat(bool $expected, $rules): void $this->addToAssertionCount(1); } - public function setRuleRulesFormatCaseProvider(): iterable + public function provideSetRuleRulesFormat(): iterable { yield 'fail-simple-object' => [ false, @@ -240,6 +240,22 @@ public function testRunReturnsFalseWithNothingToDo(): void $this->assertFalse($this->validation->run([])); } + public function testRuleClassesInstantiatedOnce(): void + { + $this->validation->setRules([]); + $this->validation->run([]); + $count1 = count( + $this->getPrivateProperty($this->validation, 'ruleSetInstances') + ); + + $this->validation->run([]); + $count2 = count( + $this->getPrivateProperty($this->validation, 'ruleSetInstances') + ); + + $this->assertSame($count1, $count2); + } + public function testRunDoesTheBasics(): void { $data = ['foo' => 'notanumber']; @@ -325,7 +341,7 @@ public function testClosureRuleWithLabel(): void /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/5368 * - * @dataProvider arrayDataProvider + * @dataProvider provideCanValidatetArrayData * * @param mixed $value */ @@ -338,7 +354,7 @@ public function testCanValidatetArrayData($value, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function arrayDataProvider(): iterable + public static function provideCanValidatetArrayData(): iterable { yield 'list array' => [ [1, 2, 3, 4, 5], @@ -378,7 +394,7 @@ public function arrayDataProvider(): iterable /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/5374 * - * @dataProvider isIntInvalidTypeDataProvider + * @dataProvider provideIsIntWithInvalidTypeData * * @param mixed $value */ @@ -390,7 +406,7 @@ public function testIsIntWithInvalidTypeData($value, bool $expected): void $this->assertSame($expected, $this->validation->run($data)); } - public function isIntInvalidTypeDataProvider(): iterable + public static function provideIsIntWithInvalidTypeData(): iterable { yield 'array with int' => [ [555], @@ -608,7 +624,7 @@ public function testRunWithCustomErrorsAndAsteriskField(): void } /** - * @dataProvider rulesSetupProvider + * @dataProvider provideRulesSetup * * @param string|string[] $rules * @param string $expected @@ -622,7 +638,7 @@ public function testRulesSetup($rules, $expected, array $errors = []): void $this->assertSame($expected, $this->validation->getError('foo')); } - public function rulesSetupProvider(): iterable + public static function provideRulesSetup(): iterable { yield from [ [ @@ -956,7 +972,7 @@ public function testRulesForObjectField(): void } /** - * @dataProvider arrayFieldDataProvider + * @dataProvider provideRulesForArrayField */ public function testRulesForArrayField(array $body, array $rules, array $results): void { @@ -970,7 +986,7 @@ public function testRulesForArrayField(array $body, array $rules, array $results $this->assertSame($results, $this->validation->getErrors()); } - public function arrayFieldDataProvider(): iterable + public static function provideRulesForArrayField(): iterable { yield from [ 'all_rules_should_pass' => [ @@ -1195,7 +1211,7 @@ public function testTranslatedLabelTagReplacement(): void } /** - * @dataProvider dotNotationForIfExistProvider + * @dataProvider provideDotNotationOnIfExistRule * * @see https://github.com/codeigniter4/CodeIgniter4/issues/4521 */ @@ -1205,7 +1221,7 @@ public function testDotNotationOnIfExistRule(bool $expected, array $rules, array $this->assertSame($expected, $actual); } - public function dotNotationForIfExistProvider(): iterable + public static function provideDotNotationOnIfExistRule(): iterable { yield 'dot-on-end-fail' => [ false, @@ -1265,7 +1281,7 @@ public function dotNotationForIfExistProvider(): iterable } /** - * @dataProvider validationArrayDataCaseProvider + * @dataProvider provideValidationOfArrayData * * @see https://github.com/codeigniter4/CodeIgniter4/issues/4510 */ @@ -1275,7 +1291,7 @@ public function testValidationOfArrayData(bool $expected, array $rules, array $d $this->assertSame($expected, $actual); } - public function validationArrayDataCaseProvider(): iterable + public static function provideValidationOfArrayData(): iterable { yield 'fail-empty-string' => [ false, @@ -1321,7 +1337,7 @@ public function validationArrayDataCaseProvider(): iterable } /** - * @dataProvider provideStringRulesCases + * @dataProvider provideSplittingOfComplexStringRules * * @see https://github.com/codeigniter4/CodeIgniter4/issues/4929 */ @@ -1331,7 +1347,7 @@ public function testSplittingOfComplexStringRules(string $input, array $expected $this->assertSame($expected, $splitter($input)); } - public function provideStringRulesCases(): iterable + public static function provideSplittingOfComplexStringRules(): iterable { yield [ 'required', diff --git a/tests/system/View/ParserTest.php b/tests/system/View/ParserTest.php index 5ad221cdca31..25b516301e50 100644 --- a/tests/system/View/ParserTest.php +++ b/tests/system/View/ParserTest.php @@ -418,7 +418,7 @@ public function testMismatchedVarPair(): void $this->assertSame($result, $this->parser->renderString($template)); } - public function escValueTypes(): iterable + public static function provideEscHandling(): iterable { return [ 'scalar' => [42], @@ -473,7 +473,7 @@ public function escValueTypes(): iterable } /** - * @dataProvider escValueTypes + * @dataProvider provideEscHandling * * @param mixed $value * @param mixed|null $expected diff --git a/user_guide_src/source/_static/css/citheme.css b/user_guide_src/source/_static/css/citheme.css index 726beeb567dc..3410fbc5cbb2 100644 --- a/user_guide_src/source/_static/css/citheme.css +++ b/user_guide_src/source/_static/css/citheme.css @@ -241,6 +241,10 @@ html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not( margin-top: 2rem; } +.highlight-console .highlight { + background-color: #fffff0; +} + /* Messages ----------------------------------------------------------------- */ .rst-content .success { diff --git a/user_guide_src/source/_static/css/citheme_dark.css b/user_guide_src/source/_static/css/citheme_dark.css index bb8442d2188c..649625a6b150 100644 --- a/user_guide_src/source/_static/css/citheme_dark.css +++ b/user_guide_src/source/_static/css/citheme_dark.css @@ -343,4 +343,8 @@ .highlight .ni { color: #b780b7; } + + .highlight-console .highlight pre { + background: #434343; + } } diff --git a/user_guide_src/source/changelogs/index.rst b/user_guide_src/source/changelogs/index.rst index 4959a51ea9c3..8c50b9144694 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.3.8 v4.3.7 v4.3.6 v4.3.5 diff --git a/user_guide_src/source/changelogs/v4.3.8.rst b/user_guide_src/source/changelogs/v4.3.8.rst new file mode 100644 index 000000000000..687b3e2208ba --- /dev/null +++ b/user_guide_src/source/changelogs/v4.3.8.rst @@ -0,0 +1,23 @@ +Version 4.3.8 +############# + +Release Date: August 25, 2023 + +**4.3.8 release of CodeIgniter4** + +.. contents:: + :local: + :depth: 3 + +Bugs Fixed +********** + +- **Controller Filters:** In previous versions, ``['except' => []]`` or ``['except' => '']`` + meant "except all". The bug has been fixed, and now + + - ``['except' => []]`` means to exclude nothing. + - ``['except' => '']`` means to exclude the baseURL only. + +See the repo's +`CHANGELOG.md `_ +for a complete list of bugs fixed. diff --git a/user_guide_src/source/cli/cli_commands.rst b/user_guide_src/source/cli/cli_commands.rst index dff328c78d6a..ddf8521c8332 100644 --- a/user_guide_src/source/cli/cli_commands.rst +++ b/user_guide_src/source/cli/cli_commands.rst @@ -65,9 +65,11 @@ run() ----- The ``run()`` method is the method that is called when the command is being run. The ``$params`` array is a list of -any CLI arguments after the command name for your use. If the CLI string was:: +any CLI arguments after the command name for your use. If the CLI string was: - > php spark foo bar baz +.. code-block:: console + + php spark foo bar baz Then **foo** is the command name, and the ``$params`` array would be: diff --git a/user_guide_src/source/cli/cli_generators.rst b/user_guide_src/source/cli/cli_generators.rst index b76fd06a6a98..8636901644f2 100644 --- a/user_guide_src/source/cli/cli_generators.rst +++ b/user_guide_src/source/cli/cli_generators.rst @@ -14,9 +14,11 @@ Introduction ************ All built-in generators reside under the ``Generators`` group when listed using ``php spark list``. -To view the full description and usage information on a particular generator, use the command:: +To view the full description and usage information on a particular generator, use the command: - > php spark help +.. code-block:: console + + php spark help where ```` will be replaced with the command to check. @@ -287,9 +289,11 @@ wrapper to the controller, model, entity, migration, and seeder generator comman name that will be used to name all the generated classes. Also, **individual options** supported by each generator command are recognized by the scaffold command. -Running this in your terminal:: +Running this in your terminal: + +.. code-block:: console - > php spark make:scaffold user + php spark make:scaffold user will create the following files: diff --git a/user_guide_src/source/cli/cli_overview.rst b/user_guide_src/source/cli/cli_overview.rst index b2c91344d1bc..4e134941f0a0 100644 --- a/user_guide_src/source/cli/cli_overview.rst +++ b/user_guide_src/source/cli/cli_overview.rst @@ -36,9 +36,11 @@ The Spark Commands CodeIgniter ships with the official command **spark** and built-in commands. -You can run the spark and see the help:: +You can run the spark and see the help: - > php spark +.. code-block:: console + + php spark See the :doc:`spark_commands` page for detailed information. diff --git a/user_guide_src/source/cli/spark_commands.rst b/user_guide_src/source/cli/spark_commands.rst index f4011f9bec3d..1fc3f061401d 100644 --- a/user_guide_src/source/cli/spark_commands.rst +++ b/user_guide_src/source/cli/spark_commands.rst @@ -23,48 +23,64 @@ Showing List of Commands When called **spark** without specifying a command, a simple help page is displayed that also provides a list of available commands and their descriptions, sorted by -categories:: +categories: - > php spark +.. code-block:: console + + php spark spark list ^^^^^^^^^^ -``php spark`` is the exactly same as the ``list`` command:: +``php spark`` is the exactly same as the ``list`` command: + +.. code-block:: console - > php spark list + php spark list You may also use the ``--simple`` option to get a raw list of all available commands, -sorted alphabetically:: +sorted alphabetically: + +.. code-block:: console - > php spark list --simple + php spark list --simple Showing Help ------------ -You can get help about any CLI command using the ``help`` command as follows:: +You can get help about any CLI command using the ``help`` command as follows: + +.. code-block:: console + + php spark help db:seed - > php spark help db:seed +Since v4.3.0, you can also use the ``--help`` option instead of the ``help`` command: -Since v4.3.0, you can also use the ``--help`` option instead of the ``help`` command:: +.. code-block:: console - > php spark db:seed --help + php spark db:seed --help Running a Command ----------------- -You should pass the name of the command as the first argument to run that command:: +You should pass the name of the command as the first argument to run that command: - > php spark migrate +.. code-block:: console -Some commands take additional arguments, which should be provided directly after the command, separated by spaces:: + php spark migrate - > php spark db:seed DevUserSeeder +Some commands take additional arguments, which should be provided directly after the command, separated by spaces: + +.. code-block:: console + + php spark db:seed DevUserSeeder For all of the commands CodeIgniter provides, if you do not provide the required arguments, you will be prompted -for the information it needs to run correctly:: +for the information it needs to run correctly: + +.. code-block:: console - > php spark make:controller + php spark make:controller Controller class name : @@ -72,17 +88,21 @@ Suppressing Header Output ------------------------- When you run a command, the header with CodeIgniter version and the current time -is output:: +is output: - > php spark env +.. code-block:: console + + php spark env CodeIgniter v4.3.5 Command Line Tool - Server Time: 2023-06-16 12:45:31 UTC+00:00 Your environment is currently set as development. -You may always pass ``--no-header`` to suppress the header output, helpful for parsing results:: +You may always pass ``--no-header`` to suppress the header output, helpful for parsing results: + +.. code-block:: console - > php spark env --no-header + php spark env --no-header Your environment is currently set as development. diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index f6d38c75b293..22722716661b 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -55,9 +55,11 @@ those classes can be found in: The key of each row is the namespace itself. This does not need a trailing back slash. The value is the location to the directory the classes can be found in. -.. note:: You can check the namespace configuration by ``spark namespaces`` command:: +.. note:: You can check the namespace configuration by ``spark namespaces`` command: - > php spark namespaces + .. code-block:: console + + php spark namespaces By default, the application directory is namespace to the ``App`` namespace. You must namespace the controllers, libraries, or models in the application directory, and they will be found under the ``App`` namespace. diff --git a/user_guide_src/source/conf.py b/user_guide_src/source/conf.py index b4279a4dae0c..7bee8268f6e0 100644 --- a/user_guide_src/source/conf.py +++ b/user_guide_src/source/conf.py @@ -26,7 +26,7 @@ version = '4.3' # The full version, including alpha/beta/rc tags. -release = '4.3.7' +release = '4.3.8' # -- General configuration --------------------------------------------------- diff --git a/user_guide_src/source/dbmgmt/db_commands.rst b/user_guide_src/source/dbmgmt/db_commands.rst index 2ccb6334b27f..53ef1cc52d06 100644 --- a/user_guide_src/source/dbmgmt/db_commands.rst +++ b/user_guide_src/source/dbmgmt/db_commands.rst @@ -19,9 +19,11 @@ db:table --show --------------- To list all the tables in your database straight from your favorite terminal, -you can use the ``db:table --show`` command:: +you can use the ``db:table --show`` command: - > php spark db:table --show +.. code-block:: console + + php spark db:table --show When using this command it is assumed that a table exists. Otherwise, CodeIgniter will complain that the database has no tables. @@ -32,21 +34,27 @@ Retrieve Some Records db:table -------- -When you have a table named ``my_table``, you can see the field names and the records of a table:: +When you have a table named ``my_table``, you can see the field names and the records of a table: + +.. code-block:: console - > php spark db:table my_table + .. code-block:: consolephp spark db:table my_table If the table ``my_table`` is not in the database, CodeIgniter displays a list of available tables to select. -You can also use the following command without the table name:: +You can also use the following command without the table name: + +.. code-block:: console - > php spark db:table + php spark db:table In this case, the table name will be asked. -You can also pass a few options:: +You can also pass a few options: - > php spark db:table my_table --limit-rows 50 --limit-field-value 20 --desc +.. code-block:: console + + php spark db:table my_table --limit-rows 50 --limit-field-value 20 --desc The option ``--limit-rows 50`` limits the number of rows to 50 rows. @@ -60,9 +68,11 @@ Retrieve Field Metadata db:table --metadata ------------------- -When you have a table named ``my_table``, you can see metadata like the column type, max length of the table with the ``--metadata`` option:: +When you have a table named ``my_table``, you can see metadata like the column type, max length of the table with the ``--metadata`` option: + +.. code-block:: console - > php spark db:table my_table --metadata + php spark db:table my_table --metadata When using this command it is assumed that the table exists. Otherwise, CodeIgniter will show a table list to select. diff --git a/user_guide_src/source/dbmgmt/forge.rst b/user_guide_src/source/dbmgmt/forge.rst index fd7c3e280b44..c14664b1ad7c 100644 --- a/user_guide_src/source/dbmgmt/forge.rst +++ b/user_guide_src/source/dbmgmt/forge.rst @@ -60,19 +60,24 @@ CodeIgniter supports creating databases straight from your favorite terminal usi command. By using this command it is assumed that the database is not yet existing. Otherwise, CodeIgniter will complain that the database creation has failed. -To start, just type the command and the name of the database (e.g., ``foo``):: +To start, just type the command and the name of the database (e.g., ``foo``): - > php spark db:create foo +.. code-block:: console + + php spark db:create foo If everything went fine, you should expect the ``Database "foo" successfully created.`` message displayed. If you are on a testing environment or you are using the SQLite3 driver, you may pass in the file extension for the file where the database will be created using the ``--ext`` option. Valid values are ``db`` and ``sqlite`` and defaults to ``db``. Remember that these should not be preceded by a period. -:: +: + +.. code-block:: console + + php spark db:create foo --ext sqlite - > php spark db:create foo --ext sqlite - // will create the db file in WRITEPATH/foo.sqlite +The above command will create the db file in **WRITEPATH/foo.sqlite**. .. note:: When using the special SQLite3 database name ``:memory:``, expect that the command will still produce a success message but no database file is created. This is because SQLite3 will just use diff --git a/user_guide_src/source/dbmgmt/migration.rst b/user_guide_src/source/dbmgmt/migration.rst index ccb2827e9947..874d276632e1 100644 --- a/user_guide_src/source/dbmgmt/migration.rst +++ b/user_guide_src/source/dbmgmt/migration.rst @@ -107,9 +107,11 @@ that wish to use them. The tools primarily provide access to the same methods th migrate ======= -Migrates a database group with all available migrations:: +Migrates a database group with all available migrations: - > php spark migrate +.. code-block:: console + + php spark migrate You can use (migrate) with the following options: @@ -117,13 +119,19 @@ You can use (migrate) with the following options: - ``-n`` - to choose namespace, otherwise (App) namespace will be used. - ``--all`` - to migrate all namespaces to the latest migration. -This example will migrate ``Acme\Blog`` namespace with any new migrations on the test database group:: +This example will migrate ``Acme\Blog`` namespace with any new migrations on the test database group: + +For Unix: + +.. code-block:: console + + php spark migrate -g test -n Acme\\Blog - For Unix: - > php spark migrate -g test -n Acme\\Blog +For Windows: - For Windows: - > php spark migrate -g test -n Acme\Blog +.. code-block:: console + + php spark migrate -g test -n Acme\Blog When using the ``--all`` option, it will scan through all namespaces attempting to find any migrations that have not been run. These will all be collected and then sorted as a group by date created. This should help @@ -132,9 +140,11 @@ to minimize any potential conflicts between the main application and any modules rollback ======== -Rolls back all migrations, taking the database group to a blank slate, effectively migration 0:: +Rolls back all migrations, taking the database group to a blank slate, effectively migration 0: + +.. code-block:: console - > php spark migrate:rollback + php spark migrate:rollback You can use (rollback) with the following options: @@ -145,9 +155,11 @@ You can use (rollback) with the following options: refresh ======= -Refreshes the database state by first rolling back all migrations, and then migrating all:: +Refreshes the database state by first rolling back all migrations, and then migrating all: - > php spark migrate:refresh +.. code-block:: console + + php spark migrate:refresh You can use (refresh) with the following options: @@ -159,9 +171,11 @@ You can use (refresh) with the following options: status ====== -Displays a list of all migrations and the date and time they ran, or '--' if they have not been run:: +Displays a list of all migrations and the date and time they ran, or '--' if they have not been run: + +.. code-block:: console - > php spark migrate:status + php spark migrate:status ... @@ -184,9 +198,9 @@ Creates a skeleton migration file in **app/Database/Migrations**. It automatically prepends the current timestamp. The class name it creates is the Pascal case version of the filename. -:: +.. code-block:: console - > php spark make:migration [options] + php spark make:migration [options] You can use (``make:migration``) with the following options: diff --git a/user_guide_src/source/dbmgmt/seeds.rst b/user_guide_src/source/dbmgmt/seeds.rst index a846705e56c8..ded3836f36cd 100644 --- a/user_guide_src/source/dbmgmt/seeds.rst +++ b/user_guide_src/source/dbmgmt/seeds.rst @@ -48,28 +48,37 @@ Command Line Seeding ==================== You can also seed data from the command line, as part of the Migrations CLI tools, if you don't want to create -a dedicated controller:: +a dedicated controller: - > php spark db:seed TestSeeder +.. code-block:: console + + php spark db:seed TestSeeder ********************* Creating Seeder Files ********************* -Using the command line, you can easily generate seed files. +Using the command line, you can easily generate seed files: + +.. code-block:: console + + php spark make:seeder user --suffix + +The above command outputs **UserSeeder.php** file located at **app/Database/Seeds** directory. + +You can supply the ``root`` namespace where the seed file will be stored by supplying the ``--namespace`` option: + +For Unix: -:: +.. code-block:: console - > php spark make:seeder user --suffix - // Output: UserSeeder.php file located at app/Database/Seeds directory. + php spark make:seeder MySeeder --namespace Acme\\Blog -You can supply the ``root`` namespace where the seed file will be stored by supplying the ``--namespace`` option:: +For Windows: - For Unix: - > php spark make:seeder MySeeder --namespace Acme\\Blog +.. code-block:: console - For Windows: - > php spark make:seeder MySeeder --namespace Acme\Blog + php spark make:seeder MySeeder --namespace Acme\Blog If ``Acme\Blog`` is mapped to **app/Blog** directory, then this command will generate **MySeeder.php** at **app/Blog/Database/Seeds** directory. diff --git a/user_guide_src/source/extending/composer_packages.rst b/user_guide_src/source/extending/composer_packages.rst new file mode 100644 index 000000000000..5f79b6ae2deb --- /dev/null +++ b/user_guide_src/source/extending/composer_packages.rst @@ -0,0 +1,201 @@ +########################## +Creating Composer Packages +########################## + +You can make the :doc:`../general/modules` you create into Composer packages, +or can create a Composer package for CodeIgniter 4. + +.. contents:: + :local: + :depth: 2 + +**************** +Folder Structure +**************** + +Here's a typical directory structure for a Composer package:: + + your-package-name/ + ├── .gitattributes + ├── .gitignore + ├── LICENSE + ├── README.md + ├── composer.json + ├── src/ + │   └── YourClass.php + └── tests/ + └── YourClassTest.php + +********************** +Creating composer.json +********************** + +In the root of your package directory, create a **composer.json** file. This file +defines metadata about your package and its dependencies. + +The ``composer init`` command helps you create it. + +For example, **composer.json** might look like this:: + + { + "name": "your-vendor/your-package", + "description": "Your package description", + "type": "library", + "license": "MIT", + "autoload": { + "psr-4": { + "YourVendor\\YourPackage\\": "src/" + } + }, + "authors": [ + { + "name": "Your Name", + "email": "yourname@example.com" + } + ], + "require": { + // Any dependencies required by your package go here + }, + "require-dev": { + // Any development dependencies (e.g., PHPUnit) go here + } + } + +Package Name +============ + +The ``name`` field is important here. Package names are generally written in the +format "vendor-name/package-name" with all lowercase. Here is a common example: + +- ``your-vendor-name``: The name that identifies the vendor (creator of the package), + such as your name or your organization. +- ``your-package-name``: The name of the package you are creating. + +Thus, it is important to make the name unique to distinguish it from other packages. +Uniqueness is especially important when publishing. + +Namespace +========= + +The package name then determines the vendor namespace in ``autoload.psr4``. + +If your package name is ``your-vendor/your-package``, the vendor namespace must +be ``YourVendor``. So you would write like the following:: + + "autoload": { + "psr-4": { + "YourVendor\\YourPackage\\": "src/" + } + }, + +This setting instructs Composer to autoload the source code for your package. + +Choosing License +================ + +If you are not familiar with open source licenses, see https://choosealicense.com/. +Many PHP packages, including CodeIgniter, use the MIT license. + +*************************** +Preparing Development Tools +*************************** + +There are many tools that help ensure quality code. So you should use them. +You can easily install and configure such tools with +`CodeIgniter DevKit `_. + +Installing DevKit +================= + +In the root of your package directory, run the following commands: + +.. code-block:: console + + composer config minimum-stability dev + composer config prefer-stable true + composer require --dev codeigniter4/devkit + +The DevKit installs various Composer packages that helps your development, and +installs templates for them in **vendor/codeigniter4/devkit/src/Template**. +Copy the files in it to your project root folder, and edit them for your needs. + +Configuring Coding Standards Fixer +================================== + +DevKit provides Coding Standards Fixer with +`CodeIgniter Coding Standard `_ +based on `PHP-CS-Fixer `_. + +Copy **vendor/codeigniter4/devkit/src/Template/.php-cs-fixer.dist.php** to your +project root folder. + +Create the **build** folder for the cache file:: + + your-package-name/ + ├── .php-cs-fixer.dist.php + ├── build/ + +Open **.php-cs-fixer.dist.php** in your editor, and fix the folder path:: + + --- a/.php-cs-fixer.dist.php + +++ b/.php-cs-fixer.dist.php + @@ -7,7 +7,7 @@ use PhpCsFixer\Finder; + $finder = Finder::create() + ->files() + ->in([ + - __DIR__ . '/app/', + + __DIR__ . '/src/', + __DIR__ . '/tests/', + ]) + ->exclude([ + +That't it. Now you can run Coding Standards Fixer: + +.. code-block:: console + + vendor/bin/php-cs-fixer fix --ansi --verbose --diff + +If you add ``scripts.cs-fix`` in your **composer.json**, you can run it with +``composer cs-fix`` command:: + + { + // ... + }, + "scripts": { + "cs-fix": "php-cs-fixer fix --ansi --verbose --diff" + } + } + +************ +Config Files +************ + +Allowing Users to Override Settings +=================================== + +If your package has a configuration file and you want users to be able to override +the settings, use :php:func:`config()` with the short classname like ``config('YourConfig')`` +to call the configuration file. + +Users can then override the package configuration by placing a configuration class +with the same short classname in **app/Config** that extends the package Config +class like ``YourVendor\YourPackage\Config\YourConfig``. + +Overriding Settings in app/Config +================================= + +If you need to override or add to known configurations in the **app/Config** folder, +you can use :ref:`Implicit Registrars `. + +********** +References +********** + +We have published some official packages. You can use these packages as references +when creating your own packages: + +- https://github.com/codeigniter4/shield +- https://github.com/codeigniter4/settings +- https://github.com/codeigniter4/tasks +- https://github.com/codeigniter4/cache + diff --git a/user_guide_src/source/extending/index.rst b/user_guide_src/source/extending/index.rst index 93227128924a..ba6284f5dc0e 100644 --- a/user_guide_src/source/extending/index.rst +++ b/user_guide_src/source/extending/index.rst @@ -12,4 +12,5 @@ CodeIgniter 4 has been designed to be easy to extend or build upon. events basecontroller authentication + composer_packages contributing diff --git a/user_guide_src/source/general/environments.rst b/user_guide_src/source/general/environments.rst index 667a5bd11e46..3eaf2c5c3587 100644 --- a/user_guide_src/source/general/environments.rst +++ b/user_guide_src/source/general/environments.rst @@ -54,9 +54,11 @@ The simplest method to set the variable is in your :ref:`.env file CI_ENVIRONMENT = development -.. note:: You can change the ``CI_ENVIRONMENT`` value in **.env** file by ``spark env`` command:: +.. note:: You can change the ``CI_ENVIRONMENT`` value in **.env** file by ``spark env`` command: - > php spark env production + .. code-block:: console + + php spark env production .. _environment-apache: @@ -135,9 +137,11 @@ Confirming the Current Environment To confirm the current environment, simply echo the constant ``ENVIRONMENT``. -You can also check the current environment by ``spark env`` command:: +You can also check the current environment by ``spark env`` command: + +.. code-block:: console - > php spark env + php spark env ************************************* Effects on Default Framework Behavior diff --git a/user_guide_src/source/general/modules.rst b/user_guide_src/source/general/modules.rst index ae79f5431779..311a6ba2b421 100644 --- a/user_guide_src/source/general/modules.rst +++ b/user_guide_src/source/general/modules.rst @@ -3,10 +3,14 @@ Code Modules ############ CodeIgniter supports a form of code modularization to help you create reusable code. Modules are typically -centered around a specific subject, and can be thought of as mini-applications within your larger application. Any +centered around a specific subject, and can be thought of as mini-applications within your larger application. + +Any of the standard file types within the framework are supported, like controllers, models, views, config files, helpers, language files, etc. Modules may contain as few, or as many, of these as you like. +If you want to create a module as a Composer package, see also :doc:`../extending/composer_packages`. + .. contents:: :local: :depth: 2 @@ -208,13 +212,20 @@ Seeds ===== Seed files can be used from both the CLI and called from within other seed files as long as the full namespace -is provided. If calling on the CLI, you will need to provide double backslashes:: +is provided. If calling on the CLI, you will need to provide double backslashes: + + +For Unix: + +.. code-block:: console + + php spark db:seed Acme\\Blog\\Database\\Seeds\\TestPostSeeder + +For Windows: - For Unix: - > php spark db:seed Acme\\Blog\\Database\\Seeds\\TestPostSeeder +.. code-block:: console - For Windows: - > php spark db:seed Acme\Blog\Database\Seeds\TestPostSeeder + php spark db:seed Acme\Blog\Database\Seeds\TestPostSeeder Helpers ======= diff --git a/user_guide_src/source/helpers/cookie_helper.rst b/user_guide_src/source/helpers/cookie_helper.rst index a26bf180f27b..10002e2a9eb5 100755 --- a/user_guide_src/source/helpers/cookie_helper.rst +++ b/user_guide_src/source/helpers/cookie_helper.rst @@ -23,7 +23,7 @@ The following functions are available: .. php:function:: set_cookie($name[, $value = ''[, $expire = ''[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = false[, $httpOnly = false[, $sameSite = '']]]]]]]]) - :param mixed $name: Cookie name *or* associative array of all of the parameters available to this function + :param array|Cookie|string $name: Cookie name *or* associative array of all of the parameters available to this function *or* an instance of ``CodeIgniter\Cookie\Cookie`` :param string $value: Cookie value :param int $expire: Number of seconds until expiration. If set to ``0`` the cookie will only last as long as the browser is open :param string $domain: Cookie domain (usually: .yourdomain.com) @@ -55,11 +55,12 @@ The following functions are available: This helper function gives you friendlier syntax to get browser cookies. Refer to the :doc:`IncomingRequest Library ` for detailed description of its use, as this function acts very - similarly to ``IncomingRequest::getCookie()``, except it will also prepend + similarly to :php:meth:`CodeIgniter\\HTTP\\IncomingRequest::getCookie()`, + except it will also prepend the ``Config\Cookie::$prefix`` that you might've set in your **app/Config/Cookie.php** file. - .. warning:: Using XSS filtering is a bad practice. It does not prevent XSS attacks perfectly. Using ``esc()`` with the correct ``$context`` in the views is recommended. + .. warning:: Using XSS filtering is a bad practice. It does not prevent XSS attacks perfectly. Using :php:func:`esc()` with the correct ``$context`` in the views is recommended. .. php:function:: delete_cookie($name[, $domain = ''[, $path = '/'[, $prefix = '']]]) @@ -74,10 +75,10 @@ The following functions are available: .. literalinclude:: cookie_helper/002.php - This function is otherwise identical to ``set_cookie()``, except that it + This function is otherwise identical to :php:func:`set_cookie()`, except that it does not have the ``value`` and ``expire`` parameters. - .. note:: When you use ``set_cookie()``, + .. note:: When you use :php:func:`set_cookie()`, if the ``value`` is set to empty string and the ``expire`` is set to ``0``, the cookie will be deleted. If the ``value`` is set to non-empty string and the ``expire`` is set to ``0``, the cookie will only last as long as the browser is open. diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst index 7571429241f3..68c7090408df 100644 --- a/user_guide_src/source/helpers/form_helper.rst +++ b/user_guide_src/source/helpers/form_helper.rst @@ -504,8 +504,8 @@ The following functions are available: Example:: - > - > + > + > .. php:function:: set_radio($field[, $value = ''[, $default = false]]) diff --git a/user_guide_src/source/incoming/filters.rst b/user_guide_src/source/incoming/filters.rst index cfd55df420a0..77734795f493 100644 --- a/user_guide_src/source/incoming/filters.rst +++ b/user_guide_src/source/incoming/filters.rst @@ -120,14 +120,14 @@ Except for a Few URIs There are times where you want to apply a filter to almost every request, but have a few that should be left alone. One common example is if you need to exclude a few URI's from the CSRF protection filter to allow requests from third-party websites to hit one or two specific URI's, while keeping the rest of them protected. To do this, add -an array with the ``except`` key and a URI to match as the value alongside the alias: +an array with the ``except`` key and a URI path (relative to BaseURL) to match as the value alongside the alias: .. literalinclude:: filters/006.php -Any place you can use a URI in the filter settings, you can use a regular expression or, like in this example, use -an asterisk (``*``) for a wildcard that will match all characters after that. In this example, any URL's starting with ``api/`` +Any place you can use a URI path (relative to BaseURL) in the filter settings, you can use a regular expression or, like in this example, use +an asterisk (``*``) for a wildcard that will match all characters after that. In this example, any URI path starting with ``api/`` would be exempted from CSRF protection, but the site's forms would all be protected. If you need to specify multiple -URI's you can use an array of URI patterns: +URI paths, you can use an array of URI path patterns: .. literalinclude:: filters/007.php @@ -153,7 +153,7 @@ $filters ======== This property is an array of filter aliases. For each alias, you can specify ``before`` and ``after`` arrays that contain -a list of URI patterns that filter should apply to: +a list of URI path (relative to BaseURL) patterns that filter should apply to: .. literalinclude:: filters/009.php @@ -179,9 +179,11 @@ filter:check .. versionadded:: 4.3.0 -Check the filters for the route ``/`` with **GET** method:: +Check the filters for the route ``/`` with **GET** method: - > php spark filter:check get / +.. code-block:: console + + php spark filter:check get / The output is like the following: diff --git a/user_guide_src/source/incoming/filters/008.php b/user_guide_src/source/incoming/filters/008.php index 749da8098c6b..945e9498b4f9 100644 --- a/user_guide_src/source/incoming/filters/008.php +++ b/user_guide_src/source/incoming/filters/008.php @@ -9,8 +9,8 @@ class Filters extends BaseConfig // ... public array $methods = [ - 'post' => ['foo', 'bar'], - 'get' => ['baz'], + 'post' => ['InvalidChars', 'csrf'], + 'get' => ['csrf'], ]; // ... diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index f1f4253b3c41..8b42914d4a8d 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -837,9 +837,11 @@ CodeIgniter has the following :doc:`command ` to display al spark routes ============ -Displays all routes and filters:: +Displays all routes and filters: - > php spark routes +.. code-block:: console + + php spark routes The output is like the following: @@ -924,6 +926,8 @@ Sort by Handler .. versionadded:: 4.3.0 -You can sort the routes by *Handler*:: +You can sort the routes by *Handler*: + +.. code-block:: console - > php spark routes -h + php spark routes -h diff --git a/user_guide_src/source/installation/installing_composer.rst b/user_guide_src/source/installation/installing_composer.rst index ca9eacf28314..8305ca9798d2 100644 --- a/user_guide_src/source/installation/installing_composer.rst +++ b/user_guide_src/source/installation/installing_composer.rst @@ -35,9 +35,11 @@ a new CodeIgniter4 based project. Installation ------------ -In the folder above your project root:: +In the folder above your project root: - > composer create-project codeigniter4/appstarter project-root +.. code-block:: console + + composer create-project codeigniter4/appstarter project-root The command above will create a **project-root** folder. @@ -49,9 +51,11 @@ If you omit the "project-root" argument, the command will create an So if you install CodeIgniter under the folder that contains the special characters like ``(``, ``)``, etc., CodeIgniter won't work. .. important:: When you deploy to your production server, don't forget to run the - following command:: + following command: + + .. code-block:: console - > composer install --no-dev + composer install --no-dev The above command will remove the Composer packages only for development that are not needed in the production environment. This will greatly reduce @@ -68,9 +72,11 @@ See :ref:`initial-configuration` for the details. Upgrading --------- -Whenever there is a new release, then from the command line in your project root:: +Whenever there is a new release, then from the command line in your project root: - > composer update +.. code-block:: console + + composer update Read the :doc:`upgrade instructions `, and check Breaking Changes and Enhancements. @@ -108,18 +114,48 @@ The `development user guide `_ is Note that this differs from the released user guide, and will pertain to the develop branch explicitly. -In your project root:: +Update for Latest Dev +^^^^^^^^^^^^^^^^^^^^^ - > php builds development +In your project root: -The command above will update **composer.json** to point to the ``develop`` branch of the -working repository, and update the corresponding paths in config and XML files. To revert -these changes run:: +.. code-block:: console - > php builds release + php builds development + +The command above will update **composer.json** to point to the ``develop`` branch of the +working repository, and update the corresponding paths in config and XML files. After using the ``builds`` command be sure to run ``composer update`` to sync your vendor -folder with the latest target build. +folder with the latest target build. Then, check the :doc:`upgrading` and update project +files if necessary. + +Next Minor Version +^^^^^^^^^^^^^^^^^^ + +If you want to use the next minor version branch, after using the ``builds`` command +edit **composer.json** manually. + +If you try the ``4.4`` branch, change the version to ``4.4.x-dev``:: + + "require": { + "php": "^7.4 || ^8.0", + "codeigniter4/codeigniter4": "4.4.x-dev" + }, + +And run ``composer update`` to sync your vendor +folder with the latest target build. Then, check the Upgrading Guide +(**user_guide_src/source/installation/upgrade_{version}.rst**) and +update project files if necessary. + +Revert to Stable Release +^^^^^^^^^^^^^^^^^^^^^^^^ + +To revert the changes run: + +.. code-block:: console + + php builds release Adding CodeIgniter4 to an Existing Project ========================================== @@ -134,14 +170,18 @@ Installation Develop your app inside the ``app`` folder, and the ``public`` folder will be your document root. -In your project root:: +In your project root: + +.. code-block:: console - > composer require codeigniter4/framework + composer require codeigniter4/framework .. important:: When you deploy to your production server, don't forget to run the - following command:: + following command: + +.. code-block:: console - > composer install --no-dev + composer install --no-dev The above command will remove the Composer packages only for development that are not needed in the production environment. This will greatly reduce @@ -167,7 +207,9 @@ Upgrading Whenever there is a new release, then from the command line in your project root:: - > composer update +.. code-block:: console + + composer update Read the :doc:`upgrade instructions `, and check Breaking Changes and Enhancements. @@ -200,8 +242,10 @@ Translations Installation If you want to take advantage of the system message translations, they can be added to your project in a similar fashion. -From the command line inside your project root:: +From the command line inside your project root: + +.. code-block:: console - > composer require codeigniter4/translations + composer require codeigniter4/translations These will be updated along with the framework whenever you do a ``composer update``. diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index c75d4a24120c..7092b8f5d68a 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -57,9 +57,11 @@ Local Development Server CodeIgniter 4 comes with a local development server, leveraging PHP's built-in web server with CodeIgniter routing. You can launch it, with the following command line -in the main directory:: +in the main directory: - > php spark serve +.. code-block:: console + + php spark serve This will launch the server and you can now view your application in your browser at http://localhost:8080. @@ -72,19 +74,25 @@ all unix-type systems (including macOS) will typically keep the file at **/etc/h The local development server can be customized with three command line options: -- You can use the ``--host`` CLI option to specify a different host to run the application at:: +- You can use the ``--host`` CLI option to specify a different host to run the application at: + + .. code-block:: console - > php spark serve --host example.dev + php spark serve --host example.dev - By default, the server runs on port 8080 but you might have more than one site running, or already have - another application using that port. You can use the ``--port`` CLI option to specify a different one:: + another application using that port. You can use the ``--port`` CLI option to specify a different one: + + .. code-block:: console - > php spark serve --port 8081 + php spark serve --port 8081 - You can also specify a specific version of PHP to use, with the ``--php`` CLI option, with its value - set to the path of the PHP executable you want to use:: + set to the path of the PHP executable you want to use: - > php spark serve --php /usr/bin/php7.6.5.4 + .. code-block:: console + + php spark serve --php /usr/bin/php7.6.5.4 ******************* Hosting with Apache @@ -206,10 +214,12 @@ Place your project folder as follows, where **htdocs** is the Apache document ro │ └── public/ └── htdocs/ -Navigate to the **htdocs** folder and create a symbolic link as follows:: +Navigate to the **htdocs** folder and create a symbolic link as follows: + +.. code-block:: console - > cd htdocs/ - > ln -s ../myproject/public/ myproject + cd htdocs/ + ln -s ../myproject/public/ myproject Using Alias ----------- diff --git a/user_guide_src/source/installation/troubleshooting.rst b/user_guide_src/source/installation/troubleshooting.rst index 0d9685558670..8ed12924732b 100644 --- a/user_guide_src/source/installation/troubleshooting.rst +++ b/user_guide_src/source/installation/troubleshooting.rst @@ -11,9 +11,11 @@ Here are some common installation problems, and suggested workarounds. How do I know if my install is working? --------------------------------------- -From the command line, at your project root:: +From the command line, at your project root: - > php spark serve +.. code-block:: console + + php spark serve ``http://localhost:8080`` in your browser should then show the default welcome page: diff --git a/user_guide_src/source/installation/upgrade_420.rst b/user_guide_src/source/installation/upgrade_420.rst index e932b8cdf1ff..03aebabb015c 100644 --- a/user_guide_src/source/installation/upgrade_420.rst +++ b/user_guide_src/source/installation/upgrade_420.rst @@ -27,11 +27,13 @@ The following files received significant changes and .. important:: If you don't update the above two files, CodeIgniter will not work at all after running ``composer update``. - The upgrade procedure, for example, is as follows:: + The upgrade procedure, for example, is as follows: - > composer update - > cp vendor/codeigniter4/framework/public/index.php public/index.php - > cp vendor/codeigniter4/framework/spark . + .. code-block:: console + + composer update + cp vendor/codeigniter4/framework/public/index.php public/index.php + cp vendor/codeigniter4/framework/spark . Config/Constants.php ==================== diff --git a/user_guide_src/source/installation/upgrade_430.rst b/user_guide_src/source/installation/upgrade_430.rst index c91aa82c723e..3475916beae5 100644 --- a/user_guide_src/source/installation/upgrade_430.rst +++ b/user_guide_src/source/installation/upgrade_430.rst @@ -21,11 +21,13 @@ Composer Version If you are using older version of Composer, upgrade your ``composer`` tool, and delete the **vendor/** directory, and run ``composer update`` again. -The procedure, for example, is as follows:: +The procedure, for example, is as follows: - > composer self-update - > rm -rf vendor/ - > composer update +.. code-block:: console + + composer self-update + rm -rf vendor/ + composer update Mandatory File Changes ********************** @@ -40,10 +42,12 @@ The following files received significant changes and .. important:: If you do not update this file, Spark commands will not work at all after running ``composer update``. - The upgrade procedure, for example, is as follows:: + The upgrade procedure, for example, is as follows: + + .. code-block:: console - > composer update - > cp vendor/codeigniter4/framework/spark . + composer update + cp vendor/codeigniter4/framework/spark . Config Files ============ diff --git a/user_guide_src/source/installation/upgrade_431.rst b/user_guide_src/source/installation/upgrade_431.rst index ae9ae6e27e1b..991651ff7e47 100644 --- a/user_guide_src/source/installation/upgrade_431.rst +++ b/user_guide_src/source/installation/upgrade_431.rst @@ -21,11 +21,13 @@ Composer Version If you are using older version of Composer, upgrade your ``composer`` tool, and delete the **vendor/** directory, and run ``composer update`` again. -The procedure, for example, is as follows:: +The procedure, for example, is as follows: - > composer self-update - > rm -rf vendor/ - > composer update +.. code-block:: console + + composer self-update + rm -rf vendor/ + composer update Mandatory File Changes ********************** diff --git a/user_guide_src/source/installation/upgrade_438.rst b/user_guide_src/source/installation/upgrade_438.rst new file mode 100644 index 000000000000..2f5decd2a7b1 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_438.rst @@ -0,0 +1,41 @@ +############################# +Upgrading from 4.3.7 to 4.3.8 +############################# + +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 + +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. + +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 +------ + +- composer.json + +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: + +- composer.json diff --git a/user_guide_src/source/installation/upgrade_migrations.rst b/user_guide_src/source/installation/upgrade_migrations.rst index 791cb81a3314..67d826863968 100644 --- a/user_guide_src/source/installation/upgrade_migrations.rst +++ b/user_guide_src/source/installation/upgrade_migrations.rst @@ -17,9 +17,11 @@ What has been changed - First of all, the sequential naming (``001_create_users``, ``002_create_posts``) of migrations is not longer supported. Version 4 of CodeIgniter only supports the timestamp scheme (``20121031100537_create_users``, ``20121031500638_create_posts``) . If you have used sequential naming you have to rename each migration file. - The migration table definition was changed. If you upgrade from CI3 to CI4 and use the same database, You need to upgrade the migration table definition and its data. -- The migration procedure has been also changed. You can now migrate the database with a simple CLI command:: +- The migration procedure has been also changed. You can now migrate the database with a simple CLI command: - > php spark migrate +.. code-block:: console + + php spark migrate Upgrade Guide ============= diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst index a44aac6cd044..7157c2ffd04d 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_438 upgrade_437 upgrade_436 upgrade_435 diff --git a/user_guide_src/source/libraries/caching.rst b/user_guide_src/source/libraries/caching.rst index 671c92cdb488..dd735a8a12c0 100644 --- a/user_guide_src/source/libraries/caching.rst +++ b/user_guide_src/source/libraries/caching.rst @@ -85,16 +85,20 @@ These tools are not required to use Cache driver but might help you. cache:clear =========== -Clears the current system caches:: +Clears the current system caches: - > php spark cache:clear +.. code-block:: console + + php spark cache:clear cache:info ========== -Shows file cache information in the current system:: +Shows file cache information in the current system: + +.. code-block:: console - > php spark cache:info + php spark cache:info .. note:: This command only supports the File cache handler. @@ -317,9 +321,11 @@ Predis Caching ============== Predis is a flexible and feature-complete PHP client library for the Redis key-value store. -To use it, from the command line inside your project root:: +To use it, from the command line inside your project root: + +.. code-block:: console - > composer require predis/predis + composer require predis/predis For more information on Redis, please see `https://github.com/nrk/predis `_. diff --git a/user_guide_src/source/libraries/cookies.rst b/user_guide_src/source/libraries/cookies.rst index 08f4c35f86a5..40177800ecbb 100644 --- a/user_guide_src/source/libraries/cookies.rst +++ b/user_guide_src/source/libraries/cookies.rst @@ -14,7 +14,7 @@ Cookies are mainly used for three purposes: - **Personalization**: User preferences, themes, and other settings - **Tracking**: Recording and analyzing user behavior -To help you efficiently use cookies across browsers with your request and response, +To help you efficiently send cookies to browsers, CodeIgniter provides the ``CodeIgniter\Cookie\Cookie`` class to abstract the cookie interaction. @@ -32,13 +32,23 @@ There are currently four (4) ways to create a new ``Cookie`` value object. When constructing the ``Cookie`` object, only the ``name`` attribute is required. All other else are optional. If the optional attributes are not modified, their values will be filled up by the default values saved in -the ``Cookie`` class. To override the defaults currently stored in the class, you can pass a ``Config\Cookie`` +the ``Cookie`` class. + +Overriding Defaults +=================== + +To override the defaults currently stored in the class, you can pass a ``Config\Cookie`` instance or an array of defaults to the static ``Cookie::setDefaults()`` method. .. literalinclude:: cookies/002.php Passing the ``Config\Cookie`` instance or an array to ``Cookie::setDefaults()`` will effectively -overwrite your defaults and will persist until new defaults are passed. If you do not want this +overwrite your defaults and will persist until new defaults are passed. + +Changing Defaults for a Limited Time +------------------------------------ + +If you do not want this behavior but only want to change defaults for a limited time, you can take advantage of ``Cookie::setDefaults()`` return which returns the old defaults array. @@ -82,7 +92,9 @@ A cookie name can be any US-ASCII character, except for the following: - separator characters, such as ``( ) < > @ , ; : \ " / [ ] ? = { }`` If setting the ``$raw`` parameter to ``true`` this validation will be strictly made. This is because -PHP's ``setcookie`` and ``setrawcookie`` will reject cookies with invalid names. Additionally, cookie +PHP's `setcookie() `_ +and `setrawcookie() `_ +will reject cookies with invalid names. Additionally, cookie names cannot be an empty string. Validating the Prefix Attribute @@ -119,20 +131,47 @@ also take advantage of the class's constants to make it not a hassle. .. literalinclude:: cookies/006.php + +*************** +Sending Cookies +*************** + +Set the ``Cookie`` objects in the ``CookieStore`` of the Response object, and +the framework will automatically send the cookies. + +Use :php:meth:`CodeIgniter\\HTTP\\Response::setCookie()` to set: + +.. literalinclude:: cookies/017.php + +You can also use the :php:func:`set_cookie()` helper function: + +.. literalinclude:: cookies/018.php + + ********************** Using the Cookie Store ********************** -The ``CookieStore`` class represents an immutable collection of ``Cookie`` objects. The ``CookieStore`` +.. note:: Normally, there is no need to use CookieStore directly. + +The ``CookieStore`` class represents an immutable collection of ``Cookie`` objects. + +Getting the Store from Response +=============================== + +The ``CookieStore`` instance can be accessed from the current ``Response`` object. .. literalinclude:: cookies/007.php +Creating CookieStore +==================== + CodeIgniter provides three (3) other ways to create a new instance of the ``CookieStore``. .. literalinclude:: cookies/008.php -.. note:: When using the global ``cookies()`` function, the passed ``Cookie`` array will only be considered +.. note:: When using the global :php:func:`cookies()` function, the passed ``Cookie`` array will only be considered if the second argument, ``$getGlobal``, is set to ``false``. Checking Cookies in Store @@ -164,8 +203,8 @@ in store will be displayed. .. literalinclude:: cookies/013.php -.. note:: The helper function ``get_cookie()`` gets the cookie from the current ``Request`` object, not - from ``Response``. This function checks the `$_COOKIE` array if that cookie is set and fetches it +.. note:: The helper function :php:func:`get_cookie()` gets the cookie from the current ``Request`` object, not + from ``Response``. This function checks the ``$_COOKIE`` array if that cookie is set and fetches it right away. Adding/Removing Cookies in Store @@ -189,6 +228,10 @@ the instance with the modified instance. Dispatching Cookies in Store ============================ +.. deprecated:: 4.1.6 + +.. important:: This method is deprecated. It will be removed in future releases. + More often than not, you do not need to concern yourself in manually sending cookies. CodeIgniter will do this for you. However, if you really need to manually send cookies, you can use the ``dispatch`` method. Just like in sending other headers, you need to make sure the headers are not yet sent by checking the value @@ -229,11 +272,11 @@ Class Reference .. php:staticmethod:: setDefaults([$config = []]) - :param \Config\Cookie|array $config: The configuration array or instance + :param \\Config\\Cookie|array $config: The configuration array or instance :rtype: array :returns: The old defaults - Set the default attributes to a Cookie instance by injecting the values from the ``\Config\Cookie`` config or an array. + Set the default attributes to a Cookie instance by injecting the values from the ``Config\Cookie`` config or an array. .. php:staticmethod:: fromHeaderString(string $header[, bool $raw = false]) diff --git a/user_guide_src/source/libraries/cookies/004.php b/user_guide_src/source/libraries/cookies/004.php index ca0cf0a74bb8..cce1ea2c726d 100644 --- a/user_guide_src/source/libraries/cookies/004.php +++ b/user_guide_src/source/libraries/cookies/004.php @@ -19,19 +19,19 @@ ] ); -$cookie->getName(); // 'remember_token' -$cookie->getPrefix(); // '__Secure-' -$cookie->getPrefixedName(); // '__Secure-remember_token' +$cookie->getName(); // 'remember_token' +$cookie->getPrefix(); // '__Secure-' +$cookie->getPrefixedName(); // '__Secure-remember_token' $cookie->getExpiresTimestamp(); // Unix timestamp -$cookie->getExpiresString(); // 'Fri, 14-Feb-2025 00:00:00 GMT' -$cookie->isExpired(); // false -$cookie->getMaxAge(); // the difference from time() to expires -$cookie->isRaw(); // false -$cookie->isSecure(); // true -$cookie->getPath(); // '/' -$cookie->getDomain(); // '' -$cookie->isHTTPOnly(); // true -$cookie->getSameSite(); // 'Lax' +$cookie->getExpiresString(); // 'Fri, 14-Feb-2025 00:00:00 GMT' +$cookie->isExpired(); // false +$cookie->getMaxAge(); // the difference from time() to expires +$cookie->isRaw(); // false +$cookie->isSecure(); // true +$cookie->getPath(); // '/' +$cookie->getDomain(); // '' +$cookie->isHTTPOnly(); // true +$cookie->getSameSite(); // 'Lax' // additional getter $cookie->getId(); // '__Secure-remember_token;;/' diff --git a/user_guide_src/source/libraries/cookies/006.php b/user_guide_src/source/libraries/cookies/006.php index a8be634a9925..1bf6c732b71a 100644 --- a/user_guide_src/source/libraries/cookies/006.php +++ b/user_guide_src/source/libraries/cookies/006.php @@ -2,6 +2,6 @@ use CodeIgniter\Cookie\Cookie; -Cookie::SAMESITE_LAX; // 'lax' -Cookie::SAMESITE_STRICT; // 'strict' -Cookie::SAMESITE_NONE; // 'none' +Cookie::SAMESITE_LAX; // 'lax' +Cookie::SAMESITE_STRICT; // 'strict' +Cookie::SAMESITE_NONE; // 'none' diff --git a/user_guide_src/source/libraries/cookies/017.php b/user_guide_src/source/libraries/cookies/017.php new file mode 100644 index 000000000000..eadbc8083e98 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/017.php @@ -0,0 +1,16 @@ + 3600 * 2, // Expires in 2 hours + ] +); + +$response->setCookie($cookie); diff --git a/user_guide_src/source/libraries/cookies/018.php b/user_guide_src/source/libraries/cookies/018.php new file mode 100644 index 000000000000..41dff8d6a2f5 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/018.php @@ -0,0 +1,15 @@ + 3600 * 2, // Expires in 2 hours + ] +); + +set_cookie($cookie); diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 74f3f1ec6308..bf4b256327c1 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -66,9 +66,11 @@ different directory and it will return any child classes found: .. literalinclude:: publisher/006.php -Most of the time you will not need to handle your own discovery, just use the provided "publish" command:: +Most of the time you will not need to handle your own discovery, just use the provided "publish" command: - > php spark publish +.. code-block:: console + + php spark publish By default on your class extension ``publish()`` will add all files from your ``$source`` and merge them out to your destination, overwriting on collision. @@ -118,10 +120,12 @@ to keep up with. You can create a publication definition in your project to sync .. literalinclude:: publisher/009.php -Now add the dependency via Composer and call ``spark publish`` to run the publication:: +Now add the dependency via Composer and call ``spark publish`` to run the publication: + +.. code-block:: console - > composer require twbs/bootstrap - > php spark publish + composer require twbs/bootstrap + php spark publish ... and you'll end up with something like this:: diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index 4e65cf7a17fa..f1df897bfad7 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -515,12 +515,13 @@ it. But be careful because the system user *running* the script is usually not your own, but something like 'www-data' instead, so only setting those permissions will probably break your application. -Instead, you should do something like this, depending on your environment -:: +Instead, you should do something like this, depending on your environment: - > mkdir //writable/sessions/ - > chmod 0700 //writable/sessions/ - > chown www-data //writable/sessions/ +.. code-block:: console + + mkdir //writable/sessions/ + chmod 0700 //writable/sessions/ + chown www-data //writable/sessions/ Bonus Tip --------- @@ -637,10 +638,12 @@ Setting Up Database Table with Command ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you'd rather not do all of this by hand, you can use the ``make:migration --session`` command -from the cli to generate a migration file for you:: +from the cli to generate a migration file for you: + +.. code-block:: console - > php spark make:migration --session - > php spark migrate + php spark make:migration --session + php spark migrate This command will take the ``$savePath`` and ``$matchIP`` settings into account when it generates the code. diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst index 8e1d99a3a973..c5c257c6b800 100644 --- a/user_guide_src/source/models/entities.rst +++ b/user_guide_src/source/models/entities.rst @@ -10,8 +10,9 @@ be used directly with the :doc:`Model ` if that fits your needs b :local: :depth: 2 +************ Entity Usage -============ +************ At its core, an Entity class is simply a class that represents a single database row. It has class properties to represent the database columns, and provides any additional methods to implement the business logic for @@ -34,7 +35,7 @@ Assume you have a database table named ``users`` that has the following schema:: .. important:: ``attributes`` is a reserved word for internal use. If you use it as a column name, the Entity does not work correctly. Create the Entity Class ------------------------ +======================= Now create a new Entity class. Since there's no default location to store these classes, and it doesn't fit in with the existing directory structure, create a new directory at **app/Entities**. Create the @@ -45,7 +46,7 @@ Entity itself at **app/Entities/User.php**. At its simplest, this is all you need to do, though we'll make it more useful in a minute. Create the Model ----------------- +================ Create the model first at **app/Models/UserModel.php** so that we can interact with it: @@ -58,7 +59,7 @@ class as the ``$returnType``. This ensures that all methods on the model that re instances of our User Entity class instead of an object or array like normal. Working with the Entity Class ------------------------------ +============================= Now that all of the pieces are in place, you would work with the Entity class as you would any other class: @@ -79,7 +80,7 @@ a new row, or update an existing one. call the ``update()``, then only values that have changed are passed. Filling Properties Quickly --------------------------- +========================== The Entity class also provides a method, ``fill()`` that allows you to shove an array of key/value pairs into the class and populate the class properties. Any property in the array will be set on the Entity. However, when saving through @@ -93,15 +94,16 @@ You can also pass the data in the constructor and the data will be passed throug .. literalinclude:: entities/005.php Bulk Accessing Properties -------------------------- +========================= The Entity class has two methods to extract all available properties into an array: ``toArray()`` and ``toRawArray()``. Using the raw version will bypass magic "getter" methods and casts. Both methods can take a boolean first parameter to specify whether returned values should be filtered by those that have changed, and a boolean final parameter to make the method recursive, in case of nested Entities. +*********************** Handling Business Logic -======================= +*********************** While the examples above are convenient, they don't help enforce any business logic. The base Entity class implements some smart ``__get()`` and ``__set()`` methods that will check for special methods and use those instead of using @@ -131,8 +133,9 @@ business logic and create objects that are pleasant to use. .. literalinclude:: entities/007.php +************ Data Mapping -============ +************ At many points in your career, you will run into situations where the use of an application has changed and the original column names in the database no longer make sense. Or you find that your coding style prefers camelCase @@ -168,11 +171,12 @@ to the database. However, ``unset()`` and ``isset()`` only work on the mapped pr for the database column name. In this example, you must define ``setFullName()`` and ``getFullName()``. +******** Mutators -======== +******** Date Mutators -------------- +============= By default, the Entity class will convert fields named `created_at`, `updated_at`, or `deleted_at` into :doc:`Time ` instances whenever they are set or retrieved. The Time class provides a large number @@ -190,12 +194,19 @@ current timezone, as set in **app/Config/App.php**: .. _entities-property-casting: Property Casting ----------------- +================ You can specify that properties in your Entity should be converted to common data types with the ``$casts`` property. This option should be an array where the key is the name of the class property, and the value is the data type it -should be cast to. Casting only affects when values are read. No conversions happen that affect the permanent value in -either the entity or the database. Properties can be cast to any of the following data types: +should be cast to. + +Property casting affects both read (get) and write (set), but some types affect +only read (get). + +Scalar Type Casting +------------------- + +Properties can be cast to any of the following data types: **integer**, **float**, **double**, **string**, **boolean**, **object**, **array**, **datetime**, **timestamp**, **uri** and **int-bool**. Add a question mark at the beginning of type to mark property as nullable, i.e., **?string**, **?integer**. @@ -242,7 +253,7 @@ Stored in the database as "red,yellow,green": .. note:: Casting as CSV uses PHP's internal ``implode`` and ``explode`` methods and assumes all values are string-safe and free of commas. For more complex data casts try ``array`` or ``json``. -Custom casting +Custom Casting -------------- You can define your own conversion types for getting and setting data. @@ -260,12 +271,12 @@ If you don't need to change values when getting or setting a value. Then just do .. literalinclude:: entities/019.php -**Parameters** +Parameters +---------- In some cases, one type is not enough. In this situation, you can use additional parameters. -Additional parameters are indicated in square brackets and listed with a comma. - -**type[param1, param2]** +Additional parameters are indicated in square brackets and listed with a comma +like ``type[param1, param2]``. .. literalinclude:: entities/020.php @@ -275,8 +286,9 @@ Additional parameters are indicated in square brackets and listed with a comma. the value ``nullable`` will be passed to the casting type handler. If casting type has predefined parameters, then ``nullable`` will be added to the end of the list. +******************************* Checking for Changed Attributes -=============================== +******************************* You can check if an Entity attribute has changed since it was created. The only parameter is the name of the attribute to check: diff --git a/user_guide_src/source/outgoing/localization.rst b/user_guide_src/source/outgoing/localization.rst index 103207c35961..a2d11c360486 100644 --- a/user_guide_src/source/outgoing/localization.rst +++ b/user_guide_src/source/outgoing/localization.rst @@ -243,9 +243,11 @@ into your **app** folder. The incorporated translations will be automatically picked up because the ``App`` namespace is mapped to your **app** folder. Alternately, a better practice would be to run the following command inside your -project:: +project: - > composer require codeigniter4/translations +.. code-block:: console + + composer require codeigniter4/translations The translated messages will be automatically picked up because the translations folders get mapped appropriately. diff --git a/user_guide_src/source/outgoing/response.rst b/user_guide_src/source/outgoing/response.rst index 1e25b4dae583..205ee8280775 100644 --- a/user_guide_src/source/outgoing/response.rst +++ b/user_guide_src/source/outgoing/response.rst @@ -445,7 +445,7 @@ The methods provided by the parent class that are available are: .. php:method:: setCookie($name = ''[, $value = ''[, $expire = ''[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = false[, $httponly = false[, $samesite = null]]]]]]]]) - :param array|Cookie|string $name: Cookie name or an array of parameters or an instance of ``CodeIgniter\Cookie\Cookie`` + :param array|Cookie|string $name: Cookie name *or* associative array of all of the parameters available to this method *or* an instance of ``CodeIgniter\Cookie\Cookie`` :param string $value: Cookie value :param int $expire: Cookie expiration time in seconds. If set to ``0`` the cookie will only last as long as the browser is open :param string $domain: Cookie domain diff --git a/user_guide_src/source/outgoing/response/003.php b/user_guide_src/source/outgoing/response/003.php index e5bff8cabf2f..da5819d98860 100644 --- a/user_guide_src/source/outgoing/response/003.php +++ b/user_guide_src/source/outgoing/response/003.php @@ -6,5 +6,6 @@ ]; return $this->response->setJSON($data); + // or return $this->response->setXML($data); diff --git a/user_guide_src/source/outgoing/view_cells.rst b/user_guide_src/source/outgoing/view_cells.rst index 91b22fadb639..09b62bcad16a 100644 --- a/user_guide_src/source/outgoing/view_cells.rst +++ b/user_guide_src/source/outgoing/view_cells.rst @@ -94,9 +94,9 @@ Generating Cell via Command You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the **app/Cells** directory. The view file will also be created in the **app/Cells** directory. -:: +.. code-block:: console - > php spark make:cell AlertMessageCell + php spark make:cell AlertMessageCell Using a Different View ====================== diff --git a/user_guide_src/source/outgoing/view_cells/018.php b/user_guide_src/source/outgoing/view_cells/018.php index 8fc2a4c5b6ae..3f64e68464e9 100644 --- a/user_guide_src/source/outgoing/view_cells/018.php +++ b/user_guide_src/source/outgoing/view_cells/018.php @@ -10,6 +10,6 @@ class RecentPostsCell extends Cell public function mount() { - $this->posts = model('PostModel')->getRecent(); + $this->posts = model('PostModel')->orderBy('created_at', 'DESC')->findAll(10); } } diff --git a/user_guide_src/source/outgoing/view_cells/019.php b/user_guide_src/source/outgoing/view_cells/019.php index 2ed71e348e29..df78ab0acec5 100644 --- a/user_guide_src/source/outgoing/view_cells/019.php +++ b/user_guide_src/source/outgoing/view_cells/019.php @@ -17,6 +17,7 @@ public function mount(?int $categoryId) $categoryId, static fn ($query, $categoryId) => $query->where('category_id', $categoryId) ) - ->getRecent(); + ->orderBy('created_at', 'DESC') + ->findAll(10); } } diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 206cebdd2698..1c09d8c36486 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -426,20 +426,11 @@ Custom Filters -------------- You can easily create your own filters by editing **app/Config/View.php** and adding new entries to the -``$filters`` array. Each key is the name of the filter is called by in the view, and its value is any valid PHP +``$filters`` array. Each key is the name which the filter is called by in the view, and its value is any valid PHP callable: .. literalinclude:: view_parser/012.php -PHP Native functions as Filters -------------------------------- - -You can use native php function as filters by editing **app/Config/View.php** and adding new entries to the -``$filters`` array.Each key is the name of the native PHP function is called by in the view, and its value is any valid native PHP -function prefixed with: - -.. literalinclude:: view_parser/013.php - Parser Plugins ============== diff --git a/user_guide_src/source/outgoing/view_parser/012.php b/user_guide_src/source/outgoing/view_parser/012.php index 000642837149..696bd2d29c22 100644 --- a/user_guide_src/source/outgoing/view_parser/012.php +++ b/user_guide_src/source/outgoing/view_parser/012.php @@ -7,8 +7,8 @@ class View extends BaseView { public $filters = [ - 'abs' => '\CodeIgniter\View\Filters::abs', - 'capitalize' => '\CodeIgniter\View\Filters::capitalize', + 'foo' => '\Some\Class::methodName', + 'str_repeat' => 'str_repeat', // native php function ]; // ... diff --git a/user_guide_src/source/outgoing/view_parser/023.php b/user_guide_src/source/outgoing/view_parser/023.php index 1bdb256d92f1..8e65d489f492 100644 --- a/user_guide_src/source/outgoing/view_parser/023.php +++ b/user_guide_src/source/outgoing/view_parser/023.php @@ -1,3 +1,3 @@ render('myview'); +return $parser->renderString('
  • Item 1
  • Item 2
'); diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index 653150c28d7c..7622339f8f0c 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -28,18 +28,24 @@ to install it globally we do not recommend it, since it can cause compatibility system as time goes on. Ensure that you have Composer installed on your system. From the project root (the directory that contains the -application and system directories) type the following from the command line:: +application and system directories) type the following from the command line: - > composer require --dev phpunit/phpunit +.. code-block:: console + + composer require --dev phpunit/phpunit This will install the correct version for your current PHP version. Once that is done, you can run all of the -tests for this project by typing:: +tests for this project by typing: + +.. code-block:: console + + vendor/bin/phpunit - > vendor/bin/phpunit +If you are using Windows, use the following command: -If you are using Windows, use the following command:: +.. code-block:: console - > vendor\bin\phpunit + vendor\bin\phpunit Phar ---- diff --git a/user_guide_src/source/testing/response.rst b/user_guide_src/source/testing/response.rst index bf82bb402403..2d5f4ddc9f13 100644 --- a/user_guide_src/source/testing/response.rst +++ b/user_guide_src/source/testing/response.rst @@ -8,6 +8,7 @@ from your test cases. Usually a ``TestResponse`` will be provided for you as a r create your own directly using any ``ResponseInterface``: .. literalinclude:: response/001.php + :lines: 2- .. contents:: :local: @@ -28,6 +29,7 @@ request() You can access directly the Request object, if it was set during testing: .. literalinclude:: response/002.php + :lines: 2- response() ---------- @@ -35,6 +37,7 @@ response() This allows you direct access to the response object: .. literalinclude:: response/003.php + :lines: 2- Checking Response Status ======================== @@ -46,6 +49,7 @@ Returns a boolean true/false based on whether the response is perceived to be "o a response status code in the 200 or 300's. An empty body is not considered valid, unless in redirects. .. literalinclude:: response/004.php + :lines: 2- assertOK() ---------- @@ -53,6 +57,7 @@ assertOK() This assertion simply uses the ``isOK()`` method to test a response. ``assertNotOK()`` is the inverse of this assertion. .. literalinclude:: response/005.php + :lines: 2- isRedirect() ------------ @@ -60,6 +65,7 @@ isRedirect() Returns a boolean true/false based on whether the response is a redirected response. .. literalinclude:: response/006.php + :lines: 2- assertRedirect() ---------------- @@ -67,6 +73,7 @@ assertRedirect() Asserts that the Response is an instance of RedirectResponse. ``assertNotRedirect()`` is the inverse of this assertion. .. literalinclude:: response/007.php + :lines: 2- assertRedirectTo() ------------------ @@ -75,6 +82,7 @@ Asserts that the Response is an instance of RedirectResponse and the destination matches the uri given. .. literalinclude:: response/008.php + :lines: 2- getRedirectUrl() ---------------- @@ -82,6 +90,7 @@ getRedirectUrl() Returns the URL set for a RedirectResponse, or null for failure. .. literalinclude:: response/009.php + :lines: 2- assertStatus(int $code) ----------------------- @@ -89,6 +98,7 @@ assertStatus(int $code) Asserts that the HTTP status code returned matches $code. .. literalinclude:: response/010.php + :lines: 2- Session Assertions ================== @@ -100,6 +110,7 @@ Asserts that a value exists in the resulting session. If $value is passed, will matches what was specified. .. literalinclude:: response/011.php + :lines: 2- assertSessionMissing(string $key) --------------------------------- @@ -107,6 +118,7 @@ assertSessionMissing(string $key) Asserts that the resulting session does not include the specified $key. .. literalinclude:: response/012.php + :lines: 2- Header Assertions ================= @@ -118,6 +130,7 @@ Asserts that a header named ``$key`` exists in the response. If ``$value`` is no the values match. .. literalinclude:: response/013.php + :lines: 2- assertHeaderMissing(string $key) -------------------------------- @@ -125,6 +138,7 @@ assertHeaderMissing(string $key) Asserts that a header name ``$key`` does not exist in the response. .. literalinclude:: response/014.php + :lines: 2- Cookie Assertions ================= @@ -136,6 +150,7 @@ Asserts that a cookie named ``$key`` exists in the response. If ``$value`` is no the values match. You can set the cookie prefix, if needed, by passing it in as the third parameter. .. literalinclude:: response/015.php + :lines: 2- assertCookieMissing(string $key) -------------------------------- @@ -143,6 +158,7 @@ assertCookieMissing(string $key) Asserts that a cookie named ``$key`` does not exist in the response. .. literalinclude:: response/016.php + :lines: 2- assertCookieExpired(string $key, string $prefix = '') ----------------------------------------------------- @@ -151,6 +167,7 @@ Asserts that a cookie named ``$key`` exists, but has expired. You can set the co in as the second parameter. .. literalinclude:: response/017.php + :lines: 2- DOM Helpers =========== @@ -161,14 +178,17 @@ are useful for using within assertions in your tests. see() ----- -The ``see()`` method checks the text on the page to see if it exists either by itself, or more specifically within +Returns a boolean true/false based on whether the text on the page exists either +by itself, or more specifically within a tag, as specified by type, class, or id: .. literalinclude:: response/018.php + :lines: 2- The ``dontSee()`` method is the exact opposite: .. literalinclude:: response/019.php + :lines: 2- seeElement() ------------ @@ -177,6 +197,7 @@ The ``seeElement()`` and ``dontSeeElement()`` are very similar to the previous m values of the elements. Instead, they simply check that the elements exist on the page: .. literalinclude:: response/020.php + :lines: 2- seeLink() --------- @@ -184,6 +205,7 @@ seeLink() You can use ``seeLink()`` to ensure that a link appears on the page with the specified text: .. literalinclude:: response/021.php + :lines: 2- seeInField() ------------ @@ -191,6 +213,7 @@ seeInField() The ``seeInField()`` method checks for any input tags exist with the name and value: .. literalinclude:: response/022.php + :lines: 2- seeCheckboxIsChecked() ---------------------- @@ -198,6 +221,7 @@ seeCheckboxIsChecked() Finally, you can check if a checkbox exists and is checked with the ``seeCheckboxIsChecked()`` method: .. literalinclude:: response/023.php + :lines: 2- DOM Assertions ============== @@ -212,6 +236,7 @@ Asserts that text/HTML is on the page, either by itself or - more specifically - a tag, as specified by type, class, or id: .. literalinclude:: response/024.php + :lines: 2- assertDontSee(string $search = null, string $element = null) ------------------------------------------------------------ @@ -219,6 +244,7 @@ assertDontSee(string $search = null, string $element = null) Asserts the exact opposite of the ``assertSee()`` method: .. literalinclude:: response/025.php + :lines: 2- assertSeeElement(string $search) -------------------------------- @@ -226,6 +252,7 @@ assertSeeElement(string $search) Similar to ``assertSee()``, however this only checks for an existing element. It does not check for specific text: .. literalinclude:: response/026.php + :lines: 2- assertDontSeeElement(string $search) ------------------------------------ @@ -234,6 +261,7 @@ Similar to ``assertSee()``, however this only checks for an existing element tha specific text: .. literalinclude:: response/027.php + :lines: 2- assertSeeLink(string $text, string $details = null) --------------------------------------------------- @@ -241,6 +269,7 @@ assertSeeLink(string $text, string $details = null) Asserts that an anchor tag is found with matching ``$text`` as the body of the tag: .. literalinclude:: response/028.php + :lines: 2- assertSeeInField(string $field, string $value = null) ----------------------------------------------------- @@ -248,6 +277,7 @@ assertSeeInField(string $field, string $value = null) Asserts that an input tag exists with the name and value: .. literalinclude:: response/029.php + :lines: 2- Working with JSON ================= @@ -261,19 +291,22 @@ getJSON() This method will return the body of the response as a JSON string: .. literalinclude:: response/030.php + :lines: 2- You can use this method to determine if ``$response`` actually holds JSON content: .. literalinclude:: response/031.php + :lines: 2- .. note:: Be aware that the JSON string will be pretty-printed in the result. assertJSONFragment(array $fragment) ----------------------------------- -Asserts that $fragment is found within the JSON response. It does not need to match the entire JSON value. +Asserts that ``$fragment`` is found within the JSON response. It does not need to match the entire JSON value. .. literalinclude:: response/032.php + :lines: 2- assertJSONExact($test) ---------------------- diff --git a/user_guide_src/source/testing/response/018.php b/user_guide_src/source/testing/response/018.php index a76172d502b0..a32d2742d4f8 100644 --- a/user_guide_src/source/testing/response/018.php +++ b/user_guide_src/source/testing/response/018.php @@ -1,10 +1,21 @@ see('Hello World'); +if ($results->see('Hello World')) { + // ... +} + // Check that "Hello World" is within an h1 tag -$results->see('Hello World', 'h1'); +if ($results->see('Hello World', 'h1')) { + // ... +} + // Check that "Hello World" is within an element with the "notice" class -$results->see('Hello World', '.notice'); +if ($results->see('Hello World', '.notice')) { + // ... +} + // Check that "Hello World" is within an element with id of "title" -$results->see('Hello World', '#title'); +if ($results->see('Hello World', '#title')) { + // ... +} diff --git a/user_guide_src/source/testing/response/019.php b/user_guide_src/source/testing/response/019.php index f96493b52e91..128e6862b99b 100644 --- a/user_guide_src/source/testing/response/019.php +++ b/user_guide_src/source/testing/response/019.php @@ -1,6 +1,11 @@ dontSee('Hello World'); +if ($results->dontSee('Hello World')) { + // ... +} + // Checks that "Hellow World" does NOT exist within any h1 tag -$results->dontSee('Hello World', 'h1'); +if ($results->dontSee('Hello World', 'h1')) { + // ... +} diff --git a/user_guide_src/source/testing/response/020.php b/user_guide_src/source/testing/response/020.php index 8b716717b696..94598bf98680 100644 --- a/user_guide_src/source/testing/response/020.php +++ b/user_guide_src/source/testing/response/020.php @@ -1,8 +1,16 @@ seeElement('.notice'); +if ($results->seeElement('.notice')) { + // ... +} + // Check that an element with id 'title' exists -$results->seeElement('#title'); +if ($results->seeElement('#title')) { + // ... +} + // Verify that an element with id 'title' does NOT exist -$results->dontSeeElement('#title'); +if ($results->dontSeeElement('#title')) { + // ... +} diff --git a/user_guide_src/source/testing/response/021.php b/user_guide_src/source/testing/response/021.php index bc74e3ad9124..d073ec5a3400 100644 --- a/user_guide_src/source/testing/response/021.php +++ b/user_guide_src/source/testing/response/021.php @@ -1,6 +1,11 @@ seeLink('Upgrade Account'); +if ($results->seeLink('Upgrade Account')) { + // ... +} + // Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' -$results->seeLink('Upgrade Account', '.upsell'); +if ($results->seeLink('Upgrade Account', '.upsell')) { + // ... +} diff --git a/user_guide_src/source/testing/response/022.php b/user_guide_src/source/testing/response/022.php index 9bb549c9db5f..791d72da4d3f 100644 --- a/user_guide_src/source/testing/response/022.php +++ b/user_guide_src/source/testing/response/022.php @@ -1,6 +1,11 @@ seeInField('user', 'John Snow'); +if ($results->seeInField('user', 'John Snow')) { + // ... +} + // Check a multi-dimensional input -$results->seeInField('user[name]', 'John Snow'); +if ($results->seeInField('user[name]', 'John Snow')) { + // ... +} diff --git a/user_guide_src/source/testing/response/023.php b/user_guide_src/source/testing/response/023.php index 3378144f6eb7..af7c768e3758 100644 --- a/user_guide_src/source/testing/response/023.php +++ b/user_guide_src/source/testing/response/023.php @@ -1,6 +1,11 @@ seeCheckboxIsChecked('.foo'); +if ($results->seeCheckboxIsChecked('.foo')) { + // ... +} + // Check if checkbox with id of 'bar' is checked -$results->seeCheckboxIsChecked('#bar'); +if ($results->seeCheckboxIsChecked('#bar')) { + // ... +} diff --git a/user_guide_src/source/testing/response/024.php b/user_guide_src/source/testing/response/024.php index 822d629744d4..9238cd2fd877 100644 --- a/user_guide_src/source/testing/response/024.php +++ b/user_guide_src/source/testing/response/024.php @@ -1,10 +1,13 @@ assertSee('Hello World'); -// Check that "Hello World" is within an h1 tag + +// Verify that "Hello World" is within an h1 tag $result->assertSee('Hello World', 'h1'); -// Check that "Hello World" is within an element with the "notice" class + +// Verify that "Hello World" is within an element with the "notice" class $result->assertSee('Hello World', '.notice'); -// Check that "Hello World" is within an element with id of "title" + +// Verify that "Hello World" is within an element with id of "title" $result->assertSee('Hello World', '#title'); diff --git a/user_guide_src/source/testing/response/025.php b/user_guide_src/source/testing/response/025.php index b255f4155ac5..ea65727d0d36 100644 --- a/user_guide_src/source/testing/response/025.php +++ b/user_guide_src/source/testing/response/025.php @@ -1,6 +1,7 @@ dontSee('Hello World'); -// Checks that "Hello World" does NOT exist within any h1 tag -$results->dontSee('Hello World', 'h1'); +// Verify that "Hello World" does NOT exist on the page +$results->assertDontSee('Hello World'); + +// Verify that "Hello World" does NOT exist within any h1 tag +$results->assertDontSee('Hello World', 'h1'); diff --git a/user_guide_src/source/testing/response/026.php b/user_guide_src/source/testing/response/026.php index 4afd20161b23..5a6b38df324b 100644 --- a/user_guide_src/source/testing/response/026.php +++ b/user_guide_src/source/testing/response/026.php @@ -1,6 +1,7 @@ seeElement('.notice'); -// Check that an element with id 'title' exists -$results->seeElement('#title'); +// Verify that an element with class 'notice' exists +$results->assertSeeElement('.notice'); + +// Verify that an element with id 'title' exists +$results->assertSeeElement('#title'); diff --git a/user_guide_src/source/testing/response/027.php b/user_guide_src/source/testing/response/027.php index 9780489133ee..e5df1d09feaa 100644 --- a/user_guide_src/source/testing/response/027.php +++ b/user_guide_src/source/testing/response/027.php @@ -1,4 +1,4 @@ dontSeeElement('#title'); +$results->assertDontSeeElement('#title'); diff --git a/user_guide_src/source/testing/response/028.php b/user_guide_src/source/testing/response/028.php index bc74e3ad9124..91b42c99a9a9 100644 --- a/user_guide_src/source/testing/response/028.php +++ b/user_guide_src/source/testing/response/028.php @@ -1,6 +1,7 @@ seeLink('Upgrade Account'); -// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' -$results->seeLink('Upgrade Account', '.upsell'); +// Verify that a link exists with 'Upgrade Account' as the text:: +$results->assertSeeLink('Upgrade Account'); + +// Verify that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' +$results->assertSeeLink('Upgrade Account', '.upsell'); diff --git a/user_guide_src/source/testing/response/029.php b/user_guide_src/source/testing/response/029.php index 1ae7910e9776..dfa511aa065f 100644 --- a/user_guide_src/source/testing/response/029.php +++ b/user_guide_src/source/testing/response/029.php @@ -1,6 +1,7 @@ assertSeeInField('user', 'John Snow'); -// Check a multi-dimensional input + +// Verify a multi-dimensional input $results->assertSeeInField('user[name]', 'John Snow'); diff --git a/user_guide_src/source/tutorial/index.rst b/user_guide_src/source/tutorial/index.rst index 85675764eceb..7675d0be9dc3 100644 --- a/user_guide_src/source/tutorial/index.rst +++ b/user_guide_src/source/tutorial/index.rst @@ -62,9 +62,11 @@ Installing CodeIgniter You can download a release manually from the site, but for this tutorial we will use the recommended way and install the AppStarter package through Composer. -From your command line type the following:: +From your command line type the following: - > composer create-project codeigniter4/appstarter ci-news +.. code-block:: console + + composer create-project codeigniter4/appstarter ci-news This creates a new folder, **ci-news**, which contains your application code, with CodeIgniter installed in the vendor folder. @@ -93,9 +95,11 @@ With that out of the way it's time to view your application in a browser. You ca serve it through any server of your choice, Apache, Nginx, etc, but CodeIgniter comes with a simple command that takes advantage of PHP's built-in server to get you up and running fast on your development machines. Type the following on the -command line from the root of your project:: +command line from the root of your project: + +.. code-block:: console - > php spark serve + php spark serve The Welcome Page **************** diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 926ed09603c7..76fd2fb11e56 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -175,9 +175,11 @@ since it will not properly process the ``.htaccess`` rules that are provided in ``public``, and which eliminate the need to specify "**index.php/**" as part of a URL. CodeIgniter has its own command that you can use though. -From the command line, at the root of your project:: +From the command line, at the root of your project: - > php spark serve +.. code-block:: console + + php spark serve will start a web server, accessible on port 8080. If you set the location field in your browser to ``localhost:8080``, you should see the CodeIgniter welcome page.