diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml deleted file mode 100644 index 174620946a..0000000000 --- a/.github/workflows/phpcs.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: PHP Coding Standard - -on: - push: - branches: - - 'master' - pull_request: - branches: - - '*' - -permissions: - contents: read - -jobs: - phpcs: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php-version: - - '7.4' - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install PHP with extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On - tools: composer - - - name: Composer get cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - - name: Cache Composer - uses: actions/cache@v3 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: | - ${{ runner.os }}-php${{ matrix.php-version }}-composer- - - - name: Install Composer Packages - run: composer install --no-ansi --no-interaction --no-progress --ignore-platform-req=php - - - name: Install CodeSniffer Rule - run: vendors/bin/phpcs --config-set installed_paths vendors/cakephp/cakephp-codesniffer - - - name: Check CodeSniffer - run: vendors/bin/phpcs -p --extensions=php --standard=ruleset.xml ./lib/Cake diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 853c59f66b..1d30e338a5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,6 +29,12 @@ jobs: db-type: sqlite - php-version: '8.1' db-type: mysql + - php-version: '8.5' + db-type: mysql + - php-version: '8.5' + db-type: pgsql + - php-version: '8.5' + db-type: sqlite services: mysql: @@ -61,13 +67,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP with extensions uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} - extensions: apcu, memcache, memcached, redis, mcrypt, pdo_mysql, pdo_pgsql, pdo_sqlite + extensions: apcu, memcache, memcached, redis, intl, pdo_mysql, pdo_pgsql, pdo_sqlite ini-values: | assert.exception=1, zend.assertions=1, @@ -105,7 +111,7 @@ jobs: run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache Composer - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }} diff --git a/README.md b/README.md index 24cea1b044..cde2fbcbb5 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,56 @@ Unfortunately branch 2.x in original repository was taken down. -## Incoming breaking changes +## Zumba fork: PHP 8.5 branch (`cakephp2-php85`) -The `strftime` function is widely used in the framework codebase. We plan to replace it with `IntlDateFormatter::format()`, this method comes from the `Intl` extension. CakePHP2 doesn't use it, so it would be a **breaking change**. We'd like to start rolling it out in early **May 2024**. +This repository (`zumba/cakephp2-php8`) is Zumba's fork of [kamilwylegala/cakephp2-php8](https://github.com/kamilwylegala/cakephp2-php8). +The `cakephp2-php85` branch is the version our applications use on PHP 8.5 containers. It contains: -If you have any concerns, let's discuss it under: https://github.com/kamilwylegala/cakephp2-php8/issues/65 +- Every upstream fix up to and including the CSRF hardening (upstream #76), the PHP 8.4 fixes (#75, #83) and the PHP 8.5 fixes (#86). +- A CI matrix that runs the framework test suite on PHP 8.0, 8.1 and 8.5. The test bootstrap converts every deprecation into a failure, so a green build means no deprecation notices on those versions. +- A local `docker/web` image based on `php:8.5-apache`. + +The code stays compatible with PHP 8.0+; no PHP 8.5-only syntax is used. + +### Requirements on PHP 8.5 + +- `ext-intl` must be installed in the container. `strftime()` was replaced by `IntlDateFormatter` (via `php81_bc/strftime`), which requires it. +- `ext-mcrypt` is no longer needed; `Security::encrypt()`/`decrypt()` use OpenSSL. + +### Using the branch in an application + +Point `composer.json` at this repository and at the branch: + +``` +{ + "require": { + "cakephp/cakephp": "dev-cakephp2-php85 as 2.11.0" + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/zumba/cakephp2-php8" + } + ] +} +``` + +### Update procedure + +Updating an application to the latest state of the branch is a standard composer update: + +``` +composer update cakephp/cakephp +``` + +Then run the application's own test suite under PHP 8.5. Commit the resulting `composer.lock`. + +### Syncing new upstream fixes into the branch + +1. `git fetch upstream` (where `upstream` is `https://github.com/kamilwylegala/cakephp2-php8.git`). +2. Bring the new upstream commits onto a feature branch cut from `cakephp2-php85` (merge or cherry-pick). +3. Run the test suite on PHP 8.5 (locally via `docker compose up` or by pushing and letting CI run the matrix). +4. Open a PR into `cakephp2-php85`. ## Why I created this fork? 🤔 @@ -38,6 +83,10 @@ Here are steps I took to migrate my project through all versions to PHP 8.1, may - ~~Due to lack of tests ☝️~~ - **you also need to rely** on tests in your application after integrating with this fork. - If after integration you spot any issues related to framework please let me know by creating an issue or pull request with fix. +### Breaking changes + +- In order to get rid of `strftime()` deprecation notices, it's required to switch to `IntlDateFormatter` class. This class is available in `intl` extension. Fork doesn't require it explicitly but to be able to use its functions Symfony ICU Polyfill is installed. To provide `strftime` behavior compatibility, `PHP81_BC\strftime` is used. `PHP81_BC` doesn't fully cover strftime, your code should work but there is a chance you'll get slightly different results. Discussed (here)[https://github.com/kamilwylegala/cakephp2-php8/pull/64] and (here)[https://github.com/kamilwylegala/cakephp2-php8/issues/65]. + ## Installation This repository **is not** available in packagist, therefore your project's `composer.json` must be changed to point to custom repository. @@ -61,6 +110,49 @@ It means that composer will look at `master` branch of repository configured und ## Changelog +### 2026-10-16 (Zumba, branch `cakephp2-php85`) + +- Version bumped to **2.11.0** (`lib/Cake/VERSION.txt`): new runtime requirement (`ext-intl`) and behaviour changes (exceptions instead of `E_USER_ERROR`, OpenSSL fallback) warrant a minor bump; upstream stays at 2.10.24, so the number also identifies this branch. Alias it as `dev-cakephp2-php85 as 2.11.0` in applications. +- Synced all upstream fixes up to `kamilwylegala/cakephp2-php8` #87 (includes the CSRF fix #76 and the PHP 8.4/8.5 fixes #75, #83, #86). +- CI matrix now runs PHP 8.0, 8.1 and 8.5; the test `app/Config/core.php` reports `E_ALL` so any deprecation fails the suite. +- PHP 8.5: `Security::cipher()` no longer casts the out-of-range `Security.cipherSeed` float to int (same seed value, no deprecation); `limit()`/`offset()` clamp out-of-range values instead of casting; `ConsoleLog` no longer calls `posix_isatty(null)`; `ReflectionProperty::setAccessible()` only on PHP < 8.1; null array offsets in `I18n`, `Helper`, `CakeResponse`, `ConsoleOptionParser`, `RequestHandlerComponent`, `Set`, `Configure`, `CakeSession` replaced by explicit checks; `libxml_disable_entity_loader()` calls removed. +- PHP 8.4: `trigger_error(..., E_USER_ERROR)` replaced by exceptions (`ConfigureException`, `CakeException`, `RuntimeException` in the webroot/console bootstrap scripts) or `ErrorHandler::handleFatalError()`. +- PHP 8.2: undeclared (dynamic) properties declared on `Scaffold`, `ConsoleOptionParser`, `HelpFormatter`, `MemcachedEngine`, `CakeTestCase`, `CakeTestFixture`, `CakeFixtureManager`, `ControllerTestDispatcher` and ~100 test classes; `ConnectionManager::create()` stores runtime connections on a `#[\AllowDynamicProperties]` subclass of `DATABASE_CONFIG`; `CakeRequest` allows dynamic properties. +- PHP 8.1: remaining "passing null to non-nullable internal parameter" cases fixed across the framework (strlen/strpos/strtolower/preg_*/trim/substr/… with `(string)` casts or null checks). +- `Security::encrypt()`/`decrypt()` fall back to OpenSSL when ext-mcrypt is missing. +- `SessionHandlerAdapter` methods marked `#[\ReturnTypeWillChange]`. +- Local `docker/web` image moved to `php:8.5-apache` (with `intl`, without `mcrypt`). + +### 2025-02-04 + +- Fixes for PHP 8.4: `session_set_save_handler` accepts object, removed `E_STRICT` reference. +- Removed github action with php code sniffer. It's quite painful to work with. Need to migrate to something newer, that will affect code base as little as possible. + +### 2024-11-16 + +- Inflector fix: str_place with null. + +### 2024-09-21 + +- Added wrapper for PDOException to avoid creating dynamic property `queryString`. + +### 2024-07-24 + +- Csrf vulnerabity fix back ported from Cake PHP 3 +- Explicit type hint definition of nullable parameters. + +### 2024-06-05 + +- Removed usage of `strftime`, replaced with Intl extension. + +### 2024-05-24 + +- Fix deprecation error in Model: `Automatic conversion of false to array is deprecated` + +### 2024-05-22 + +- Fix deprecation error in I18n: `Automatic conversion of false to array is deprecated` + ### 2024-02-02 - `str_len` deprecation warning fix in CakeResponse (passing null instead of `string`) diff --git a/app/Config/core.php b/app/Config/core.php index da5555a340..adc85d98cc 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -53,7 +53,7 @@ */ Configure::write('Error', array( 'handler' => 'ErrorHandler::handleError', - 'level' => E_ALL & ~E_DEPRECATED, + 'level' => E_ALL, 'trace' => true )); diff --git a/app/Console/cake.php b/app/Console/cake.php index d4a6aeaf01..4eed898d09 100644 --- a/app/Console/cake.php +++ b/app/Console/cake.php @@ -40,7 +40,7 @@ } if (!include $dispatcher) { - trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); + throw new RuntimeException('Could not locate CakePHP core files.'); } unset($dispatcher); diff --git a/app/webroot/index.php b/app/webroot/index.php index 18c098d8e0..7a9679b60c 100644 --- a/app/webroot/index.php +++ b/app/webroot/index.php @@ -106,7 +106,7 @@ $failed = true; } if (!empty($failed)) { - trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); + throw new RuntimeException("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory."); } App::uses('Dispatcher', 'Routing'); diff --git a/app/webroot/test.php b/app/webroot/test.php index 2f8f8d3c0c..a3274584c6 100644 --- a/app/webroot/test.php +++ b/app/webroot/test.php @@ -100,7 +100,7 @@ } } if (!empty($failed)) { - trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/test.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); + throw new RuntimeException("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/test.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory."); } if (Configure::read('debug') < 1) { diff --git a/composer.json b/composer.json index 8fbb39241c..426391415f 100644 --- a/composer.json +++ b/composer.json @@ -18,15 +18,18 @@ "source": "https://github.com/cakephp/cakephp" }, "require": { - "php": "^8.0" + "php": "^8.0", + "ext-mbstring": "*", + "symfony/polyfill-intl-icu": "^1.29", + "php81_bc/strftime": "^0.7.5" }, "suggest": { "ext-openssl": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption", - "ext-mcrypt": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption" + "ext-mcrypt": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption", + "ext-intl": "Required to use IntlDateFormatter instead of strftime, if not Symfony polyfill will be used." }, "require-dev": { - "phpunit/phpunit": "^9.5", - "cakephp/cakephp-codesniffer": "^1.0.0" + "phpunit/phpunit": "^9.5" }, "config": { "vendor-dir": "vendors/", @@ -37,10 +40,8 @@ ], "scripts": { "check": [ - "@cs-check", "@test" ], - "cs-check": "./vendors/bin/phpcs -p --extensions=php --standard=CakePHP ./lib/Cake", "test": "./lib/Cake/Console/cake test core AllTests --stderr --verbose" } } diff --git a/docker/web/Dockerfile b/docker/web/Dockerfile index d9c90b56e1..7fc1c4785e 100644 --- a/docker/web/Dockerfile +++ b/docker/web/Dockerfile @@ -1,12 +1,12 @@ -FROM php:8.2-apache +FROM php:8.5-apache RUN apt-get update && apt-get install -y --no-install-recommends \ - && apt-get install -y libpq-dev libzip-dev unzip openssl libmcrypt-dev libmemcached-dev locales \ + && apt-get install -y libpq-dev libzip-dev unzip openssl libmcrypt-dev libmemcached-dev libicu-dev locales \ && rm -rf /var/lib/apt/lists/* -RUN docker-php-ext-install pdo_mysql pdo_pgsql zip \ - && pecl install apcu redis memcached mcrypt xdebug \ - && docker-php-ext-enable redis memcached mcrypt \ +RUN docker-php-ext-install pdo_mysql pdo_pgsql zip intl \ + && pecl install apcu redis memcached xdebug \ + && docker-php-ext-enable redis memcached \ && docker-php-ext-enable xdebug \ && echo "extension=apcu.so" >> /usr/local/etc/php/php.ini \ && echo "apc.enable_cli = 1" >> /usr/local/etc/php/php.ini diff --git a/lib/Cake/Cache/Engine/MemcachedEngine.php b/lib/Cake/Cache/Engine/MemcachedEngine.php index 655eb5d1cf..691d658e70 100644 --- a/lib/Cake/Cache/Engine/MemcachedEngine.php +++ b/lib/Cake/Cache/Engine/MemcachedEngine.php @@ -54,6 +54,14 @@ class MemcachedEngine extends CacheEngine { */ public $settings = array(); +/** + * Contains the compiled group names + * (prefixed with the global configuration prefix) + * + * @var array + */ + protected $_compiledGroupNames = array(); + /** * List of available serializer engines * diff --git a/lib/Cake/Cache/Engine/RedisEngine.php b/lib/Cake/Cache/Engine/RedisEngine.php index 405729227f..c95619bf3c 100644 --- a/lib/Cake/Cache/Engine/RedisEngine.php +++ b/lib/Cake/Cache/Engine/RedisEngine.php @@ -173,7 +173,7 @@ public function decrement($key, $offset = 1) { * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { - return $this->_Redis->delete($key) > 0; + return $this->_Redis->del($key) > 0; } /** diff --git a/lib/Cake/Console/Command/SchemaShell.php b/lib/Cake/Console/Command/SchemaShell.php index 6a704bda81..7ebfaef96c 100644 --- a/lib/Cake/Console/Command/SchemaShell.php +++ b/lib/Cake/Console/Command/SchemaShell.php @@ -62,7 +62,7 @@ public function startup() { $name = $this->params['name'] = $this->args[0]; } - if (strpos($name, '.')) { + if ($name !== null && strpos($name, '.')) { list($this->params['plugin'], $splitName) = pluginSplit($name); $name = $this->params['name'] = $splitName; } diff --git a/lib/Cake/Console/Command/Task/CommandTask.php b/lib/Cake/Console/Command/Task/CommandTask.php index 99c888f8e8..f4bd84774e 100644 --- a/lib/Cake/Console/Command/Task/CommandTask.php +++ b/lib/Cake/Console/Command/Task/CommandTask.php @@ -133,7 +133,7 @@ public function subCommands($commandName) { public function getShell($commandName) { list($pluginDot, $name) = pluginSplit($commandName, true); - if (in_array(strtolower($pluginDot), array('app.', 'core.'))) { + if (in_array(strtolower((string)$pluginDot), array('app.', 'core.'))) { $commandName = $name; $pluginDot = ''; } diff --git a/lib/Cake/Console/Command/Task/ExtractTask.php b/lib/Cake/Console/Command/Task/ExtractTask.php index eaa691e318..fd94873f38 100644 --- a/lib/Cake/Console/Command/Task/ExtractTask.php +++ b/lib/Cake/Console/Command/Task/ExtractTask.php @@ -173,7 +173,7 @@ public function execute() { $this->_extractCore = !(strtolower($this->params['extract-core']) === 'no'); } else { $response = $this->in(__d('cake_console', 'Would you like to extract the messages from the CakePHP core?'), array('y', 'n'), 'n'); - $this->_extractCore = strtolower($response) === 'y'; + $this->_extractCore = strtolower((string)$response) === 'y'; } if (!empty($this->params['exclude-plugins']) && $this->_isExtractingApp()) { @@ -221,7 +221,7 @@ public function execute() { } else { $this->out(); $response = $this->in(__d('cake_console', 'Would you like to merge all domain and category strings into the default.pot file?'), array('y', 'n'), 'n'); - $this->_merge = strtolower($response) === 'y'; + $this->_merge = strtolower((string)$response) === 'y'; } if (empty($this->_files)) { diff --git a/lib/Cake/Console/Command/Task/FixtureTask.php b/lib/Cake/Console/Command/Task/FixtureTask.php index 7b2ee52e7d..23b021042f 100644 --- a/lib/Cake/Console/Command/Task/FixtureTask.php +++ b/lib/Cake/Console/Command/Task/FixtureTask.php @@ -203,7 +203,7 @@ public function importOptions($modelName) { if (!isset($options['records']) && $this->interactive) { $prompt = __d('cake_console', "Would you like to build this fixture with data from %s's table?", $modelName); $fromTable = $this->in($prompt, array('y', 'n'), 'n'); - if (strtolower($fromTable) === 'y') { + if (strtolower((string)$fromTable) === 'y') { $options['fromTable'] = true; } } @@ -248,7 +248,7 @@ public function bake($model, $useTable = false, $importOptions = array()) { $this->_Schema = new CakeSchema(); $data = $this->_Schema->read(array('models' => false, 'connection' => $this->connection)); if (!isset($data['tables'][$useTable])) { - $this->err("Warning: Could not find the '${useTable}' table for ${model}."); + $this->err("Warning: Could not find the '{$useTable}' table for {$model}."); return null; } diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php index f70cf656d5..f26912ec85 100644 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ b/lib/Cake/Console/Command/Task/ModelTask.php @@ -170,7 +170,7 @@ public function inOptions($options, $prompt = null, $default = null) { while (!$valid) { $len = strlen(count($options) + 1); foreach ($options as $i => $option) { - $this->out(sprintf("%${len}d. %s", $i + 1, $option)); + $this->out(sprintf("%{$len}d. %s", $i + 1, $option)); } if (empty($prompt)) { $prompt = __d('cake_console', 'Make a selection from the choices above'); @@ -426,7 +426,7 @@ public function fieldValidation($fieldName, $metaData, $primaryKey = 'id') { $this->hr(); $optionText = ''; - for ($i = 1, $m = $defaultChoice / 2; $i <= $m; $i++) { + for ($i = 1, $m = (int)($defaultChoice / 2); $i <= $m; $i++) { $line = sprintf("%2d. %s", $i, $this->_validations[$i]); $optionText .= $line . str_repeat(" ", 31 - strlen($line)); if ($m + $i !== $defaultChoice) { @@ -710,7 +710,7 @@ public function confirmAssociations(Model $model, $associations) { $prompt = "{$model->name} {$type} {$assoc['alias']}?"; $response = $this->in($prompt, array('y', 'n'), 'y'); - if (strtolower($response) === 'n') { + if (strtolower((string)$response) === 'n') { unset($associations[$type][$i]); } elseif ($type === 'hasMany') { unset($associations['hasOne'][$i]); @@ -901,7 +901,7 @@ public function listAll($useDbConfig = null) { $this->out(__d('cake_console', 'Possible Models based on your current database:')); $len = strlen($count + 1); for ($i = 0; $i < $count; $i++) { - $this->out(sprintf("%${len}d. %s", $i + 1, $this->_modelNames[$i])); + $this->out(sprintf("%{$len}d. %s", $i + 1, $this->_modelNames[$i])); } } return $this->_tables; diff --git a/lib/Cake/Console/Command/Task/TestTask.php b/lib/Cake/Console/Command/Task/TestTask.php index a4c4e936b0..dd410c977d 100644 --- a/lib/Cake/Console/Command/Task/TestTask.php +++ b/lib/Cake/Console/Command/Task/TestTask.php @@ -456,7 +456,7 @@ protected function _addFixture($name) { public function getUserFixtures() { $proceed = $this->in(__d('cake_console', 'Bake could not detect fixtures, would you like to add some?'), array('y', 'n'), 'n'); $fixtures = array(); - if (strtolower($proceed) === 'y') { + if (strtolower((string)$proceed) === 'y') { $fixtureList = $this->in(__d('cake_console', "Please provide a comma separated list of the fixtures names you'd like to use.\nExample: 'app.comment, app.post, plugin.forums.post'")); $fixtureListTrimmed = str_replace(' ', '', $fixtureList); $fixtures = explode(',', $fixtureListTrimmed); diff --git a/lib/Cake/Console/ConsoleInputOption.php b/lib/Cake/Console/ConsoleInputOption.php index 139c983539..2a7096e5a9 100644 --- a/lib/Cake/Console/ConsoleInputOption.php +++ b/lib/Cake/Console/ConsoleInputOption.php @@ -90,7 +90,7 @@ public function __construct($name, $short = null, $help = '', $boolean = false, $this->_default = $default; $this->_choices = $choices; } - if (strlen($this->_short) > 1) { + if (strlen((string)$this->_short) > 1) { throw new ConsoleException( __d('cake_console', 'Short option "%s" is invalid, short options must be one letter.', $this->_short) ); @@ -204,7 +204,7 @@ public function xml(SimpleXmlElement $parent) { $option = $parent->addChild('option'); $option->addAttribute('name', '--' . $this->_name); $short = ''; - if (strlen($this->_short)) { + if (strlen((string)$this->_short)) { $short = '-' . $this->_short; } $option->addAttribute('short', $short); diff --git a/lib/Cake/Console/ConsoleOptionParser.php b/lib/Cake/Console/ConsoleOptionParser.php index f313c41c96..f80e8e85c8 100644 --- a/lib/Cake/Console/ConsoleOptionParser.php +++ b/lib/Cake/Console/ConsoleOptionParser.php @@ -86,6 +86,13 @@ class ConsoleOptionParser { */ protected $_description = null; +/** + * Tokens left to parse while parse() is running. + * + * @var array + */ + protected $_tokens = array(); + /** * Epilog text - displays after options when help is generated * @@ -473,7 +480,7 @@ public function subcommands() { * @throws ConsoleException When an invalid parameter is encountered. */ public function parse($argv, $command = null) { - if (isset($this->_subcommands[$command]) && $this->_subcommands[$command]->parser()) { + if ($command !== null && isset($this->_subcommands[$command]) && $this->_subcommands[$command]->parser()) { return $this->_subcommands[$command]->parser()->parse($argv); } $params = $args = array(); @@ -521,7 +528,7 @@ public function parse($argv, $command = null) { * @return string Generated help. */ public function help($subcommand = null, $format = 'text', $width = 72) { - if (isset($this->_subcommands[$subcommand]) && + if ($subcommand !== null && isset($this->_subcommands[$subcommand]) && $this->_subcommands[$subcommand]->parser() instanceof self ) { $subparser = $this->_subcommands[$subcommand]->parser(); diff --git a/lib/Cake/Console/HelpFormatter.php b/lib/Cake/Console/HelpFormatter.php index 0c4259aae3..6cf2f1d081 100644 --- a/lib/Cake/Console/HelpFormatter.php +++ b/lib/Cake/Console/HelpFormatter.php @@ -37,6 +37,13 @@ class HelpFormatter { */ protected $_maxArgs = 6; +/** + * Option parser being formatted. + * + * @var ConsoleOptionParser + */ + protected $_parser = null; + /** * The maximum number of options shown when generating usage. * diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index 2e9cebf257..dd0663f2f2 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -851,7 +851,7 @@ protected function _checkUnitTest() { * @link https://book.cakephp.org/2.0/en/console-and-shells.html#Shell::shortPath */ public function shortPath($file) { - $shortPath = str_replace(ROOT, null, $file); + $shortPath = str_replace(ROOT, '', $file); $shortPath = str_replace('..' . DS, '', $shortPath); return str_replace(DS . DS, DS, $shortPath); } diff --git a/lib/Cake/Console/TaskCollection.php b/lib/Cake/Console/TaskCollection.php index 5d2e7a7a9a..50fd73610b 100644 --- a/lib/Cake/Console/TaskCollection.php +++ b/lib/Cake/Console/TaskCollection.php @@ -87,7 +87,7 @@ public function load($task, $settings = array()) { if (!$exists) { throw new MissingTaskException(array( 'class' => $taskClass, - 'plugin' => substr($plugin, 0, -1) + 'plugin' => substr((string)$plugin, 0, -1) )); } diff --git a/lib/Cake/Console/Templates/skel/Console/cake.php b/lib/Cake/Console/Templates/skel/Console/cake.php index 280613a271..34d90895ff 100644 --- a/lib/Cake/Console/Templates/skel/Console/cake.php +++ b/lib/Cake/Console/Templates/skel/Console/cake.php @@ -41,7 +41,7 @@ } if (!include $dispatcher) { - trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); + throw new RuntimeException('Could not locate CakePHP core files.'); } unset($dispatcher); diff --git a/lib/Cake/Console/Templates/skel/webroot/index.php b/lib/Cake/Console/Templates/skel/webroot/index.php index 4f9a70955d..fd0172a528 100644 --- a/lib/Cake/Console/Templates/skel/webroot/index.php +++ b/lib/Cake/Console/Templates/skel/webroot/index.php @@ -99,7 +99,7 @@ $failed = true; } if (!empty($failed)) { - trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); + throw new RuntimeException("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory."); } App::uses('Dispatcher', 'Routing'); diff --git a/lib/Cake/Console/Templates/skel/webroot/test.php b/lib/Cake/Console/Templates/skel/webroot/test.php index caa2933165..166f9c3453 100644 --- a/lib/Cake/Console/Templates/skel/webroot/test.php +++ b/lib/Cake/Console/Templates/skel/webroot/test.php @@ -84,7 +84,7 @@ } } if (!empty($failed)) { - trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); + throw new RuntimeException("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory."); } if (Configure::read('debug') < 1) { diff --git a/lib/Cake/Console/cake.php b/lib/Cake/Console/cake.php index b825e02364..52aa35a3ef 100644 --- a/lib/Cake/Console/cake.php +++ b/lib/Cake/Console/cake.php @@ -41,7 +41,7 @@ } elseif (file_exists($rootInstall)) { include $rootInstall; } else { - trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); + throw new RuntimeException('Could not locate CakePHP core files.'); } unset($rootInstall, $composerInstall); diff --git a/lib/Cake/Controller/Component/Auth/BaseAuthorize.php b/lib/Cake/Controller/Component/Auth/BaseAuthorize.php index 1e6a0d6886..feefb88c29 100644 --- a/lib/Cake/Controller/Component/Auth/BaseAuthorize.php +++ b/lib/Cake/Controller/Component/Auth/BaseAuthorize.php @@ -89,7 +89,7 @@ abstract public function authorize($user, CakeRequest $request); * @return mixed * @throws CakeException */ - public function controller(Controller $controller = null) { + public function controller(?Controller $controller = null) { if ($controller) { if (!$controller instanceof Controller) { throw new CakeException(__d('cake_dev', '$controller needs to be an instance of Controller')); diff --git a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php index b19f23c934..aa350f6720 100644 --- a/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php @@ -84,9 +84,9 @@ public function authenticate(CakeRequest $request, CakeResponse $response) { public function getUser(CakeRequest $request) { $username = env('PHP_AUTH_USER'); $pass = env('PHP_AUTH_PW'); - if (!strlen($username)) { + if (!strlen((string)$username)) { $httpAuthorization = $request->header('Authorization'); - if (strlen($httpAuthorization) > 0 && strpos($httpAuthorization, 'Basic') !== false) { + if (strlen((string)$httpAuthorization) > 0 && strpos($httpAuthorization, 'Basic') !== false) { list($username, $pass) = explode(':', base64_decode(substr($httpAuthorization, 6))); } } diff --git a/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php b/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php index c55ef3d3ea..62b3065067 100644 --- a/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php +++ b/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php @@ -43,7 +43,7 @@ class ControllerAuthorize extends BaseAuthorize { * @return mixed * @throws CakeException */ - public function controller(Controller $controller = null) { + public function controller(?Controller $controller = null) { if ($controller) { if (!method_exists($controller, 'isAuthorized')) { throw new CakeException(__d('cake_dev', '$controller does not implement an %s method.', 'isAuthorized()')); diff --git a/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php b/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php index 04637994fd..175f94d07c 100644 --- a/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php @@ -102,7 +102,7 @@ public function __construct(ComponentCollection $collection, $settings) { $this->settings['nonce'] = uniqid(''); } if (empty($this->settings['opaque'])) { - $this->settings['opaque'] = md5($this->settings['realm']); + $this->settings['opaque'] = md5((string)$this->settings['realm']); } } diff --git a/lib/Cake/Controller/Component/AuthComponent.php b/lib/Cake/Controller/Component/AuthComponent.php index a652e950ab..f21ac5cacd 100644 --- a/lib/Cake/Controller/Component/AuthComponent.php +++ b/lib/Cake/Controller/Component/AuthComponent.php @@ -453,7 +453,7 @@ protected function _setDefaults() { * @param CakeRequest|null $request The request to authenticate for. If empty, the current request will be used. * @return bool True if $user is authorized, otherwise false */ - public function isAuthorized($user = null, CakeRequest $request = null) { + public function isAuthorized($user = null, ?CakeRequest $request = null) { if (empty($user) && !$this->user()) { return false; } diff --git a/lib/Cake/Controller/Component/RequestHandlerComponent.php b/lib/Cake/Controller/Component/RequestHandlerComponent.php index 513af4029e..72ffebd644 100644 --- a/lib/Cake/Controller/Component/RequestHandlerComponent.php +++ b/lib/Cake/Controller/Component/RequestHandlerComponent.php @@ -686,7 +686,7 @@ public function respondAs($type, $options = array()) { $cType = $this->response->getMimeType($type); } if (is_array($cType)) { - if (isset($cType[$options['index']])) { + if ($options['index'] !== null && isset($cType[$options['index']])) { $cType = $cType[$options['index']]; } diff --git a/lib/Cake/Controller/Component/SecurityComponent.php b/lib/Cake/Controller/Component/SecurityComponent.php index 308f27c738..e9d779e76a 100644 --- a/lib/Cake/Controller/Component/SecurityComponent.php +++ b/lib/Cake/Controller/Component/SecurityComponent.php @@ -227,7 +227,7 @@ class SecurityComponent extends Component { public function startup(Controller $controller) { $this->request = $controller->request; $this->_action = $controller->request->params['action']; - $hasData = ($controller->request->data || $controller->request->is(array('put', 'post', 'delete', 'patch'))); + $hasData = ($controller->request->data || !$controller->request->is(['head', 'get', 'options'])); try { $this->_methodsRequired($controller); $this->_secureRequired($controller); @@ -344,7 +344,7 @@ public function requireAuth() { * @link https://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#handling-blackhole-callbacks * @throws BadRequestException */ - public function blackHole(Controller $controller, $error = '', SecurityException $exception = null) { + public function blackHole(Controller $controller, $error = '', ?SecurityException $exception = null) { if (!$this->blackHoleCallback) { $this->_throwException($exception); } @@ -822,7 +822,7 @@ protected function _expireTokens($tokens) { * @param string $method Method to execute * @param array $params Parameters to send to method * @return mixed Controller callback method's response - * @throws BadRequestException When a the blackholeCallback is not callable. + * @throws BadRequestException When the blackholeCallback is not callable. */ protected function _callback(Controller $controller, $method, $params = array()) { if (!is_callable(array($controller, $method))) { diff --git a/lib/Cake/Controller/ComponentCollection.php b/lib/Cake/Controller/ComponentCollection.php index a9500dab2d..911f953778 100644 --- a/lib/Cake/Controller/ComponentCollection.php +++ b/lib/Cake/Controller/ComponentCollection.php @@ -110,7 +110,7 @@ public function load($component, $settings = array()) { if (!class_exists($componentClass)) { throw new MissingComponentException(array( 'class' => $componentClass, - 'plugin' => substr($plugin, 0, -1) + 'plugin' => substr((string)$plugin, 0, -1) )); } $this->_loaded[$alias] = new $componentClass($this, $settings); diff --git a/lib/Cake/Controller/Scaffold.php b/lib/Cake/Controller/Scaffold.php index 33999ecb7d..2c7692d785 100644 --- a/lib/Cake/Controller/Scaffold.php +++ b/lib/Cake/Controller/Scaffold.php @@ -96,6 +96,41 @@ class Scaffold { */ public $scaffoldTitle = null; +/** + * Model instance being scaffolded. + * + * @var Model + */ + public $ScaffoldModel = null; + +/** + * Name of the model class being scaffolded. + * + * @var string + */ + public $modelClass = null; + +/** + * Key of the model being scaffolded. + * + * @var string + */ + public $modelKey = null; + +/** + * URL to redirect to after a scaffold action completes. + * + * @var array|string + */ + public $redirect = null; + +/** + * Actions that are scaffolded. + * + * @var array|bool|string + */ + public $scaffoldActions = null; + /** * Construct and set up given controller with given parameters. * diff --git a/lib/Cake/Core/Configure.php b/lib/Cake/Core/Configure.php index 901606cd23..7c7c26448c 100644 --- a/lib/Cake/Core/Configure.php +++ b/lib/Cake/Core/Configure.php @@ -70,11 +70,10 @@ public static function bootstrap($boot = true) { static::_appDefaults(); if (!include CONFIG . 'core.php') { - trigger_error(__d('cake_dev', - "Can't find application core file. Please create %s, and make sure it is readable by PHP.", - CONFIG . 'core.php'), - E_USER_ERROR - ); + throw new ConfigureException(__d('cake_dev', + "Can't find application core file. Please create %s, and make sure it is readable by PHP.", + CONFIG . 'core.php' + )); } App::init(); App::$bootstrapping = false; @@ -96,11 +95,10 @@ public static function bootstrap($boot = true) { static::_setErrorHandlers($error, $exception); if (!include CONFIG . 'bootstrap.php') { - trigger_error(__d('cake_dev', - "Can't find application bootstrap file. Please create %s, and make sure it is readable by PHP.", - CONFIG . 'bootstrap.php'), - E_USER_ERROR - ); + throw new ConfigureException(__d('cake_dev', + "Can't find application bootstrap file. Please create %s, and make sure it is readable by PHP.", + CONFIG . 'bootstrap.php' + )); } restore_error_handler(); @@ -209,6 +207,9 @@ public static function read($var = null) { * @return array|null */ public static function consume($var) { + if ($var === null) { + return null; + } $simple = strpos($var, '.') === false; if ($simple && !isset(static::$_values[$var])) { return null; diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php index de892f6be0..c260578deb 100644 --- a/lib/Cake/Error/ErrorHandler.php +++ b/lib/Cake/Error/ErrorHandler.php @@ -135,7 +135,7 @@ public static function handleException($exception) { ); static::$_bailExceptionRendering = true; - trigger_error($message, E_USER_ERROR); + static::handleFatalError(E_USER_ERROR, $message, $e->getFile(), $e->getLine()); } } @@ -302,10 +302,6 @@ public static function mapErrorCode($code) { $error = 'Notice'; $log = LOG_NOTICE; break; - case E_STRICT: - $error = 'Strict'; - $log = LOG_NOTICE; - break; case E_DEPRECATED: case E_USER_DEPRECATED: $error = 'Deprecated'; diff --git a/lib/Cake/Error/exceptions.php b/lib/Cake/Error/exceptions.php index 6608f62218..373d01a1bd 100644 --- a/lib/Cake/Error/exceptions.php +++ b/lib/Cake/Error/exceptions.php @@ -297,7 +297,7 @@ class PrivateActionException extends CakeException { protected $_messageTemplate = 'Private Action %s::%s() is not directly accessible.'; //@codingStandardsIgnoreStart - public function __construct($message, $code = 404, Exception $previous = null) { + public function __construct($message, $code = 404, ?Exception $previous = null) { parent::__construct($message, $code, $previous); } //@codingStandardsIgnoreEnd diff --git a/lib/Cake/I18n/I18n.php b/lib/Cake/I18n/I18n.php index 814c2cfe08..dfa828bde4 100644 --- a/lib/Cake/I18n/I18n.php +++ b/lib/Cake/I18n/I18n.php @@ -196,6 +196,9 @@ public static function translate($singular, $plural = null, $domain = null, $cat $count = null, $language = null, $context = null ) { $_this = I18n::getInstance(); + if ($context === null) { + $context = ''; + } if (strpos($singular, "\r\n") !== false) { $singular = str_replace("\r\n", "\n", $singular); @@ -401,6 +404,9 @@ protected function _bindTextDomain($domain) { if (is_file($localeDef)) { $definitions = static::loadLocaleDefinition($localeDef); if ($definitions !== false) { + if (!isset($this->_domains[$domain][$this->_lang]) || !is_array($this->_domains[$domain][$this->_lang])) { + $this->_domains[$domain][$this->_lang] = array(); + } $this->_domains[$domain][$this->_lang][$this->category] = $definitions; $this->_noLocale = false; return $domain; @@ -419,6 +425,9 @@ protected function _bindTextDomain($domain) { } if ($translations !== false) { + if (!isset($this->_domains[$domain][$this->_lang]) || !is_array($this->_domains[$domain][$this->_lang])) { + $this->_domains[$domain][$this->_lang] = array(); + } $this->_domains[$domain][$this->_lang][$this->category] = $translations; $merge[$domain][$this->_lang][$this->category] = $this->_domains[$domain][$this->_lang][$this->category]; $this->_noLocale = false; @@ -437,7 +446,13 @@ protected function _bindTextDomain($domain) { } if ($translations !== false) { - $this->_domains[$domain][$this->_lang][$this->category] = $translations; + if ($this->_domains[$domain][$this->_lang] === false) { + $this->_domains[$domain][$this->_lang] = [ + $this->category => $translations + ]; + } else { + $this->_domains[$domain][$this->_lang][$this->category] = $translations; + } $this->_noLocale = false; break 2; } @@ -445,7 +460,13 @@ protected function _bindTextDomain($domain) { } if (empty($this->_domains[$domain][$this->_lang][$this->category])) { - $this->_domains[$domain][$this->_lang][$this->category] = array(); + if ($this->_domains[$domain][$this->_lang] === false) { + $this->_domains[$domain][$this->_lang] = [ + $this->category => [] + ]; + } else { + $this->_domains[$domain][$this->_lang][$this->category] = []; + } return $domain; } @@ -465,8 +486,8 @@ protected function _bindTextDomain($domain) { } $this->_domains = Hash::mergeDiff($this->_domains, $merge); - if (isset($this->_domains[$domain][$this->_lang][$this->category][null])) { - unset($this->_domains[$domain][$this->_lang][$this->category][null]); + if (isset($this->_domains[$domain][$this->_lang][$this->category][''])) { + unset($this->_domains[$domain][$this->_lang][$this->category]['']); } } @@ -496,7 +517,7 @@ public static function loadMo($filename) { $r = unpack("L1len/L1offs", substr($data, $o_msg + $n * 8, 8)); $msgid = substr($data, $r["offs"], $r["len"]); unset($msgid_plural); - $context = null; + $context = ''; if (strpos($msgid, "\x04") !== false) { list($context, $msgid) = explode("\x04", $msgid); @@ -542,14 +563,14 @@ public static function loadPo($filename) { $type = 0; $translations = array(); $translationKey = ''; - $translationContext = null; + $translationContext = ''; $plural = 0; $header = ''; do { $line = trim(fgets($file)); if ($line === '' || $line[0] === '#') { - $translationContext = null; + $translationContext = ''; continue; } @@ -598,7 +619,7 @@ public static function loadPo($filename) { unset($translations[$translationKey][$translationContext]); $type = 0; $translationKey = ''; - $translationContext = null; + $translationContext = ''; $plural = 0; } } while (!feof($file)); diff --git a/lib/Cake/Log/Engine/ConsoleLog.php b/lib/Cake/Log/Engine/ConsoleLog.php index ced97e6398..6ba752c063 100644 --- a/lib/Cake/Log/Engine/ConsoleLog.php +++ b/lib/Cake/Log/Engine/ConsoleLog.php @@ -48,8 +48,10 @@ class ConsoleLog extends BaseLog { */ public function __construct($config = array()) { parent::__construct($config); + // The ConsoleOutput stream does not exist yet, so there is no handle to inspect with + // posix_isatty(). Keep the historical default: plain output wherever posix is available. if ((DS === '\\' && !(bool)env('ANSICON') && env('ConEmuANSI') !== 'ON') || - (function_exists('posix_isatty') && !posix_isatty($this->_output)) + function_exists('posix_isatty') ) { $outputAs = ConsoleOutput::PLAIN; } else { diff --git a/lib/Cake/Model/Behavior/TranslateBehavior.php b/lib/Cake/Model/Behavior/TranslateBehavior.php index e4bb53734b..b2fc10ba1c 100644 --- a/lib/Cake/Model/Behavior/TranslateBehavior.php +++ b/lib/Cake/Model/Behavior/TranslateBehavior.php @@ -86,11 +86,9 @@ class TranslateBehavior extends ModelBehavior { public function setup(Model $Model, $config = array()) { $db = ConnectionManager::getDataSource($Model->useDbConfig); if (!$db->connected) { - trigger_error( - __d('cake_dev', 'Datasource %s for TranslateBehavior of model %s is not connected', $Model->useDbConfig, $Model->alias), - E_USER_ERROR + throw new CakeException( + __d('cake_dev', 'Datasource %s for TranslateBehavior of model %s is not connected', $Model->useDbConfig, $Model->alias) ); - return false; } $this->settings[$Model->alias] = array(); @@ -689,11 +687,9 @@ public function bindTranslation(Model $Model, $fields, $reset = true) { foreach (array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany') as $type) { if (isset($Model->{$type}[$association]) || isset($Model->__backAssociation[$type][$association])) { - trigger_error( - __d('cake_dev', 'Association %s is already bound to model %s', $association, $Model->alias), - E_USER_ERROR + throw new CakeException( + __d('cake_dev', 'Association %s is already bound to model %s', $association, $Model->alias) ); - return false; } } $associations[$association] = array_merge($default, array('conditions' => array( diff --git a/lib/Cake/Model/BehaviorCollection.php b/lib/Cake/Model/BehaviorCollection.php index faae57064f..1320658950 100644 --- a/lib/Cake/Model/BehaviorCollection.php +++ b/lib/Cake/Model/BehaviorCollection.php @@ -120,7 +120,7 @@ public function load($behavior, $config = array()) { if (!class_exists($class)) { throw new MissingBehaviorException(array( 'class' => $class, - 'plugin' => substr($plugin, 0, -1) + 'plugin' => substr((string)$plugin, 0, -1) )); } diff --git a/lib/Cake/Model/CakeDatabaseConfig.php b/lib/Cake/Model/CakeDatabaseConfig.php new file mode 100644 index 0000000000..f4c12af192 --- /dev/null +++ b/lib/Cake/Model/CakeDatabaseConfig.php @@ -0,0 +1,27 @@ +plugin = $options['plugin']; } - if (strtolower($this->name) === 'cake') { + if (strtolower((string)$this->name) === 'cake') { $this->name = 'App'; } diff --git a/lib/Cake/Model/ConnectionManager.php b/lib/Cake/Model/ConnectionManager.php index 2a93624cbb..78422988fc 100644 --- a/lib/Cake/Model/ConnectionManager.php +++ b/lib/Cake/Model/ConnectionManager.php @@ -66,11 +66,32 @@ class ConnectionManager { protected static function _init() { include_once CONFIG . 'database.php'; if (class_exists('DATABASE_CONFIG')) { - static::$config = new DATABASE_CONFIG(); + static::$config = static::_createConfig(); } static::$_init = true; } +/** + * Instantiates the application's DATABASE_CONFIG class. + * + * ConnectionManager::create() stores runtime connections as properties of that object. + * Since PHP 8.2 creating such dynamic properties is deprecated unless the class allows them, + * so the object is created through CakeDatabaseConfig, a subclass that declares + * `#[\AllowDynamicProperties]`. The application class is used as-is when it cannot be extended. + * + * @return DATABASE_CONFIG + */ + protected static function _createConfig() { + $reflection = new ReflectionClass('DATABASE_CONFIG'); + if ($reflection->isFinal() || $reflection->getAttributes('AllowDynamicProperties')) { + return new DATABASE_CONFIG(); + } + if (!class_exists('CakeDatabaseConfig', false)) { + require CAKE . 'Model' . DS . 'CakeDatabaseConfig.php'; + } + return new CakeDatabaseConfig(); + } + /** * Gets a reference to a DataSource object * @@ -177,7 +198,7 @@ public static function loadDataSource($connName) { if (!class_exists($conn['classname'])) { throw new MissingDatasourceException(array( 'class' => $conn['classname'], - 'plugin' => substr($plugin, 0, -1) + 'plugin' => substr((string)$plugin, 0, -1) )); } return true; diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php index e67731429b..7991c8ac04 100644 --- a/lib/Cake/Model/Datasource/CakeSession.php +++ b/lib/Cake/Model/Datasource/CakeSession.php @@ -23,6 +23,8 @@ App::uses('Hash', 'Utility'); App::uses('Security', 'Utility'); +App::uses('SessionHandlerAdapter', 'Model/Datasource'); + /** * Session class for CakePHP. @@ -200,8 +202,8 @@ protected static function _setPath($base = null) { */ protected static function _setHost($host) { static::$host = $host; - if (strpos(static::$host, ':') !== false) { - static::$host = substr(static::$host, 0, strpos(static::$host, ':')); + if (is_string($host) && strpos($host, ':') !== false) { + static::$host = substr($host, 0, strpos($host, ':')); } } @@ -248,6 +250,9 @@ public static function check($name) { if (!static::_hasSession() || !static::start()) { return false; } + if ($name === null) { + return false; + } if (isset($_SESSION[$name])) { return true; } @@ -591,12 +596,7 @@ protected static function _configureSession() { $handler = static::_getHandler($sessionConfig['handler']['engine']); if (!function_exists('session_status') || session_status() !== PHP_SESSION_ACTIVE) { session_set_save_handler( - array($handler, 'open'), - array($handler, 'close'), - array($handler, 'read'), - array($handler, 'write'), - array($handler, 'destroy'), - array($handler, 'gc') + new SessionHandlerAdapter($handler) ); } } diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 000a19ea95..5fb953c8e8 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -161,14 +161,23 @@ public function connect() { $config = $this->config; $this->connected = false; + // PDO::MYSQL_ATTR_* constants are deprecated in PHP 8.5; Pdo\Mysql class is available since PHP 8.1 + if (class_exists('Pdo\Mysql')) { + $mysqlAttrUseBufferedQuery = Pdo\Mysql::ATTR_USE_BUFFERED_QUERY; + $mysqlAttrInitCommand = Pdo\Mysql::ATTR_INIT_COMMAND; + } else { + $mysqlAttrUseBufferedQuery = PDO::MYSQL_ATTR_USE_BUFFERED_QUERY; + $mysqlAttrInitCommand = PDO::MYSQL_ATTR_INIT_COMMAND; + } + $flags = $config['flags'] + array( PDO::ATTR_PERSISTENT => $config['persistent'], - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, + $mysqlAttrUseBufferedQuery => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ); if (!empty($config['encoding'])) { - $flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding']; + $flags[$mysqlAttrInitCommand] = 'SET NAMES ' . $config['encoding']; } if (!empty($config['ssl_key']) && !empty($config['ssl_cert'])) { $flags[PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key']; diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index f81bee5b3b..0043a3ca8f 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -251,7 +251,7 @@ public function describe($model) { 'default' => preg_replace( "/^'(.*)'$/", "$1", - preg_replace('/::[\w\s]+/', '', $c->default) + preg_replace('/::[\w\s]+/', '', (string)$c->default) ), 'length' => $length, ); @@ -681,9 +681,9 @@ protected function _alterIndexes($table, $indexes) { */ public function limit($limit, $offset = null) { if ($limit) { - $rt = sprintf(' LIMIT %u', $limit); + $rt = sprintf(' LIMIT %u', $this->_limitValue($limit)); if ($offset) { - $rt .= sprintf(' OFFSET %u', $offset); + $rt .= sprintf(' OFFSET %u', $this->_limitValue($offset)); } return $rt; } diff --git a/lib/Cake/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index 487868be4a..d53557bbef 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Sqlite.php @@ -179,7 +179,7 @@ public function describe($model) { ); foreach ($result as $column) { - $default = ($column['dflt_value'] === 'NULL') ? null : trim($column['dflt_value'], "'"); + $default = ($column['dflt_value'] === 'NULL') ? null : trim((string)$column['dflt_value'], "'"); $fields[$column['name']] = array( 'type' => $this->column($column['type']), @@ -187,7 +187,7 @@ public function describe($model) { 'default' => $default, 'length' => $this->length($column['type']) ); - if (in_array($fields[$column['name']]['type'], array('timestamp', 'datetime')) && strtoupper($fields[$column['name']]['default']) === 'CURRENT_TIMESTAMP') { + if (in_array($fields[$column['name']]['type'], array('timestamp', 'datetime')) && strtoupper((string)$fields[$column['name']]['default']) === 'CURRENT_TIMESTAMP') { $fields[$column['name']]['default'] = null; } if ($column['pk'] == 1) { @@ -393,9 +393,9 @@ public function fetchResult() { */ public function limit($limit, $offset = null) { if ($limit) { - $rt = sprintf(' LIMIT %u', $limit); + $rt = sprintf(' LIMIT %u', $this->_limitValue($limit)); if ($offset) { - $rt .= sprintf(' OFFSET %u', $offset); + $rt .= sprintf(' OFFSET %u', $this->_limitValue($offset)); } return $rt; } diff --git a/lib/Cake/Model/Datasource/Database/Sqlserver.php b/lib/Cake/Model/Datasource/Database/Sqlserver.php index c25934409b..0259da20de 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlserver.php +++ b/lib/Cake/Model/Datasource/Database/Sqlserver.php @@ -414,9 +414,9 @@ public function limit($limit, $offset = null) { if (!strpos(strtolower($limit), 'top') || strpos(strtolower($limit), 'top') === 0) { $rt = ' TOP'; } - $rt .= sprintf(' %u', $limit); + $rt .= sprintf(' %u', $this->_limitValue($limit)); if ((is_int($offset) || ctype_digit($offset)) && $offset > 0) { - $rt = sprintf(' OFFSET %u ROWS FETCH FIRST %u ROWS ONLY', $offset, $limit); + $rt = sprintf(' OFFSET %u ROWS FETCH FIRST %u ROWS ONLY', $this->_limitValue($offset), $this->_limitValue($limit)); } return $rt; } diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 0322668ee9..d320b61d04 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -17,6 +17,7 @@ */ App::uses('DataSource', 'Model/Datasource'); +App::uses('PDOExceptionWithQueryString', 'Model/Datasource'); App::uses('CakeText', 'Utility'); App::uses('View', 'View'); @@ -512,12 +513,13 @@ protected function _execute($sql, $params = array(), $prepareOptions = array()) } return $query; } catch (PDOException $e) { + $wrapperException = new PDOExceptionWithQueryString($e); if (isset($query->queryString)) { - $e->queryString = $query->queryString; + $wrapperException->queryString = $query->queryString; } else { - $e->queryString = $sql; + $wrapperException->queryString = $sql; } - throw $e; + throw $wrapperException; } } @@ -527,7 +529,7 @@ protected function _execute($sql, $params = array(), $prepareOptions = array()) * @param PDOStatement $query the query to extract the error from if any * @return string Error message with error number */ - public function lastError(PDOStatement $query = null) { + public function lastError(?PDOStatement $query = null) { if ($query) { $error = $query->errorInfo(); } else { @@ -2761,7 +2763,7 @@ public function fields(Model $Model, $alias = null, $fields = array(), $quote = * @param Model $Model A reference to the Model instance making the query * @return string SQL fragment */ - public function conditions($conditions, $quoteValues = true, $where = true, Model $Model = null) { + public function conditions($conditions, $quoteValues = true, $where = true, ?Model $Model = null) { $clause = $out = ''; if ($where) { @@ -2804,7 +2806,7 @@ public function conditions($conditions, $quoteValues = true, $where = true, Mode * @param Model $Model A reference to the Model instance making the query * @return string SQL fragment */ - public function conditionKeysToString($conditions, $quoteValues = true, Model $Model = null) { + public function conditionKeysToString($conditions, $quoteValues = true, ?Model $Model = null) { $out = array(); $data = $columnType = null; @@ -2909,7 +2911,7 @@ public function conditionKeysToString($conditions, $quoteValues = true, Model $M * @param Model $Model Model object initiating the query * @return string */ - protected function _parseKey($key, $value, Model $Model = null) { + protected function _parseKey($key, $value, ?Model $Model = null) { $operatorMatch = '/^(((' . implode(')|(', $this->_sqlOps); $operatorMatch .= ')\\x20?)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is'; $bound = (strpos($key, '?') !== false || (is_array($value) && strpos($key, ':') !== false)); @@ -3066,15 +3068,40 @@ public function limit($limit, $offset = null) { $rt = ' LIMIT'; if ($offset) { - $rt .= sprintf(' %u,', $offset); + $rt .= sprintf(' %u,', $this->_limitValue($offset)); } - $rt .= sprintf(' %u', $limit); + $rt .= sprintf(' %u', $this->_limitValue($limit)); return $rt; } return null; } +/** + * Normalizes a LIMIT/OFFSET value so that it can be formatted with sprintf('%u'). + * + * Floats that do not fit into an integer (for example a page number taken from the URL that is + * far too large) are clamped instead of being cast, which PHP 8.5 reports as a deprecation. + * + * @param mixed $value The limit or offset value. + * @return mixed Integer when the value was a float or a numeric string, the original value otherwise. + */ + protected function _limitValue($value) { + if (is_string($value) && is_numeric($value)) { + $value = $value + 0; + } + if (is_float($value)) { + if (!is_finite($value) || $value >= (float)PHP_INT_MAX) { + return PHP_INT_MAX; + } + if ($value <= (float)PHP_INT_MIN) { + return PHP_INT_MIN; + } + return (int)$value; + } + return $value; + } + /** * Returns an ORDER BY clause as a string. * @@ -3083,7 +3110,7 @@ public function limit($limit, $offset = null) { * @param Model $Model Model reference (used to look for virtual field) * @return string ORDER BY clause */ - public function order($keys, $direction = 'ASC', Model $Model = null) { + public function order($keys, $direction = 'ASC', ?Model $Model = null) { if (!is_array($keys)) { $keys = array($keys); } @@ -3166,7 +3193,7 @@ public function order($keys, $direction = 'ASC', Model $Model = null) { * @param Model $Model The model to get group by fields for. * @return string Group By clause or null. */ - public function group($fields, Model $Model = null) { + public function group($fields, ?Model $Model = null) { if (empty($fields)) { return null; } @@ -3196,7 +3223,7 @@ public function group($fields, Model $Model = null) { * @param Model $Model A reference to the Model instance making the query * @return string|null HAVING clause or null */ - public function having($fields, $quoteValues = true, Model $Model = null) { + public function having($fields, $quoteValues = true, ?Model $Model = null) { if (!$fields) { return null; } diff --git a/lib/Cake/Model/Datasource/PDOExceptionWithQueryString.php b/lib/Cake/Model/Datasource/PDOExceptionWithQueryString.php new file mode 100644 index 0000000000..7f0c55a252 --- /dev/null +++ b/lib/Cake/Model/Datasource/PDOExceptionWithQueryString.php @@ -0,0 +1,25 @@ +getMessage(), 0, $e->getPrevious()); + + $this->errorInfo = $e->errorInfo; + $this->code = $e->code; + } +} diff --git a/lib/Cake/Model/Datasource/SessionHandlerAdapter.php b/lib/Cake/Model/Datasource/SessionHandlerAdapter.php new file mode 100644 index 0000000000..50b2517eab --- /dev/null +++ b/lib/Cake/Model/Datasource/SessionHandlerAdapter.php @@ -0,0 +1,49 @@ +cakeSessionHandler->close(); + } + + #[\ReturnTypeWillChange] + public function destroy(string $id) + { + return $this->cakeSessionHandler->destroy($id); + } + + #[\ReturnTypeWillChange] + public function gc(int $max_lifetime) + { + return $this->cakeSessionHandler->gc($max_lifetime); + } + + #[\ReturnTypeWillChange] + public function open(string $path, string $name) + { + //Cake interface ignores these parameters. + return $this->cakeSessionHandler->open(); + } + + #[\ReturnTypeWillChange] + public function read(string $id) + { + return $this->cakeSessionHandler->read($id); + } + + #[\ReturnTypeWillChange] + public function write(string $id, string $data) + { + return $this->cakeSessionHandler->write($id, $data); + } +} diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index aef3c1085f..3ac6f6d6f5 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1979,7 +1979,7 @@ protected function _doSave($data = null, $options = array()) { $this->_clearCache(); $this->validationErrors = array(); $this->whitelist = $_whitelist; - $this->data = false; + $this->data = []; return $success; } @@ -3913,7 +3913,7 @@ protected function _clearCache($type = null) { * If null a new ModelValidator instance will be made using current model object * @return ModelValidator */ - public function validator(ModelValidator $instance = null) { + public function validator(?ModelValidator $instance = null) { if ($instance) { $this->_validator = $instance; } elseif (!$this->_validator) { diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index f8f5e176c8..c757173d9b 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -32,6 +32,7 @@ * @property array $pass Array of passed arguments parsed from the URL. * @package Cake.Network */ +#[\AllowDynamicProperties] class CakeRequest implements ArrayAccess { /** @@ -171,10 +172,10 @@ protected function _processPost() { if ($_POST) { $this->data = $_POST; } elseif (($this->is('put') || $this->is('delete')) && - strpos($this->contentType(), 'application/x-www-form-urlencoded') === 0 + strpos((string)$this->contentType(), 'application/x-www-form-urlencoded') === 0 ) { $data = $this->_readInput(); - parse_str($data, $this->data); + parse_str((string)$data, $this->data); } if (ini_get('magic_quotes_gpc') === '1') { $this->data = stripslashes_deep($this->data); @@ -1030,7 +1031,7 @@ public function input($callback = null) { $args = func_get_args(); if (!empty($args)) { $callback = array_shift($args); - array_unshift($args, $input); + array_unshift($args, (string)$input); return call_user_func_array($callback, $args); } return $input; diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index 6ad28da512..1da480e6ac 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -590,7 +590,7 @@ public function header($header = null, $value = null) { if ($value === null && strpos($header, ':') !== false) { list($header, $value) = explode(':', $header, 2); } - $this->_headers[$header] = is_array($value) ? array_map('trim', $value) : trim($value); + $this->_headers[$header] = is_array($value) ? array_map('trim', $value) : trim((string)$value); } return $this->_headers; } @@ -750,7 +750,7 @@ public function type($contentType = null) { * @return mixed string mapped mime type or false if $alias is not mapped */ public function getMimeType($alias) { - if (isset($this->_mimeTypes[$alias])) { + if ($alias !== null && isset($this->_mimeTypes[$alias])) { return $this->_mimeTypes[$alias]; } return false; @@ -1102,7 +1102,7 @@ public function compress() { * @return bool */ public function outputCompressed() { - return strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false + return strpos((string)env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false && (ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers())); } @@ -1378,7 +1378,7 @@ public function file($path, $options = array()) { $fileSize = $file->size(); if ($download) { - $agent = env('HTTP_USER_AGENT'); + $agent = (string)env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) { $contentType = 'application/octet-stream'; diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index ee4da73d9b..fb1a545b30 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -353,7 +353,7 @@ public function __construct($config = null) { if ($this->_appCharset !== null) { $this->charset = $this->_appCharset; } - $this->_domain = preg_replace('/\:\d+$/', '', env('HTTP_HOST')); + $this->_domain = preg_replace('/\:\d+$/', '', (string)env('HTTP_HOST')); if (empty($this->_domain)) { $this->_domain = php_uname('n'); } @@ -1375,6 +1375,7 @@ protected function _encodeString($text, $charset) { * @return array Wrapped message */ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { + $message = (string)$message; if (strlen($message) === 0) { return array(''); } diff --git a/lib/Cake/Network/Http/HttpResponse.php b/lib/Cake/Network/Http/HttpResponse.php index 61ffab0bba..00bf2737f4 100644 --- a/lib/Cake/Network/Http/HttpResponse.php +++ b/lib/Cake/Network/Http/HttpResponse.php @@ -18,10 +18,10 @@ App::uses('HttpSocketResponse', 'Network/Http'); if (class_exists('HttpResponse')) { - trigger_error(__d( + throw new CakeException(__d( 'cake_dev', "HttpResponse is deprecated due to naming conflicts. Use HttpSocketResponse instead." - ), E_USER_ERROR); + )); } /** diff --git a/lib/Cake/Network/Http/HttpSocket.php b/lib/Cake/Network/Http/HttpSocket.php index a02d71db58..061f7a79a5 100644 --- a/lib/Cake/Network/Http/HttpSocket.php +++ b/lib/Cake/Network/Http/HttpSocket.php @@ -843,7 +843,7 @@ protected function _parseQuery($query) { } $key = urldecode($key); - $value = urldecode($value); + $value = urldecode((string)$value); if (preg_match_all('/\[([^\[\]]*)\]/iUs', $key, $matches)) { $subKeys = $matches[1]; diff --git a/lib/Cake/Routing/Route/CakeRoute.php b/lib/Cake/Routing/Route/CakeRoute.php index 0ac38d2bfd..251d3d1208 100644 --- a/lib/Cake/Routing/Route/CakeRoute.php +++ b/lib/Cake/Routing/Route/CakeRoute.php @@ -275,7 +275,7 @@ protected function _parseArgs($args, $context) { $namedConfig = Router::namedConfig(); $greedy = $namedConfig['greedyNamed']; - $rules = $namedConfig['rules']; + $rules = is_array($namedConfig['rules']) ? $namedConfig['rules'] : array(); if (!empty($this->options['named'])) { $greedy = isset($this->options['greedyNamed']) && $this->options['greedyNamed'] === true; foreach ((array)$this->options['named'] as $key => $val) { @@ -510,7 +510,7 @@ protected function _writeUrl($params) { if (is_array($value)) { $flat = Hash::flatten($value, '%5D%5B'); foreach ($flat as $namedKey => $namedValue) { - $named[] = $key . "%5B{$namedKey}%5D" . $separator . rawurlencode($namedValue); + $named[] = $key . "%5B{$namedKey}%5D" . $separator . rawurlencode((string)$namedValue); } } else { $named[] = $key . $separator . rawurlencode($value); diff --git a/lib/Cake/Test/Case/Cache/CacheTest.php b/lib/Cake/Test/Case/Cache/CacheTest.php index 3bd850217d..334ced4679 100644 --- a/lib/Cake/Test/Case/Cache/CacheTest.php +++ b/lib/Cake/Test/Case/Cache/CacheTest.php @@ -24,6 +24,15 @@ * @package Cake.Test.Case.Cache */ class CacheTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_cacheDisable = null; + +/** + * @var mixed + */ + protected $_defaultCacheConfig = null; protected $_count = 0; diff --git a/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php index 038fa6561b..4162940c69 100644 --- a/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Cache.Engine */ class ApcEngineTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_cacheDisable = null; /** * APC extension to be used diff --git a/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php index 05a6dbf24c..9fa4bdb545 100644 --- a/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php @@ -24,6 +24,33 @@ * * @package Cake.Test.Case.Cache.Engine */ +/** + * Records the arguments passed to set() instead of talking to a memcache server. + * + * A PHPUnit mock of the Memcache class cannot be used here: the generated mock repeats the + * extension's implicitly nullable parameters, which PHP 8.4+ reports as deprecated. + */ +class RecordingMemcache { + +/** + * Arguments of every set() call + * + * @var array + */ + public $calls = array(); + +/** + * Record a set() call. + * + * @return bool + */ + public function set() { + $this->calls[] = func_get_args(); + return true; + } + +} + class TestMemcacheEngine extends MemcacheEngine { /** @@ -48,6 +75,10 @@ public function setMemcache($memcache) { * @package Cake.Test.Case.Cache.Engine */ class MemcacheEngineTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_cacheDisable = null; /** * setUp method @@ -413,14 +444,13 @@ public function testLongDurationEqualToZero() { $memcache = new TestMemcacheEngine(); $memcache->settings['compress'] = false; - $mock = $this->getMock('Memcache'); - $memcache->setMemcache($mock); - $mock->expects($this->once()) - ->method('set') - ->with('key', 'value', false, 0); + $recorder = new RecordingMemcache(); + $memcache->setMemcache($recorder); $value = 'value'; $memcache->write('key', $value, 50 * DAY); + + $this->assertEquals(array(array('key', 'value', false, 0)), $recorder->calls); } /** diff --git a/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php index 00c5ffb3ea..ba4f5c32c6 100644 --- a/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php @@ -25,6 +25,10 @@ * @package Cake.Test.Case.Cache.Engine */ class RedisEngineTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_cacheDisable = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php index ba4b6da18c..1eb974ff7b 100644 --- a/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Cache.Engine */ class WincacheEngineTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_cacheDisable = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php index 645a7fe024..27c895c8b5 100644 --- a/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Cache.Engine */ class XcacheEngineTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_cacheDisable = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Configure/IniReaderTest.php b/lib/Cake/Test/Case/Configure/IniReaderTest.php index 2644392337..ed812dd20b 100644 --- a/lib/Cake/Test/Case/Configure/IniReaderTest.php +++ b/lib/Cake/Test/Case/Configure/IniReaderTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Configure */ class IniReaderTest extends CakeTestCase { +/** + * @var mixed + */ + public $path = null; /** * Test data to serialize and unserialize. diff --git a/lib/Cake/Test/Case/Configure/PhpReaderTest.php b/lib/Cake/Test/Case/Configure/PhpReaderTest.php index 4c5c65f140..03714c1695 100644 --- a/lib/Cake/Test/Case/Configure/PhpReaderTest.php +++ b/lib/Cake/Test/Case/Configure/PhpReaderTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Configure */ class PhpReaderTest extends CakeTestCase { +/** + * @var mixed + */ + public $path = null; /** * Test data to serialize and unserialize. diff --git a/lib/Cake/Test/Case/Console/Command/AclShellTest.php b/lib/Cake/Test/Case/Console/Command/AclShellTest.php index 688d3acc3d..144d9a1696 100644 --- a/lib/Cake/Test/Case/Console/Command/AclShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/AclShellTest.php @@ -29,6 +29,10 @@ * @package Cake.Test.Case.Console.Command */ class AclShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * Fixtures diff --git a/lib/Cake/Test/Case/Console/Command/ApiShellTest.php b/lib/Cake/Test/Case/Console/Command/ApiShellTest.php index 0d67608147..f1cb89f796 100644 --- a/lib/Cake/Test/Case/Console/Command/ApiShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/ApiShellTest.php @@ -28,6 +28,10 @@ * @package Cake.Test.Case.Console.Command */ class ApiShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Shell = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/BakeShellTest.php b/lib/Cake/Test/Case/Console/Command/BakeShellTest.php index 060d6217e5..9f07a2db48 100644 --- a/lib/Cake/Test/Case/Console/Command/BakeShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/BakeShellTest.php @@ -32,6 +32,10 @@ class UsersController extends Controller { } class BakeShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Shell = null; /** * fixtures diff --git a/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php b/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php index 2032af3f62..dba6871eea 100644 --- a/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php @@ -43,6 +43,10 @@ protected function _write($message) { * @package Cake.Test.Case.Console.Command */ class CommandListShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Shell = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php b/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php index 427066a7a3..c8a4e06c82 100644 --- a/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php @@ -45,6 +45,10 @@ protected function _write($message) { * @package Cake.Test.Case.Console.Command */ class CompletionShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Shell = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php b/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php index 2c3a07de23..c283fed3ca 100644 --- a/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php @@ -86,6 +86,20 @@ class SchemaShellTestSchema extends CakeSchema { * @package Cake.Test.Case.Console.Command */ class SchemaShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Dispatcher = null; + +/** + * @var mixed + */ + public $Shell = null; + +/** + * @var mixed + */ + public $file = null; /** * Fixtures diff --git a/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php index 5dbc7a59de..1d1d1bfa68 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/CommandTaskTest.php @@ -22,6 +22,10 @@ * @package Cake.Test.Case.Console.Command.Task */ class CommandTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $CommandTask = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php index e9fbc57a67..e610453626 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php @@ -56,6 +56,10 @@ class BakeArticle extends Model { * @package Cake.Test.Case.Console.Command.Task */ class ControllerTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * fixtures diff --git a/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php index 2e1ebe8611..af956c4938 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php @@ -28,6 +28,10 @@ * @package Cake.Test.Case.Console.Command.Task */ class DbConfigTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php index 53ba40ab60..fa7d1d5cd1 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php @@ -31,6 +31,25 @@ * @package Cake.Test.Case.Console.Command.Task */ class ExtractTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; + +/** + * @var mixed + */ + public $in = null; + +/** + * @var mixed + */ + public $out = null; + +/** + * @var mixed + */ + public $path = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php index 9c5aba39e5..85e4dd7d43 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php @@ -31,6 +31,10 @@ * @package Cake.Test.Case.Console.Command.Task */ class FixtureTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * fixtures diff --git a/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php index 2df4980d05..1cb7533ab4 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php @@ -33,6 +33,10 @@ * @property ModelTask $Task */ class ModelTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * fixtures diff --git a/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php index c5e879d180..8ae3dfa36e 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php @@ -33,6 +33,30 @@ * @package Cake.Test.Case.Console.Command.Task */ class PluginTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; + +/** + * @var mixed + */ + protected $_paths = null; + +/** + * @var mixed + */ + protected $_testPath = null; + +/** + * @var mixed + */ + public $in = null; + +/** + * @var mixed + */ + public $out = null; /** * setUp method @@ -68,7 +92,7 @@ public function setUp() : void { * @return void */ public function tearDown() : void { - if (file_exists($this->Task->bootstrap)) { + if ($this->Task->bootstrap !== null && file_exists($this->Task->bootstrap)) { unlink($this->Task->bootstrap); } parent::tearDown(); diff --git a/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php index 72c5563c1b..54dadcc223 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php @@ -32,6 +32,10 @@ * @package Cake.Test.Case.Console.Command.Task */ class ProjectTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php index e90968f060..7a913e424b 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php @@ -30,6 +30,10 @@ * @package Cake.Test.Case.Console.Command.Task */ class TemplateTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php index e53693da1c..31e4f51d5d 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php @@ -178,6 +178,25 @@ class TestTaskCommentsController extends Controller { * @package Cake.Test.Case.Console.Command.Task */ class TestTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Example = null; + +/** + * @var mixed + */ + public $Task = null; + +/** + * @var mixed + */ + public $TestTaskArticle = null; + +/** + * @var mixed + */ + public $TestTaskComments = null; /** * Fixtures diff --git a/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php index 639e849212..d7c33aaae4 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php @@ -169,6 +169,10 @@ public function admin_delete() { * @package Cake.Test.Case.Console.Command.Task */ class ViewTaskTest extends CakeTestCase { +/** + * @var mixed + */ + public $Task = null; /** * Fixtures diff --git a/lib/Cake/Test/Case/Console/Command/TestShellTest.php b/lib/Cake/Test/Case/Console/Command/TestShellTest.php index 46a4d64f6b..291b32167d 100644 --- a/lib/Cake/Test/Case/Console/Command/TestShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/TestShellTest.php @@ -42,6 +42,10 @@ public function mapFileToCategory($file) { * @package Cake.Test.Case.Console.Command */ class TestShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Shell = null; /** * setUp test case diff --git a/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php b/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php index dae3907e3f..e1c8d03743 100644 --- a/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php +++ b/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Console */ class ConsoleErrorHandlerTest extends CakeTestCase { +/** + * @var mixed + */ + public $Error = null; /** * setup, create mocks @@ -161,7 +165,9 @@ public function testNonIntegerExceptionCode() { $class = new ReflectionClass('Exception'); $property = $class->getProperty('code'); - $property->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $property->setAccessible(true); + } $property->setValue($exception, '42S22'); ConsoleErrorHandler::$stderr->expects($this->once())->method('write') diff --git a/lib/Cake/Test/Case/Console/ConsoleOutputTest.php b/lib/Cake/Test/Case/Console/ConsoleOutputTest.php index f6ac6fc319..055b4cc8d9 100644 --- a/lib/Cake/Test/Case/Console/ConsoleOutputTest.php +++ b/lib/Cake/Test/Case/Console/ConsoleOutputTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Console */ class ConsoleOutputTest extends CakeTestCase { +/** + * @var mixed + */ + public $output = null; /** * setup diff --git a/lib/Cake/Test/Case/Console/Helper/ProgressShellHelperTest.php b/lib/Cake/Test/Case/Console/Helper/ProgressShellHelperTest.php index 03e9c6dc56..807a9c94c0 100644 --- a/lib/Cake/Test/Case/Console/Helper/ProgressShellHelperTest.php +++ b/lib/Cake/Test/Case/Console/Helper/ProgressShellHelperTest.php @@ -21,6 +21,15 @@ * @property ProgressShellHelper $helper */ class ProgressShellHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $consoleOutput = null; + +/** + * @var mixed + */ + public $helper = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/Helper/TableShellHelperTest.php b/lib/Cake/Test/Case/Console/Helper/TableShellHelperTest.php index 755fcb90ae..f757ce7f15 100644 --- a/lib/Cake/Test/Case/Console/Helper/TableShellHelperTest.php +++ b/lib/Cake/Test/Case/Console/Helper/TableShellHelperTest.php @@ -21,6 +21,15 @@ * @property TableShellHelper $helper */ class TableShellHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $consoleOutput = null; + +/** + * @var mixed + */ + public $helper = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Console/ShellTest.php b/lib/Cake/Test/Case/Console/ShellTest.php index 2617320e6f..df0b7ed643 100644 --- a/lib/Cake/Test/Case/Console/ShellTest.php +++ b/lib/Cake/Test/Case/Console/ShellTest.php @@ -121,6 +121,10 @@ class TestBananaTask extends Shell { * @package Cake.Test.Case.Console.Command */ class ShellTest extends CakeTestCase { +/** + * @var mixed + */ + public $Shell = null; /** * Fixtures used in this test case @@ -607,7 +611,7 @@ public function testCreateFileNonInteractive() { $this->Shell->interactive = false; - $contents = "Shell->createFile($file, $contents); $this->assertTrue($result); $this->assertTrue(file_exists($file)); diff --git a/lib/Cake/Test/Case/Console/TaskCollectionTest.php b/lib/Cake/Test/Case/Console/TaskCollectionTest.php index 8444427ce0..809a1fee3a 100644 --- a/lib/Cake/Test/Case/Console/TaskCollectionTest.php +++ b/lib/Cake/Test/Case/Console/TaskCollectionTest.php @@ -31,6 +31,10 @@ class DbConfigAliasedTask extends Shell { * @package Cake.Test.Case.Console */ class TaskCollectionTest extends CakeTestCase { +/** + * @var mixed + */ + public $Tasks = null; /** * setUp diff --git a/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php b/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php index 6c658b6d08..26a5c7f189 100644 --- a/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php +++ b/lib/Cake/Test/Case/Controller/ApplicationControllerTest.php @@ -51,12 +51,21 @@ public function next() { */ class ApplicationControllerTest extends ControllerTestCase { +/** + * Session configuration restored after each test + * + * @var array + */ + protected $_sessionConfig = array(); + /** * setupDown method * * @return void */ public function setUp() : void { + $this->_sessionConfig = Configure::read('Session'); + $this->skipIf(PHP_VERSION_ID >= 80400, 'Enabling session.use_trans_sid is deprecated since PHP 8.4.'); CakeSession::destroy(); parent::setUp(); } @@ -68,6 +77,9 @@ public function setUp() : void { */ public function tearDown() : void { CakeSession::destroy(); + if (!empty($this->_sessionConfig)) { + Configure::write('Session', $this->_sessionConfig); + } parent::tearDown(); } diff --git a/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php b/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php index 57d4854087..8ad0e19314 100644 --- a/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php @@ -175,6 +175,10 @@ public function __construct() { * @package Cake.Test.Case.Controller.Component.Acl */ class DbAclTest extends CakeTestCase { +/** + * @var mixed + */ + public $Acl = null; /** * fixtures property diff --git a/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php b/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php index 07bfdc0370..fbc33b915f 100644 --- a/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php @@ -26,6 +26,15 @@ class_exists('AclComponent'); * @package Cake.Test.Case.Controller.Component.Acl */ class PhpAclTest extends CakeTestCase { +/** + * @var mixed + */ + public $Acl = null; + +/** + * @var mixed + */ + public $PhpAcl = null; /** * Setup diff --git a/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php index f59ce29309..533b14c481 100644 --- a/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php @@ -25,6 +25,10 @@ class_exists('AclComponent'); * @package Cake.Test.Case.Controller.Component */ class AclComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $Acl = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php index a18a2b9db9..189ac7e62a 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php @@ -28,6 +28,25 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class ActionsAuthorizeTest extends CakeTestCase { +/** + * @var mixed + */ + public $Acl = null; + +/** + * @var mixed + */ + public $Collection = null; + +/** + * @var mixed + */ + public $auth = null; + +/** + * @var mixed + */ + public $controller = null; /** * setUp diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php index 7da3634fa9..784e2a429e 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php @@ -28,6 +28,20 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class BasicAuthenticateTest extends CakeTestCase { +/** + * @var mixed + */ + public $Collection = null; + +/** + * @var mixed + */ + public $auth = null; + +/** + * @var mixed + */ + public $response = null; /** * Fixtures diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/BlowfishAuthenticateTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/BlowfishAuthenticateTest.php index d62bdee01e..69535a88e4 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/BlowfishAuthenticateTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/BlowfishAuthenticateTest.php @@ -31,6 +31,20 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class BlowfishAuthenticateTest extends CakeTestCase { +/** + * @var mixed + */ + public $Collection = null; + +/** + * @var mixed + */ + public $auth = null; + +/** + * @var mixed + */ + public $response = null; public $fixtures = array('core.user', 'core.auth_user'); diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php index a06c40fb8e..69b822e21b 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php @@ -27,6 +27,20 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class ControllerAuthorizeTest extends CakeTestCase { +/** + * @var mixed + */ + public $auth = null; + +/** + * @var mixed + */ + public $components = null; + +/** + * @var mixed + */ + public $controller = null; /** * setup diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php index 784909e592..c2c6a9902e 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php @@ -28,6 +28,20 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class CrudAuthorizeTest extends CakeTestCase { +/** + * @var mixed + */ + public $Acl = null; + +/** + * @var mixed + */ + public $Components = null; + +/** + * @var mixed + */ + public $auth = null; /** * setup diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php index d7fcd63ac8..fd366e3946 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php @@ -29,6 +29,25 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class DigestAuthenticateTest extends CakeTestCase { +/** + * @var mixed + */ + public $Collection = null; + +/** + * @var mixed + */ + public $auth = null; + +/** + * @var mixed + */ + public $response = null; + +/** + * @var mixed + */ + public $server = null; /** * Fixtures diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php index 6480ed3d85..453e16502a 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php @@ -28,6 +28,20 @@ * @package Cake.Test.Case.Controller.Component.Auth */ class FormAuthenticateTest extends CakeTestCase { +/** + * @var mixed + */ + public $Collection = null; + +/** + * @var mixed + */ + public $auth = null; + +/** + * @var mixed + */ + public $response = null; /** * Fixtrues diff --git a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php index 2d6af32cd2..63c8d3aaf4 100644 --- a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php @@ -352,6 +352,20 @@ public function listenerFunction() { * @package Cake.Test.Case.Controller.Component */ class AuthComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $Auth = null; + +/** + * @var mixed + */ + public $AuthUser = null; + +/** + * @var mixed + */ + public $Controller = null; /** * name property diff --git a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php index 99fc97b30f..bad180e500 100644 --- a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php @@ -56,6 +56,10 @@ public function beforeFilter() { * @package Cake.Test.Case.Controller.Component */ class CookieComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $Cookie = null; /** * Controller property diff --git a/lib/Cake/Test/Case/Controller/Component/FlashComponentTest.php b/lib/Cake/Test/Case/Controller/Component/FlashComponentTest.php index d56d29fdfe..31e6ba86b8 100644 --- a/lib/Cake/Test/Case/Controller/Component/FlashComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/FlashComponentTest.php @@ -27,6 +27,15 @@ * @package Cake.Test.Case.Controller.Component */ class FlashComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $Components = null; + +/** + * @var mixed + */ + public $Flash = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php b/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php index b20bf6b46f..6afe862e41 100644 --- a/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php @@ -284,6 +284,20 @@ protected function _findTotalsOperation($state, $query, $results = array()) { } class PaginatorComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $Controller = null; + +/** + * @var mixed + */ + public $Paginator = null; + +/** + * @var mixed + */ + public $request = null; /** * fixtures property diff --git a/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php b/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php index c79e5bd1ee..5bcc9363f0 100644 --- a/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php @@ -86,6 +86,10 @@ class CustomJsonView extends JsonView { * @package Cake.Test.Case.Controller.Component */ class RequestHandlerComponentTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_extensions = null; /** * Controller property @@ -442,7 +446,9 @@ public function testStartupCustomTypeProcess() { $this->Controller->request->expects($this->once()) ->method('_readInput') ->will($this->returnValue('"A","csv","string"')); - $this->RequestHandler->addInputType('csv', array('str_getcsv')); + $this->RequestHandler->addInputType('csv', array(function ($input) { + return str_getcsv($input, ',', '"', '\\'); + })); $this->RequestHandler->startup($this->Controller); $expected = array( 'A', 'csv', 'string' diff --git a/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php b/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php index 0fba140b28..9e929953db 100644 --- a/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php @@ -140,6 +140,10 @@ protected function _fail() { * @package Cake.Test.Case.Controller.Component */ class SecurityComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $Security = null; /** * Controller property @@ -162,6 +166,7 @@ class SecurityComponentTest extends CakeTestCase { */ public function setUp() : void { parent::setUp(); + $_SERVER['REQUEST_METHOD'] = 'GET'; $request = $this->getMock('CakeRequest', array('here'), array('posts/index', false)); $request->addParams(array('controller' => 'posts', 'action' => 'index')); @@ -321,7 +326,7 @@ public function testRequireSecureFail() { * @return void */ public function testRequireSecureSucceed() { - $_SERVER['REQUEST_METHOD'] = 'Secure'; + $_SERVER['REQUEST_METHOD'] = 'GET'; $this->Controller->request['action'] = 'posted'; $_SERVER['HTTPS'] = 'on'; $this->Controller->Security->requireSecure('posted'); diff --git a/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php b/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php index ef587da278..d789151e7c 100644 --- a/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php @@ -75,6 +75,10 @@ public function sessionId() { * @package Cake.Test.Case.Controller.Component */ class SessionComponentTest extends CakeTestCase { +/** + * @var mixed + */ + public $ComponentCollection = null; protected static $_sessionBackup; diff --git a/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php b/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php index 8c66526cab..ac99b6ece2 100644 --- a/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php +++ b/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php @@ -28,6 +28,10 @@ class CookieAliasComponent extends CookieComponent { } class ComponentCollectionTest extends CakeTestCase { +/** + * @var mixed + */ + public $Components = null; /** * setUp diff --git a/lib/Cake/Test/Case/Controller/ComponentTest.php b/lib/Cake/Test/Case/Controller/ComponentTest.php index 0686ac335f..065ccf0c9d 100644 --- a/lib/Cake/Test/Case/Controller/ComponentTest.php +++ b/lib/Cake/Test/Case/Controller/ComponentTest.php @@ -200,6 +200,10 @@ class SomethingWithEmailComponent extends Component { * @package Cake.Test.Case.Controller */ class ComponentTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_pluginPaths = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Controller/ScaffoldTest.php b/lib/Cake/Test/Case/Controller/ScaffoldTest.php index cbad1a32e8..8a4f5b90ba 100644 --- a/lib/Cake/Test/Case/Controller/ScaffoldTest.php +++ b/lib/Cake/Test/Case/Controller/ScaffoldTest.php @@ -113,6 +113,10 @@ public function beforeScaffold($method) { * @package Cake.Test.Case.Controller */ class TestScaffoldMock extends Scaffold { +/** + * @var mixed + */ + protected $_params = null; /** * Overload _scaffold diff --git a/lib/Cake/Test/Case/Core/CakeObjectTest.php b/lib/Cake/Test/Case/Core/CakeObjectTest.php index 5d829da079..527699c6c1 100644 --- a/lib/Cake/Test/Case/Core/CakeObjectTest.php +++ b/lib/Cake/Test/Case/Core/CakeObjectTest.php @@ -280,6 +280,10 @@ class ObjectTestModel extends CakeTestModel { * @package Cake.Test.Case.Core */ class ObjectTest extends CakeTestCase { +/** + * @var mixed + */ + public $object = null; /** * fixtures diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index 6309063d13..30f485e63a 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -863,6 +863,7 @@ public function testRenderWithNoRequest() { */ public function testPDOException() { $exception = new PDOException('There was an error in the SQL query'); + $exception = new PDOExceptionWithQueryString($exception); $exception->queryString = 'SELECT * from poo_query < 5 and :seven'; $exception->params = array('seven' => 7); $ExceptionRenderer = new ExceptionRenderer($exception); diff --git a/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php b/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php index 4de920e907..a432bc3a1f 100644 --- a/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php +++ b/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php @@ -35,7 +35,13 @@ class TestConsoleLog extends ConsoleLog { class TestCakeLog extends CakeLog { public static function replace($key, &$engine) { - static::$_Collection->{$key} = $engine; + $property = new ReflectionProperty('ObjectCollection', '_loaded'); + if (PHP_VERSION_ID < 80100) { + $property->setAccessible(true); + } + $loaded = $property->getValue(static::$_Collection); + $loaded[$key] = $engine; + $property->setValue(static::$_Collection, $loaded); } } @@ -140,7 +146,7 @@ public function testDefaultOutputAs() { 'engine' => 'TestConsole', )); if ((DS === '\\' && !(bool)env('ANSICON') && env('ConEmuANSI') !== 'ON') || - (function_exists('posix_isatty') && !posix_isatty(null)) + function_exists('posix_isatty') ) { $expected = ConsoleOutput::PLAIN; } else { diff --git a/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php b/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php index 9c5e639ee0..9eb0b85fed 100644 --- a/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php @@ -27,6 +27,35 @@ * @package Cake.Test.Case.Model.Behavior */ class ContainableBehaviorTest extends CakeTestCase { +/** + * @var mixed + */ + public $Article = null; + +/** + * @var mixed + */ + public $JoinA = null; + +/** + * @var mixed + */ + public $JoinB = null; + +/** + * @var mixed + */ + public $JoinC = null; + +/** + * @var mixed + */ + public $Tag = null; + +/** + * @var mixed + */ + public $User = null; /** * Fixtures associated with this test case diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php index e107de9a28..4ab2747e34 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php @@ -27,6 +27,10 @@ * @package Cake.Test.Case.Model.Behavior */ class TreeBehaviorAfterTest extends CakeTestCase { +/** + * @var mixed + */ + public $Tree = null; /** * Whether backup global state for each test method or not diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php index d7d8aadddc..bd2adf43fb 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php @@ -29,6 +29,10 @@ * @package Cake.Test.Case.Model.Behavior */ class TreeBehaviorNumberTest extends CakeTestCase { +/** + * @var mixed + */ + public $Tree = null; /** * Whether backup global state for each test method or not diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php index 22f3aeda9b..bb88aad176 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php @@ -29,6 +29,20 @@ * @package Cake.Test.Case.Model.Behavior */ class TreeBehaviorScopedTest extends CakeTestCase { +/** + * @var mixed + */ + public $Ad = null; + +/** + * @var mixed + */ + public $Tree = null; + +/** + * @var mixed + */ + public $TreeTwo = null; /** * Whether backup global state for each test method or not diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php index cfa2559af9..2a9fce72c4 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php @@ -30,6 +30,10 @@ * @package Cake.Test.Case.Model.Behavior */ class TreeBehaviorUuidTest extends CakeTestCase { +/** + * @var mixed + */ + public $Tree = null; /** * Whether backup global state for each test method or not diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index ac3e5490e7..b375efa7b9 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -434,6 +434,10 @@ class SchemaPrefixAuthUser extends CakeTestModel { * @package Cake.Test.Case.Model */ class CakeSchemaTest extends CakeTestCase { +/** + * @var mixed + */ + public $Schema = null; /** * fixtures property diff --git a/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php b/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php index 98e54a0912..0f316c5609 100644 --- a/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php @@ -142,13 +142,13 @@ public function testSessionConfigIniSetting() { 'checkAgent' => false, 'timeout' => 86400, 'ini' => array( - 'session.referer_check' => 'example.com', + 'session.cache_expire' => '123', 'session.use_trans_sid' => false ) )); TestCakeSession::start(); $this->assertEquals('', ini_get('session.use_trans_sid'), 'Ini value is incorrect'); - $this->assertEquals('example.com', ini_get('session.referer_check'), 'Ini value is incorrect'); + $this->assertEquals('123', ini_get('session.cache_expire'), 'Ini value is incorrect'); $this->assertEquals('test', ini_get('session.name'), 'Ini value is incorrect'); } diff --git a/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php index 846be3d87b..855aff5609 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php @@ -94,6 +94,15 @@ public function calculate(Model $Model, $func, $params = array()) { * @package Cake.Test.Case.Model.Datasource */ class DataSourceTest extends CakeTestCase { +/** + * @var mixed + */ + public $Model = null; + +/** + * @var mixed + */ + public $Source = null; /** * Name of test source diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index ed44627dae..8e8cb87b35 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -29,6 +29,30 @@ * @package Cake.Test.Case.Model.Datasource.Database */ class MysqlTest extends CakeTestCase { +/** + * @var mixed + */ + public $Featured2 = null; + +/** + * @var mixed + */ + public $Model = null; + +/** + * @var mixed + */ + protected $_debug = null; + +/** + * @var mixed + */ + public $model = null; + +/** + * @var mixed + */ + public $startTime = null; /** * autoFixtures property @@ -62,11 +86,11 @@ class MysqlTest extends CakeTestCase { */ public function setUp() : void { parent::setUp(); + $this->_debug = Configure::read('debug'); $this->Dbo = ConnectionManager::getDataSource('test'); if (!($this->Dbo instanceof Mysql)) { $this->markTestSkipped('The MySQL extension is not available.'); } - $this->_debug = Configure::read('debug'); Configure::write('debug', 1); $this->model = ClassRegistry::init('MysqlTestModel'); } diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php index ed499e077d..02682e03a8 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php @@ -176,6 +176,10 @@ public function schema($field = false) { * @package Cake.Test.Case.Model.Datasource.Database */ class PostgresTest extends CakeTestCase { +/** + * @var mixed + */ + public $model = null; /** * Do not automatically load fixtures for each test, they will be loaded manually diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php index 0ad014b3a2..f7d93bcb5b 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php @@ -237,6 +237,15 @@ public function fetch() { * @package Cake.Test.Case.Model.Datasource.Database */ class SqlserverTest extends CakeTestCase { +/** + * @var mixed + */ + public $Dbo = null; + +/** + * @var mixed + */ + public $model = null; /** * The Dbo instance to be tested diff --git a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php index 802cefc085..7561a8ad1a 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php @@ -161,6 +161,15 @@ public function cacheMethodFilter($method, $key, $value) { * @package Cake.Test.Case.Model.Datasource */ class DboSourceTest extends CakeTestCase { +/** + * @var mixed + */ + public $Model = null; + +/** + * @var mixed + */ + public $testDb = null; /** * autoFixtures property @@ -2151,7 +2160,9 @@ public function testFlushQueryCache() { $this->db->query('SELECT 2'); $property = new ReflectionProperty($this->db, '_queryCache'); - $property->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $property->setAccessible(true); + } $this->assertCount(2, $property->getValue($this->db)); diff --git a/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php b/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php index d3e1c6738e..017bfc29a5 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php @@ -26,6 +26,10 @@ class_exists('CakeSession'); * @package Cake.Test.Case.Model.Datasource.Session */ class CacheSessionTest extends CakeTestCase { +/** + * @var mixed + */ + public $storage = null; protected static $_sessionBackup; diff --git a/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php b/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php index 231fa3332f..9f20e2224b 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php @@ -38,6 +38,10 @@ class SessionTestModel extends Model { * @package Cake.Test.Case.Model.Datasource.Session */ class DatabaseSessionTest extends CakeTestCase { +/** + * @var mixed + */ + public $storage = null; protected static $_sessionBackup; diff --git a/lib/Cake/Test/Case/Model/ModelTestBase.php b/lib/Cake/Test/Case/Model/ModelTestBase.php index 30f7efe3c2..77520be605 100644 --- a/lib/Cake/Test/Case/Model/ModelTestBase.php +++ b/lib/Cake/Test/Case/Model/ModelTestBase.php @@ -27,6 +27,10 @@ * @package Cake.Test.Case.Model */ abstract class BaseModelTest extends CakeTestCase { +/** + * @var mixed + */ + public $debug = null; /** * autoFixtures property diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index 6324d381f4..942637f292 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -58,6 +58,15 @@ public function reConstruct($url = 'some/path', $parseEnvironment = true) { * CakeRequestTest */ class CakeRequestTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_app = null; + +/** + * @var mixed + */ + protected $_case = null; /** * Setup callback diff --git a/lib/Cake/Test/Case/Network/CakeSocketTest.php b/lib/Cake/Test/Case/Network/CakeSocketTest.php index 41651df9c5..75a2ce4af0 100644 --- a/lib/Cake/Test/Case/Network/CakeSocketTest.php +++ b/lib/Cake/Test/Case/Network/CakeSocketTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.Network */ class CakeSocketTest extends CakeTestCase { +/** + * @var mixed + */ + public $Socket = null; /** * setUp method @@ -393,7 +397,11 @@ public function testGetContext() { ) ); $this->Socket = new CakeSocket($config); - $this->Socket->connect(); + try { + $this->Socket->connect(); + } catch (SocketException $e) { + $this->markTestSkipped('Cannot test network, skipping.'); + } $result = $this->Socket->context(); $this->assertSame($config['context']['ssl']['capture_peer'], $result['ssl']['capture_peer']); } @@ -416,7 +424,11 @@ public function testConfigContext() { ); $this->Socket = new CakeSocket($config); - $this->Socket->connect(); + try { + $this->Socket->connect(); + } catch (SocketException $e) { + $this->markTestSkipped('Cannot test network, skipping.'); + } $result = $this->Socket->context(); $this->assertTrue($result['ssl']['verify_peer']); diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index 0bd0607fc1..c67cf32693 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -143,6 +143,15 @@ class ExtendTransport { * @package Cake.Test.Case.Network.Email */ class CakeEmailTest extends CakeTestCase { +/** + * @var mixed + */ + public $CakeEmail = null; + +/** + * @var mixed + */ + protected $_configFileExists = null; /** * setUp diff --git a/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php b/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php index 4f53868832..95d042c8d4 100644 --- a/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php +++ b/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php @@ -24,6 +24,10 @@ * Test case */ class DebugTransportTest extends CakeTestCase { +/** + * @var mixed + */ + public $DebugTransport = null; /** * Setup diff --git a/lib/Cake/Test/Case/Network/Email/MailTransportTest.php b/lib/Cake/Test/Case/Network/Email/MailTransportTest.php index 60f218c1f5..d8ace9969b 100644 --- a/lib/Cake/Test/Case/Network/Email/MailTransportTest.php +++ b/lib/Cake/Test/Case/Network/Email/MailTransportTest.php @@ -24,6 +24,10 @@ * Test case */ class MailTransportTest extends CakeTestCase { +/** + * @var mixed + */ + public $MailTransport = null; /** * Setup diff --git a/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php index 7377e88ec5..8f80234dee 100644 --- a/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php +++ b/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php @@ -61,6 +61,15 @@ public function __call($method, $args) { * Test case */ class SmtpTransportTest extends CakeTestCase { +/** + * @var mixed + */ + public $SmtpTransport = null; + +/** + * @var mixed + */ + public $socket = null; /** * Setup diff --git a/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php b/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php index 928fb0dbd8..36061e7061 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php @@ -83,6 +83,10 @@ public function tokenEscapeChars($hex = true, $chars = null) { * @package Cake.Test.Case.Network.Http */ class HttpResponseTest extends CakeTestCase { +/** + * @var mixed + */ + public $HttpResponse = null; /** * This function sets up a HttpResponse diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index 07dfb6c87a..9acdb5e0d9 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -1845,6 +1845,7 @@ public function testVerifyPeer() { } catch (SocketException $e) { $message = $e->getMessage(); $this->skipIf(strpos($message, 'Invalid HTTP') !== false, 'Invalid HTTP Response received, skipping.'); + $this->skipIf(strpos($message, 'getaddrinfo') !== false, 'Could not resolve host, network unavailable, skipping.'); $this->assertStringContainsString('Failed to enable crypto', $message); } } diff --git a/lib/Cake/Test/Case/Routing/DispatcherTest.php b/lib/Cake/Test/Case/Routing/DispatcherTest.php index 08d45e46f8..ac4670dad3 100644 --- a/lib/Cake/Test/Case/Routing/DispatcherTest.php +++ b/lib/Cake/Test/Case/Routing/DispatcherTest.php @@ -45,6 +45,11 @@ protected function _sendHeader($name, $value = null) { */ class TestDispatcher extends Dispatcher { +/** + * @var mixed + */ + public $base = null; + /** * Controller instance, made publicly available for testing * @@ -537,6 +542,40 @@ public function afterDispatch(CakeEvent $event) { * @package Cake.Test.Case.Routing */ class DispatcherTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_app = null; + +/** + * @var mixed + */ + protected $_cache = null; + +/** + * @var mixed + */ + protected $_debug = null; + +/** + * @var mixed + */ + protected $_files = null; + +/** + * @var mixed + */ + protected $_get = null; + +/** + * @var mixed + */ + protected $_post = null; + +/** + * @var mixed + */ + protected $_server = null; /** * setUp method diff --git a/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php b/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php index e501b50ac2..fa00a95376 100644 --- a/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php +++ b/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php @@ -222,6 +222,20 @@ class FixturePrefixTest extends Model { * @package Cake.Test.Case.TestSuite */ class CakeTestFixtureTest extends CakeTestCase { +/** + * @var mixed + */ + public $insertMulti = null; + +/** + * @var mixed + */ + protected $_backupConfig = null; + +/** + * @var mixed + */ + public $criticDb = null; /** * setUp method diff --git a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php index a0a7f57e97..597c16487c 100644 --- a/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php +++ b/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php @@ -112,6 +112,10 @@ class ControllerTestCaseTestController extends AppController { * @package Cake.Test.Case.TestSuite */ class ControllerTestCaseTest extends CakeTestCase { +/** + * @var mixed + */ + public $Case = null; /** * fixtures property diff --git a/lib/Cake/Test/Case/TestSuite/Fixture/CakeFixtureManagerTest.php b/lib/Cake/Test/Case/TestSuite/Fixture/CakeFixtureManagerTest.php index 433065bab4..e908274899 100644 --- a/lib/Cake/Test/Case/TestSuite/Fixture/CakeFixtureManagerTest.php +++ b/lib/Cake/Test/Case/TestSuite/Fixture/CakeFixtureManagerTest.php @@ -63,7 +63,9 @@ public function testLoadTruncatesTable() { $fixtureManagerReflection = new ReflectionClass($fixtureManager); $loadedProperty = $fixtureManagerReflection->getProperty('_loaded'); - $loadedProperty->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $loadedProperty->setAccessible(true); + } $loadedProperty->setValue($fixtureManager, array('core.uuid' => $MockFixture)); $TestCase = $this->getMock('CakeTestCase'); @@ -90,7 +92,9 @@ public function testLoadSingleTruncatesTable() { $fixtureManagerReflection = new ReflectionClass($fixtureManager); $fixtureMapProperty = $fixtureManagerReflection->getProperty('_fixtureMap'); - $fixtureMapProperty->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $fixtureMapProperty->setAccessible(true); + } $fixtureMapProperty->setValue($fixtureManager, array('UuidFixture' => $MockFixture)); $dboMethods = array_diff(get_class_methods('DboSource'), array('enabled')); diff --git a/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php b/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php index d8299e0ed3..4be105e2bb 100644 --- a/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php +++ b/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php @@ -27,6 +27,10 @@ * @package Cake.Test.Case.TestSuite */ class HtmlCoverageReportTest extends CakeTestCase { +/** + * @var mixed + */ + public $Coverage = null; /** * setUp diff --git a/lib/Cake/Test/Case/TestSuite/Stub/ConsoleOutputStubTest.php b/lib/Cake/Test/Case/TestSuite/Stub/ConsoleOutputStubTest.php index 95e90f971c..10202cb7b1 100644 --- a/lib/Cake/Test/Case/TestSuite/Stub/ConsoleOutputStubTest.php +++ b/lib/Cake/Test/Case/TestSuite/Stub/ConsoleOutputStubTest.php @@ -18,6 +18,10 @@ * ConsoleOutputStub test */ class ConsoleOutputStubTest extends CakeTestCase { +/** + * @var mixed + */ + public $stub = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Utility/CakeNumberTest.php b/lib/Cake/Test/Case/Utility/CakeNumberTest.php index bf6576821e..29349a84fa 100644 --- a/lib/Cake/Test/Case/Utility/CakeNumberTest.php +++ b/lib/Cake/Test/Case/Utility/CakeNumberTest.php @@ -25,6 +25,10 @@ * @package Cake.Test.Case.Utility */ class CakeNumberTest extends CakeTestCase { +/** + * @var mixed + */ + public $Number = null; /** * setUp method diff --git a/lib/Cake/Test/Case/Utility/CakeTextTest.php b/lib/Cake/Test/Case/Utility/CakeTextTest.php index 185ade4e7a..e4a8aae1cd 100644 --- a/lib/Cake/Test/Case/Utility/CakeTextTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTextTest.php @@ -25,6 +25,10 @@ * @coversDefaultClass CakeText */ class CakeTextTest extends CakeTestCase { +/** + * @var mixed + */ + public $Text = null; /** * Setup object under test diff --git a/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/lib/Cake/Test/Case/Utility/CakeTimeTest.php index f9ce1158c0..613546efe6 100644 --- a/lib/Cake/Test/Case/Utility/CakeTimeTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTimeTest.php @@ -24,6 +24,10 @@ * @package Cake.Test.Case.View.Helper */ class CakeTimeTest extends CakeTestCase { +/** + * @var mixed + */ + public $Time = null; /** * Default system timezone identifier @@ -279,9 +283,7 @@ public function testTimeAgoInWordsWithFormat() { $this->assertEquals('on 2007-09-25', $result); $result = $this->Time->timeAgoInWords('2007-9-25', '%x'); - // @codingStandardsIgnoreStart - $this->assertEquals('on ' . @strftime('%x', strtotime('2007-9-25')), $result); - // @codingStandardsIgnoreEnd + $this->assertEquals('on ' . PHP81_BC\strftime('%x', strtotime('2007-9-25')), $result); $result = $this->Time->timeAgoInWords( strtotime('+2 weeks +2 days'), @@ -306,7 +308,7 @@ public function testTimeAgoInWordsWithFormat() { array('end' => '1 month', 'format' => '%x') ); // @codingStandardsIgnoreStart - $this->assertEquals('on ' . @strftime('%x', strtotime('+2 months +2 days')), $result); + $this->assertEquals('on ' . PHP81_BC\strftime('%x', strtotime('+2 months +2 days')), $result); // @codingStandardsIgnoreEnd } @@ -476,11 +478,11 @@ public function testNiceShort() { * @return void */ public function testNiceShortI18n() { - $restore = setlocale(LC_ALL, 0); - setlocale(LC_ALL, 'es_ES'); + $restore = Locale::getDefault(); + Locale::setDefault('es_ES'); $time = strtotime('2015-01-07 03:05:00'); $this->assertEquals('ene 7th 2015, 03:05', $this->Time->niceShort($time)); - setlocale(LC_ALL, $restore); + Locale::setDefault($restore); } /** @@ -561,7 +563,7 @@ public function testToServer() { $expected = $date->format('Y-m-d H:i:s'); $this->assertEquals($expected, $result); - $date = new DateTime(null, new DateTimeZone('America/New_York')); + $date = new DateTime('now', new DateTimeZone('America/New_York')); $result = $this->Time->toServer($date, 'Pacific/Tahiti'); $date->setTimezone(new DateTimeZone(date_default_timezone_get())); $expected = $date->format('Y-m-d H:i:s'); @@ -1166,6 +1168,7 @@ public function testConvertPercentE() { * @return void */ public function testI18nFormat() { + $resetLocale = Locale::getDefault(); App::build(array( 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS) ), App::RESET); @@ -1173,13 +1176,14 @@ public function testI18nFormat() { $time = strtotime('Thu Jan 14 13:59:28 2010'); + Locale::setDefault('en_US'); $result = $this->Time->i18nFormat($time); $expected = '14/01/10'; $this->assertEquals($expected, $result); $result = $this->Time->i18nFormat($time, '%c'); // @codingStandardsIgnoreStart - $expected = 'jue 14 ene 2010 13:59:28 ' . mb_convert_encoding(@strftime('%Z', $time), 'UTF-8', 'ISO-8859-1'); + $expected = 'jue 14 ene 2010 13:59:28 ' . mb_convert_encoding(PHP81_BC\strftime('%Z', $time), 'UTF-8', 'ISO-8859-1'); // @codingStandardsIgnoreEnd $this->assertEquals($expected, $result); @@ -1194,9 +1198,7 @@ public function testI18nFormat() { $this->assertEquals($expected, $result); $result = $this->Time->i18nFormat($time, '%c'); - // @codingStandardsIgnoreStart - $expected = 'mié 13 ene 2010 13:59:28 ' . mb_convert_encoding(@strftime('%Z', $time), 'UTF-8', 'ISO-8859-1'); - // @codingStandardsIgnoreEnd + $expected = 'mié 13 ene 2010 13:59:28 ' . mb_convert_encoding(PHP81_BC\strftime('%Z', $time), 'UTF-8', 'ISO-8859-1'); $this->assertEquals($expected, $result); $result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x'); @@ -1206,6 +1208,8 @@ public function testI18nFormat() { $result = $this->Time->i18nFormat('invalid date', '%x', 'Date invalid'); $expected = 'Date invalid'; $this->assertEquals($expected, $result); + + Locale::setDefault($resetLocale); } public function testI18nFormatTimezoneConversionToUTC() { diff --git a/lib/Cake/Test/Case/Utility/DebuggerTest.php b/lib/Cake/Test/Case/Utility/DebuggerTest.php index a14fd8110b..466fb80a0b 100644 --- a/lib/Cake/Test/Case/Utility/DebuggerTest.php +++ b/lib/Cake/Test/Case/Utility/DebuggerTest.php @@ -86,7 +86,8 @@ public function testExcerpt() { $this->assertTrue(is_array($result)); $this->assertEquals(4, count($result)); - $pattern = '/.*?.*?<\?php/'; + // PHP 8.3 changed highlight_string() output to `` and hexadecimal colors + $pattern = '/.*?.*?<\?php/'; $this->assertMatchesRegularExpression($pattern, $result[0]); $result = Debugger::excerpt(__FILE__, 11, 2); diff --git a/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php b/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php index dc0c9ec925..4a414d9762 100644 --- a/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php +++ b/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php @@ -23,6 +23,15 @@ * A generic object class */ class GenericObject { +/** + * @var mixed + */ + protected $_Collection = null; + +/** + * @var mixed + */ + public $settings = null; /** * Constructor @@ -128,6 +137,25 @@ public function setObject($name, $object, $settings = array()) { } class ObjectCollectionTest extends CakeTestCase { +/** + * @var mixed + */ + public $FirstGenericObject = null; + +/** + * @var mixed + */ + public $Objects = null; + +/** + * @var mixed + */ + public $SecondGenericObject = null; + +/** + * @var mixed + */ + public $ThirdGenericObject = null; /** * setUp diff --git a/lib/Cake/Test/Case/Utility/ValidationTest.php b/lib/Cake/Test/Case/Utility/ValidationTest.php index 37339eff82..e39504391e 100644 --- a/lib/Cake/Test/Case/Utility/ValidationTest.php +++ b/lib/Cake/Test/Case/Utility/ValidationTest.php @@ -113,6 +113,15 @@ protected static function _isUploadedFile($path) { * @package Cake.Test.Case.Utility */ class ValidationTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_appEncoding = null; + +/** + * @var mixed + */ + protected $_appLocale = null; /** * setUp method @@ -175,7 +184,7 @@ public function testNotBlankISO88591AppEncoding() { $this->assertTrue(Validation::notBlank('fooo' . chr(243) . 'blabla')); $this->assertTrue(Validation::notBlank('abçďĕʑʘπй')); $this->assertTrue(Validation::notBlank('José')); - $this->assertTrue(Validation::notBlank(utf8_decode('José'))); + $this->assertTrue(Validation::notBlank(mb_convert_encoding('José', 'ISO-8859-1', 'UTF-8'))); $this->assertFalse(Validation::notBlank("\t ")); $this->assertFalse(Validation::notBlank("")); } @@ -1523,7 +1532,7 @@ public function testDecimalWithPlacesNull() { $this->assertTrue(Validation::decimal('-1234', null)); $this->assertTrue(Validation::decimal('+1234', null)); $this->assertTrue(Validation::decimal((float)1234, null)); - $this->assertTrue(Validation::decimal((double)1234, null)); + $this->assertTrue(Validation::decimal((float)1234, null)); $this->assertTrue(Validation::decimal((int)1234, null)); $this->assertFalse(Validation::decimal('', null)); @@ -1553,7 +1562,7 @@ public function testDecimalWithPlacesTrue() { $this->assertTrue(Validation::decimal(.01, true)); $this->assertTrue(Validation::decimal('.01', true)); $this->assertTrue(Validation::decimal((float)1234, true)); - $this->assertTrue(Validation::decimal((double)1234, true)); + $this->assertTrue(Validation::decimal((float)1234, true)); $this->assertFalse(Validation::decimal('', true)); $this->assertFalse(Validation::decimal('string', true)); @@ -1593,7 +1602,7 @@ public function testDecimalWithPlacesNumeric() { $this->assertFalse(Validation::decimal(.0, 1)); $this->assertFalse(Validation::decimal(.00, 2)); $this->assertFalse(Validation::decimal((float)1234, 1)); - $this->assertFalse(Validation::decimal((double)1234, 1)); + $this->assertFalse(Validation::decimal((float)1234, 1)); $this->assertFalse(Validation::decimal((int)1234, 1)); $this->assertFalse(Validation::decimal('1234.5678', '3')); $this->assertFalse(Validation::decimal(1234.5678, 3)); diff --git a/lib/Cake/Test/Case/Utility/XmlTest.php b/lib/Cake/Test/Case/Utility/XmlTest.php index 8fa7fd9ef5..3f04a5b0fd 100644 --- a/lib/Cake/Test/Case/Utility/XmlTest.php +++ b/lib/Cake/Test/Case/Utility/XmlTest.php @@ -78,6 +78,10 @@ class XmlUser extends CakeTestModel { * @package Cake.Test.Case.Utility */ class XmlTest extends CakeTestCase { +/** + * @var mixed + */ + protected $_appEncoding = null; /** * autoFixtures property @@ -201,6 +205,17 @@ public function testBuildFromUrlWhenDisabled() { Xml::build($xml, array('readFile' => false)); } +/** + * Test that the readFile option disables https url parsing too. + * + * @return void + */ + public function testBuildFromHttpsUrlWhenDisabled() { + $this->expectException(XmlException::class); + $xml = 'https://www.google.com'; + Xml::build($xml, array('readFile' => false)); + } + /** * data provider function for testBuildInvalidData * diff --git a/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php b/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php index 1d276f8be1..41c647c785 100644 --- a/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php @@ -58,6 +58,15 @@ public function cache_parsing() { * @package Cake.Test.Case.View.Helper */ class CacheHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Cache = null; + +/** + * @var mixed + */ + public $Controller = null; /** * Checks if TMP/views is writable, and skips the case if it is not. diff --git a/lib/Cake/Test/Case/View/Helper/FlashHelperTest.php b/lib/Cake/Test/Case/View/Helper/FlashHelperTest.php index f01d69f760..7b32fed3b3 100644 --- a/lib/Cake/Test/Case/View/Helper/FlashHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FlashHelperTest.php @@ -28,6 +28,15 @@ * @package Cake.Test.Case.View.Helper */ class FlashHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Flash = null; + +/** + * @var mixed + */ + public $View = null; /** * setupBeforeClass method diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 6024e39fed..0ad11df506 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -505,6 +505,40 @@ class TestMail extends CakeTestModel { * @property FormHelper $Form */ class FormHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Controller = null; + +/** + * @var mixed + */ + public $Form = null; + +/** + * @var mixed + */ + public $UserForm = null; + +/** + * @var mixed + */ + public $ValidateUser = null; + +/** + * @var mixed + */ + public $View = null; + +/** + * @var mixed + */ + public $dateRegex = null; + +/** + * @var mixed + */ + public $oldSalt = null; /** * Fixtures to be used @@ -8791,7 +8825,9 @@ public function testPostLinkSecurityHashInline() { $this->assertStringContainsString($hash, $result, 'Should contain the correct hash.'); $property = new ReflectionProperty($this->Form, '_lastAction'); - $property->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $property->setAccessible(true); + } $this->assertSame( '/basedir/posts/add', @@ -11217,7 +11253,9 @@ public function testLastActionWithNamedNumeric() { $this->Form->create('User'); $property = new ReflectionProperty($this->Form, '_lastAction'); - $property->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $property->setAccessible(true); + } $this->assertSame($here, $property->getValue($this->Form), "_lastAction shouldn't be empty."); } @@ -11236,7 +11274,9 @@ public function testLastActionWithNamedString() { $this->Form->create('User'); $property = new ReflectionProperty($this->Form, '_lastAction'); - $property->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $property->setAccessible(true); + } $this->assertSame($here, $property->getValue($this->Form), "_lastAction shouldn't be empty."); } diff --git a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php index 755ad27d55..5f65508fb6 100644 --- a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php @@ -116,6 +116,10 @@ class Html5TestHelper extends TestHtmlHelper { * @package Cake.Test.Case.View.Helper */ class HtmlHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $View = null; /** * Regexp for CDATA start block diff --git a/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php b/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php index 671822e6da..baf2151b14 100644 --- a/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php @@ -26,6 +26,15 @@ * @package Cake.Test.Case.View.Helper */ class JqueryEngineHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Jquery = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp diff --git a/lib/Cake/Test/Case/View/Helper/JsHelperTest.php b/lib/Cake/Test/Case/View/Helper/JsHelperTest.php index bd62b79912..a0f8c4ff3c 100644 --- a/lib/Cake/Test/Case/View/Helper/JsHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/JsHelperTest.php @@ -117,6 +117,15 @@ public function serializeForm($options = array()) { * @package Cake.Test.Case.View.Helper */ class JsHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Js = null; + +/** + * @var mixed + */ + public $View = null; /** * Regexp for CDATA start block @@ -743,6 +752,15 @@ public function testSetVarsAtTopOfBufferedScripts() { * @package Cake.Test.Case.View.Helper */ class JsBaseEngineTest extends CakeTestCase { +/** + * @var mixed + */ + public $JsEngine = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php b/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php index 99cc49fd78..a6655bd9f2 100644 --- a/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php @@ -26,6 +26,15 @@ * @package Cake.Test.Case.View.Helper */ class MootoolsEngineHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Moo = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp diff --git a/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php b/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php index f5074258e1..3066c0edd8 100644 --- a/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php @@ -46,6 +46,10 @@ class CakeNumberMock { * @package Cake.Test.Case.View.Helper */ class NumberHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php b/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php index ea5a02ca84..b0f98915ed 100644 --- a/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php @@ -32,6 +32,15 @@ * @package Cake.Test.Case.View.Helper */ class PaginatorHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Paginator = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php b/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php index 3808cfd414..b5194ba833 100644 --- a/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php @@ -26,6 +26,15 @@ * @package Cake.Test.Case.View.Helper */ class PrototypeEngineHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Proto = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp diff --git a/lib/Cake/Test/Case/View/Helper/RssHelperTest.php b/lib/Cake/Test/Case/View/Helper/RssHelperTest.php index f8f1b6f75c..3a144f65d1 100644 --- a/lib/Cake/Test/Case/View/Helper/RssHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/RssHelperTest.php @@ -27,6 +27,15 @@ * @package Cake.Test.Case.View.Helper */ class RssHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Rss = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php b/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php index c998e7c6ff..f06615b886 100644 --- a/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php @@ -26,6 +26,15 @@ * @package Cake.Test.Case.View.Helper */ class SessionHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Session = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/Helper/TextHelperTest.php b/lib/Cake/Test/Case/View/Helper/TextHelperTest.php index b73a882e65..13f6292679 100644 --- a/lib/Cake/Test/Case/View/Helper/TextHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/TextHelperTest.php @@ -50,6 +50,15 @@ class CakeTextMock { * @package Cake.Test.Case.View.Helper */ class TextHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Text = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php b/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php index 109789d2f4..81f0ae657b 100644 --- a/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php @@ -51,6 +51,10 @@ class CakeTimeMock { * @package Cake.Test.Case.View.Helper */ class TimeHelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $View = null; public $Time = null; diff --git a/lib/Cake/Test/Case/View/HelperCollectionTest.php b/lib/Cake/Test/Case/View/HelperCollectionTest.php index bdcaf4c781..f7cc528933 100644 --- a/lib/Cake/Test/Case/View/HelperCollectionTest.php +++ b/lib/Cake/Test/Case/View/HelperCollectionTest.php @@ -32,6 +32,15 @@ class HtmlAliasHelper extends HtmlHelper { * @package Cake.Test.Case.View */ class HelperCollectionTest extends CakeTestCase { +/** + * @var mixed + */ + public $Helpers = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp diff --git a/lib/Cake/Test/Case/View/HelperTest.php b/lib/Cake/Test/Case/View/HelperTest.php index d3f4b1b77f..371a361cb8 100644 --- a/lib/Cake/Test/Case/View/HelperTest.php +++ b/lib/Cake/Test/Case/View/HelperTest.php @@ -195,6 +195,15 @@ public function parseAttributes($options, $exclude = null, $insertBefore = ' ', * @package Cake.Test.Case.View */ class HelperTest extends CakeTestCase { +/** + * @var mixed + */ + public $Helper = null; + +/** + * @var mixed + */ + public $View = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/MediaViewTest.php b/lib/Cake/Test/Case/View/MediaViewTest.php index 1ba2af21e5..93669a20e9 100644 --- a/lib/Cake/Test/Case/View/MediaViewTest.php +++ b/lib/Cake/Test/Case/View/MediaViewTest.php @@ -26,6 +26,10 @@ * @package Cake.Test.Case.View */ class MediaViewTest extends CakeTestCase { +/** + * @var mixed + */ + public $MediaView = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/ScaffoldViewTest.php b/lib/Cake/Test/Case/View/ScaffoldViewTest.php index 9b118c9c12..13aa805110 100644 --- a/lib/Cake/Test/Case/View/ScaffoldViewTest.php +++ b/lib/Cake/Test/Case/View/ScaffoldViewTest.php @@ -70,6 +70,15 @@ class ScaffoldViewMockController extends Controller { * @package Cake.Test.Case.Controller */ class ScaffoldViewTest extends CakeTestCase { +/** + * @var mixed + */ + public $Controller = null; + +/** + * @var mixed + */ + public $request = null; /** * fixtures property diff --git a/lib/Cake/Test/Case/View/ThemeViewTest.php b/lib/Cake/Test/Case/View/ThemeViewTest.php index bfa7ddae13..381e36deac 100644 --- a/lib/Cake/Test/Case/View/ThemeViewTest.php +++ b/lib/Cake/Test/Case/View/ThemeViewTest.php @@ -97,6 +97,20 @@ public function getLayoutFileName($name = null) { * @package Cake.Test.Case.View */ class ThemeViewTest extends CakeTestCase { +/** + * @var mixed + */ + public $Controller = null; + +/** + * @var mixed + */ + public $PostsController = null; + +/** + * @var mixed + */ + public $ThemeView = null; /** * setUp method diff --git a/lib/Cake/Test/Case/View/ViewTest.php b/lib/Cake/Test/Case/View/ViewTest.php index 2b0f808e5a..a5369f592a 100644 --- a/lib/Cake/Test/Case/View/ViewTest.php +++ b/lib/Cake/Test/Case/View/ViewTest.php @@ -301,6 +301,35 @@ public function afterRender($event) { * @package Cake.Test.Case.View */ class ViewTest extends CakeTestCase { +/** + * @var mixed + */ + public $Controller = null; + +/** + * @var mixed + */ + public $PostsController = null; + +/** + * @var mixed + */ + public $ThemeController = null; + +/** + * @var mixed + */ + public $ThemePostsController = null; + +/** + * @var mixed + */ + public $ThemeView = null; + +/** + * @var mixed + */ + public $View = null; /** * Fixtures used in this test. diff --git a/lib/Cake/TestSuite/CakeTestCase.php b/lib/Cake/TestSuite/CakeTestCase.php index 3d8acaca37..45ff451a64 100644 --- a/lib/Cake/TestSuite/CakeTestCase.php +++ b/lib/Cake/TestSuite/CakeTestCase.php @@ -33,6 +33,13 @@ abstract class CakeTestCase extends \PHPUnit\Framework\TestCase { */ public $fixtureManager = null; +/** + * The test datasource, assigned by CakeFixtureManager::fixturize() + * + * @var DataSource|null + */ + public $db = null; + /** * By default, all fixtures attached to this class will be truncated and reloaded after each test. * Set this to false to handle manually diff --git a/lib/Cake/TestSuite/ControllerTestCase.php b/lib/Cake/TestSuite/ControllerTestCase.php index 8d8f7bd3a3..562cd0669e 100644 --- a/lib/Cake/TestSuite/ControllerTestCase.php +++ b/lib/Cake/TestSuite/ControllerTestCase.php @@ -38,6 +38,13 @@ class ControllerTestDispatcher extends Dispatcher { */ public $testController = null; +/** + * The response object used by the dispatched request + * + * @var CakeResponse + */ + public $response = null; + /** * Use custom routes during tests * diff --git a/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php b/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php index f671713b1e..41cb25210f 100644 --- a/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php +++ b/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php @@ -54,6 +54,13 @@ class CakeFixtureManager { */ protected $_fixtureMap = array(); +/** + * Test classes whose fixtures have already been loaded, indexed by class name + * + * @var array + */ + protected $_processed = array(); + /** * Inspects the test to look for unloaded fixtures and loads them * diff --git a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php index 0bf9d1e8d8..245d46e5d0 100644 --- a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php +++ b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php @@ -90,6 +90,21 @@ class CakeTestFixture { */ public $canUseMemory = true; +/** + * Import configuration (table or model to import the schema and/or records from). + * Defined by fixtures that import their definition instead of declaring $fields. + * + * @var array|null + */ + public $import = null; + +/** + * Schema object used to create/drop the fixture table. + * + * @var CakeSchema + */ + public $Schema = null; + /** * Instantiate the fixture. * @@ -164,7 +179,7 @@ public function init() { ClassRegistry::flush(); } - if (!empty($db->config['prefix']) && strpos($this->table, $db->config['prefix']) === 0) { + if (!empty($db->config['prefix']) && strpos((string)$this->table, $db->config['prefix']) === 0) { $this->table = str_replace($db->config['prefix'], '', $this->table); } diff --git a/lib/Cake/Utility/CakeNumber.php b/lib/Cake/Utility/CakeNumber.php index 7aa05d5216..ff8e45e595 100644 --- a/lib/Cake/Utility/CakeNumber.php +++ b/lib/Cake/Utility/CakeNumber.php @@ -269,7 +269,7 @@ protected static function _numberFormat($value, $places = 0, $decimals = '.', $t static::$_numberFormatSupport = version_compare(PHP_VERSION, '5.4.0', '>='); } if (static::$_numberFormatSupport) { - return number_format($value, $places, $decimals, $thousands); + return number_format($value, (int)$places, (string)$decimals, (string)$thousands); } $value = number_format($value, $places, '.', ''); $after = ''; diff --git a/lib/Cake/Utility/CakeText.php b/lib/Cake/Utility/CakeText.php index 66f7d87746..7519af4214 100644 --- a/lib/Cake/Utility/CakeText.php +++ b/lib/Cake/Utility/CakeText.php @@ -233,9 +233,9 @@ public static function cleanInsert($str, $options) { ), $clean); $kleenex = sprintf( '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i', - preg_quote($options['before'], '/'), + preg_quote((string)$options['before'], '/'), $clean['word'], - preg_quote($options['after'], '/') + preg_quote((string)$options['after'], '/') ); $str = preg_replace($kleenex, $clean['replacement'], $str); if ($clean['andText']) { @@ -252,14 +252,14 @@ public static function cleanInsert($str, $options) { $kleenex = sprintf( '/(%s%s%s%s|%s%s%s%s)/', - preg_quote($options['before'], '/'), + preg_quote((string)$options['before'], '/'), $clean['word'], - preg_quote($options['after'], '/'), + preg_quote((string)$options['after'], '/'), $clean['gap'], $clean['gap'], - preg_quote($options['before'], '/'), + preg_quote((string)$options['before'], '/'), $clean['word'], - preg_quote($options['after'], '/') + preg_quote((string)$options['after'], '/') ); $str = preg_replace($kleenex, $clean['replacement'], $str); break; @@ -657,7 +657,7 @@ public static function toList($list, $and = null, $separator = ', ') { $and = __d('cake', 'and'); } if (count($list) > 1) { - return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list); + return implode($separator, array_slice($list, 0, -1)) . ' ' . $and . ' ' . array_pop($list); } return array_pop($list); diff --git a/lib/Cake/Utility/CakeTime.php b/lib/Cake/Utility/CakeTime.php index 75fae995e3..fb9f1cad03 100644 --- a/lib/Cake/Utility/CakeTime.php +++ b/lib/Cake/Utility/CakeTime.php @@ -1167,9 +1167,8 @@ public static function listTimezones($filter = null, $country = null, $options = * @return string formatted string with correct encoding. */ protected static function _strftime($format, $timestamp) { - // @codingStandardsIgnoreStart - $format = @strftime($format, $timestamp); - // @codingStandardsIgnoreEnd + $format = PHP81_BC\strftime($format, $timestamp); + $encoding = Configure::read('App.encoding'); if (!empty($encoding) && $encoding === 'UTF-8') { if (function_exists('mb_check_encoding')) { diff --git a/lib/Cake/Utility/Debugger.php b/lib/Cake/Utility/Debugger.php index e71e0ea5ed..42785fc451 100644 --- a/lib/Cake/Utility/Debugger.php +++ b/lib/Cake/Utility/Debugger.php @@ -592,7 +592,9 @@ protected static function _object($var, $depth, $indent) { foreach ($filters as $filter => $visibility) { $reflectionProperties = $ref->getProperties($filter); foreach ($reflectionProperties as $reflectionProperty) { - $reflectionProperty->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $reflectionProperty->setAccessible(true); + } if (!$reflectionProperty->isInitialized($var)) { continue; diff --git a/lib/Cake/Utility/File.php b/lib/Cake/Utility/File.php index 6c4bed1070..5de5846a99 100644 --- a/lib/Cake/Utility/File.php +++ b/lib/Cake/Utility/File.php @@ -394,7 +394,7 @@ public function md5($maxsize = 5) { public function pwd() { if ($this->path === null) { $dir = $this->Folder->pwd(); - if (is_dir($dir)) { + if ($dir !== null && is_dir($dir)) { $this->path = $this->Folder->slashTerm($dir) . $this->name; } } @@ -409,7 +409,7 @@ public function pwd() { */ public function exists() { $this->clearStatCache(); - return (file_exists($this->path) && is_file($this->path)); + return ($this->path !== null && file_exists($this->path) && is_file($this->path)); } /** @@ -580,7 +580,7 @@ public function mime() { * @return void */ public function clearStatCache($all = false) { - if ($all === false && version_compare(PHP_VERSION, '5.3.0') >= 0) { + if ($all === false && $this->path !== null) { return clearstatcache(true, $this->path); } diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index b2396f5d5d..cc8d53b78f 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -230,7 +230,7 @@ protected static function _matches(array $data, $selector) { // Pattern matches and other operators. if ($op === '=' && $val && $val[0] === '/') { - if (!preg_match($val, $prop)) { + if (!preg_match($val, (string)$prop)) { return false; } } elseif (($op === '=' && $prop != $val) || diff --git a/lib/Cake/Utility/Inflector.php b/lib/Cake/Utility/Inflector.php index d0ec62f470..cfff6cec43 100644 --- a/lib/Cake/Utility/Inflector.php +++ b/lib/Cake/Utility/Inflector.php @@ -500,7 +500,7 @@ public static function underscore($camelCasedWord) { */ public static function humanize($lowerCaseAndUnderscoredWord) { if (!($result = static::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) { - $result = explode(' ', str_replace('_', ' ', $lowerCaseAndUnderscoredWord)); + $result = explode(' ', str_replace('_', ' ', $lowerCaseAndUnderscoredWord ?? "")); foreach ($result as &$word) { $word = mb_strtoupper(mb_substr($word, 0, 1)) . mb_substr($word, 1); } @@ -576,7 +576,7 @@ public static function slug($string, $replacement = '_') { ); $map = static::$_transliteration + $merge; - return preg_replace(array_keys($map), array_values($map), $string); + return preg_replace(array_keys($map), array_values($map), (string)$string); } } diff --git a/lib/Cake/Utility/Security.php b/lib/Cake/Utility/Security.php index 322b29d9e0..18118629d4 100644 --- a/lib/Cake/Utility/Security.php +++ b/lib/Cake/Utility/Security.php @@ -109,7 +109,7 @@ public static function hash($string, $type = null, $salt = false) { if (empty($type)) { $type = static::$hashType; } - $type = strtolower($type); + $type = strtolower((string)$type); if ($type === 'blowfish') { return static::_crypt($string, $salt); @@ -128,14 +128,7 @@ public static function hash($string, $type = null, $salt = false) { $type = 'sha256'; } - if ($type === 'sha256' && function_exists('mhash')) { - return bin2hex(mhash(MHASH_SHA256, $string)); - } - - if (function_exists('hash')) { - return hash($type, $string); - } - return md5($string); + return hash($type, $string); } /** @@ -202,6 +195,36 @@ public static function randomBytes($length) { return substr($bytes, 0, $length); } +/** + * Converts the configured cipher seed into an integer. + * + * `Security.cipherSeed` is traditionally a numeric string that is larger than PHP_INT_MAX. + * Before PHP 8.5 `(int)(float)$seed` silently wrapped the value around modulo 2^64; PHP 8.5 + * deprecates that cast. This reproduces the same wrap-around so that existing seeds keep + * producing the same cipher output. + * + * @param mixed $seed The configured seed. + * @return int Seed usable with srand(). + */ + protected static function _cipherSeed($seed) { + $seed = (float)$seed; + if (!is_finite($seed)) { + return 0; + } + if ($seed >= (float)PHP_INT_MIN && $seed < (float)PHP_INT_MAX) { + return (int)$seed; + } + $twoPow64 = 18446744073709551616.0; + $seed = fmod($seed, $twoPow64); + if ($seed < 0) { + $seed += $twoPow64; + } + if ($seed >= 9223372036854775808.0) { + $seed -= $twoPow64; + } + return (int)$seed; + } + /** * Runs $text through a XOR cipher. * @@ -223,8 +246,9 @@ public static function cipher($text, $key) { return ''; } - srand((int)(float)Configure::read('Security.cipherSeed')); + srand(static::_cipherSeed(Configure::read('Security.cipherSeed'))); $out = ''; + $text = (string)$text; $keyLength = strlen($key); for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) { $j = ord(substr($key, $i % $keyLength, 1)); @@ -352,7 +376,7 @@ public static function encrypt($plain, $key, $hmacSalt = null) { // Generate the encryption and hmac key. $key = substr(hash('sha256', $key . $hmacSalt), 0, 32); - if (Configure::read('Security.useOpenSsl')) { + if (Configure::read('Security.useOpenSsl') || !function_exists('mcrypt_encrypt')) { $method = 'AES-256-CBC'; $ivSize = openssl_cipher_iv_length($method); $iv = openssl_random_pseudo_bytes($ivSize); @@ -419,7 +443,7 @@ public static function decrypt($cipher, $key, $hmacSalt = null) { return false; } - if (Configure::read('Security.useOpenSsl')) { + if (Configure::read('Security.useOpenSsl') || !function_exists('mcrypt_decrypt')) { $method = 'AES-256-CBC'; $ivSize = openssl_cipher_iv_length($method); $iv = substr($cipher, 0, $ivSize); diff --git a/lib/Cake/Utility/Set.php b/lib/Cake/Utility/Set.php index ac811da75a..53f8683b92 100644 --- a/lib/Cake/Utility/Set.php +++ b/lib/Cake/Utility/Set.php @@ -390,7 +390,7 @@ public static function extract($path, $data = null, $options = array()) { if (!is_numeric($key)) { $ctext[] = $token; $tok = array_shift($tokens); - if (isset($items[$tok])) { + if ($tok !== null && isset($items[$tok])) { $ctext[] = $tok; $item = $items[$tok]; $matches[] = array( @@ -501,7 +501,7 @@ public static function matches($conditions, $data = array(), $i = null, $length $val = $data[$key]; if ($op === '=' && $expected && $expected[0] === '/') { - return preg_match($expected, $val); + return preg_match($expected, (string)$val); } if ($op === '=' && $val != $expected) { return false; diff --git a/lib/Cake/Utility/Validation.php b/lib/Cake/Utility/Validation.php index 95a960ce0a..ceaadf4d05 100644 --- a/lib/Cake/Utility/Validation.php +++ b/lib/Cake/Utility/Validation.php @@ -229,7 +229,7 @@ public static function comparison($check1, $operator = null, $check2 = null) { if ((float)$check1 != $check1) { return false; } - $operator = str_replace(array(' ', "\t", "\n", "\r", "\0", "\x0B"), '', strtolower($operator)); + $operator = str_replace(array(' ', "\t", "\n", "\r", "\0", "\x0B"), '', strtolower((string)$operator)); switch ($operator) { case 'isgreater': diff --git a/lib/Cake/Utility/Xml.php b/lib/Cake/Utility/Xml.php index 84a67ea5d9..2808f13a28 100644 --- a/lib/Cake/Utility/Xml.php +++ b/lib/Cake/Utility/Xml.php @@ -76,7 +76,8 @@ class Xml { * * - `return` Can be 'simplexml' to return object of SimpleXMLElement or 'domdocument' to return DOMDocument. * - `loadEntities` Defaults to false. Set to true to enable loading of ` array('redirect' => 10))); $response = $socket->get($input); @@ -133,11 +134,7 @@ public static function build($input, $options = array()) { * @throws XmlException */ protected static function _loadXml($input, $options) { - $hasDisable = function_exists('libxml_disable_entity_loader'); $internalErrors = libxml_use_internal_errors(true); - if ($hasDisable && !$options['loadEntities']) { - libxml_disable_entity_loader(true); - } $flags = LIBXML_NOCDATA; if (!empty($options['parseHuge'])) { $flags |= LIBXML_PARSEHUGE; @@ -152,9 +149,6 @@ protected static function _loadXml($input, $options) { } catch (Exception $e) { $xml = null; } - if ($hasDisable && !$options['loadEntities']) { - libxml_disable_entity_loader(false); - } libxml_use_internal_errors($internalErrors); if ($xml === null) { throw new XmlException(__d('cake_dev', 'Xml cannot be read.')); @@ -221,7 +215,7 @@ public static function fromArray($input, $options = array()) { ); $options += $defaults; - $dom = new DOMDocument($options['version'], $options['encoding']); + $dom = new DOMDocument($options['version'], (string)$options['encoding']); if ($options['pretty']) { $dom->formatOutput = true; } diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index cef2c4856c..81c948a6e9 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license https://opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.10.24 +2.11.0 diff --git a/lib/Cake/View/Helper.php b/lib/Cake/View/Helper.php index 7512e5c899..d3fce20da3 100644 --- a/lib/Cake/View/Helper.php +++ b/lib/Cake/View/Helper.php @@ -605,6 +605,7 @@ public function setEntity($entity, $setScope = false) { $this->_association = null; $isHabtm = ( + $this->_modelScope !== null && isset($this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type']) && $this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type'] === 'multiple' ); diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 89b7f11274..b8100393f6 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -213,8 +213,9 @@ protected function _introspectModel($model, $key, $field = null) { if ($key === 'fields') { if (!isset($this->fieldset[$model]['fields'])) { $this->fieldset[$model]['fields'] = $object->schema(); + $objectAlias = $object->alias === null ? '' : $object->alias; foreach ($object->hasAndBelongsToMany as $alias => $assocData) { - $this->fieldset[$object->alias]['fields'][$alias] = array('type' => 'multiple'); + $this->fieldset[$objectAlias]['fields'][$alias] = array('type' => 'multiple'); } } if ($field === null || $field === false) { @@ -1684,7 +1685,7 @@ public function radio($fieldName, $options = array(), $attributes = array()) { )); } } - $out = $hidden . implode($separator, $out); + $out = $hidden . implode((string)$separator, $out); if (is_array($between)) { $between = ''; @@ -2300,7 +2301,7 @@ public function day($fieldName = null, $attributes = array()) { $attributes += array('empty' => true, 'value' => null); $attributes = $this->_dateTimeSelected('day', $fieldName, $attributes); - if (strlen($attributes['value']) > 2) { + if (strlen((string)$attributes['value']) > 2) { $date = date_create($attributes['value']); $attributes['value'] = null; if ($date) { @@ -2356,7 +2357,7 @@ public function year($fieldName, $minYear = null, $maxYear = null, $attributes = } } - if (strlen($attributes['value']) > 4 || $attributes['value'] === 'now') { + if (strlen((string)$attributes['value']) > 4 || $attributes['value'] === 'now') { $date = date_create($attributes['value']); $attributes['value'] = null; if ($date) { @@ -2396,7 +2397,7 @@ public function month($fieldName, $attributes = array()) { $attributes += array('empty' => true, 'value' => null); $attributes = $this->_dateTimeSelected('month', $fieldName, $attributes); - if (strlen($attributes['value']) > 2) { + if (strlen((string)$attributes['value']) > 2) { $date = date_create($attributes['value']); $attributes['value'] = null; if ($date) { @@ -2441,7 +2442,7 @@ public function hour($fieldName, $format24Hours = false, $attributes = array()) $attributes += array('empty' => true, 'value' => null); $attributes = $this->_dateTimeSelected('hour', $fieldName, $attributes); - if (strlen($attributes['value']) > 2) { + if (strlen((string)$attributes['value']) > 2) { try { $date = new DateTime($attributes['value']); if ($format24Hours) { @@ -2488,7 +2489,7 @@ public function minute($fieldName, $attributes = array()) { $attributes += array('empty' => true, 'value' => null); $attributes = $this->_dateTimeSelected('min', $fieldName, $attributes); - if (strlen($attributes['value']) > 2) { + if (strlen((string)$attributes['value']) > 2) { $date = date_create($attributes['value']); $attributes['value'] = null; if ($date) { @@ -2767,9 +2768,7 @@ protected function _getDateTimeValue($value, $timeFormat) { } if (is_numeric($value)) { - // @codingStandardsIgnoreStart - $value = @strftime('%Y-%m-%d %H:%M:%S', $value); - // @codingStandardsIgnoreEnd + $value = PHP81_BC\strftime('%Y-%m-%d %H:%M:%S', $value); } $meridian = 'am'; $pos = strpos($value, '-'); @@ -3024,7 +3023,7 @@ protected function _generateOptions($name, $options = array()) { } else { for ($m = 1; $m <= 12; $m++) { // @codingStandardsIgnoreStart - $data[sprintf("%02s", $m)] = @strftime("%m", mktime(1, 1, 1, $m, 1, 1999)); + $data[sprintf("%02s", $m)] = PHP81_BC\strftime("%m", mktime(1, 1, 1, $m, 1, 1999)); // @codingStandardsIgnoreEnd } } diff --git a/lib/Cake/View/Helper/HtmlHelper.php b/lib/Cake/View/Helper/HtmlHelper.php index bc7163e869..267ea26385 100644 --- a/lib/Cake/View/Helper/HtmlHelper.php +++ b/lib/Cake/View/Helper/HtmlHelper.php @@ -318,7 +318,7 @@ public function meta($type, $url = null, $options = array()) { */ public function charset($charset = null) { if (empty($charset)) { - $charset = strtolower(Configure::read('App.encoding')); + $charset = strtolower((string)Configure::read('App.encoding')); } return sprintf($this->_tags['charset'], (!empty($charset) ? $charset : 'utf-8')); } diff --git a/lib/Cake/View/Helper/PrototypeEngineHelper.php b/lib/Cake/View/Helper/PrototypeEngineHelper.php index 332ea69496..920cd9b425 100644 --- a/lib/Cake/View/Helper/PrototypeEngineHelper.php +++ b/lib/Cake/View/Helper/PrototypeEngineHelper.php @@ -219,7 +219,7 @@ public function effect($name, $options = array()) { case 'fadeIn': case 'fadeOut': $name = ($name === 'fadeIn') ? 'appear' : 'fade'; - $effect = $this->selection . '.' . $name . '(' . substr($optionString, 2) . ');'; + $effect = $this->selection . '.' . $name . '(' . substr((string)$optionString, 2) . ');'; break; } return $effect; diff --git a/lib/Cake/View/HelperCollection.php b/lib/Cake/View/HelperCollection.php index 2f67b23669..69e248e74d 100644 --- a/lib/Cake/View/HelperCollection.php +++ b/lib/Cake/View/HelperCollection.php @@ -130,7 +130,7 @@ public function load($helper, $settings = array()) { if (!class_exists($helperClass)) { throw new MissingHelperException(array( 'class' => $helperClass, - 'plugin' => substr($plugin, 0, -1) + 'plugin' => substr((string)$plugin, 0, -1) )); } $this->_loaded[$alias] = new $helperClass($this->_View, $settings); diff --git a/lib/Cake/View/JsonView.php b/lib/Cake/View/JsonView.php index 2284233a59..d5412c46f1 100644 --- a/lib/Cake/View/JsonView.php +++ b/lib/Cake/View/JsonView.php @@ -65,7 +65,7 @@ class JsonView extends View { * * @param Controller $controller Controller instance. */ - public function __construct(Controller $controller = null) { + public function __construct(?Controller $controller = null) { parent::__construct($controller); if (isset($controller->response) && $controller->response instanceof CakeResponse) { $controller->response->type('json'); diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 085928d2e8..2b7410f660 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -330,7 +330,7 @@ class View extends CakeObject { * * @param Controller $controller A controller object to pull View::_passedVars from. */ - public function __construct(Controller $controller = null) { + public function __construct(?Controller $controller = null) { if (is_object($controller)) { $count = count($this->_passedVars); for ($j = 0; $j < $count; $j++) { diff --git a/lib/Cake/View/XmlView.php b/lib/Cake/View/XmlView.php index a8f4fcb16b..eb6267b13e 100644 --- a/lib/Cake/View/XmlView.php +++ b/lib/Cake/View/XmlView.php @@ -65,7 +65,7 @@ class XmlView extends View { * * @param Controller $controller Controller instance. */ - public function __construct(Controller $controller = null) { + public function __construct(?Controller $controller = null) { parent::__construct($controller); if (isset($controller->response) && $controller->response instanceof CakeResponse) { diff --git a/lib/Cake/basics.php b/lib/Cake/basics.php index 3b9417ed81..e78aeeaf75 100644 --- a/lib/Cake/basics.php +++ b/lib/Cake/basics.php @@ -250,7 +250,7 @@ function h($text, $double = true, $charset = null) { * @link https://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#pluginSplit */ function pluginSplit($name, $dotAppend = false, $plugin = null) { - if (strpos($name, '.') !== false) { + if (strpos((string)$name, '.') !== false) { $parts = explode('.', $name, 2); if ($dotAppend) { $parts[0] .= '.'; @@ -359,12 +359,12 @@ function env($key) { $name = env('SCRIPT_NAME'); $filename = env('SCRIPT_FILENAME'); $offset = 0; - if (!strpos($name, '.php')) { + if (!strpos((string)$name, '.php')) { $offset = 4; } - return substr($filename, 0, -(strlen($name) + $offset)); + return substr((string)$filename, 0, -(strlen((string)$name) + $offset)); case 'PHP_SELF': - return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME')); + return str_replace((string)env('DOCUMENT_ROOT'), '', (string)env('SCRIPT_FILENAME')); case 'CGI_MODE': return (PHP_SAPI === 'cgi'); case 'HTTP_BASE': @@ -490,7 +490,7 @@ function cache($path, $data = null, $expires = '+1 day', $target = 'cache') { */ function clearCache($params = null, $type = 'views', $ext = '.php') { if (is_string($params) || $params === null) { - $params = preg_replace('/\/\//', '/', $params); + $params = preg_replace('/\/\//', '/', (string)$params); $cache = CACHE . $type . DS . $params; if (is_file($cache . $ext)) {