diff --git a/.github/workflows/deploy-distributables.yml b/.github/workflows/deploy-distributables.yml index 3d4b31f289e6..f28a62544fa5 100644 --- a/.github/workflows/deploy-distributables.yml +++ b/.github/workflows/deploy-distributables.yml @@ -66,7 +66,7 @@ jobs: run: ./source/.github/scripts/deploy-framework ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/framework ${GITHUB_REF##*/} - name: Release - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{secrets.ACCESS_TOKEN}} script: | @@ -116,7 +116,7 @@ jobs: run: ./source/.github/scripts/deploy-appstarter ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/appstarter ${GITHUB_REF##*/} - name: Release - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{secrets.ACCESS_TOKEN}} script: | @@ -172,7 +172,7 @@ jobs: run: ./source/.github/scripts/deploy-userguide ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/userguide ${GITHUB_REF##*/} - name: Release - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{secrets.ACCESS_TOKEN}} script: | diff --git a/.github/workflows/test-autoreview.yml b/.github/workflows/test-autoreview.yml index 44feb4e33139..69545ca6af01 100644 --- a/.github/workflows/test-autoreview.yml +++ b/.github/workflows/test-autoreview.yml @@ -1,4 +1,4 @@ -name: Automatic Code Review +name: AutoReview on: pull_request: @@ -23,9 +23,10 @@ permissions: jobs: auto-review-tests: + name: Automatic Code Review uses: ./.github/workflows/reusable-serviceless-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo with: - job-name: Automatic Code Review [PHP 8.1] + job-name: PHP 8.1 php-version: '8.1' job-id: auto-review-tests group-name: AutoReview diff --git a/.github/workflows/test-phpcpd.yml b/.github/workflows/test-phpcpd.yml index 53daa8ebab95..04ef53bb99c5 100644 --- a/.github/workflows/test-phpcpd.yml +++ b/.github/workflows/test-phpcpd.yml @@ -56,4 +56,5 @@ jobs: --exclude system/Database/Postgre/Builder.php --exclude system/Debug/Exceptions.php --exclude system/HTTP/SiteURI.php + --exclude system/Validation/Rules.php -- app/ public/ system/ diff --git a/.github/workflows/test-phpunit.yml b/.github/workflows/test-phpunit.yml index 9ca4ed8e15e4..53124f695162 100644 --- a/.github/workflows/test-phpunit.yml +++ b/.github/workflows/test-phpunit.yml @@ -50,6 +50,7 @@ jobs: echo "version=8.1" >> $GITHUB_OUTPUT sanity-tests: + name: Others needs: coverage-php-version strategy: @@ -77,6 +78,7 @@ jobs: extra-composer-options: ${{ matrix.composer-option }} database-live-tests: + name: DatabaseLive needs: - coverage-php-version - sanity-tests @@ -97,17 +99,17 @@ jobs: - SQLSRV - SQLite3 mysql-version: - - '5.7' + - '8.0' include: - php-version: '7.4' db-platform: MySQLi - mysql-version: '8.0' + mysql-version: '5.7' - php-version: '8.3' composer-option: '--ignore-platform-req=php' uses: ./.github/workflows/reusable-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo with: - job-name: Database Live Tests + job-name: '' php-version: ${{ matrix.php-version }} job-id: database-live-tests db-platform: ${{ matrix.db-platform }} @@ -120,6 +122,7 @@ jobs: extra-composer-options: ${{ matrix.composer-option }} separate-process-tests: + name: SeparateProcess needs: - coverage-php-version - sanity-tests @@ -138,7 +141,7 @@ jobs: uses: ./.github/workflows/reusable-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo with: - job-name: Separate Process Tests + job-name: '' php-version: ${{ matrix.php-version }} job-id: separate-process-tests group-name: SeparateProcess @@ -149,6 +152,7 @@ jobs: extra-composer-options: ${{ matrix.composer-option }} cache-live-tests: + name: CacheLive needs: - coverage-php-version - sanity-tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cf10b0f8372..61b773f58ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,59 @@ # Changelog +## [v4.4.4](https://github.com/codeigniter4/CodeIgniter4/tree/v4.4.4) (2023-12-28) +[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.3...v4.4.4) + +### Breaking Changes + +* fix: Validation rule with `*` gets incorrect values as dot array syntax by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8129 +* fix: validation rule `matches` and `differs` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8122 +* fix: [CURLRequest] skip hostname checks if options 'verify' false by @NicolaeIotu in https://github.com/codeigniter4/CodeIgniter4/pull/8258 +* fix: get_filenames() does not follow symlinks by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8298 + +### Fixed Bugs + +* fix: change make:command default $group to `App` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8109 +* fix: typo in help message in `spark filter:check` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8118 +* fix: Hot reloading when session is enabled by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/8112 +* fix: make:cell help message by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8133 +* fix: [DebugBar] dark mode timeline "Controller" by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8125 +* fix: PHPDoc types in controller.tpl.php by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8144 +* fix: `@return` in filter.tpl.php by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8145 +* fix: when request body is `0`, $body will be null by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8161 +* fix: `spark routes` outputs `` only when {locale} with `useSupportedLocalesOnly(true)` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8167 +* fix: Undefined array key error in `spark db:table` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8173 +* fix: force_https() redirects to wrong URL when baseURL has subfolder by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8191 +* fix: Validation raises TypeError when invalid JSON comes by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8153 +* fix: FilterTestTrait Undefined variable $filterClasses by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8195 +* fix: Image::save() causes error with webp by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8210 +* fix issue where running FileLocator::getClassname() on a directory would cause a PHP error by @colethorsen in https://github.com/codeigniter4/CodeIgniter4/pull/8216 +* fix: make Request::getEnv() deprecated by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8234 +* fix: ExceptionHandler displays incorrect Exception classname by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8239 +* fix: [Cache] Double prefix for increment in FileHandler by @il-coder in https://github.com/codeigniter4/CodeIgniter4/pull/8255 +* docs: fix Database Utility Class `getXMLFromResult()` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8276 +* fix: autoload helpers in test bootstrap by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8275 +* fix: Model handling of Entity $primaryKey casting by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8282 +* fix: Handle non-array JSON in validation by @woodongwong in https://github.com/codeigniter4/CodeIgniter4/pull/8288 +* fix: DEPRECATED error in Honeypot by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8316 +* fix: [Auto Routing Improved] `spark routes` shows incorrect routes when translateURIDashes is enabled by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8320 +* fix: migrations not using custom DB connection of migration runner by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/8221 +* Always return a new instance of a Cell by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/8330 +* fix: DOMParser cannot see element with `id="0"` by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8360 + +### Refactoring + +* [Rector] Apply SingleInArrayToCompareRector by @samsonasik in https://github.com/codeigniter4/CodeIgniter4/pull/8102 +* refactor: RedisHandler ttl() calls by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8155 +* [Testing] Use assertEqualsWithDelta() when possible by @samsonasik in https://github.com/codeigniter4/CodeIgniter4/pull/8158 +* refactor: replace non-boolean if conditions in Model by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8193 +* refactor: View classes to fix PHPStan errors by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8208 +* refactor: Model by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8260 +* replace -1 with E_ALL in error_reporting calls by @ThomasMeschke in https://github.com/codeigniter4/CodeIgniter4/pull/8212 +* refactor: apply SimplifyEmptyCheckOnEmptyArrayRector by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8341 +* refactor: apply DisallowedEmptyRuleFixerRector by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8344 +* refactor: rely on $config property in ViewDecoratorTrait by @mostafakhudair in https://github.com/codeigniter4/CodeIgniter4/pull/8021 +* refactor: replace empty() Part 1 by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8345 + ## [v4.4.3](https://github.com/codeigniter4/CodeIgniter4/tree/v4.4.3) (2023-10-26) [Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.2...v4.4.3) @@ -59,8 +113,6 @@ * refactor: delete duplicate code for Composer loading by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8004 * [Rector] Apply BooleanInIfConditionRuleFixerRector by @samsonasik in https://github.com/codeigniter4/CodeIgniter4/pull/7951 -**Full Changelog**: https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.1...v4.4.2 - ## [v4.4.1](https://github.com/codeigniter4/CodeIgniter4/tree/v4.4.1) (2023-09-05) [Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.0...v4.4.1) diff --git a/admin/RELEASE.md b/admin/RELEASE.md index 98089ae8181f..8d68ccd9923a 100644 --- a/admin/RELEASE.md +++ b/admin/RELEASE.md @@ -2,7 +2,7 @@ > Documentation guide based on the releases of `4.0.5` and `4.1.0` on January 31, 2021. > -> Updated for `4.3.0` on January 10, 2023. +> Updated for `4.4.3` on October 27, 2023. > > -MGatner, kenjis @@ -53,12 +53,18 @@ Work off direct clones of the repos so the release branches persist for a time. * [ ] Clone both **codeigniter4/CodeIgniter4** and **codeigniter4/userguide** and resolve any necessary PRs ```console + rm -rf CodeIgniter4.bk userguide.bk + mv CodeIgniter4 CodeIgniter4.bk + mv userguide userguide.bk git clone git@github.com:codeigniter4/CodeIgniter4.git git clone git@github.com:codeigniter4/userguide.git ``` * [ ] Vet the **admin/** folders for any removed hidden files (Action deploy scripts *do not remove these*) - * git diff --name-status origin/master admin/ + ```console + cd CodeIgniter4 + git diff --name-status origin/master admin/ + ``` * [ ] Merge any Security Advisory PRs in private forks ## Process @@ -67,21 +73,26 @@ Work off direct clones of the repos so the release branches persist for a time. > been included with their PR, so this process assumes you will not be > generating much new content. -* [ ] Create a new branch `release-4.x.x` -* [ ] Update **system/CodeIgniter.php** with the new version number: - `const CI_VERSION = '4.x.x';` -* [ ] Update **user_guide_src/source/conf.py** with the new `version = '4.x'` (if applicable) - and `release = '4.x.x'` * [ ] Replace **CHANGELOG.md** with the new version generated above * [ ] Update **user_guide_src/source/changelogs/{version}.rst** - * Set the date to format `Release Date: January 31, 2021` * Remove the section titles that have no items * [ ] Update **user_guide_src/source/installation/upgrade_{ver}.rst** * fill in the "All Changes" section, and add it to **upgrading.rst** * git diff --name-status origin/master -- . ':!system' * Remove the section titles that have no items * [Minor version only] Update the "from" version in the title. E.g., `from 4.3.x` → `from 4.3.8` -* [ ] Commit the changes with `Prep for 4.x.x release` and push to origin +* [ ] Run `php admin/prepare-release.php 4.x.x` and push to origin + * The above command does the following: + * Create a new branch `release-4.x.x` + * Update **system/CodeIgniter.php** with the new version number: + `const CI_VERSION = '4.x.x';` + * Update **user_guide_src/source/conf.py** with the new `version = '4.x'` (if applicable) + and `release = '4.x.x'` + * Update **user_guide_src/source/changelogs/{version}.rst** + * Set the date to format `Release Date: January 31, 2021` + * Update **phpdoc.dist.xml** with the new `CodeIgniter v4.x API` + and `` + * Commit the changes with `Prep for 4.x.x release` * [ ] Create a new PR from `release-4.x.x` to `develop`: * Title: `Prep for 4.x.x release` * Description: @@ -119,6 +130,7 @@ Work off direct clones of the repos so the release branches persist for a time. * [ ] Run the following commands to install and test `appstarter` and verify the new version: ```console + rm -rf release-test composer create-project codeigniter4/appstarter release-test cd release-test composer test && composer info codeigniter4/framework @@ -152,7 +164,7 @@ Work off direct clones of the repos so the release branches persist for a time. git switch -c 4.x git push origin HEAD ``` -* [ ] Publish any Security Advisories that were resolved from private forks +* [ ] Request CVEs and Publish any Security Advisories that were resolved from private forks (note: publishing is restricted to administrators): * [ ] Announce the release on the forums and Slack channel (note: this forum is restricted to administrators): @@ -160,11 +172,13 @@ Work off direct clones of the repos so the release branches persist for a time. https://forum.codeigniter.com/forum-2.html * The content is somewhat organic, but should include any major features and changes as well as a link to the User Guide's changelog +* [ ] Run `php admin/create-new-changelog.php ` + * The above command does the following: + * Create **user_guide_src/source/changelogs/{next_version}.rst** and add it to + **index.rst** (See **next-changelog-*.rst**) + * Create **user_guide_src/source/installation/upgrade_{next_version}.rst** and add it to + **upgrading.rst** (See **next-upgrading-guide.rst**) * [ ] Create a PR for new changelog and upgrade for the next version - * Create **user_guide_src/source/changelogs/{next_version}.rst** and add it to - **index.rst** (See **next-changelog-*.rst**) - * Create **user_guide_src/source/installation/upgrade_{next_version}.rst** and add it to - **upgrading.rst** (See **next-upgrading-guide.rst**) ## Appendix diff --git a/admin/create-new-changelog.php b/admin/create-new-changelog.php new file mode 100644 index 000000000000..ff371345d166 --- /dev/null +++ b/admin/create-new-changelog.php @@ -0,0 +1,87 @@ + " . PHP_EOL; + echo "E.g.,: php {$argv[0]} 4.4.3 4.4.4" . PHP_EOL; + + exit(1); +} + +// Gets version number from argument. +$versionCurrent = $argv[1]; // e.g., '4.4.3' +$versionCurrentParts = explode('.', $versionCurrent); +$minorCurrent = $versionCurrentParts[0] . '.' . $versionCurrentParts[1]; +$version = $argv[2]; // e.g., '4.4.4' +$versionParts = explode('.', $version); +$minor = $versionParts[0] . '.' . $versionParts[1]; +$isMinorUpdate = ($minorCurrent !== $minor); + +// Creates a branch for release. +system('git switch develop'); +system('git switch -c docs-changelog-' . $version); +system('git switch docs-changelog-' . $version); + +// Copy changelog +$changelog = "./user_guide_src/source/changelogs/v{$version}.rst"; +$changelogIndex = './user_guide_src/source/changelogs/index.rst'; +if ($isMinorUpdate) { + copy('./admin/next-changelog-minor.rst', $changelog); +} else { + copy('./admin/next-changelog-patch.rst', $changelog); +} +// Add changelog to index.rst. +replace_file_content( + $changelogIndex, + '/\.\. toctree::\n :titlesonly:\n/u', + ".. toctree::\n :titlesonly:\n\n v{$version}" +); +// Replace {version} +$length = mb_strlen("Version {$version}"); +$underline = str_repeat('#', $length); +replace_file_content( + $changelog, + '/#################\nVersion {version}\n#################/u', + "{$underline}\nVersion {$version}\n{$underline}" +); +replace_file_content( + $changelog, + '/{version}/u', + "{$version}" +); + +// Copy upgrading +$versionWithoutDots = str_replace('.', '', $version); +$upgrading = "./user_guide_src/source/installation/upgrade_{$versionWithoutDots}.rst"; +$upgradingIndex = './user_guide_src/source/installation/upgrading.rst'; +copy('./admin/next-upgrading-guide.rst', $upgrading); +// Add upgrading to upgrading.rst. +replace_file_content( + $upgradingIndex, + '/ backward_compatibility_notes\n/u', + " backward_compatibility_notes\n\n upgrade_{$versionWithoutDots}" +); +// Replace {version} +$length = mb_strlen("Upgrading from {$versionCurrent} to {$version}"); +$underline = str_repeat('#', $length); +replace_file_content( + $upgrading, + '/##############################\nUpgrading from {version} to {version}\n##############################/u', + "{$underline}\nUpgrading from {$versionCurrent} to {$version}\n{$underline}" +); + +// Commits +system("git add {$changelog} {$changelogIndex}"); +system("git add {$upgrading} {$upgradingIndex}"); +system('git commit -m "docs: add changelog and upgrade for v' . $version . '"'); diff --git a/admin/css/debug-toolbar/_theme-dark.scss b/admin/css/debug-toolbar/_theme-dark.scss index 5f68f8c20b5f..ead7d02a58e3 100644 --- a/admin/css/debug-toolbar/_theme-dark.scss +++ b/admin/css/debug-toolbar/_theme-dark.scss @@ -150,10 +150,6 @@ .timer { background-color: $g-orange; } - - .timeline-parent-open td { - color: $t-dark; - } } } diff --git a/admin/framework/composer.json b/admin/framework/composer.json index f93daa275b1d..9d7cba44ddbb 100644 --- a/admin/framework/composer.json +++ b/admin/framework/composer.json @@ -20,7 +20,7 @@ "require-dev": { "codeigniter/coding-standard": "^1.5", "fakerphp/faker": "^1.9", - "friendsofphp/php-cs-fixer": "3.13.0", + "friendsofphp/php-cs-fixer": "~3.41.0", "kint-php/kint": "^5.0.4", "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.6", @@ -43,6 +43,7 @@ "ext-readline": "Improves CLI::input() usability", "ext-redis": "If you use Cache class RedisHandler", "ext-simplexml": "If you format XML", + "ext-sodium": "If you use Encryption SodiumHandler", "ext-sqlite3": "If you use SQLite3", "ext-sqlsrv": "If you use SQL Server", "ext-xdebug": "If you use CIUnitTestCase::assertHeaderEmitted()" diff --git a/admin/next-changelog-minor.rst b/admin/next-changelog-minor.rst index f5bb20004d77..c22f0be7d9f3 100644 --- a/admin/next-changelog-minor.rst +++ b/admin/next-changelog-minor.rst @@ -1,3 +1,4 @@ +################# Version {version} ################# @@ -9,11 +10,13 @@ Release Date: Unreleased :local: :depth: 3 +********** Highlights ********** - TBD +******** BREAKING ******** @@ -26,6 +29,7 @@ Interface Changes Method Signature Changes ======================== +************ Enhancements ************ @@ -59,15 +63,19 @@ Helpers and Functions Others ====== +*************** Message Changes *************** +******* Changes ******* +************ Deprecations ************ +********** Bugs Fixed ********** diff --git a/admin/next-changelog-patch.rst b/admin/next-changelog-patch.rst index 4c76ca01a112..ed2ba70570b3 100644 --- a/admin/next-changelog-patch.rst +++ b/admin/next-changelog-patch.rst @@ -1,3 +1,4 @@ +################# Version {version} ################# @@ -9,18 +10,23 @@ Release Date: Unreleased :local: :depth: 3 +******** BREAKING ******** +*************** Message Changes *************** +******* Changes ******* +************ Deprecations ************ +********** Bugs Fixed ********** diff --git a/admin/next-upgrading-guide.rst b/admin/next-upgrading-guide.rst index fb97f320e95a..bcffc3fe3de5 100644 --- a/admin/next-upgrading-guide.rst +++ b/admin/next-upgrading-guide.rst @@ -12,15 +12,19 @@ Please refer to the upgrade instructions corresponding to your installation meth :local: :depth: 2 +********************** Mandatory File Changes ********************** +**************** Breaking Changes **************** +********************* Breaking Enhancements ********************* +************* Project Files ************* diff --git a/admin/prepare-release.php b/admin/prepare-release.php new file mode 100644 index 000000000000..aebc1ea98c06 --- /dev/null +++ b/admin/prepare-release.php @@ -0,0 +1,73 @@ +" . PHP_EOL; + echo "E.g.,: php {$argv[0]} 4.4.3" . PHP_EOL; + + exit(1); +} + +// Gets version number from argument. +$version = $argv[1]; // e.g., '4.4.3' +$versionParts = explode('.', $version); +$minor = $versionParts[0] . '.' . $versionParts[1]; + +// Creates a branch for release. +system('git switch develop'); +system('git switch -c release-' . $version); +system('git switch docs-changelog-' . $version); + +// Updates version number in "CodeIgniter.php". +replace_file_content( + './system/CodeIgniter.php', + '/public const CI_VERSION = \'.*?\';/u', + "public const CI_VERSION = '{$version}';" +); + +// Updates version number in "conf.py". +replace_file_content( + './user_guide_src/source/conf.py', + '/^version = \'.*?\'/mu', + "version = '{$minor}'" +); +replace_file_content( + './user_guide_src/source/conf.py', + '/^release = \'.*?\'/mu', + "release = '{$version}'" +); + +// Updates version number in "phpdoc.dist.xml". +replace_file_content( + './phpdoc.dist.xml', + '!CodeIgniter v.*? API!mu', + "CodeIgniter v{$minor} API" +); +replace_file_content( + './phpdoc.dist.xml', + '//mu', + "" +); + +// Updates release date in changelogs. +$date = date('F j, Y'); +replace_file_content( + "./user_guide_src/source/changelogs/v{$version}.rst", + '/^Release Date: .*/mu', + "Release Date: {$date}" +); + +// Commits +system('git add -u'); +system('git commit -m "Prep for ' . $version . ' release"'); diff --git a/app/Config/App.php b/app/Config/App.php index 186bfa86bb02..6ae678625e7b 100644 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -27,8 +27,7 @@ class App extends BaseConfig * 'http://accounts.example.com/': * ['media.example.com', 'accounts.example.com'] * - * @var string[] - * @phpstan-var list + * @var list */ public array $allowedHostnames = []; diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index 22f05ecdab26..7a4602d72920 100644 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -41,8 +41,7 @@ class Autoload extends AutoloadConfig * 'App' => APPPATH * ]; * - * @var array|string> - * @phpstan-var array> + * @var array|string> */ public $psr4 = [ APP_NAMESPACE => APPPATH, // For custom app namespace @@ -81,8 +80,7 @@ class Autoload extends AutoloadConfig * '/path/to/my/file.php', * ]; * - * @var string[] - * @phpstan-var list + * @var list */ public $files = []; @@ -95,8 +93,7 @@ class Autoload extends AutoloadConfig * 'form', * ]; * - * @var string[] - * @phpstan-var list + * @var list */ public $helpers = []; } diff --git a/app/Config/Boot/development.php b/app/Config/Boot/development.php index aa8099a46501..a868447a8e37 100644 --- a/app/Config/Boot/development.php +++ b/app/Config/Boot/development.php @@ -10,7 +10,7 @@ | | If you set 'display_errors' to '1', CI4's detailed error report will show. */ -error_reporting(-1); +error_reporting(E_ALL); ini_set('display_errors', '1'); /* diff --git a/app/Config/Boot/testing.php b/app/Config/Boot/testing.php index e84670e972f6..40b6ca83cf3f 100644 --- a/app/Config/Boot/testing.php +++ b/app/Config/Boot/testing.php @@ -14,7 +14,7 @@ | make sure they don't make it to production. And save us hours of | painful debugging. */ -error_reporting(-1); +error_reporting(E_ALL); ini_set('display_errors', '1'); /* diff --git a/app/Config/Cache.php b/app/Config/Cache.php index 61cdd50de890..b5b2cdc1738f 100644 --- a/app/Config/Cache.php +++ b/app/Config/Cache.php @@ -158,8 +158,7 @@ class Cache extends BaseConfig * This is an array of cache engine alias' and class names. Only engines * that are listed here are allowed to be used. * - * @var array - * @phpstan-var array> + * @var array> */ public array $validHandlers = [ 'dummy' => DummyHandler::class, diff --git a/app/Config/Email.php b/app/Config/Email.php index 01b805a5c1fa..4dce650b32ec 100644 --- a/app/Config/Email.php +++ b/app/Config/Email.php @@ -26,7 +26,7 @@ class Email extends BaseConfig public string $mailPath = '/usr/sbin/sendmail'; /** - * SMTP Server Address + * SMTP Server Hostname */ public string $SMTPHost = ''; diff --git a/app/Config/Filters.php b/app/Config/Filters.php index 41e76267a448..ac37b414c45c 100644 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -15,9 +15,8 @@ class Filters extends BaseConfig * Configures aliases for Filter classes to * make reading things nicer and simpler. * - * @var array|string> [filter_name => classname] - * or [filter_name => [classname1, classname2, ...]] - * @phpstan-var array> + * @var array> [filter_name => classname] + * or [filter_name => [classname1, classname2, ...]] */ public array $aliases = [ 'csrf' => CSRF::class, @@ -31,8 +30,7 @@ class Filters extends BaseConfig * List of filter aliases that are always * applied before and after every request. * - * @var array>>|array> - * @phpstan-var array>|array>> + * @var array>>|array> */ public array $globals = [ 'before' => [ diff --git a/app/Config/Kint.php b/app/Config/Kint.php index cc8b54592b6b..117e66d87c45 100644 --- a/app/Config/Kint.php +++ b/app/Config/Kint.php @@ -27,8 +27,7 @@ class Kint extends BaseConfig */ /** - * @var array - * @phpstan-var list|ConstructablePluginInterface> + * @var list|ConstructablePluginInterface>|null */ public $plugins; @@ -46,14 +45,12 @@ class Kint extends BaseConfig public int $richSort = AbstractRenderer::SORT_FULL; /** - * @var array - * @phpstan-var array> + * @var array>|null */ public $richObjectPlugins; /** - * @var array - * @phpstan-var array> + * @var array>|null */ public $richTabPlugins; diff --git a/app/Config/Modules.php b/app/Config/Modules.php index f84580c856d3..8d4bf56544b0 100644 --- a/app/Config/Modules.php +++ b/app/Config/Modules.php @@ -58,7 +58,7 @@ class Modules extends BaseModules * ], * ] * - * @var array + * @var array{only?: list, exclude?: list} */ public $composerPackages = []; @@ -72,7 +72,7 @@ class Modules extends BaseModules * * If it is not listed, only the base application elements will be used. * - * @var string[] + * @var list */ public $aliases = [ 'events', diff --git a/app/Config/Publisher.php b/app/Config/Publisher.php index 47475112c080..bf03be1db7e0 100644 --- a/app/Config/Publisher.php +++ b/app/Config/Publisher.php @@ -19,7 +19,7 @@ class Publisher extends BasePublisher * result in a PublisherException. Files that do no fit the * pattern will cause copy/merge to fail. * - * @var array + * @var array */ public $restrictions = [ ROOTPATH => '*', diff --git a/app/Config/Session.php b/app/Config/Session.php index ea834805e5a6..e077df64bd46 100644 --- a/app/Config/Session.php +++ b/app/Config/Session.php @@ -19,7 +19,7 @@ class Session extends BaseConfig * - `CodeIgniter\Session\Handlers\MemcachedHandler` * - `CodeIgniter\Session\Handlers\RedisHandler` * - * @phpstan-var class-string + * @var class-string */ public string $driver = FileHandler::class; diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php index f24e98fb9a49..98d83b0ed3a6 100644 --- a/app/Views/errors/cli/error_exception.php +++ b/app/Views/errors/cli/error_exception.php @@ -3,17 +3,26 @@ use CodeIgniter\CLI\CLI; // The main Exception -CLI::newLine(); CLI::write('[' . get_class($exception) . ']', 'light_gray', 'red'); -CLI::newLine(); CLI::write($message); -CLI::newLine(); CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green')); CLI::newLine(); +$last = $exception; + +while ($prevException = $last->getPrevious()) { + $last = $prevException; + + CLI::write(' Caused by:'); + CLI::write(' [' . get_class($prevException) . ']', 'red'); + CLI::write(' ' . $prevException->getMessage()); + CLI::write(' at ' . CLI::color(clean_path($prevException->getFile()) . ':' . $prevException->getLine(), 'green')); + CLI::newLine(); +} + // The backtrace if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) { - $backtraces = $exception->getTrace(); + $backtraces = $last->getTrace(); if ($backtraces) { CLI::write('Backtrace:', 'green'); diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php index 1c094d728872..406b48ec6772 100644 --- a/app/Views/errors/html/error_exception.php +++ b/app/Views/errors/html/error_exception.php @@ -44,6 +44,29 @@ +
+ getPrevious()) { + $last = $prevException; + ?> + +
+    Caused by:
+    getCode() ? ' #' . $prevException->getCode() : '') ?>
+
+    getMessage())) ?>
+    getMessage())) ?>"
+       rel="noreferrer" target="_blank">search →
+    getFile()) . ':' . $prevException->getLine()) ?>
+    
+ + +
+
diff --git a/changelogs/CHANGELOG_4.3.md b/changelogs/CHANGELOG_4.3.md index 94a007bcc8f6..fdeefbd5fde9 100644 --- a/changelogs/CHANGELOG_4.3.md +++ b/changelogs/CHANGELOG_4.3.md @@ -230,7 +230,7 @@ * fix: ResponseInterface (1) by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/6556 * Improve BaseConnection::getForeignKeyData() and Forge::addForeignKey() by @sclubricants in https://github.com/codeigniter4/CodeIgniter4/pull/6468 * Refactor BaseBuilder *Batch() Methods by @sclubricants in https://github.com/codeigniter4/CodeIgniter4/pull/6536 -* refactor: remove `type="text/javascript"` in
diff --git a/system/Email/Email.php b/system/Email/Email.php index a6ad2d993204..d18b40ff7cef 100644 --- a/system/Email/Email.php +++ b/system/Email/Email.php @@ -71,7 +71,7 @@ class Email public $protocol = 'mail'; /** - * STMP Server host + * STMP Server Hostname * * @var string */ @@ -352,8 +352,7 @@ class Email * Character sets valid for 7-bit encoding, * excluding language suffix. * - * @var array - * @phpstan-var list + * @var list */ protected $baseCharsets = [ 'us-ascii', @@ -732,7 +731,7 @@ public function setHeader($header, $value) } /** - * @param string $email + * @param array|string $email * * @return array */ @@ -1237,13 +1236,13 @@ protected function buildMessage() . $this->prepQuotedPrintable($this->body) . $this->newline . $this->newline . '--' . $altBoundary . '--' . $this->newline . $this->newline; - if (! empty($relBoundary)) { + if (isset($relBoundary)) { $body .= $this->newline . $this->newline; $this->appendAttachments($body, $relBoundary, 'related'); } // multipart/mixed attachments - if (! empty($atcBoundary)) { + if (isset($atcBoundary)) { $body .= $this->newline . $this->newline; $this->appendAttachments($body, $atcBoundary, 'mixed'); } diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 65898c012dc9..0e751b684843 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -55,8 +55,7 @@ class Entity implements JsonSerializable /** * The date fields. * - * @var array - * @phpstan-var list + * @var list */ protected $dates = [ 'created_at', @@ -320,7 +319,7 @@ public function setAttributes(array $data) */ protected function mapProperty(string $key) { - if (empty($this->datamap)) { + if ($this->datamap === []) { return $key; } diff --git a/system/Exceptions/FrameworkException.php b/system/Exceptions/FrameworkException.php index 4cafd71177e2..faf3f1480126 100644 --- a/system/Exceptions/FrameworkException.php +++ b/system/Exceptions/FrameworkException.php @@ -66,7 +66,7 @@ public static function forMissingExtension(string $extension) 'The framework needs the following extension(s) installed and loaded: %s.', $extension ); - // @codeCoverageIgnoreEnd + // @codeCoverageIgnoreEnd } else { $message = lang('Core.missingExtension', [$extension]); } diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php index df27e3f6cee3..18001b103844 100644 --- a/system/Filters/Filters.php +++ b/system/Filters/Filters.php @@ -87,16 +87,14 @@ class Filters /** * Any arguments to be passed to filters. * - * @var array|null> [name => params] - * @phpstan-var array|null> + * @var array|null> [name => params] */ protected $arguments = []; /** * Any arguments to be passed to filtersClass. * - * @var array [classname => arguments] - * @phpstan-var array>|null> + * @var array>|null> [classname => arguments] */ protected $argumentsClass = []; @@ -373,8 +371,7 @@ public function enableFilter(string $name, string $when = 'before') * * @param string $name filter_name or filter_name:arguments like 'role:admin,manager' * - * @return array [name, arguments] - * @phpstan-return array{0: string, 1: list} + * @return array{0: string, 1: list} [name, arguments] */ private function getCleanName(string $name): array { diff --git a/system/HTTP/CLIRequest.php b/system/HTTP/CLIRequest.php index 878e8a1d66c6..01823dbfc4c5 100644 --- a/system/HTTP/CLIRequest.php +++ b/system/HTTP/CLIRequest.php @@ -95,7 +95,7 @@ public function getPath(): string { $path = implode('/', $this->segments); - return empty($path) ? '' : $path; + return ($path === '') ? '' : $path; } /** @@ -147,7 +147,7 @@ public function getOption(string $key) */ public function getOptionString(bool $useLongOpts = false): string { - if (empty($this->options)) { + if ($this->options === []) { return ''; } diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php index c8b3b9fe9f92..500b425d2dc5 100644 --- a/system/HTTP/CURLRequest.php +++ b/system/HTTP/CURLRequest.php @@ -549,16 +549,18 @@ protected function setCURLOptions(array $curlOptions = [], array $config = []) // SSL Verification if (isset($config['verify'])) { if (is_string($config['verify'])) { - $file = realpath($config['ssl_key']) ?: $config['ssl_key']; + $file = realpath($config['verify']) ?: $config['verify']; if (! is_file($file)) { - throw HTTPException::forInvalidSSLKey($config['ssl_key']); + throw HTTPException::forInvalidSSLKey($config['verify']); } $curlOptions[CURLOPT_CAINFO] = $file; - $curlOptions[CURLOPT_SSL_VERIFYPEER] = 1; + $curlOptions[CURLOPT_SSL_VERIFYPEER] = true; + $curlOptions[CURLOPT_SSL_VERIFYHOST] = 2; } elseif (is_bool($config['verify'])) { $curlOptions[CURLOPT_SSL_VERIFYPEER] = $config['verify']; + $curlOptions[CURLOPT_SSL_VERIFYHOST] = $config['verify'] ? 2 : 0; } } diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index 37b0ce650ff7..f4970bf7c544 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -790,7 +790,7 @@ protected function addToHeader(string $name, $values = null) $reportSources = []; foreach ($values as $value => $reportOnly) { - if (is_numeric($value) && is_string($reportOnly) && ! empty($reportOnly)) { + if (is_numeric($value) && is_string($reportOnly) && ($reportOnly !== '')) { $value = $reportOnly; $reportOnly = $this->reportOnly; } @@ -806,11 +806,11 @@ protected function addToHeader(string $name, $values = null) } } - if (! empty($sources)) { + if ($sources !== []) { $this->tempHeaders[$name] = implode(' ', $sources); } - if (! empty($reportSources)) { + if ($reportSources !== []) { $this->reportOnlyHeaders[$name] = implode(' ', $reportSources); } } diff --git a/system/HTTP/Exceptions/HTTPException.php b/system/HTTP/Exceptions/HTTPException.php index d22c48bcb9f3..3fcfe73fa674 100644 --- a/system/HTTP/Exceptions/HTTPException.php +++ b/system/HTTP/Exceptions/HTTPException.php @@ -72,6 +72,19 @@ public static function forInvalidNegotiationType(string $type) return new static(lang('HTTP.invalidNegotiationType', [$type])); } + /** + * Thrown in IncomingRequest when the json_decode() produces + * an error code other than JSON_ERROR_NONE. + * + * @param string $error The error message + * + * @return static + */ + public static function forInvalidJSON(?string $error = null) + { + return new static(lang('HTTP.invalidJSON', [$error])); + } + /** * For Message * @@ -215,4 +228,15 @@ public static function forInvalidSameSiteSetting(string $samesite) { return new static(lang('Security.invalidSameSiteSetting', [$samesite])); } + + /** + * Thrown when the JSON format is not supported. + * This is specifically for cases where data validation is expected to work with key-value structures. + * + * @return HTTPException + */ + public static function forUnsupportedJSONFormat() + { + return new static(lang('HTTP.unsupportedJSONFormat')); + } } diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php index f01cc69f5902..124381ec33bb 100644 --- a/system/HTTP/Files/FileCollection.php +++ b/system/HTTP/Files/FileCollection.php @@ -77,7 +77,7 @@ public function getFile(string $name) /** * Verify if a file exist in the collection of uploaded files and is have been uploaded with multiple option. * - * @return array|null + * @return list|null */ public function getFileMultiple(string $name) { @@ -148,7 +148,7 @@ protected function populateFiles() $this->files = []; - if (empty($_FILES)) { + if ($_FILES === []) { return; } @@ -245,7 +245,7 @@ protected function fixFilesArray(array $data): array * @param array $index The index sequence we are navigating down * @param array $value The portion of the array to process * - * @return UploadedFile|null + * @return list|UploadedFile|null */ protected function getValueDotNotationSyntax(array $index, array $value) { diff --git a/system/HTTP/IncomingRequest.php b/system/HTTP/IncomingRequest.php index 079a3b69d02f..8bc246f7956d 100755 --- a/system/HTTP/IncomingRequest.php +++ b/system/HTTP/IncomingRequest.php @@ -152,7 +152,7 @@ class IncomingRequest extends Request */ public function __construct($config, ?URI $uri = null, $body = 'php://input', ?UserAgent $userAgent = null) { - if (empty($uri) || empty($userAgent)) { + if (! $uri instanceof URI || ! $userAgent instanceof UserAgent) { throw new InvalidArgumentException('You must supply the parameters: uri, userAgent.'); } @@ -169,9 +169,14 @@ public function __construct($config, ?URI $uri = null, $body = 'php://input', ?U $body = file_get_contents('php://input'); } + // If file_get_contents() returns false or empty string, set null. + if ($body === false || $body === '') { + $body = null; + } + $this->config = $config; $this->uri = $uri; - $this->body = ! empty($body) ? $body : null; + $this->body = $body; $this->userAgent = $userAgent; $this->validLocales = $config->supportedLocales; @@ -251,7 +256,7 @@ protected function detectURI(string $protocol, string $baseURL) */ public function detectPath(string $protocol = ''): string { - if (empty($protocol)) { + if ($protocol === '') { $protocol = 'REQUEST_URI'; } @@ -568,10 +573,22 @@ public function getVar($index = null, $filter = null, $flags = null) * @see http://php.net/manual/en/function.json-decode.php * * @return array|bool|float|int|stdClass|null + * + * @throws HTTPException When the body is invalid as JSON. */ public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0) { - return json_decode($this->body ?? '', $assoc, $depth, $options); + if ($this->body === null) { + return null; + } + + $result = json_decode($this->body, $assoc, $depth, $options); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw HTTPException::forInvalidJSON(json_last_error_msg()); + } + + return $result; } /** diff --git a/system/HTTP/Negotiate.php b/system/HTTP/Negotiate.php index b1d5fdfa93a3..9c903908695f 100644 --- a/system/HTTP/Negotiate.php +++ b/system/HTTP/Negotiate.php @@ -93,7 +93,7 @@ public function charset(array $supported): string // If no charset is shown as a match, ignore the directive // as allowed by the RFC, and tell it a default value. - if (empty($match)) { + if ($match === '') { return 'utf-8'; } @@ -154,11 +154,11 @@ protected function getBestMatch( bool $strictMatch = false, bool $matchLocales = false ): string { - if (empty($supported)) { + if ($supported === []) { throw HTTPException::forEmptySupportedNegotiations(); } - if (empty($header)) { + if ($header === null || $header === '') { return $strictMatch ? '' : $supported[0]; } diff --git a/system/HTTP/RequestTrait.php b/system/HTTP/RequestTrait.php index 52ffa812a315..6db903ddacec 100644 --- a/system/HTTP/RequestTrait.php +++ b/system/HTTP/RequestTrait.php @@ -35,10 +35,9 @@ trait RequestTrait protected $ipAddress = ''; /** - * Stores values we've retrieved from - * PHP globals. + * Stores values we've retrieved from PHP globals. * - * @var array + * @var array{get?: array, post?: array, request?: array, cookie?: array, server?: array} */ protected $globals = []; @@ -204,22 +203,27 @@ public function getServer($index = null, $filter = null, $flags = null) * @param array|int|null $flags * * @return mixed + * + * @deprecated 4.4.4 This method does not work from the beginning. Use `env()`. */ public function getEnv($index = null, $filter = null, $flags = null) { + // @phpstan-ignore-next-line return $this->fetchGlobal('env', $index, $filter, $flags); } /** * Allows manually setting the value of PHP global, like $_GET, $_POST, etc. * + * @param string $name Supergrlobal name (lowercase) + * @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name * @param mixed $value * * @return $this */ - public function setGlobal(string $method, $value) + public function setGlobal(string $name, $value) { - $this->globals[$method] = $value; + $this->globals[$name] = $value; return $this; } @@ -234,19 +238,18 @@ public function setGlobal(string $method, $value) * * http://php.net/manual/en/filter.filters.sanitize.php * - * @param string $method Input filter constant + * @param string $name Supergrlobal name (lowercase) + * @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name * @param array|string|null $index * @param int|null $filter Filter constant * @param array|int|null $flags Options * * @return array|bool|float|int|object|string|null */ - public function fetchGlobal(string $method, $index = null, ?int $filter = null, $flags = null) + public function fetchGlobal(string $name, $index = null, ?int $filter = null, $flags = null) { - $method = strtolower($method); - - if (! isset($this->globals[$method])) { - $this->populateGlobals($method); + if (! isset($this->globals[$name])) { + $this->populateGlobals($name); } // Null filters cause null values to return. @@ -257,9 +260,9 @@ public function fetchGlobal(string $method, $index = null, ?int $filter = null, if ($index === null) { $values = []; - foreach ($this->globals[$method] as $key => $value) { + foreach ($this->globals[$name] as $key => $value) { $values[$key] = is_array($value) - ? $this->fetchGlobal($method, $key, $filter, $flags) + ? $this->fetchGlobal($name, $key, $filter, $flags) : filter_var($value, $filter, $flags); } @@ -271,7 +274,7 @@ public function fetchGlobal(string $method, $index = null, ?int $filter = null, $output = []; foreach ($index as $key) { - $output[$key] = $this->fetchGlobal($method, $key, $filter, $flags); + $output[$key] = $this->fetchGlobal($name, $key, $filter, $flags); } return $output; @@ -279,7 +282,7 @@ public function fetchGlobal(string $method, $index = null, ?int $filter = null, // Does the index contain array notation? if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) { - $value = $this->globals[$method]; + $value = $this->globals[$name]; for ($i = 0; $i < $count; $i++) { $key = trim($matches[0][$i], '[]'); @@ -297,7 +300,7 @@ public function fetchGlobal(string $method, $index = null, ?int $filter = null, } if (! isset($value)) { - $value = $this->globals[$method][$index] ?? null; + $value = $this->globals[$name][$index] ?? null; } if (is_array($value) @@ -326,20 +329,23 @@ public function fetchGlobal(string $method, $index = null, ?int $filter = null, } /** - * Saves a copy of the current state of one of several PHP globals + * Saves a copy of the current state of one of several PHP globals, * so we can retrieve them later. * + * @param string $name Superglobal name (lowercase) + * @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name + * * @return void */ - protected function populateGlobals(string $method) + protected function populateGlobals(string $name) { - if (! isset($this->globals[$method])) { - $this->globals[$method] = []; + if (! isset($this->globals[$name])) { + $this->globals[$name] = []; } // Don't populate ENV as it might contain // sensitive data that we don't want to get logged. - switch ($method) { + switch ($name) { case 'get': $this->globals['get'] = $_GET; break; diff --git a/system/HTTP/ResponseInterface.php b/system/HTTP/ResponseInterface.php index 878d1488c25d..a6d41c77be3c 100644 --- a/system/HTTP/ResponseInterface.php +++ b/system/HTTP/ResponseInterface.php @@ -110,8 +110,6 @@ interface ResponseInterface extends MessageInterface * to understand and satisfy the request. * * @return int Status code. - * - * @deprecated To be replaced by the PSR-7 version (compatible) */ public function getStatusCode(): int; diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php index 7c0741317bc0..b385bfea45de 100644 --- a/system/HTTP/ResponseTrait.php +++ b/system/HTTP/ResponseTrait.php @@ -156,13 +156,13 @@ public function setStatusCode(int $code, string $reason = '') } // Unknown and no message? - if (! array_key_exists($code, static::$statusCodes) && empty($reason)) { + if (! array_key_exists($code, static::$statusCodes) && ($reason === '')) { throw HTTPException::forUnkownStatusCode($code); } $this->statusCode = $code; - $this->reason = ! empty($reason) ? $reason : static::$statusCodes[$code]; + $this->reason = ($reason !== '') ? $reason : static::$statusCodes[$code]; return $this; } @@ -226,7 +226,7 @@ public function setLink(PagerInterface $pager) public function setContentType(string $mime, string $charset = 'UTF-8') { // add charset attribute if not already there and provided as parm - if ((strpos($mime, 'charset=') < 1) && ! empty($charset)) { + if ((strpos($mime, 'charset=') < 1) && ($charset !== '')) { $mime .= '; charset=' . $charset; } @@ -377,7 +377,7 @@ public function noCache() */ public function setCache(array $options = []) { - if (empty($options)) { + if ($options === []) { return $this; } diff --git a/system/HTTP/SiteURI.php b/system/HTTP/SiteURI.php index d01f614a1c85..6d56507314e7 100644 --- a/system/HTTP/SiteURI.php +++ b/system/HTTP/SiteURI.php @@ -197,7 +197,7 @@ private function normalizeBaseURL(App $configApp): string // Validate baseURL if (filter_var($baseURL, FILTER_VALIDATE_URL) === false) { throw new ConfigException( - 'Config\App::$baseURL is invalid.' + 'Config\App::$baseURL "' . $baseURL . '" is not a valid URL.' ); } diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index 608f8b75d5ba..5bec38013bf2 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -163,11 +163,11 @@ public static function createURIString( ?string $fragment = null ): string { $uri = ''; - if (! empty($scheme)) { + if ($scheme !== null && $scheme !== '') { $uri .= $scheme . '://'; } - if (! empty($authority)) { + if ($authority !== null && $authority !== '') { $uri .= $authority; } @@ -886,7 +886,7 @@ public function setQuery(string $query) } // Can't have leading ? - if (! empty($query) && strpos($query, '?') === 0) { + if ($query !== '' && strpos($query, '?') === 0) { $query = substr($query, 1); } @@ -1097,7 +1097,7 @@ public function resolveRelativeURI(string $uri) $transformed = clone $relative; // 5.2.2 Transform References in a non-strict method (no scheme) - if (! empty($relative->getAuthority())) { + if ($relative->getAuthority() !== '') { $transformed ->setAuthority($relative->getAuthority()) ->setPath($relative->getPath()) @@ -1139,7 +1139,7 @@ public function resolveRelativeURI(string $uri) */ protected function mergePaths(self $base, self $reference): string { - if (! empty($base->getAuthority()) && $base->getPath() === '') { + if ($base->getAuthority() !== '' && $base->getPath() === '') { return '/' . ltrim($reference->getPath(), '/ '); } diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php index 77e7cb4392fc..2294b02a2b48 100644 --- a/system/HTTP/UserAgent.php +++ b/system/HTTP/UserAgent.php @@ -260,7 +260,7 @@ public function parse(string $string) // Set the new user-agent string and parse it, unless empty $this->agent = $string; - if (! empty($string)) { + if ($string !== '') { $this->compileData(); } } diff --git a/system/Helpers/array_helper.php b/system/Helpers/array_helper.php index 65645c3cc316..b8bd1a4d956f 100644 --- a/system/Helpers/array_helper.php +++ b/system/Helpers/array_helper.php @@ -85,7 +85,7 @@ function _array_search_dot(array $indexes, array $array) // If this is the last index, make sure to return it now, // and not try to recurse through things. - if (empty($indexes)) { + if ($indexes === []) { return $array[$currentIndex]; } @@ -152,7 +152,7 @@ function array_deep_search($key, array $array) function array_sort_by_multiple_keys(array &$array, array $sortColumns): bool { // Check if there really are columns to sort after - if (empty($sortColumns) || empty($array)) { + if ($sortColumns === [] || $array === []) { return false; } diff --git a/system/Helpers/date_helper.php b/system/Helpers/date_helper.php index ba9c9a249455..cf1dc33a74ea 100644 --- a/system/Helpers/date_helper.php +++ b/system/Helpers/date_helper.php @@ -20,11 +20,13 @@ * Returns Time::now()->getTimestamp() based on the timezone parameter or on the * app_timezone() setting * + * @param non-empty-string|null $timezone + * * @throws Exception */ function now(?string $timezone = null): int { - $timezone = empty($timezone) ? app_timezone() : $timezone; + $timezone = ($timezone === null || $timezone === '') ? app_timezone() : $timezone; if ($timezone === 'local' || $timezone === date_default_timezone_get()) { return Time::now()->getTimestamp(); diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php index 47c829bbc3c6..4e0e8b1532e9 100644 --- a/system/Helpers/filesystem_helper.php +++ b/system/Helpers/filesystem_helper.php @@ -209,7 +209,7 @@ function get_filenames( try { foreach (new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS), + new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS), RecursiveIteratorIterator::SELF_FIRST ) as $name => $object) { $basename = pathinfo($name, PATHINFO_BASENAME); diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php index 7edb05cf1de3..d3abd7e247b0 100644 --- a/system/Helpers/form_helper.php +++ b/system/Helpers/form_helper.php @@ -288,7 +288,7 @@ function form_dropdown($data = '', $options = [], $selected = [], $extra = ''): } // If no selected state was submitted we will attempt to set it automatically - if (empty($selected)) { + if ($selected === []) { if (is_array($data)) { if (isset($data['name'], $_POST[$data['name']])) { $selected = [$_POST[$data['name']]]; @@ -312,7 +312,7 @@ function form_dropdown($data = '', $options = [], $selected = [], $extra = ''): $key = (string) $key; if (is_array($val)) { - if (empty($val)) { + if ($val === []) { continue; } @@ -784,7 +784,7 @@ function parse_form_attributes($attributes, array $default): string unset($attributes[$key]); } } - if (! empty($attributes)) { + if ($attributes !== []) { $default = array_merge($default, $attributes); } } diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php index c7a36e270860..075dcd510b43 100755 --- a/system/Helpers/html_helper.php +++ b/system/Helpers/html_helper.php @@ -313,7 +313,7 @@ function video($src, string $unsupportedMessage = '', string $attributes = '', a $video .= _space_indent() . $track . "\n"; } - if (! empty($unsupportedMessage)) { + if ($unsupportedMessage !== '') { $video .= _space_indent() . $unsupportedMessage . "\n"; @@ -359,7 +359,7 @@ function audio($src, string $unsupportedMessage = '', string $attributes = '', a $audio .= "\n" . _space_indent() . $track; } - if (! empty($unsupportedMessage)) { + if ($unsupportedMessage !== '') { $audio .= "\n" . _space_indent() . $unsupportedMessage . "\n"; } @@ -377,7 +377,7 @@ function _media(string $name, array $types = [], string $unsupportedMessage = '' { $media = '<' . $name; - if (empty($attributes)) { + if ($attributes === '') { $media .= '>'; } else { $media .= ' ' . $attributes . '>'; @@ -393,7 +393,7 @@ function _media(string $name, array $types = [], string $unsupportedMessage = '' $media .= _space_indent() . $track . "\n"; } - if (! empty($unsupportedMessage)) { + if ($unsupportedMessage !== '') { $media .= _space_indent() . $unsupportedMessage . "\n"; } @@ -421,7 +421,7 @@ function source(string $src, string $type = 'unknown', string $attributes = '', $source = ''; - if (! empty($params)) { + if ($params !== []) { $object .= "\n"; } diff --git a/system/Helpers/kint_helper.php b/system/Helpers/kint_helper.php index eaa2e947bc96..4221573a2ce6 100644 --- a/system/Helpers/kint_helper.php +++ b/system/Helpers/kint_helper.php @@ -18,7 +18,7 @@ * * @param array $vars * - * @phpstan-return never + * @return never * * @codeCoverageIgnore Can't be tested ... exits */ diff --git a/system/Helpers/number_helper.php b/system/Helpers/number_helper.php index 74173501e177..8ca5d3e2320f 100644 --- a/system/Helpers/number_helper.php +++ b/system/Helpers/number_helper.php @@ -15,7 +15,8 @@ /** * Formats a numbers as bytes, based on size, and adds the appropriate suffix * - * @param int|string $num Will be cast as int + * @param int|string $num Will be cast as int + * @param non-empty-string|null $locale [optional] * * @return bool|string */ @@ -32,7 +33,7 @@ function number_to_size($num, int $precision = 1, ?string $locale = null) // ignore sub part $generalLocale = $locale; - if (! empty($locale) && ($underscorePos = strpos($locale, '_'))) { + if ($locale !== null && $locale !== '' && ($underscorePos = strpos($locale, '_'))) { $generalLocale = substr($locale, 0, $underscorePos); } @@ -68,9 +69,9 @@ function number_to_size($num, int $precision = 1, ?string $locale = null) * * @see https://simple.wikipedia.org/wiki/Names_for_large_numbers * - * @param int|string $num Will be cast as int - * @param int $precision [optional] The optional number of decimal digits to round to. - * @param string|null $locale [optional] + * @param int|string $num Will be cast as int + * @param int $precision [optional] The optional number of decimal digits to round to. + * @param non-empty-string|null $locale [optional] * * @return bool|string */ @@ -88,7 +89,7 @@ function number_to_amount($num, int $precision = 0, ?string $locale = null) // ignore sub part $generalLocale = $locale; - if (! empty($locale) && ($underscorePos = strpos($locale, '_'))) { + if ($locale !== null && $locale !== '' && ($underscorePos = strpos($locale, '_'))) { $generalLocale = substr($locale, 0, $underscorePos); } diff --git a/system/Helpers/text_helper.php b/system/Helpers/text_helper.php index 56cf856fbda7..9c8f7be07ec2 100755 --- a/system/Helpers/text_helper.php +++ b/system/Helpers/text_helper.php @@ -98,7 +98,7 @@ function ascii_to_entities(string $str): string $out .= $str[$i]; } else { - if (empty($temp)) { + if ($temp === []) { $count = ($ordinal < 224) ? 2 : 3; } @@ -172,7 +172,7 @@ function entities_to_ascii(string $str, bool $all = true): string */ function word_censor(string $str, array $censored, string $replacement = ''): string { - if (empty($censored)) { + if ($censored === []) { return $str; } diff --git a/system/Helpers/url_helper.php b/system/Helpers/url_helper.php index 27e3ce1d079f..8099558aa343 100644 --- a/system/Helpers/url_helper.php +++ b/system/Helpers/url_helper.php @@ -290,7 +290,7 @@ function safe_mailto(string $email, string $title = '', $attributes = ''): strin if ($ordinal < 128) { $x[] = '|' . $ordinal; } else { - if (empty($temp)) { + if ($temp === []) { $count = ($ordinal < 224) ? 2 : 3; } diff --git a/system/Honeypot/Honeypot.php b/system/Honeypot/Honeypot.php index 82da90020cac..c0998c475bbc 100644 --- a/system/Honeypot/Honeypot.php +++ b/system/Honeypot/Honeypot.php @@ -44,7 +44,7 @@ public function __construct(HoneypotConfig $config) throw HoneypotException::forNoHiddenValue(); } - if (empty($this->config->container) || strpos($this->config->container, '{template}') === false) { + if ($this->config->container === '' || strpos($this->config->container, '{template}') === false) { $this->config->container = '
{template}
'; } @@ -78,6 +78,10 @@ public function hasContent(RequestInterface $request) */ public function attachHoneypot(ResponseInterface $response) { + if ($response->getBody() === null) { + return; + } + if ($response->getCSP()->enabled()) { // Add id attribute to the container tag. $this->config->container = str_ireplace( diff --git a/system/HotReloader/HotReloader.php b/system/HotReloader/HotReloader.php index 564ba544283a..579bcd4ac598 100644 --- a/system/HotReloader/HotReloader.php +++ b/system/HotReloader/HotReloader.php @@ -18,6 +18,10 @@ final class HotReloader { public function run(): void { + if (session_status() === PHP_SESSION_ACTIVE) { + session_write_close(); + } + ini_set('zlib.output_compression', 'Off'); header('Cache-Control: no-store'); diff --git a/system/I18n/Time.php b/system/I18n/Time.php index 520f38eb90d1..f01718aac6e0 100644 --- a/system/I18n/Time.php +++ b/system/I18n/Time.php @@ -19,7 +19,23 @@ * * Requires the intl PHP extension. * - * @property string $date + * @property int $age read-only + * @property string $day read-only + * @property string $dayOfWeek read-only + * @property string $dayOfYear read-only + * @property bool $dst read-only + * @property string $hour read-only + * @property bool $local read-only + * @property string $minute read-only + * @property string $month read-only + * @property string $quarter read-only + * @property string $second read-only + * @property int $timestamp read-only + * @property bool $utc read-only + * @property string $weekOfMonth read-only + * @property string $weekOfYear read-only + * @property string $year read-only + * * @see \CodeIgniter\I18n\TimeTest */ class Time extends DateTimeImmutable diff --git a/system/I18n/TimeLegacy.php b/system/I18n/TimeLegacy.php index 7be9f80fac20..35523e322475 100644 --- a/system/I18n/TimeLegacy.php +++ b/system/I18n/TimeLegacy.php @@ -20,7 +20,22 @@ * This is not immutable! Some methods are immutable, * but some methods can alter the state. * - * @property string $date + * @property int $age read-only + * @property string $day read-only + * @property string $dayOfWeek read-only + * @property string $dayOfYear read-only + * @property bool $dst read-only + * @property string $hour read-only + * @property bool $local read-only + * @property string $minute read-only + * @property string $month read-only + * @property string $quarter read-only + * @property string $second read-only + * @property int $timestamp read-only + * @property bool $utc read-only + * @property string $weekOfMonth read-only + * @property string $weekOfYear read-only + * @property string $year read-only * * @deprecated Use Time instead. * @see \CodeIgniter\I18n\TimeLegacyTest diff --git a/system/I18n/TimeTrait.php b/system/I18n/TimeTrait.php index 7f2068b7a30c..93f03d8a84bd 100644 --- a/system/I18n/TimeTrait.php +++ b/system/I18n/TimeTrait.php @@ -212,14 +212,22 @@ public static function createFromTime(?int $hour = null, ?int $minutes = null, ? * * @throws Exception */ - public static function create(?int $year = null, ?int $month = null, ?int $day = null, ?int $hour = null, ?int $minutes = null, ?int $seconds = null, $timezone = null, ?string $locale = null) - { + public static function create( + ?int $year = null, + ?int $month = null, + ?int $day = null, + ?int $hour = null, + ?int $minutes = null, + ?int $seconds = null, + $timezone = null, + ?string $locale = null + ) { $year ??= date('Y'); $month ??= date('m'); $day ??= date('d'); - $hour = empty($hour) ? 0 : $hour; - $minutes = empty($minutes) ? 0 : $minutes; - $seconds = empty($seconds) ? 0 : $seconds; + $hour ??= 0; + $minutes ??= 0; + $seconds ??= 0; return new self(date('Y-m-d H:i:s', strtotime("{$year}-{$month}-{$day} {$hour}:{$minutes}:{$seconds}")), $timezone, $locale); } @@ -1182,6 +1190,8 @@ public function __wakeup(): void $timezone = $this->timezone; $this->timezone = new DateTimeZone($timezone); + + // @phpstan-ignore-next-line `$this->date` is a special property for PHP internal use. parent::__construct($this->date, $this->timezone); } } diff --git a/system/Images/Handlers/BaseHandler.php b/system/Images/Handlers/BaseHandler.php index cf23fd0fcd23..92644eede3db 100644 --- a/system/Images/Handlers/BaseHandler.php +++ b/system/Images/Handlers/BaseHandler.php @@ -691,6 +691,8 @@ abstract public function getVersion(); * $image->resize(100, 200, true) * ->save($target); * + * @param non-empty-string|null $target + * * @return bool */ abstract public function save(?string $target = null, int $quality = 90); diff --git a/system/Images/Handlers/GDHandler.php b/system/Images/Handlers/GDHandler.php index 15bb97b6b839..f2cd55874044 100644 --- a/system/Images/Handlers/GDHandler.php +++ b/system/Images/Handlers/GDHandler.php @@ -204,11 +204,13 @@ protected function process(string $action) * Example: * $image->resize(100, 200, true) * ->save(); + * + * @param non-empty-string|null $target */ public function save(?string $target = null, int $quality = 90): bool { $original = $target; - $target = empty($target) ? $this->image()->getPathname() : $target; + $target = ($target === null || $target === '') ? $this->image()->getPathname() : $target; // If no new resource has been created, then we're // simply copy the existing one. @@ -227,6 +229,7 @@ public function save(?string $target = null, int $quality = 90): bool // for png and webp we can actually preserve transparency if (in_array($this->image()->imageType, $this->supportTransparency, true)) { + imagepalettetotruecolor($this->resource); imagealphablending($this->resource, false); imagesavealpha($this->resource, true); } diff --git a/system/Images/Handlers/ImageMagickHandler.php b/system/Images/Handlers/ImageMagickHandler.php index 857a273d5372..7dd5e5d755ee 100644 --- a/system/Images/Handlers/ImageMagickHandler.php +++ b/system/Images/Handlers/ImageMagickHandler.php @@ -223,11 +223,13 @@ protected function process(string $action, int $quality = 100): array * Example: * $image->resize(100, 200, true) * ->save(); + * + * @param non-empty-string|null $target */ public function save(?string $target = null, int $quality = 90): bool { $original = $target; - $target = empty($target) ? $this->image()->getPathname() : $target; + $target = ($target === null || $target === '') ? $this->image()->getPathname() : $target; // If no new resource has been created, then we're // simply copy the existing one. diff --git a/system/Images/ImageHandlerInterface.php b/system/Images/ImageHandlerInterface.php index 1c3593a99bd4..76a016b08918 100644 --- a/system/Images/ImageHandlerInterface.php +++ b/system/Images/ImageHandlerInterface.php @@ -132,7 +132,7 @@ public function text(string $text, array $options = []); * $image->resize(100, 200, true) * ->save($target); * - * @param string|null $target The path to save the file to. + * @param non-empty-string|null $target The path to save the file to. * * @return bool */ diff --git a/system/Language/Language.php b/system/Language/Language.php index 32eee39f2a13..8633f8a2dd9c 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -88,7 +88,7 @@ public function getLocale(): string * Parses the language string for a file, loads the file, if necessary, * getting the line. * - * @return string|string[] + * @return list|string */ public function getLine(string $line, array $args = []) { diff --git a/system/Language/en/HTTP.php b/system/Language/en/HTTP.php index a7861c7188d1..ee5ca4f81f46 100644 --- a/system/Language/en/HTTP.php +++ b/system/Language/en/HTTP.php @@ -19,6 +19,8 @@ // IncomingRequest 'invalidNegotiationType' => '"{0}" is not a valid negotiation type. Must be one of: media, charset, encoding, language.', + 'invalidJSON' => 'Failed to parse JSON string. Error: {0}', + 'unsupportedJSONFormat' => 'The provided JSON format is not supported.', // Message 'invalidHTTPProtocol' => 'Invalid HTTP Protocol Version: {0}', diff --git a/system/Log/Logger.php b/system/Log/Logger.php index afd703147870..e5f482cb63d2 100644 --- a/system/Log/Logger.php +++ b/system/Log/Logger.php @@ -93,8 +93,7 @@ class Logger implements LoggerInterface * value is an associative array of configuration * items. * - * @var array - * @phpstan-var array|string|int>> + * @var array|string>> */ protected $handlerConfig = []; @@ -138,7 +137,7 @@ public function __construct($config, bool $debug = CI_DEBUG) $this->dateFormat = $config->dateFormat ?? $this->dateFormat; - if (! is_array($config->handlers) || empty($config->handlers)) { + if (! is_array($config->handlers) || $config->handlers === []) { throw LogException::forNoHandlers('LoggerConfig'); } diff --git a/system/Model.php b/system/Model.php index e53c0aae4bd1..5dba810c8c59 100644 --- a/system/Model.php +++ b/system/Model.php @@ -84,6 +84,8 @@ * @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) + * + * @phpstan-import-type row_array from BaseModel */ class Model extends BaseModel { @@ -178,6 +180,7 @@ public function setTable(string $table) * @param array|int|string|null $id One primary key or an array of primary keys * * @return array|object|null The resulting row of data, or null. + * @phpstan-return ($singleton is true ? row_array|null|object : list) */ protected function doFind(bool $singleton, $id = null) { @@ -209,6 +212,7 @@ protected function doFind(bool $singleton, $id = null) * @param string $columnName Column Name * * @return array|null The resulting row of data, or null if no data found. + * @phpstan-return list|null */ protected function doFindColumn(string $columnName) { @@ -224,6 +228,7 @@ protected function doFindColumn(string $columnName) * @param int $offset Offset * * @return array + * @phpstan-return list */ protected function doFindAll(int $limit = 0, int $offset = 0) { @@ -244,6 +249,7 @@ protected function doFindAll(int $limit = 0, int $offset = 0) * This method works only with dbCalls. * * @return array|object|null + * @phpstan-return row_array|object|null */ protected function doFirst() { @@ -251,13 +257,13 @@ protected function doFirst() if ($this->tempUseSoftDeletes) { $builder->where($this->table . '.' . $this->deletedField, null); - } elseif ($this->useSoftDeletes && empty($builder->QBGroupBy) && $this->primaryKey) { + } elseif ($this->useSoftDeletes && ($builder->QBGroupBy === []) && $this->primaryKey) { $builder->groupBy($this->table . '.' . $this->primaryKey); } // Some databases, like PostgreSQL, need order // information to consistently return correct results. - if ($builder->QBGroupBy && empty($builder->QBOrderBy) && $this->primaryKey) { + if ($builder->QBGroupBy && ($builder->QBOrderBy === []) && $this->primaryKey) { $builder->orderBy($this->table . '.' . $this->primaryKey, 'asc'); } @@ -268,29 +274,30 @@ protected function doFirst() * Inserts data into the current table. * This method works only with dbCalls. * - * @param array $data Data + * @param array $row Row data + * @phpstan-param row_array $row * * @return bool */ - protected function doInsert(array $data) + protected function doInsert(array $row) { $escape = $this->escape; $this->escape = []; // Require non-empty primaryKey when // not using auto-increment feature - if (! $this->useAutoIncrement && empty($data[$this->primaryKey])) { + if (! $this->useAutoIncrement && ! isset($row[$this->primaryKey])) { throw DataException::forEmptyPrimaryKey('insert'); } $builder = $this->builder(); // Must use the set() method to ensure to set the correct escape flag - foreach ($data as $key => $val) { + foreach ($row as $key => $val) { $builder->set($key, $val, $escape[$key] ?? null); } - if ($this->allowEmptyInserts && empty($data)) { + if ($this->allowEmptyInserts && $row === []) { $table = $this->db->protectIdentifiers($this->table, true, null, false); if ($this->db->getPlatform() === 'MySQLi') { $sql = 'INSERT INTO ' . $table . ' VALUES ()'; @@ -321,7 +328,7 @@ protected function doInsert(array $data) // If insertion succeeded then save the insert ID if ($result) { - $this->insertID = ! $this->useAutoIncrement ? $data[$this->primaryKey] : $this->db->insertID(); + $this->insertID = ! $this->useAutoIncrement ? $row[$this->primaryKey] : $this->db->insertID(); } return $result; @@ -344,7 +351,7 @@ protected function doInsertBatch(?array $set = null, ?bool $escape = null, int $ foreach ($set as $row) { // Require non-empty primaryKey when // not using auto-increment feature - if (! $this->useAutoIncrement && empty($row[$this->primaryKey])) { + if (! $this->useAutoIncrement && ! isset($row[$this->primaryKey])) { throw DataException::forEmptyPrimaryKey('insertBatch'); } } @@ -358,9 +365,10 @@ protected function doInsertBatch(?array $set = null, ?bool $escape = null, int $ * This method works only with dbCalls. * * @param array|int|string|null $id - * @param array|null $data + * @param array|null $row Row data + * @phpstan-param row_array|null $row */ - protected function doUpdate($id = null, $data = null): bool + protected function doUpdate($id = null, $row = null): bool { $escape = $this->escape; $this->escape = []; @@ -372,7 +380,7 @@ protected function doUpdate($id = null, $data = null): bool } // Must use the set() method to ensure to set the correct escape flag - foreach ($data as $key => $val) { + foreach ($row as $key => $val) { $builder->set($key, $val, $escape[$key] ?? null); } @@ -411,7 +419,7 @@ protected function doUpdateBatch(?array $set = null, ?string $index = null, int * @param array|int|string|null $id The rows primary key(s) * @param bool $purge Allows overriding the soft deletes setting. * - * @return bool|string + * @return bool|string SQL string when testMode * * @throws DatabaseException */ @@ -425,7 +433,7 @@ protected function doDelete($id = null, bool $purge = false) } if ($this->useSoftDeletes && ! $purge) { - if (empty($builder->getCompiledQBWhere())) { + if ($builder->getCompiledQBWhere() === []) { throw new DatabaseException( 'Deletes are not allowed unless they contain a "where" or "like" clause.' ); @@ -435,7 +443,7 @@ protected function doDelete($id = null, bool $purge = false) $set[$this->deletedField] = $this->setDate(); - if ($this->useTimestamps && $this->updatedField) { + if ($this->useTimestamps && $this->updatedField !== '') { $set[$this->updatedField] = $this->setDate(); } @@ -450,7 +458,7 @@ protected function doDelete($id = null, bool $purge = false) * through soft deletes (deleted = 1) * This method works only with dbCalls. * - * @return bool|string Returns a string if in test mode. + * @return bool|string Returns a SQL string if in test mode. */ protected function doPurgeDeleted() { @@ -475,14 +483,15 @@ protected function doOnlyDeleted() * Compiles a replace into string and runs the query * This method works only with dbCalls. * - * @param array|null $data Data - * @param bool $returnSQL Set to true to return Query String + * @param array|null $row Data + * @phpstan-param row_array|null $row + * @param bool $returnSQL Set to true to return Query String * * @return BaseResult|false|Query|string */ - protected function doReplace(?array $data = null, bool $returnSQL = false) + protected function doReplace(?array $row = null, bool $returnSQL = false) { - return $this->builder()->testMode($returnSQL)->replace($data); + return $this->builder()->testMode($returnSQL)->replace($row); } /** @@ -491,7 +500,7 @@ protected function doReplace(?array $data = null, bool $returnSQL = false) * ['source' => 'message'] * This method works only with dbCalls. * - * @return array + * @return array */ protected function doErrors() { @@ -522,18 +531,34 @@ protected function idValue($data) /** * Returns the id value for the data array or object * - * @param array|object $data Data + * @param array|object $row Row data + * @phpstan-param row_array|object $row * * @return array|int|string|null */ - public function getIdValue($data) + public function getIdValue($row) { - if (is_object($data) && isset($data->{$this->primaryKey})) { - return $data->{$this->primaryKey}; + if (is_object($row) && isset($row->{$this->primaryKey})) { + // Get the raw primary key value of the Entity. + if ($row instanceof Entity) { + $cast = $row->cast(); + + // Disable Entity casting, because raw primary key value is needed for database. + $row->cast(false); + + $primaryKey = $row->{$this->primaryKey}; + + // Restore Entity casting setting. + $row->cast($cast); + + return $primaryKey; + } + + return $row->{$this->primaryKey}; } - if (is_array($data) && ! empty($data[$this->primaryKey])) { - return $data[$this->primaryKey]; + if (is_array($row) && isset($row[$this->primaryKey])) { + return $row[$this->primaryKey]; } return null; @@ -566,7 +591,7 @@ public function chunk(int $size, Closure $userFunc) $offset += $size; - if (empty($rows)) { + if ($rows === []) { continue; } @@ -602,6 +627,8 @@ public function countAllResults(bool $reset = true, bool $test = false) /** * Provides a shared instance of the Query Builder. * + * @param non-empty-string|null $table + * * @return BaseBuilder * * @throws ModelException @@ -621,11 +648,11 @@ public function builder(?string $table = null) // We're going to force a primary key to exist // so we don't have overly convoluted code, // and future features are likely to require them. - if (empty($this->primaryKey)) { + if ($this->primaryKey === '') { throw ModelException::forNoPrimaryKey(static::class); } - $table = empty($table) ? $this->table : $table; + $table = ($table === null || $table === '') ? $this->table : $table; // Ensure we have a good db connection if (! $this->db instanceof BaseConnection) { @@ -670,11 +697,11 @@ public function set($key, $value = '', ?bool $escape = null) * This method is called on save to determine if entry have to be updated * If this method return false insert operation will be executed * - * @param array|object $data Data + * @param array|object $row Data */ - protected function shouldUpdate($data): bool + protected function shouldUpdate($row): bool { - if (parent::shouldUpdate($data) === false) { + if (parent::shouldUpdate($row) === false) { return false; } @@ -684,70 +711,73 @@ protected function shouldUpdate($data): bool // When useAutoIncrement feature is disabled, check // in the database if given record already exists - return $this->where($this->primaryKey, $this->getIdValue($data))->countAllResults() === 1; + return $this->where($this->primaryKey, $this->getIdValue($row))->countAllResults() === 1; } /** * Inserts data into the database. If an object is provided, * it will attempt to convert it to an array. * - * @param array|object|null $data - * @param bool $returnID Whether insert ID should be returned or not. + * @param array|object|null $row + * @phpstan-param row_array|object|null $row + * @param bool $returnID Whether insert ID should be returned or not. * - * @return BaseResult|false|int|object|string + * @return bool|int|string + * @phpstan-return ($returnID is true ? int|string|false : bool) * * @throws ReflectionException */ - public function insert($data = null, bool $returnID = true) + public function insert($row = null, bool $returnID = true) { - if (! empty($this->tempData['data'])) { - if (empty($data)) { - $data = $this->tempData['data']; + if (isset($this->tempData['data'])) { + if ($row === null) { + $row = $this->tempData['data']; } else { - $data = $this->transformDataToArray($data, 'insert'); - $data = array_merge($this->tempData['data'], $data); + $row = $this->transformDataToArray($row, 'insert'); + $row = array_merge($this->tempData['data'], $row); } } $this->escape = $this->tempData['escape'] ?? []; $this->tempData = []; - return parent::insert($data, $returnID); + return parent::insert($row, $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. + * @used-by insert() to protect against mass assignment vulnerabilities. + * @used-by insertBatch() to protect against mass assignment vulnerabilities. * - * @param array $data Data + * @param array $row Row data + * @phpstan-param row_array $row * * @throws DataException */ - protected function doProtectFieldsForInsert(array $data): array + protected function doProtectFieldsForInsert(array $row): array { if (! $this->protectFields) { - return $data; + return $row; } - if (empty($this->allowedFields)) { + if ($this->allowedFields === []) { throw DataException::forInvalidAllowedFields(static::class); } - foreach (array_keys($data) as $key) { + foreach (array_keys($row) 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]); + unset($row[$key]); } } - return $data; + return $row; } /** @@ -755,71 +785,42 @@ protected function doProtectFieldsForInsert(array $data): array * it will attempt to convert it into an array. * * @param array|int|string|null $id - * @param array|object|null $data + * @param array|object|null $row + * @phpstan-param row_array|object|null $row * * @throws ReflectionException */ - public function update($id = null, $data = null): bool + public function update($id = null, $row = null): bool { - if (! empty($this->tempData['data'])) { - if (empty($data)) { - $data = $this->tempData['data']; + if (isset($this->tempData['data'])) { + if ($row === null) { + $row = $this->tempData['data']; } else { - $data = $this->transformDataToArray($data, 'update'); - $data = array_merge($this->tempData['data'], $data); + $row = $this->transformDataToArray($row, 'update'); + $row = array_merge($this->tempData['data'], $row); } } $this->escape = $this->tempData['escape'] ?? []; $this->tempData = []; - return parent::update($id, $data); + return parent::update($id, $row); } /** * 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 cast as array as well + * @param object $object Object + * @param bool $recursive If true, inner entities will be cast as array as well * - * @return array|null Array + * @return array * * @throws ReflectionException */ - protected function objectToRawArray($data, bool $onlyChanged = true, bool $recursive = false): ?array + protected function objectToRawArray($object, bool $onlyChanged = true, bool $recursive = false): array { - $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($primaryKey) - ) - ) { - $properties[$this->primaryKey] = $primaryKey; - } - - return $properties; + return parent::objectToRawArray($object, $onlyChanged); } /** @@ -909,7 +910,7 @@ public static function classToArray($data, $primaryKey = null, string $dateForma $properties = $data->toRawArray($onlyChanged); // Always grab the primary key otherwise updates will fail. - if (! empty($properties) && ! empty($primaryKey) && ! in_array($primaryKey, $properties, true) && ! empty($data->{$primaryKey})) { + if ($properties !== [] && isset($primaryKey) && ! in_array($primaryKey, $properties, true) && isset($data->{$primaryKey})) { $properties[$primaryKey] = $data->{$primaryKey}; } } else { diff --git a/system/Modules/Modules.php b/system/Modules/Modules.php index f99e7215e733..e17b9f3c2415 100644 --- a/system/Modules/Modules.php +++ b/system/Modules/Modules.php @@ -37,7 +37,7 @@ class Modules /** * Auto-Discover Rules Handler * - * @var array + * @var list */ public $aliases = []; diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php index b08cb00410fd..d9de5faab401 100644 --- a/system/Pager/Pager.php +++ b/system/Pager/Pager.php @@ -310,7 +310,7 @@ public function getNextPageURI(string $group = 'default', bool $returnObject = f $curr = $this->getCurrentPage($group); $page = null; - if (! empty($last) && ! empty($curr) && $last === $curr) { + if (! empty($last) && $curr !== 0 && $last === $curr) { return null; } @@ -334,7 +334,7 @@ public function getPreviousPageURI(string $group = 'default', bool $returnObject $curr = $this->getCurrentPage($group); $page = null; - if (! empty($first) && ! empty($curr) && $first === $curr) { + if ($first !== 0 && $curr !== 0 && $first === $curr) { return null; } diff --git a/system/Pager/PagerRenderer.php b/system/Pager/PagerRenderer.php index 454ac9f1cd93..9e6d2950caf0 100644 --- a/system/Pager/PagerRenderer.php +++ b/system/Pager/PagerRenderer.php @@ -25,14 +25,14 @@ class PagerRenderer { /** - * First page number. + * First page number in the set of links to be displayed. * * @var int */ protected $first; /** - * Last page number. + * Last page number in the set of links to be displayed. * * @var int */ @@ -85,8 +85,11 @@ class PagerRenderer */ public function __construct(array $details) { - $this->first = 1; - $this->last = $details['pageCount']; + // `first` and `last` will be updated by `setSurroundCount()`. + // You must call `setSurroundCount()` after instantiation. + $this->first = 1; + $this->last = $details['pageCount']; + $this->current = $details['currentPage']; $this->total = $details['total']; $this->uri = $details['uri']; @@ -122,8 +125,6 @@ public function hasPrevious(): bool * page before the current page, but is the page just before the * "first" page. * - * You MUST call hasPrevious() first, or this value may be invalid. - * * @return string|null */ public function getPrevious() @@ -162,8 +163,6 @@ public function hasNext(): bool * page after the current page, but is the page that follows the * "last" page. * - * You MUST call hasNext() first, or this value may be invalid. - * * @return string|null */ public function getNext() @@ -260,6 +259,8 @@ public function getCurrent(): string * is represented by another array containing of the URI the link * should go to, the title (number) of the link, and a boolean * value representing whether this link is active or not. + * + * @return list */ public function links(): array { @@ -381,7 +382,7 @@ public function getNextPage() } /** - * Returns the page number of the first page. + * Returns the page number of the first page in the set of links to be displayed. */ public function getFirstPageNumber(): int { @@ -397,7 +398,7 @@ public function getCurrentPageNumber(): int } /** - * Returns the page number of the last page. + * Returns the page number of the last page in the set of links to be displayed. */ public function getLastPageNumber(): int { diff --git a/system/RESTful/ResourceController.php b/system/RESTful/ResourceController.php index 03ba4d314613..6ffb602c8bd1 100644 --- a/system/RESTful/ResourceController.php +++ b/system/RESTful/ResourceController.php @@ -105,6 +105,7 @@ public function delete($id = null) * Set/change the expected response representation for returned objects * * @param string $format json/xml + * @phpstan-param 'json'|'xml' $format * * @return void */ diff --git a/system/Router/AutoRouter.php b/system/Router/AutoRouter.php index f7cd02a3d329..87a5b3ac3bc1 100644 --- a/system/Router/AutoRouter.php +++ b/system/Router/AutoRouter.php @@ -90,7 +90,7 @@ public function getRoute(string $uri, string $httpVerb): array // If we don't have any segments left - use the default controller; // If not empty, then the first segment should be the controller - if (! empty($segments)) { + if ($segments !== []) { $this->controller = ucfirst(array_shift($segments)); } @@ -103,7 +103,7 @@ public function getRoute(string $uri, string $httpVerb): array // Use the method name if it exists. // If it doesn't, no biggie - the default method name // has already been set. - if (! empty($segments)) { + if ($segments !== []) { $this->method = array_shift($segments) ?: $this->method; } @@ -115,7 +115,7 @@ public function getRoute(string $uri, string $httpVerb): array /** @var array $params An array of params to the controller method. */ $params = []; - if (! empty($segments)) { + if ($segments !== []) { $params = $segments; } @@ -259,7 +259,7 @@ private function isValidSegment(string $segment): bool */ public function setDirectory(?string $dir = null, bool $append = false, bool $validate = true) { - if (empty($dir)) { + if ($dir === null || $dir === '') { $this->directory = null; return; @@ -275,7 +275,7 @@ public function setDirectory(?string $dir = null, bool $append = false, bool $va } } - if ($append !== true || empty($this->directory)) { + if ($append !== true || ($this->directory === null || $this->directory === '')) { $this->directory = trim($dir, '/') . '/'; } else { $this->directory .= trim($dir, '/') . '/'; @@ -290,7 +290,7 @@ public function setDirectory(?string $dir = null, bool $append = false, bool $va */ public function directory(): string { - return ! empty($this->directory) ? $this->directory : ''; + return ($this->directory !== null && $this->directory !== '') ? $this->directory : ''; } private function controllerName(): string diff --git a/system/Router/AutoRouterImproved.php b/system/Router/AutoRouterImproved.php index 0a26fc12f865..a86e92f0161a 100644 --- a/system/Router/AutoRouterImproved.php +++ b/system/Router/AutoRouterImproved.php @@ -49,7 +49,7 @@ final class AutoRouterImproved implements AutoRouterInterface /** * An array of params to the controller method. * - * @phpstan-var list + * @var list */ private array $params = []; @@ -77,7 +77,7 @@ final class AutoRouterImproved implements AutoRouterInterface /** * The URI segments. * - * @phpstan-var list + * @var list */ private array $segments = []; @@ -286,7 +286,7 @@ public function getRoute(string $uri, string $httpVerb): array } // The first item may be a method name. - /** @phpstan-var list $params */ + /** @var list $params */ $params = $this->params; $methodParam = array_shift($params); diff --git a/system/Router/DefinedRouteCollector.php b/system/Router/DefinedRouteCollector.php index f8e245d19723..4fdbbb02597b 100644 --- a/system/Router/DefinedRouteCollector.php +++ b/system/Router/DefinedRouteCollector.php @@ -29,7 +29,7 @@ public function __construct(RouteCollection $routes) } /** - * @phpstan-return Generator + * @return Generator */ public function collect(): Generator { diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index b3bb96e9fa2b..4407c1076f3d 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -560,11 +560,12 @@ public function shouldAutoRoute(): bool /** * Returns the raw array of available routes. * - * @param bool $includeWildcard Whether to include '*' routes. + * @param non-empty-string|null $verb + * @param bool $includeWildcard Whether to include '*' routes. */ public function getRoutes(?string $verb = null, bool $includeWildcard = true): array { - if (empty($verb)) { + if ($verb === null || $verb === '') { $verb = $this->getHTTPVerb(); } @@ -995,7 +996,7 @@ public function presenter(string $name, ?array $options = null): RouteCollection */ public function match(array $verbs = [], string $from = '', $to = '', ?array $options = null): RouteCollectionInterface { - if (empty($from) || empty($to)) { + if ($from === '' || empty($to)) { throw new InvalidArgumentException('You must supply the parameters: from, to.'); } @@ -1267,8 +1268,7 @@ public function getFilterForRoute(string $search, ?string $verb = null): string * * @param string $search routeKey * - * @return array filter_name or filter_name:arguments like 'role:admin,manager' - * @phpstan-return list + * @return list filter_name or filter_name:arguments like 'role:admin,manager' */ public function getFiltersForRoute(string $search, ?string $verb = null): array { @@ -1305,8 +1305,7 @@ protected function fillRouteParams(string $from, ?array $params = null): string * Build our resulting string, inserting the $params in * the appropriate places. * - * @var array $patterns - * @phpstan-var list $patterns + * @var list $patterns */ $patterns = $matches[0]; @@ -1357,8 +1356,7 @@ protected function buildReverseRoute(string $from, array $params): string * Build our resulting string, inserting the $params in * the appropriate places. * - * @var array $placeholders - * @phpstan-var list $placeholders + * @var list $placeholders */ $placeholders = $matches[0]; @@ -1691,8 +1689,7 @@ public function resetRoutes() /** * Load routes options based on verb * - * @return array> [routeKey(or from) => [key => value]] - * @phpstan-return array< + * @return array< * string, * array{ * filter?: string|list, namespace?: string, hostname?: string, @@ -1740,8 +1737,7 @@ public function setPrioritize(bool $enabled = true) * * @param string|null $verb HTTP verb. `'*'` returns all controllers in any verb. * - * @return array controller name list - * @phpstan-return list + * @return list controller name list */ public function getRegisteredControllers(?string $verb = '*'): array { diff --git a/system/Router/Router.php b/system/Router/Router.php index 0013d7cdf920..723c292cb931 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -589,7 +589,7 @@ protected function scanControllers(array $segments): array */ public function setDirectory(?string $dir = null, bool $append = false, bool $validate = true) { - if (empty($dir)) { + if ($dir === null || $dir === '') { $this->directory = null; } @@ -623,7 +623,7 @@ private function isValidSegment(string $segment): bool protected function setRequest(array $segments = []) { // If we don't have any segments - use the default controller; - if (empty($segments)) { + if ($segments === []) { return; } diff --git a/system/Session/Handlers/MemcachedHandler.php b/system/Session/Handlers/MemcachedHandler.php index abccfafb5ba4..aa0c1cd3a4ff 100644 --- a/system/Session/Handlers/MemcachedHandler.php +++ b/system/Session/Handlers/MemcachedHandler.php @@ -70,9 +70,7 @@ public function __construct(SessionConfig $config, string $ipAddress) $this->keyPrefix .= $this->ipAddress . ':'; } - if (! empty($this->keyPrefix)) { - ini_set('memcached.sess_prefix', $this->keyPrefix); - } + ini_set('memcached.sess_prefix', $this->keyPrefix); } /** @@ -125,7 +123,7 @@ public function open($path, $name): bool } } - if (empty($serverList)) { + if ($serverList === []) { $this->logger->error('Session: Memcached server pool is empty.'); return false; diff --git a/system/Session/Handlers/RedisHandler.php b/system/Session/Handlers/RedisHandler.php index 815e3644984b..b429792929b4 100644 --- a/system/Session/Handlers/RedisHandler.php +++ b/system/Session/Handlers/RedisHandler.php @@ -71,7 +71,7 @@ public function __construct(SessionConfig $config, string $ipAddress) parent::__construct($config, $ipAddress); // Store Session configurations - $this->sessionExpiration = empty($config->expiration) + $this->sessionExpiration = ($config->expiration === 0) ? (int) ini_get('session.gc_maxlifetime') : $config->expiration; // Add sessionCookieName for multiple session cookies. @@ -293,7 +293,10 @@ protected function lockSession(string $sessionID): bool $attempt = 0; do { - if (($ttl = $this->redis->ttl($lockKey)) > 0) { + $ttl = $this->redis->ttl($lockKey); + assert(is_int($ttl)); + + if ($ttl > 0) { sleep(1); continue; diff --git a/system/Session/Session.php b/system/Session/Session.php index 4e4a01581ba2..5c087579a2e4 100644 --- a/system/Session/Session.php +++ b/system/Session/Session.php @@ -241,7 +241,7 @@ public function start() $this->startSession(); // Is session ID auto-regeneration configured? (ignoring ajax requests) - if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') + if ((! isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') && ($regenerateTime = $this->config->timeToUpdate) > 0 ) { if (! isset($_SESSION['__ci_last_regenerate'])) { @@ -299,7 +299,7 @@ protected function configure() ini_set('session.gc_maxlifetime', (string) $this->config->expiration); } - if (! empty($this->config->savePath)) { + if ($this->config->savePath !== '') { ini_set('session.save_path', $this->config->savePath); } @@ -368,7 +368,7 @@ protected function configureSidLength() */ protected function initVars() { - if (empty($_SESSION['__ci_vars'])) { + if (! isset($_SESSION['__ci_vars'])) { return; } @@ -384,7 +384,7 @@ protected function initVars() } } - if (empty($_SESSION['__ci_vars'])) { + if ($_SESSION['__ci_vars'] === []) { unset($_SESSION['__ci_vars']); } } @@ -486,21 +486,21 @@ public function set($data, $value = null) * * Replaces the legacy method $session->userdata(); * - * @param string|null $key Identifier of the session property to retrieve + * @param non-empty-string|null $key Identifier of the session property to retrieve * * @return array|bool|float|int|object|string|null The property value(s) */ public function get(?string $key = null) { - if (! empty($key) && (null !== ($value = $_SESSION[$key] ?? null) || null !== ($value = dot_array_search($key, $_SESSION ?? [])))) { + if ($key !== null && $key !== '' && (null !== ($value = $_SESSION[$key] ?? null) || null !== ($value = dot_array_search($key, $_SESSION ?? [])))) { return $value; } - if (empty($_SESSION)) { + if ($_SESSION === []) { return $key === null ? [] : null; } - if (! empty($key)) { + if ($key !== null && $key !== '') { return null; } @@ -646,7 +646,7 @@ public function getFlashdata(?string $key = null) $flashdata = []; - if (! empty($_SESSION['__ci_vars'])) { + if (isset($_SESSION['__ci_vars'])) { foreach ($_SESSION['__ci_vars'] as $key => &$value) { if (! is_int($value)) { $flashdata[$key] = $_SESSION[$key]; @@ -706,7 +706,7 @@ public function markAsFlashdata($key): bool */ public function unmarkFlashdata($key) { - if (empty($_SESSION['__ci_vars'])) { + if (! isset($_SESSION['__ci_vars'])) { return; } @@ -720,7 +720,7 @@ public function unmarkFlashdata($key) } } - if (empty($_SESSION['__ci_vars'])) { + if ($_SESSION['__ci_vars'] === []) { unset($_SESSION['__ci_vars']); } } @@ -778,7 +778,7 @@ public function getTempdata(?string $key = null) $tempdata = []; - if (! empty($_SESSION['__ci_vars'])) { + if (isset($_SESSION['__ci_vars'])) { foreach ($_SESSION['__ci_vars'] as $key => &$value) { if (is_int($value)) { $tempdata[$key] = $_SESSION[$key]; @@ -856,7 +856,7 @@ public function markAsTempdata($key, int $ttl = 300): bool */ public function unmarkTempdata($key) { - if (empty($_SESSION['__ci_vars'])) { + if (! isset($_SESSION['__ci_vars'])) { return; } @@ -870,7 +870,7 @@ public function unmarkTempdata($key) } } - if (empty($_SESSION['__ci_vars'])) { + if ($_SESSION['__ci_vars'] === []) { unset($_SESSION['__ci_vars']); } } diff --git a/system/Session/SessionInterface.php b/system/Session/SessionInterface.php index e78736bf34b7..424834c79639 100644 --- a/system/Session/SessionInterface.php +++ b/system/Session/SessionInterface.php @@ -51,7 +51,7 @@ public function set($data, $value = null); * * Replaces the legacy method $session->userdata(); * - * @param string $key Identifier of the session property to retrieve + * @param non-empty-string|null $key Identifier of the session property to retrieve * * @return array|bool|float|int|object|string|null The property value(s) */ diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index a0c84c48f2b7..b27db73f229e 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -123,7 +123,7 @@ abstract class CIUnitTestCase extends TestCase /** * The namespace(s) to help us find the migration classes. - * Empty is equivalent to running `spark migrate --all`. + * `null` is equivalent to running `spark migrate --all`. * Note that running "all" runs migrations in date order, * but specifying namespaces runs them in namespace order (then date) * @@ -135,8 +135,7 @@ abstract class CIUnitTestCase extends TestCase * The name of the database group to connect to. * If not present, will use the defaultGroup. * - * @var string - * @phpstan-var non-empty-string + * @var non-empty-string */ protected $DBGroup = 'tests'; diff --git a/system/Test/ControllerTestTrait.php b/system/Test/ControllerTestTrait.php index 2da65d1aa2f7..a99b899eaf63 100644 --- a/system/Test/ControllerTestTrait.php +++ b/system/Test/ControllerTestTrait.php @@ -215,7 +215,7 @@ public function execute(string $method, ...$params) /** * Set controller's config, with method chaining. * - * @param mixed $appConfig + * @param App $appConfig * * @return $this */ @@ -229,7 +229,7 @@ public function withConfig($appConfig) /** * Set controller's request, with method chaining. * - * @param mixed $request + * @param IncomingRequest $request * * @return $this */ @@ -260,7 +260,7 @@ public function withResponse($response) /** * Set controller's logger, with method chaining. * - * @param mixed $logger + * @param LoggerInterface $logger * * @return $this */ diff --git a/system/Test/DOMParser.php b/system/Test/DOMParser.php index 100b14b72dff..1565452159f9 100644 --- a/system/Test/DOMParser.php +++ b/system/Test/DOMParser.php @@ -189,23 +189,23 @@ protected function doXPath(?string $search, string $element, array $paths = []) $path = ''; // By ID - if (! empty($selector['id'])) { - $path = empty($selector['tag']) + if (isset($selector['id'])) { + $path = ($selector['tag'] === '') ? "id(\"{$selector['id']}\")" : "//{$selector['tag']}[@id=\"{$selector['id']}\"]"; } // By Class - elseif (! empty($selector['class'])) { - $path = empty($selector['tag']) + elseif (isset($selector['class'])) { + $path = ($selector['tag'] === '') ? "//*[@class=\"{$selector['class']}\"]" : "//{$selector['tag']}[@class=\"{$selector['class']}\"]"; } // By tag only - elseif (! empty($selector['tag'])) { + elseif ($selector['tag'] !== '') { $path = "//{$selector['tag']}"; } - if (! empty($selector['attr'])) { + if (isset($selector['attr'])) { foreach ($selector['attr'] as $key => $value) { $path .= "[@{$key}=\"{$value}\"]"; } @@ -213,7 +213,7 @@ protected function doXPath(?string $search, string $element, array $paths = []) // $paths might contain a number of different // ready to go xpath portions to tack on. - if (! empty($paths) && is_array($paths)) { + if ($paths !== [] && is_array($paths)) { foreach ($paths as $extra) { $path .= $extra; } @@ -231,7 +231,7 @@ protected function doXPath(?string $search, string $element, array $paths = []) /** * Look for the a selector in the passed text. * - * @return array + * @return array{tag: string, id: string|null, class: string|null, attr: array|null} */ public function parseSelector(string $selector) { diff --git a/system/Test/DatabaseTestTrait.php b/system/Test/DatabaseTestTrait.php index d7b8b02ddaa8..f69a535f41ec 100644 --- a/system/Test/DatabaseTestTrait.php +++ b/system/Test/DatabaseTestTrait.php @@ -120,7 +120,7 @@ protected function regressDatabase() } // If no namespace was specified then rollback all - if (empty($this->namespace)) { + if ($this->namespace === null) { $this->migrations->setNamespace(null); $this->migrations->regress(0, 'tests'); } @@ -146,7 +146,7 @@ protected function migrateDatabase() } // If no namespace was specified then migrate all - if (empty($this->namespace)) { + if ($this->namespace === null) { $this->migrations->setNamespace(null); $this->migrations->latest('tests'); self::$doneMigration = true; @@ -182,8 +182,8 @@ protected function setUpSeed() */ protected function runSeeds() { - if (! empty($this->seed)) { - if (! empty($this->basePath)) { + if ($this->seed !== '') { + if ($this->basePath !== '') { $this->seeder->setPath(rtrim($this->basePath, '/') . '/Seeds'); } diff --git a/system/Test/Fabricator.php b/system/Test/Fabricator.php index 3a28f281d127..c247b8741b01 100644 --- a/system/Test/Fabricator.php +++ b/system/Test/Fabricator.php @@ -128,7 +128,7 @@ public function __construct($model, ?array $formatters = null, ?string $locale = // Determine eligible date fields foreach (['createdField', 'updatedField', 'deletedField'] as $field) { - if (! empty($this->model->{$field})) { + if (isset($this->model->{$field})) { $this->dateFields[] = $this->model->{$field}; } } @@ -152,7 +152,7 @@ public static function resetCounts() */ public static function getCount(string $table): int { - return empty(self::$tableCounts[$table]) ? 0 : self::$tableCounts[$table]; + return ! isset(self::$tableCounts[$table]) ? 0 : self::$tableCounts[$table]; } /** @@ -282,7 +282,7 @@ protected function detectFormatters(): self { $this->formatters = []; - if (! empty($this->model->allowedFields)) { + if (isset($this->model->allowedFields)) { foreach ($this->model->allowedFields as $field) { $this->formatters[$field] = $this->guessFormatter($field); } @@ -513,12 +513,12 @@ protected function createMock(?int $count = null) // Determine which fields we will need $fields = []; - if (! empty($this->model->useTimestamps)) { + if ($this->model->useTimestamps) { $fields[$this->model->createdField] = $datetime; $fields[$this->model->updatedField] = $datetime; } - if (! empty($this->model->useSoftDeletes)) { + if ($this->model->useSoftDeletes) { $fields[$this->model->deletedField] = null; } diff --git a/system/Test/FeatureTestCase.php b/system/Test/FeatureTestCase.php index c94cf926ca89..fff624a840f3 100644 --- a/system/Test/FeatureTestCase.php +++ b/system/Test/FeatureTestCase.php @@ -186,7 +186,7 @@ public function call(string $method, string $path, ?array $params = null) ->run($routes, true); $output = \ob_get_contents(); - if (empty($response->getBody()) && ! empty($output)) { + if (($response->getBody() === null) && ! ($output === '' || $output === false)) { $response->setBody($output); } @@ -335,7 +335,7 @@ protected function populateGlobals(string $method, $request, ?array $params = nu { // $params should set the query vars if present, // otherwise set it from the URL. - $get = ! empty($params) && $method === 'get' + $get = ($params !== null && $params !== [] && $method === 'get') ? $params : $this->getPrivateProperty($request->getUri(), 'query'); @@ -371,16 +371,19 @@ protected function setRequestBody($request, ?array $params = null) } if (isset($this->bodyFormat) && $this->bodyFormat !== '') { - if (empty($params)) { + if ($params === null || $params === []) { $params = $request->fetchGlobal('request'); } + $formatMime = ''; + if ($this->bodyFormat === 'json') { $formatMime = 'application/json'; } elseif ($this->bodyFormat === 'xml') { $formatMime = 'application/xml'; } - if (! empty($formatMime) && ! empty($params)) { + + if ($formatMime !== '' && ! ($params === null || $params === [])) { $formatted = Services::format()->getFormatter($formatMime)->format($params); $request->setBody($formatted); $request->setHeader('Content-Type', $formatMime); diff --git a/system/Test/FeatureTestTrait.php b/system/Test/FeatureTestTrait.php index 6acef638f6b3..565e4e892780 100644 --- a/system/Test/FeatureTestTrait.php +++ b/system/Test/FeatureTestTrait.php @@ -326,7 +326,8 @@ protected function setupHeaders(IncomingRequest $request) * * Always populate the GET vars based on the URI. * - * @param string $method HTTP verb + * @param string $method HTTP verb + * @param non-empty-array|null $params * * @return Request * @@ -336,7 +337,7 @@ protected function populateGlobals(string $method, Request $request, ?array $par { // $params should set the query vars if present, // otherwise set it from the URL. - $get = (! empty($params) && $method === 'get') + $get = ($params !== null && $params !== [] && $method === 'get') ? $params : $this->getPrivateProperty($request->getUri(), 'query'); diff --git a/system/Test/FilterTestTrait.php b/system/Test/FilterTestTrait.php index 084a6cd082fc..523717e54679 100644 --- a/system/Test/FilterTestTrait.php +++ b/system/Test/FilterTestTrait.php @@ -125,6 +125,10 @@ protected function getFilterCaller($filter, string $position): Closure throw new InvalidArgumentException('Invalid filter position passed: ' . $position); } + if ($filter instanceof FilterInterface) { + $filterInstances = [$filter]; + } + if (is_string($filter)) { // Check for an alias (no namespace) if (strpos($filter, '\\') === false) { @@ -132,28 +136,31 @@ protected function getFilterCaller($filter, string $position): Closure throw new RuntimeException("No filter found with alias '{$filter}'"); } - $filterClasses = $this->filtersConfig->aliases[$filter]; + $filterClasses = (array) $this->filtersConfig->aliases[$filter]; + } else { + // FQCN + $filterClasses = [$filter]; } - $filterClasses = (array) $filterClasses; - } + $filterInstances = []; - foreach ($filterClasses as $class) { - // Get an instance - $filter = new $class(); + foreach ($filterClasses as $class) { + // Get an instance + $filter = new $class(); - if (! $filter instanceof FilterInterface) { - throw FilterException::forIncorrectInterface(get_class($filter)); + if (! $filter instanceof FilterInterface) { + throw FilterException::forIncorrectInterface(get_class($filter)); + } + + $filterInstances[] = $filter; } } $request = clone $this->request; if ($position === 'before') { - return static function (?array $params = null) use ($filterClasses, $request) { - foreach ($filterClasses as $class) { - $filter = new $class(); - + return static function (?array $params = null) use ($filterInstances, $request) { + foreach ($filterInstances as $filter) { $result = $filter->before($request, $params); // @TODO The following logic is in Filters class. @@ -177,10 +184,8 @@ protected function getFilterCaller($filter, string $position): Closure $response = clone $this->response; - return static function (?array $params = null) use ($filterClasses, $request, $response) { - foreach ($filterClasses as $class) { - $filter = new $class(); - + return static function (?array $params = null) use ($filterInstances, $request, $response) { + foreach ($filterInstances as $filter) { $result = $filter->after($request, $response, $params); // @TODO The following logic is in Filters class. diff --git a/system/Test/Mock/MockCache.php b/system/Test/Mock/MockCache.php index 73a755802285..082807b559ec 100644 --- a/system/Test/Mock/MockCache.php +++ b/system/Test/Mock/MockCache.php @@ -22,7 +22,7 @@ class MockCache extends BaseHandler implements CacheInterface /** * Mock cache storage. * - * @var array + * @var array */ protected $cache = []; @@ -155,7 +155,7 @@ public function increment(string $key, int $offset = 1) $key = static::validateKey($key, $this->prefix); $data = $this->cache[$key] ?: null; - if (empty($data)) { + if ($data === null) { $data = 0; } elseif (! is_int($data)) { return false; @@ -175,7 +175,7 @@ public function decrement(string $key, int $offset = 1) $data = $this->cache[$key] ?: null; - if (empty($data)) { + if ($data === null) { $data = 0; } elseif (! is_int($data)) { return false; @@ -281,9 +281,9 @@ public function assertHasValue(string $key, $value = null) { $item = $this->get($key); - // Let assertHas handle throwing the error for consistency + // Let assertHas() handle throwing the error for consistency // if the key is not found - if (empty($item)) { + if ($item === null) { $this->assertHas($key); } diff --git a/system/Test/Mock/MockConnection.php b/system/Test/Mock/MockConnection.php index ea4ebac9b471..2e9ebe3b527a 100644 --- a/system/Test/Mock/MockConnection.php +++ b/system/Test/Mock/MockConnection.php @@ -62,7 +62,7 @@ public function query(string $sql, $binds = null, bool $setEscapeFlags = true, s $query->setQuery($sql, $binds, $setEscapeFlags); - if (! empty($this->swapPre) && ! empty($this->DBPrefix)) { + if ($this->swapPre !== '' && $this->DBPrefix !== '') { $query->swapPrefix($this->DBPrefix, $this->swapPre); } diff --git a/system/Test/TestResponse.php b/system/Test/TestResponse.php index 956b32188ac8..215942d54fe9 100644 --- a/system/Test/TestResponse.php +++ b/system/Test/TestResponse.php @@ -136,8 +136,10 @@ public function isOK(): bool return false; } + $body = (string) $this->response->getBody(); + // Empty bodies are not considered valid, unless in redirects - return ! ($status < 300 && empty($this->response->getBody())); + return ! ($status < 300 && $body === ''); } /** diff --git a/system/Test/bootstrap.php b/system/Test/bootstrap.php index 3145725afe96..3e2d54fdb564 100644 --- a/system/Test/bootstrap.php +++ b/system/Test/bootstrap.php @@ -46,7 +46,7 @@ defined('FCPATH') || define('FCPATH', realpath(PUBLICPATH) . DIRECTORY_SEPARATOR); defined('TESTPATH') || define('TESTPATH', realpath(HOMEPATH . 'tests/') . DIRECTORY_SEPARATOR); defined('SUPPORTPATH') || define('SUPPORTPATH', realpath(TESTPATH . '_support/') . DIRECTORY_SEPARATOR); -defined('COMPOSER_PATH') || define('COMPOSER_PATH', realpath(HOMEPATH . 'vendor/autoload.php')); +defined('COMPOSER_PATH') || define('COMPOSER_PATH', (string) realpath(HOMEPATH . 'vendor/autoload.php')); defined('VENDORPATH') || define('VENDORPATH', realpath(HOMEPATH . 'vendor') . DIRECTORY_SEPARATOR); // Load Common.php from App then System @@ -75,6 +75,7 @@ // Initialize and register the loader with the SPL autoloader stack. Services::autoloader()->initialize(new Autoload(), new Modules())->register(); +Services::autoloader()->loadHelpers(); // Now load Composer's if it's available if (is_file(COMPOSER_PATH)) { diff --git a/system/ThirdParty/Kint/CallFinder.php b/system/ThirdParty/Kint/CallFinder.php index e36e91eac0d0..f85b1ae017a9 100644 --- a/system/ThirdParty/Kint/CallFinder.php +++ b/system/ThirdParty/Kint/CallFinder.php @@ -138,7 +138,7 @@ class CallFinder /** * @psalm-param callable-array|callable-string $function * - * @param mixed $function + * @psalm-return list}> * * @return array List of matching calls on the relevant line */ @@ -187,6 +187,7 @@ public static function getFunctionCalls(string $source, int $line, $function): a $identifier[T_NAME_RELATIVE] = true; } + /** @psalm-var list */ $tokens = \token_get_all($source); $cursor = 1; $function_calls = []; @@ -449,8 +450,6 @@ private static function realTokenIndex(array $tokens, int $index): ?int * for `$token[0]` then "..." will incorrectly match the "." operator. * * @psalm-param PhpToken $token The token to check - * - * @param mixed $token */ private static function tokenIsOperator($token): bool { diff --git a/system/ThirdParty/Kint/Kint.php b/system/ThirdParty/Kint/Kint.php index 47e34abef52b..418c1f3f8789 100644 --- a/system/ThirdParty/Kint/Kint.php +++ b/system/ThirdParty/Kint/Kint.php @@ -133,7 +133,7 @@ class Kint implements FacadeInterface public static $aliases = [ ['Kint\\Kint', 'dump'], ['Kint\\Kint', 'trace'], - ['Kint\\Kint', 'dumpArray'], + ['Kint\\Kint', 'dumpAll'], ]; /** @@ -537,7 +537,7 @@ public static function trace() * * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace()) * - * @param mixed ...$args + * @psalm-param array ...$args * * @return int|string */ @@ -599,6 +599,7 @@ public static function shortenPath(string $file): string $match = '/'; foreach (static::$app_root_dirs as $path => $alias) { + /** @psalm-var string $path */ if (empty($path)) { continue; } diff --git a/system/ThirdParty/Kint/Parser/BlacklistPlugin.php b/system/ThirdParty/Kint/Parser/BlacklistPlugin.php index 90ec3c223327..fa54a3a6743e 100644 --- a/system/ThirdParty/Kint/Parser/BlacklistPlugin.php +++ b/system/ThirdParty/Kint/Parser/BlacklistPlugin.php @@ -29,6 +29,7 @@ use Kint\Zval\InstanceValue; use Kint\Zval\Value; +use Psr\Container\ContainerInterface; class BlacklistPlugin extends AbstractPlugin { @@ -44,7 +45,7 @@ class BlacklistPlugin extends AbstractPlugin * * @var array */ - public static $shallow_blacklist = ['Psr\\Container\\ContainerInterface']; + public static $shallow_blacklist = [ContainerInterface::class]; public function getTypes(): array { diff --git a/system/ThirdParty/Kint/Parser/ClosurePlugin.php b/system/ThirdParty/Kint/Parser/ClosurePlugin.php index 8b199781078e..84ea582646f8 100644 --- a/system/ThirdParty/Kint/Parser/ClosurePlugin.php +++ b/system/ThirdParty/Kint/Parser/ClosurePlugin.php @@ -67,7 +67,7 @@ public function parse(&$var, Value &$o, int $trigger): void } $p = new Representation('Parameters'); - $p->contents = &$o->parameters; + $p->contents = $o->parameters; $o->addRepresentation($p, 0); $statics = []; diff --git a/system/ThirdParty/Kint/Parser/Parser.php b/system/ThirdParty/Kint/Parser/Parser.php index 50642b90a123..f044a9de913f 100644 --- a/system/ThirdParty/Kint/Parser/Parser.php +++ b/system/ThirdParty/Kint/Parser/Parser.php @@ -72,7 +72,7 @@ class Parser * @param int $depth_limit Maximum depth to parse data * @param ?string $caller Caller class name */ - public function __construct(int $depth_limit = 0, ?string $caller = null) + public function __construct(int $depth_limit = 0, string $caller = null) { $this->marker = "kint\0".\random_bytes(16); @@ -83,7 +83,7 @@ public function __construct(int $depth_limit = 0, ?string $caller = null) /** * Set the caller class. */ - public function setCallerClass(?string $caller = null): void + public function setCallerClass(string $caller = null): void { $this->noRecurseCall(); diff --git a/system/ThirdParty/Kint/Parser/PluginInterface.php b/system/ThirdParty/Kint/Parser/PluginInterface.php index ff169fd17d4d..3afb1a77674b 100644 --- a/system/ThirdParty/Kint/Parser/PluginInterface.php +++ b/system/ThirdParty/Kint/Parser/PluginInterface.php @@ -38,7 +38,7 @@ public function getTypes(): array; public function getTriggers(): int; /** - * @param mixed &$var + * @psalm-param mixed &$var */ public function parse(&$var, Value &$o, int $trigger): void; } diff --git a/system/ThirdParty/Kint/Parser/TablePlugin.php b/system/ThirdParty/Kint/Parser/TablePlugin.php index 8d7e155c95cc..5afe75980bc8 100644 --- a/system/ThirdParty/Kint/Parser/TablePlugin.php +++ b/system/ThirdParty/Kint/Parser/TablePlugin.php @@ -30,6 +30,12 @@ use Kint\Zval\Representation\Representation; use Kint\Zval\Value; +// Note: Interaction with ArrayLimitPlugin: +// Any array limited children will be shown in tables identically to +// non-array-limited children since the table only shows that it is an array +// and it's size anyway. Because ArrayLimitPlugin halts the parse on finding +// a limit all other plugins including this one are stopped, so you cannot get +// a tabular representation of an array that is longer than the limit. class TablePlugin extends AbstractPlugin { public function getTypes(): array diff --git a/system/ThirdParty/Kint/Renderer/RichRenderer.php b/system/ThirdParty/Kint/Renderer/RichRenderer.php index f206e560c9c0..b3d86ea1dd5f 100644 --- a/system/ThirdParty/Kint/Renderer/RichRenderer.php +++ b/system/ThirdParty/Kint/Renderer/RichRenderer.php @@ -140,6 +140,13 @@ class RichRenderer extends AbstractRenderer */ public static $sort = self::SORT_NONE; + /** + * Timestamp to print in footer in date() format. + * + * @var ?string + */ + public static $timestamp = null; + public static $needs_pre_render = true; public static $needs_folder_render = true; @@ -465,29 +472,7 @@ public function postRender(): string $output .= ''; } - if (isset($this->call_info['callee']['file'])) { - $output .= 'Called from '.$this->ideLink( - $this->call_info['callee']['file'], - $this->call_info['callee']['line'] - ); - } - - if ( - isset($this->call_info['callee']['function']) && - ( - !empty($this->call_info['callee']['class']) || - !\in_array( - $this->call_info['callee']['function'], - ['include', 'include_once', 'require', 'require_once'], - true - ) - ) - ) { - $output .= ' ['; - $output .= $this->call_info['callee']['class'] ?? ''; - $output .= $this->call_info['callee']['type'] ?? ''; - $output .= $this->call_info['callee']['function'].'()]'; - } + $output .= $this->calledFrom(); if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) { $output .= '
    '; @@ -497,8 +482,8 @@ public function postRender(): string } $output .= '
  1. '.$this->ideLink($step['file'], $step['line']); // closing tag not required - if (isset($step['function']) - && !\in_array($step['function'], ['include', 'include_once', 'require', 'require_once'], true) + if (isset($step['function']) && + !\in_array($step['function'], ['include', 'include_once', 'require', 'require_once'], true) ) { $output .= ' ['; $output .= $step['class'] ?? ''; @@ -516,8 +501,6 @@ public function postRender(): string /** * @psalm-param Encoding $encoding - * - * @param mixed $encoding */ public function escape(string $string, $encoding = false): string { @@ -559,6 +542,45 @@ public function ideLink(string $file, int $line): string return ''.$path.''; } + protected function calledFrom(): string + { + $output = ''; + + if (isset($this->call_info['callee']['file'])) { + $output .= ' '.$this->ideLink( + $this->call_info['callee']['file'], + $this->call_info['callee']['line'] + ); + } + + if ( + isset($this->call_info['callee']['function']) && + ( + !empty($this->call_info['callee']['class']) || + !\in_array( + $this->call_info['callee']['function'], + ['include', 'include_once', 'require', 'require_once'], + true + ) + ) + ) { + $output .= ' ['; + $output .= $this->call_info['callee']['class'] ?? ''; + $output .= $this->call_info['callee']['type'] ?? ''; + $output .= $this->call_info['callee']['function'].'()]'; + } + + if ('' !== $output) { + $output = 'Called from'.$output; + } + + if (null !== self::$timestamp) { + $output .= ' '.\date(self::$timestamp); + } + + return $output; + } + protected function renderTab(Value $o, Representation $rep): string { if (($plugin = $this->getPlugin(self::$tab_plugins, $rep->hints)) && $plugin instanceof TabPluginInterface) { diff --git a/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php b/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php index 4d3c7e2a9791..16feccaab6c5 100644 --- a/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php @@ -42,7 +42,7 @@ public function __construct(TextRenderer $r) $this->renderer = $r; } - public function renderLockedHeader(Value $o, ?string $content = null): string + public function renderLockedHeader(Value $o, string $content = null): string { $out = ''; diff --git a/system/ThirdParty/Kint/Renderer/TextRenderer.php b/system/ThirdParty/Kint/Renderer/TextRenderer.php index 833320a6c196..2538e4da06af 100644 --- a/system/ThirdParty/Kint/Renderer/TextRenderer.php +++ b/system/ThirdParty/Kint/Renderer/TextRenderer.php @@ -108,6 +108,13 @@ class TextRenderer extends AbstractRenderer */ public static $sort = self::SORT_NONE; + /** + * Timestamp to print in footer in date() format. + * + * @var ?string + */ + public static $timestamp = null; + public $header_width = 80; public $indent_width = 4; @@ -300,7 +307,7 @@ public function filterParserPlugins(array $plugins): array { $return = []; - foreach ($plugins as $index => $plugin) { + foreach ($plugins as $plugin) { foreach (self::$parser_plugin_whitelist as $whitelist) { if ($plugin instanceof $whitelist) { $return[] = $plugin; @@ -319,8 +326,6 @@ public function ideLink(string $file, int $line): string /** * @psalm-param Encoding $encoding - * - * @param mixed $encoding */ public function escape(string $string, $encoding = false): string { @@ -355,6 +360,13 @@ protected function calledFrom(): string $output .= $this->call_info['callee']['function'].'()]'; } + if (null !== self::$timestamp) { + if (\strlen($output)) { + $output .= ' '; + } + $output .= \date(self::$timestamp); + } + return $output; } diff --git a/system/ThirdParty/Kint/Utils.php b/system/ThirdParty/Kint/Utils.php index 78b5a1e8c5ca..545709586dc4 100644 --- a/system/ThirdParty/Kint/Utils.php +++ b/system/ThirdParty/Kint/Utils.php @@ -255,8 +255,6 @@ public static function normalizeAliases(array &$aliases): void /** * @psalm-param Encoding $encoding - * - * @param mixed $encoding */ public static function truncateString(string $input, int $length = PHP_INT_MAX, string $end = '...', $encoding = false): string { diff --git a/system/ThirdParty/Kint/Zval/BlobValue.php b/system/ThirdParty/Kint/Zval/BlobValue.php index ff5a6a24cfc9..5e9f129d1181 100644 --- a/system/ThirdParty/Kint/Zval/BlobValue.php +++ b/system/ThirdParty/Kint/Zval/BlobValue.php @@ -122,8 +122,6 @@ public function transplant(Value $old): void /** * @psalm-param Encoding $encoding - * - * @param mixed $encoding */ public static function strlen(string $string, $encoding = false): int { @@ -142,10 +140,8 @@ public static function strlen(string $string, $encoding = false): int /** * @psalm-param Encoding $encoding - * - * @param mixed $encoding */ - public static function substr(string $string, int $start, ?int $length = null, $encoding = false): string + public static function substr(string $string, int $start, int $length = null, $encoding = false): string { if (\function_exists('mb_substr')) { if (false === $encoding) { diff --git a/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php index 806a800667d4..8853603440c3 100644 --- a/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php @@ -211,7 +211,7 @@ public function __construct(string $value) $this->setValues($value); } - public function getColor(?int $variant = null): ?string + public function getColor(int $variant = null): ?string { if (!$variant) { $variant = $this->variant; @@ -275,7 +275,7 @@ public function getColor(?int $variant = null): ?string return null; } - public function hasAlpha(?int $variant = null): bool + public function hasAlpha(int $variant = null): bool { if (null === $variant) { $variant = $this->variant; diff --git a/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php index d25539b1c7c6..027b0ce21f38 100644 --- a/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php @@ -44,7 +44,7 @@ class MicrotimeRepresentation extends Representation public $mem_peak_real = 0; public $hints = ['microtime']; - public function __construct(int $seconds, int $microseconds, int $group, ?float $lap = null, ?float $total = null, int $i = 0) + public function __construct(int $seconds, int $microseconds, int $group, float $lap = null, float $total = null, int $i = 0) { parent::__construct('Microtime'); diff --git a/system/ThirdParty/Kint/Zval/Representation/Representation.php b/system/ThirdParty/Kint/Zval/Representation/Representation.php index c4680c3d1f75..76d695b8d599 100644 --- a/system/ThirdParty/Kint/Zval/Representation/Representation.php +++ b/system/ThirdParty/Kint/Zval/Representation/Representation.php @@ -36,7 +36,7 @@ class Representation protected $name; - public function __construct(string $label, ?string $name = null) + public function __construct(string $label, string $name = null) { $this->label = $label; diff --git a/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php index d05bf088d46a..2fefc582ccc9 100644 --- a/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php @@ -57,7 +57,7 @@ public function __construct(string $filename, int $line, int $padding = 7) * @param int $start_line The first line to display (1 based) * @param null|int $length Amount of lines to show */ - public static function getSource(string $filename, int $start_line = 1, ?int $length = null): ?array + public static function getSource(string $filename, int $start_line = 1, int $length = null): ?array { if (!$filename || !\file_exists($filename) || !\is_readable($filename)) { return null; diff --git a/system/ThirdParty/Kint/Zval/Value.php b/system/ThirdParty/Kint/Zval/Value.php index facb6cd835e4..01a206d48a9c 100644 --- a/system/ThirdParty/Kint/Zval/Value.php +++ b/system/ThirdParty/Kint/Zval/Value.php @@ -53,8 +53,8 @@ class Value public $reference = false; public $depth = 0; public $size; - public $value; public $hints = []; + public $value; protected $representations = []; @@ -62,7 +62,7 @@ public function __construct() { } - public function addRepresentation(Representation $rep, ?int $pos = null): bool + public function addRepresentation(Representation $rep, int $pos = null): bool { if (isset($this->representations[$rep->getName()])) { return false; @@ -81,7 +81,7 @@ public function addRepresentation(Representation $rep, ?int $pos = null): bool return true; } - public function replaceRepresentation(Representation $rep, ?int $pos = null): void + public function replaceRepresentation(Representation $rep, int $pos = null): void { if (null === $pos) { $this->representations[$rep->getName()] = $rep; @@ -234,7 +234,7 @@ public function transplant(self $old): void /** * Creates a new basic object with a name and access path. */ - public static function blank(?string $name = null, ?string $access_path = null): self + public static function blank(string $name = null, string $access_path = null): self { $o = new self(); $o->name = $name; diff --git a/system/ThirdParty/Kint/init.php b/system/ThirdParty/Kint/init.php index 7605415b6e6e..039489ab43ad 100644 --- a/system/ThirdParty/Kint/init.php +++ b/system/ThirdParty/Kint/init.php @@ -45,6 +45,7 @@ \define('KINT_PHP81', \version_compare(PHP_VERSION, '8.1') >= 0); \define('KINT_PHP82', \version_compare(PHP_VERSION, '8.2') >= 0); \define('KINT_PHP83', \version_compare(PHP_VERSION, '8.3') >= 0); +\define('KINT_PHP84', \version_compare(PHP_VERSION, '8.4') >= 0); // Dynamic default settings if (false !== \ini_get('xdebug.file_link_format')) { diff --git a/system/ThirdParty/Kint/init_helpers.php b/system/ThirdParty/Kint/init_helpers.php index 561425b2a0d6..b4d5f4d9bd86 100644 --- a/system/ThirdParty/Kint/init_helpers.php +++ b/system/ThirdParty/Kint/init_helpers.php @@ -32,7 +32,7 @@ /** * Alias of Kint::dump(). * - * @param mixed ...$args + * @psalm-param mixed ...$args * * @return int|string */ @@ -53,7 +53,7 @@ function d(...$args) * * If run in CLI colors are disabled * - * @param mixed ...$args + * @psalm-param mixed ...$args * * @return int|string */ diff --git a/system/ThirdParty/Kint/resources/compiled/aante-dark.css b/system/ThirdParty/Kint/resources/compiled/aante-dark.css new file mode 100644 index 000000000000..6aa8b702cb23 --- /dev/null +++ b/system/ThirdParty/Kint/resources/compiled/aante-dark.css @@ -0,0 +1 @@ +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(0,0,0,.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:8px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#555;color:#e2e1e1}.kint-rich .kint-focused{box-shadow:0 0 3px 2px aqua}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#e2e1e1;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:8px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#070707;border:1px solid #282828;color:#e2e1e1;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:4px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#555}.kint-rich>dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiNBQUEiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjQUFBIi8+PC9zdmc+") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #282828}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#f90;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:aqua}.kint-rich dfn{font-style:normal;font-family:monospace;color:#e2e1e1}.kint-rich pre{color:#e2e1e1;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #282828;background:#070707;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(226,225,225,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#070707;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#e2e1e1;background:#070707}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #282828;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#e2e1e1;background:#070707;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#070707;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#070707}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#070707;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#e2e1e1}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#e2e1e1;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#e2e1e1;border-bottom:1px dotted #e2e1e1}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #282828}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#070707;border:1px solid #282828;border-top:0}.kint-rich ul.kint-tabs>li{background:#070707;border:1px solid #282828;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#555;color:aqua}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#070707;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#555;color:aqua}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #282828;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#555}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #282828;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#070707;color:#e2e1e1}.kint-rich table td{background:#070707;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #555 inset}.kint-rich table tr:hover var{color:aqua}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #070707}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #555;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#070707}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #555,0 1px #555,1px 0 #555,0 -1px #555;color:#070707;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px aqua}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:#070707}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:#070707;border:1px solid #282828;border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:25px}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:1px solid #282828;background:#000;font-weight:bold;padding-top:0;border-bottom:1px solid #000 !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid #000}.kint-rich ul>li>pre{border:1px solid #282828}.kint-rich dt:hover+dd>ul{border-color:#555}.kint-rich pre{background:#000;margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:#303}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:#000}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:#000}.kint-rich table tr:hover>td{box-shadow:none;background:#303} diff --git a/system/ThirdParty/Kint/resources/compiled/aante-light.css b/system/ThirdParty/Kint/resources/compiled/aante-light.css index 832dee718de4..16194736e83c 100644 --- a/system/ThirdParty/Kint/resources/compiled/aante-light.css +++ b/system/ThirdParty/Kint/resources/compiled/aante-light.css @@ -1 +1 @@ -.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,0.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:8px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#aaa;color:#1d1e1e}.kint-rich .kint-focused{box-shadow:0 0 3px 2px red}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#1d1e1e;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:8px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#f8f8f8;border:1px solid #d7d7d7;color:#1d1e1e;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:4px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#aaa}.kint-rich>dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjNTU1Ii8+PC9zdmc+") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #d7d7d7}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#06f;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:red}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #d7d7d7;background:#f8f8f8;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#f8f8f8;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#f8f8f8}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #d7d7d7;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#f8f8f8;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#f8f8f8;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f8f8f8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#f8f8f8;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #d7d7d7}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#f8f8f8;border:1px solid #d7d7d7;border-top:0}.kint-rich ul.kint-tabs>li{background:#f8f8f8;border:1px solid #d7d7d7;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#aaa;color:red}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#f8f8f8;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#aaa;color:red}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #d7d7d7;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#aaa}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #d7d7d7;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#f8f8f8;color:#1d1e1e}.kint-rich table td{background:#f8f8f8;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #aaa inset}.kint-rich table tr:hover var{color:red}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #f8f8f8}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #aaa;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#f8f8f8}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #aaa,0 1px #aaa,1px 0 #aaa,0 -1px #aaa;color:#f8f8f8;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px red}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:#f8f8f8}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:#f8f8f8;border:1px solid #d7d7d7;border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:25px}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:1px solid #d7d7d7;background:#fff;font-weight:bold;padding-top:0;border-bottom:1px solid #fff !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid #fff}.kint-rich ul>li>pre{border:1px solid #d7d7d7}.kint-rich dt:hover+dd>ul{border-color:#aaa}.kint-rich pre{background:#fff;margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:#cfc}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:#fff}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:#fff}.kint-rich table tr:hover>td{box-shadow:none;background:#cfc} +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:8px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#aaa;color:#1d1e1e}.kint-rich .kint-focused{box-shadow:0 0 3px 2px red}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#1d1e1e;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:8px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#f8f8f8;border:1px solid #d7d7d7;color:#1d1e1e;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:4px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#aaa}.kint-rich>dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjNTU1Ii8+PC9zdmc+") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #d7d7d7}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#06f;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:red}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #d7d7d7;background:#f8f8f8;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#f8f8f8;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#f8f8f8}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #d7d7d7;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#f8f8f8;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#f8f8f8;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f8f8f8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#f8f8f8;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #d7d7d7}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#f8f8f8;border:1px solid #d7d7d7;border-top:0}.kint-rich ul.kint-tabs>li{background:#f8f8f8;border:1px solid #d7d7d7;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#aaa;color:red}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#f8f8f8;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#aaa;color:red}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #d7d7d7;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#aaa}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #d7d7d7;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#f8f8f8;color:#1d1e1e}.kint-rich table td{background:#f8f8f8;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #aaa inset}.kint-rich table tr:hover var{color:red}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #f8f8f8}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #aaa;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#f8f8f8}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #aaa,0 1px #aaa,1px 0 #aaa,0 -1px #aaa;color:#f8f8f8;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px red}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:#f8f8f8}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:#f8f8f8;border:1px solid #d7d7d7;border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:25px}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:1px solid #d7d7d7;background:#fff;font-weight:bold;padding-top:0;border-bottom:1px solid #fff !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid #fff}.kint-rich ul>li>pre{border:1px solid #d7d7d7}.kint-rich dt:hover+dd>ul{border-color:#aaa}.kint-rich pre{background:#fff;margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:#cfc}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:#fff}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:#fff}.kint-rich table tr:hover>td{box-shadow:none;background:#cfc} diff --git a/system/ThirdParty/Kint/resources/compiled/original.css b/system/ThirdParty/Kint/resources/compiled/original.css index e3c2bf413adb..331b2c38fb65 100644 --- a/system/ThirdParty/Kint/resources/compiled/original.css +++ b/system/ThirdParty/Kint/resources/compiled/original.css @@ -1 +1 @@ -.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,0.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:8px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#0092db;color:#1d1e1e}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #5cb730}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#1d1e1e;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:8px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#e0eaef;border:1px solid #b6cedb;color:#1d1e1e;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:4px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#0092db}.kint-rich>dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxnIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0iI0ZGRiI+PHBhdGggZD0iTTEgMWgyOHYyOEgxem01IDE0aDE4bS05IDlWNk0xIDYxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzM3OSIvPjxwYXRoIGQ9Ik0xIDMxaDI4djI4SDF6bTUgMTRoMThtLTkgOVYzNk0xIDkxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzVBMyIvPjxwYXRoIGQ9Ik0xIDEyMWgyOHYyOEgxem01IDVsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZT0iI0NDQyIvPjwvZz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #b6cedb}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#0092db;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#5cb730}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #b6cedb;background:#e0eaef;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#e0eaef;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#e0eaef}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #b6cedb;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#c1d4df;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#d0d0d0;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#e8e8e8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#c1d4df;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #b6cedb}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#e0eaef;border:1px solid #b6cedb;border-top:0}.kint-rich ul.kint-tabs>li{background:#c1d4df;border:1px solid #b6cedb;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#0092db;color:#5cb730}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#e0eaef;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#0092db;color:#5cb730}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #b6cedb;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#0092db}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #b6cedb;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#c1d4df;color:#1d1e1e}.kint-rich table td{background:#e0eaef;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #0092db inset}.kint-rich table tr:hover var{color:#5cb730}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #c1d4df}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #0092db;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#c1d4df}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #0092db,0 1px #0092db,1px 0 #0092db,0 -1px #0092db;color:#e0eaef;font-weight:bold}input.kint-note-input{width:100%}.kint-rich>dl>dt{background:linear-gradient(to bottom, #e3ecf0 0, #c0d4df 100%)}.kint-rich ul.kint-tabs{background:linear-gradient(to bottom, #9dbed0 0px, #b2ccda 100%)}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li{background:#e0eaef}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li.kint-active-tab{background:#c1d4df}.kint-rich>dl.kint-trace>dt{background:linear-gradient(to bottom, #c0d4df 0px, #e3ecf0 100%)}.kint-rich .kint-source .kint-highlight{background:#f0eb96} +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:8px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#0092db;color:#1d1e1e}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #5cb730}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#1d1e1e;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:8px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#e0eaef;border:1px solid #b6cedb;color:#1d1e1e;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:4px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#0092db}.kint-rich>dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxnIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0iI0ZGRiI+PHBhdGggZD0iTTEgMWgyOHYyOEgxem01IDE0aDE4bS05IDlWNk0xIDYxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzM3OSIvPjxwYXRoIGQ9Ik0xIDMxaDI4djI4SDF6bTUgMTRoMThtLTkgOVYzNk0xIDkxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzVBMyIvPjxwYXRoIGQ9Ik0xIDEyMWgyOHYyOEgxem01IDVsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZT0iI0NDQyIvPjwvZz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #b6cedb}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#0092db;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#5cb730}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #b6cedb;background:#e0eaef;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#e0eaef;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#e0eaef}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #b6cedb;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#c1d4df;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#d0d0d0;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#e8e8e8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#c1d4df;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #b6cedb}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#e0eaef;border:1px solid #b6cedb;border-top:0}.kint-rich ul.kint-tabs>li{background:#c1d4df;border:1px solid #b6cedb;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#0092db;color:#5cb730}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#e0eaef;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#0092db;color:#5cb730}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #b6cedb;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#0092db}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #b6cedb;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#c1d4df;color:#1d1e1e}.kint-rich table td{background:#e0eaef;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #0092db inset}.kint-rich table tr:hover var{color:#5cb730}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #c1d4df}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #0092db;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#c1d4df}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #0092db,0 1px #0092db,1px 0 #0092db,0 -1px #0092db;color:#e0eaef;font-weight:bold}input.kint-note-input{width:100%}.kint-rich>dl>dt{background:linear-gradient(to bottom, #e3ecf0 0, #c0d4df 100%)}.kint-rich ul.kint-tabs{background:linear-gradient(to bottom, #9dbed0 0px, #b2ccda 100%)}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li{background:#e0eaef}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li.kint-active-tab{background:#c1d4df}.kint-rich>dl.kint-trace>dt{background:linear-gradient(to bottom, #c0d4df 0px, #e3ecf0 100%)}.kint-rich .kint-source .kint-highlight{background:#f0eb96} diff --git a/system/ThirdParty/Kint/resources/compiled/plain.css b/system/ThirdParty/Kint/resources/compiled/plain.css index ba1eba0ae27f..85a4e739408c 100644 --- a/system/ThirdParty/Kint/resources/compiled/plain.css +++ b/system/ThirdParty/Kint/resources/compiled/plain.css @@ -1 +1 @@ -.kint-plain{background:rgba(255,255,255,0.9);white-space:pre;display:block;font-family:monospace;color:#222}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-lap{font-weight:bold;text-shadow:1px 0 #fff, 0 1px #fff, -1px 0 #fff, 0 -1px #fff} +.kint-plain{background:rgba(255,255,255,.9);white-space:pre;display:block;font-family:monospace;color:#222}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-lap{font-weight:bold;text-shadow:1px 0 #fff,0 1px #fff,-1px 0 #fff,0 -1px #fff} diff --git a/system/ThirdParty/Kint/resources/compiled/solarized-dark.css b/system/ThirdParty/Kint/resources/compiled/solarized-dark.css index 4ab5e287c54a..2cc125edca72 100644 --- a/system/ThirdParty/Kint/resources/compiled/solarized-dark.css +++ b/system/ThirdParty/Kint/resources/compiled/solarized-dark.css @@ -1 +1 @@ -.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:#073642}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#839496}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#839496;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#002b36;border:1px solid #586e75;color:#839496;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd} +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:#073642}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#839496}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#839496;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#002b36;border:1px solid #586e75;color:#839496;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd} diff --git a/system/ThirdParty/Kint/resources/compiled/solarized.css b/system/ThirdParty/Kint/resources/compiled/solarized.css index 952453edc311..8c1a67f08969 100644 --- a/system/ThirdParty/Kint/resources/compiled/solarized.css +++ b/system/ThirdParty/Kint/resources/compiled/solarized.css @@ -1 +1 @@ -.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,0.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#657b83}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#657b83;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#fdf6e3;border:1px solid #93a1a1;color:#657b83;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #93a1a1}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#586e75}.kint-rich pre{color:#657b83;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #93a1a1;background:#fdf6e3;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(101,123,131,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#fdf6e3;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#657b83;background:#fdf6e3}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #93a1a1;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#586e75;background:#eee8d5;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#e2e2e2;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f0f0f0}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#eee8d5;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#657b83}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#657b83;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#586e75;border-bottom:1px dotted #586e75}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #93a1a1}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#fdf6e3;border:1px solid #93a1a1;border-top:0}.kint-rich ul.kint-tabs>li{background:#eee8d5;border:1px solid #93a1a1;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#fdf6e3;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #93a1a1;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #93a1a1;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#eee8d5;color:#586e75}.kint-rich table td{background:#fdf6e3;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #eee8d5}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#eee8d5}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#fdf6e3;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px} +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#657b83}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#657b83;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#fdf6e3;border:1px solid #93a1a1;color:#657b83;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #93a1a1}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#586e75}.kint-rich pre{color:#657b83;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #93a1a1;background:#fdf6e3;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(101,123,131,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#fdf6e3;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#657b83;background:#fdf6e3}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #93a1a1;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#586e75;background:#eee8d5;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#e2e2e2;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f0f0f0}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#eee8d5;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#657b83}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#657b83;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#586e75;border-bottom:1px dotted #586e75}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #93a1a1}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#fdf6e3;border:1px solid #93a1a1;border-top:0}.kint-rich ul.kint-tabs>li{background:#eee8d5;border:1px solid #93a1a1;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#fdf6e3;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #93a1a1;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #93a1a1;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#eee8d5;color:#586e75}.kint-rich table td{background:#fdf6e3;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #eee8d5}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#eee8d5}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#fdf6e3;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px} diff --git a/system/Validation/CreditCardRules.php b/system/Validation/CreditCardRules.php index 61f59d7bfe86..8e17b75d375f 100644 --- a/system/Validation/CreditCardRules.php +++ b/system/Validation/CreditCardRules.php @@ -185,7 +185,7 @@ public function valid_cc_number(?string $ccNumber, string $type): bool } // If empty, it's not a card type we recognize, or invalid type. - if (empty($info)) { + if ($info === null) { return false; } diff --git a/system/Validation/DotArrayFilter.php b/system/Validation/DotArrayFilter.php index 43cb19370784..4f696886451d 100644 --- a/system/Validation/DotArrayFilter.php +++ b/system/Validation/DotArrayFilter.php @@ -93,7 +93,7 @@ private static function filter(array $indexes, array $array): array // If this is the last index, make sure to return it now, // and not try to recurse through things. - if (empty($indexes)) { + if ($indexes === []) { return [$currentIndex => $array[$currentIndex]]; } diff --git a/system/Validation/FormatRules.php b/system/Validation/FormatRules.php index 5089f5a0961f..88775d14de8f 100644 --- a/system/Validation/FormatRules.php +++ b/system/Validation/FormatRules.php @@ -252,7 +252,7 @@ public function valid_emails(?string $str = null): bool */ public function valid_ip(?string $ip = null, ?string $which = null): bool { - if (empty($ip)) { + if ($ip === null || $ip === '') { return false; } @@ -281,7 +281,7 @@ public function valid_ip(?string $ip = null, ?string $which = null): bool */ public function valid_url(?string $str = null): bool { - if (empty($str)) { + if ($str === null || $str === '') { return false; } @@ -305,7 +305,7 @@ public function valid_url(?string $str = null): bool */ public function valid_url_strict(?string $str = null, ?string $validSchemes = null): bool { - if (empty($str)) { + if ($str === null || $str === '' || $str === '0') { return false; } @@ -322,6 +322,8 @@ public function valid_url_strict(?string $str = null, ?string $validSchemes = nu /** * Checks for a valid date and matches a given date format + * + * @param non-empty-string|null $format */ public function valid_date(?string $str = null, ?string $format = null): bool { @@ -329,7 +331,7 @@ public function valid_date(?string $str = null, ?string $format = null): bool return false; } - if (empty($format)) { + if ($format === null || $format === '') { return strtotime($str) !== false; } diff --git a/system/Validation/Rules.php b/system/Validation/Rules.php index b7c585f56c30..7a051f902ed8 100644 --- a/system/Validation/Rules.php +++ b/system/Validation/Rules.php @@ -24,9 +24,10 @@ class Rules /** * The value does not match another field in $data. * - * @param array $data Other field/value pairs + * @param string|null $str + * @param array $data Other field/value pairs */ - public function differs(?string $str, string $field, array $data): bool + public function differs($str, string $field, array $data): bool { if (strpos($field, '.') !== false) { return $str !== dot_array_search($field, $data); @@ -104,7 +105,8 @@ public function is_not_unique(?string $str, string $field, array $data): bool ->limit(1); if ( - ! empty($whereField) && ! empty($whereValue) + $whereField !== null && $whereField !== '' + && $whereValue !== null && $whereValue !== '' && ! preg_match('/^\{(\w+)\}$/', $whereValue) ) { $row = $row->where($whereField, $whereValue); @@ -149,7 +151,8 @@ public function is_unique(?string $str, string $field, array $data): bool ->limit(1); if ( - ! empty($ignoreField) && ! empty($ignoreValue) + $ignoreField !== null && $ignoreField !== '' + && $ignoreValue !== null && $ignoreValue !== '' && ! preg_match('/^\{(\w+)\}$/', $ignoreValue) ) { $row = $row->where("{$ignoreField} !=", $ignoreValue); @@ -177,15 +180,16 @@ public function less_than_equal_to(?string $str, string $max): bool /** * Matches the value of another field in $data. * - * @param array $data Other field/value pairs + * @param string|null $str + * @param array $data Other field/value pairs */ - public function matches(?string $str, string $field, array $data): bool + public function matches($str, string $field, array $data): bool { if (strpos($field, '.') !== false) { return $str === dot_array_search($field, $data); } - return array_key_exists($field, $data) && $str === $data[$field]; + return isset($data[$field]) && $str === $data[$field]; } /** @@ -254,7 +258,7 @@ public function required($str = null): bool */ public function required_with($str = null, ?string $fields = null, array $data = []): bool { - if ($fields === null || empty($data)) { + if ($fields === null || $data === []) { throw new InvalidArgumentException('You must supply the parameters: fields, data.'); } @@ -274,14 +278,16 @@ public function required_with($str = null, ?string $fields = null, array $data = foreach (explode(',', $fields) as $field) { if ( - (array_key_exists($field, $data) && ! empty($data[$field])) - || (strpos($field, '.') !== false && ! empty(dot_array_search($field, $data))) + (array_key_exists($field, $data) + && ! empty($data[$field])) // @phpstan-ignore-line Use empty() + || (strpos($field, '.') !== false + && ! empty(dot_array_search($field, $data))) // @phpstan-ignore-line Use empty() ) { $requiredFields[] = $field; } } - return empty($requiredFields); + return $requiredFields === []; } /** @@ -303,7 +309,7 @@ public function required_without( ?string $error = null, ?string $field = null ): bool { - if ($otherFields === null || empty($data)) { + if ($otherFields === null || $data === []) { throw new InvalidArgumentException('You must supply the parameters: otherFields, data.'); } @@ -321,7 +327,8 @@ public function required_without( foreach (explode(',', $otherFields) as $otherField) { if ( (strpos($otherField, '.') === false) - && (! array_key_exists($otherField, $data) || empty($data[$otherField])) + && (! array_key_exists($otherField, $data) + || empty($data[$otherField])) // @phpstan-ignore-line Use empty() ) { return false; } @@ -336,7 +343,7 @@ public function required_without( $fieldKey = $fieldSplitArray[1]; if (is_array($fieldData)) { - return ! empty(dot_array_search($otherField, $data)[$fieldKey]); + return ! empty(dot_array_search($otherField, $data)[$fieldKey]); // @phpstan-ignore-line Use empty() } $nowField = str_replace('*', $fieldKey, $otherField); $nowFieldVaule = dot_array_search($nowField, $data); diff --git a/system/Validation/StrictRules/Rules.php b/system/Validation/StrictRules/Rules.php index 0887eff28ada..3086ca5a1d95 100644 --- a/system/Validation/StrictRules/Rules.php +++ b/system/Validation/StrictRules/Rules.php @@ -36,13 +36,26 @@ public function __construct() * @param array|bool|float|int|object|string|null $str * @param array $data Other field/value pairs */ - public function differs($str, string $field, array $data): bool - { - if (! is_string($str)) { + public function differs( + $str, + string $otherField, + array $data, + ?string $error = null, + ?string $field = null + ): bool { + if (strpos($otherField, '.') !== false) { + return $str !== dot_array_search($otherField, $data); + } + + if (! array_key_exists($field, $data)) { return false; } - return $this->nonStrictRules->differs($str, $field, $data); + if (! array_key_exists($otherField, $data)) { + return false; + } + + return $str !== ($data[$otherField] ?? null); } /** @@ -144,7 +157,8 @@ public function is_not_unique($str, string $field, array $data): bool ->limit(1); if ( - ! empty($whereField) && ! empty($whereValue) + $whereField !== null && $whereField !== '' + && $whereValue !== null && $whereValue !== '' && ! preg_match('/^\{(\w+)\}$/', $whereValue) ) { $row = $row->where($whereField, $whereValue); @@ -203,7 +217,8 @@ public function is_unique($str, string $field, array $data): bool ->limit(1); if ( - ! empty($ignoreField) && ! empty($ignoreValue) + $ignoreField !== null && $ignoreField !== '' + && $ignoreValue !== null && $ignoreValue !== '' && ! preg_match('/^\{(\w+)\}$/', $ignoreValue) ) { $row = $row->where("{$ignoreField} !=", $ignoreValue); @@ -254,9 +269,26 @@ public function less_than_equal_to($str, string $max): bool * @param array|bool|float|int|object|string|null $str * @param array $data Other field/value pairs */ - public function matches($str, string $field, array $data): bool - { - return $this->nonStrictRules->matches($str, $field, $data); + public function matches( + $str, + string $otherField, + array $data, + ?string $error = null, + ?string $field = null + ): bool { + if (strpos($otherField, '.') !== false) { + return $str === dot_array_search($otherField, $data); + } + + if (! array_key_exists($field, $data)) { + return false; + } + + if (! array_key_exists($otherField, $data)) { + return false; + } + + return $str === ($data[$otherField] ?? null); } /** diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index ad95cde7bc6b..83bb361e7017 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Validation; use Closure; +use CodeIgniter\HTTP\Exceptions\HTTPException; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\Validation\Exceptions\ValidationException; @@ -147,7 +148,7 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup // If no rules exist, we return false to ensure // the developer didn't forget to set the rules. - if (empty($this->rules)) { + if ($this->rules === []) { return false; } @@ -168,12 +169,14 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup } if (strpos($field, '*') !== false) { - $values = array_filter(array_flatten_with_dots($data), static fn ($key) => preg_match( - '/^' - . str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/')) - . '$/', - $key - ), ARRAY_FILTER_USE_KEY); + $flattenedArray = array_flatten_with_dots($data); + + $values = array_filter( + $flattenedArray, + static fn ($key) => preg_match(self::getRegex($field), $key), + ARRAY_FILTER_USE_KEY + ); + // if keys not found $values = $values ?: [$field => null]; } else { @@ -211,6 +214,20 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup return false; } + /** + * Returns regex pattern for key with dot array syntax. + */ + private static function getRegex(string $field): string + { + return '/\A' + . str_replace( + ['\.\*', '\*\.'], + ['\.[^.]+', '[^.]+\.'], + preg_quote($field, '/') + ) + . '\z/'; + } + /** * Runs the validation process, returning true or false determining whether * validation was successful or not. @@ -480,6 +497,10 @@ public function withRequest(RequestInterface $request): ValidationInterface if (strpos($request->getHeaderLine('Content-Type'), 'application/json') !== false) { $this->data = $request->getJSON(true); + if (! is_array($this->data)) { + throw HTTPException::forUnsupportedJSONFormat(); + } + return $this; } @@ -686,7 +707,7 @@ public function showError(string $field, string $template = 'single'): string */ protected function loadRuleSets() { - if (empty($this->ruleSetFiles)) { + if ($this->ruleSetFiles === [] || $this->ruleSetFiles === null) { throw ValidationException::forNoRuleSets(); } @@ -703,13 +724,15 @@ protected function loadRuleSets() * same format used with setRules(). Additionally, check * for {group}_errors for an array of custom error messages. * + * @param non-empty-string|null $group + * * @return array [rules, customErrors] * * @throws ValidationException */ public function loadRuleGroup(?string $group = null) { - if (empty($group)) { + if ($group === null || $group === '') { return []; } @@ -814,9 +837,7 @@ private function retrievePlaceholders(string $rule, array $data): array */ public function hasError(string $field): bool { - $pattern = '/^' . str_replace('\.\*', '\..+', preg_quote($field, '/')) . '$/'; - - return (bool) preg_grep($pattern, array_keys($this->getErrors())); + return (bool) preg_grep(self::getRegex($field), array_keys($this->getErrors())); } /** @@ -829,10 +850,11 @@ public function getError(?string $field = null): string $field = array_key_first($this->rules); } - $errors = array_filter($this->getErrors(), static fn ($key) => preg_match( - '/^' . str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/')) . '$/', - $key - ), ARRAY_FILTER_USE_KEY); + $errors = array_filter( + $this->getErrors(), + static fn ($key) => preg_match(self::getRegex($field), $key), + ARRAY_FILTER_USE_KEY + ); return $errors === [] ? '' : implode("\n", $errors); } @@ -868,7 +890,8 @@ public function setError(string $field, string $error): ValidationInterface /** * Attempts to find the appropriate error message * - * @param string|null $value The value that caused the validation to fail. + * @param non-empty-string|null $label + * @param string|null $value The value that caused the validation to fail. */ protected function getErrorMessage( string $rule, @@ -892,10 +915,10 @@ protected function getErrorMessage( $message = lang('Validation.' . $rule); } - $message = str_replace('{field}', empty($label) ? $field : lang($label), $message); + $message = str_replace('{field}', ($label === null || $label === '') ? $field : lang($label), $message); $message = str_replace( '{param}', - empty($this->rules[$param]['label']) ? $param : lang($this->rules[$param]['label']), + (! isset($this->rules[$param]['label'])) ? $param : lang($this->rules[$param]['label']), $message ); diff --git a/system/Validation/ValidationInterface.php b/system/Validation/ValidationInterface.php index 78c38468ddd0..c289afc4541d 100644 --- a/system/Validation/ValidationInterface.php +++ b/system/Validation/ValidationInterface.php @@ -134,6 +134,8 @@ public function reset(): ValidationInterface; * same format used with setRules(). Additionally, check * for {group}_errors for an array of custom error messages. * + * @param non-empty-string|null $group + * * @return array */ public function loadRuleGroup(?string $group = null); diff --git a/system/Validation/Views/list.php b/system/Validation/Views/list.php index cc95156cd5c4..3669f038e806 100644 --- a/system/Validation/Views/list.php +++ b/system/Validation/Views/list.php @@ -1,4 +1,4 @@ - +