diff --git a/.htaccess b/.htaccess deleted file mode 100644 index f13591f2c8..0000000000 --- a/.htaccess +++ /dev/null @@ -1,8 +0,0 @@ - - RewriteEngine on - # Uncomment if you have a .well-known directory in the root folder, e.g. for the Let's Encrypt challenge - # https://tools.ietf.org/html/rfc5785 - #RewriteRule ^(\.well-known/.*)$ $1 [L] - RewriteRule ^$ app/webroot/ [L] - RewriteRule (.*) app/webroot/$1 [L] - \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4320c1fbcb..e03cb2cff3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,75 @@ ## Unreleased +### PHPUnit Integration + +- **PHPUnit 9+ Migration**: Complete migration to PHPUnit 9+ ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + - Refactored `CakeTestLoader` to implement `TestSuiteLoader` interface with composition pattern + - Fixed critical infinite recursion bug in `CakeTestLoader::reload()` method + - Updated `CakeBaseReporter` from extending `PHPUnit_TextUI_ResultPrinter` to implementing `ResultPrinter` interface + - Added missing interface methods: `write()`, `addWarning()`, `addRiskyTest()` to `CakeBaseReporter` + - Added type declarations throughout TestSuite classes for PHP 8.0+ compatibility + - Added `run()` method to `CakeTestSuiteCommand` with proper test file resolution + - Updated all PHPUnit class references from `PHPUnit_Framework_*` to `PHPUnit\Framework\*` namespace + - Removed legacy `CakeTestRunner` class (functionality moved to `CakeTestSuiteCommand`) + - Updated test assertions to use `withConsecutive()` and callback-based output verification + - Fixed `HtmlCoverageReportTest` to use `CakeHtmlReporter` instead of `CakeBaseReporter` + - All tests now pass with PHPUnit 9.6+ + +### Code Modernization + +- **Legacy PHP Version Checks Removal**: Removed compatibility code for PHP < 8.0 ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + - Removed PHP 5.3/5.4 version checks from `ErrorHandler`, `Debugger`, `CakeSocket` + - Removed PHP 5.4 fallback logic in `CakeNumber::_numberFormat()` + - Removed PHP version checks from `CakeTimeTest` + - Simplified SSL/TLS configuration in `CakeSocket` (removed PHP 5.3.2/5.6.0 checks) + - Removed obsolete Debugger workarounds for PHP < 5.3 + - Updated `strpos()` to `str_ends_with()` in `CakeTestLoader` + - Changed `include` to `require_once` in bootstrap files for consistency + - Fixed indentation in `basics.php` to standardize whitespace + +### Performance Improvements + +- **JSON Output Optimization**: Improved JSON rendering performance ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + - `JsonView` now only applies `JSON_PRETTY_PRINT` when debug mode is enabled + - Reduces JSON encoding overhead in production environments + +### Autoloading Improvements + +- **App::load() Enhancement**: Added class existence check ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + - `App::load()` now returns early if class already exists + - Prevents unnecessary file loading and improves performance + - Replaced direct `ShellDispatcher` require with `App::load()` in test bootstrap + - Added `class_exists()` guard in test bootstrap to prevent double definition errors + +### Code Quality + +- **Coding Standards**: Applied phpcs fixes and removed deprecated exclusions ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + - Removed `get_magic_quotes_gpc` exclusion from phpcs.xml (function removed in PHP 7.4) + - Added trailing commas to `trigger_error()` calls for consistency + - Added `CakeHtmlReporter` to unused variable exclusion list + +### Documentation + +- **GitHub URLs Update**: Updated all GitHub organization references ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + - Changed GitHub URLs from `cakephp` to `friendsofcake2` in `home.ctp` templates + - Updated changelog, issues, wiki, and plugin repository links + - Removed upstream `CONTRIBUTING.md` (fork has different contribution guidelines) + +### Dispatcher Improvements + +- **Simplified Dispatcher Entry Points**: Streamlined autoload handling in dispatcher files + - Removed manual `CAKE_CORE_INCLUDE_PATH` detection from dispatcher files (set automatically in bootstrap.php) + - Removed `include_path` manipulation logic (Composer autoload handles this) + - Removed legacy `app/Vendor/cakephp/cakephp` path detection + - Added clear error messages when Composer vendors directory or autoload.php is missing + - Added clear error messages when CakePHP core is not installed via Composer + - **Breaking Change**: Projects must use Composer for installation (non-Composer installation no longer supported) + - **Migration**: If upgrading, copy updated dispatcher files from `vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/` to your project: + - `skel/webroot/index.php` → `app/webroot/index.php` + - `skel/webroot/test.php` → `app/webroot/test.php` + - `skel/Console/cake` → `app/Console/cake` + ### PHP Support - **PHP 8.5 Support**: Added PHP 8.5 to CI testing matrix ([PR #12](https://github.com/friendsofcake2/cakephp/pull/12)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 8c7ceb48b1..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,81 +0,0 @@ -# How to contribute - -CakePHP loves to welcome your contributions. There are several ways to help out: -* Create an [issue](https://github.com/cakephp/cakephp/issues) on GitHub, if you have found a bug -* Write test cases for open bug issues -* Write patches for open bug/feature issues, preferably with test cases included -* Contribute to the [documentation](https://github.com/cakephp/docs) - -There are a few guidelines that we need contributors to follow so that we have a -chance of keeping on top of things. - -## Code of Conduct - -Help us keep CakePHP open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cakephp/code-of-conduct/blob/master/CODE_OF_CONDUCT.md). - -## Getting Started - -* Make sure you have a [GitHub account](https://github.com/signup/free). -* Submit an [issue](https://github.com/cakephp/cakephp/issues), assuming one does not already exist. - * Clearly describe the issue including steps to reproduce when it is a bug. - * Make sure you fill in the earliest version that you know has the issue. -* Fork the repository on GitHub. - -## Making Changes - -* Create a topic branch from where you want to base your work. - * This is usually the master branch. - * Only target release branches if you are certain your fix must be on that - branch. - * To quickly create a topic branch based on master; `git branch - master/my_contribution master` then checkout the new branch with `git - checkout master/my_contribution`. Better avoid working directly on the - `master` branch, to avoid conflicts if you pull in updates from origin. -* Make commits of logical units. -* Check for unnecessary whitespace with `git diff --check` before committing. -* Use descriptive commit messages and reference the #issue number. -* Core test cases should continue to pass. You can run tests locally or enable - [travis-ci](https://travis-ci.org/) for your fork, so all tests and codesniffs - will be executed. -* Your work should apply the [CakePHP coding standards](https://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html). - -## Which branch to base the work - -* Bugfix branches will be based on master. -* New features that are backwards compatible will be based on next minor release - branch. -* New features or other non backwards compatible changes will go in the next major release branch. - -## Submitting Changes - -* Push your changes to a topic branch in your fork of the repository. -* Submit a pull request to the repository in the cakephp organization, with the - correct target branch. - -## Test cases and codesniffer - -CakePHP tests requires [PHPUnit](https://phpunit.de/manual/current/en/installation.html) -3.7, version 4 is not compatible. To run the test cases locally use the following command: - - ./lib/Cake/Console/cake test core AllTests --stderr - -To run the sniffs for CakePHP coding standards: - - phpcs -p --extensions=php --standard=CakePHP ./lib/Cake - -Check the [cakephp-codesniffer](https://github.com/cakephp/cakephp-codesniffer) -repository to setup the CakePHP standard. The [README](https://github.com/cakephp/cakephp-codesniffer/blob/master/README.md) contains installation info -for the sniff and phpcs. - -## Reporting a Security Issue - -If you've found a security related issue in CakePHP, please don't open an issue in GitHub. Instead contact us at security@cakephp.org. For more information on how we handle security issues, [see the CakePHP Security Issue Process](https://book.cakephp.org/2.0/en/contributing/tickets.html#reporting-security-issues). - -# Additional Resources - -* [CakePHP coding standards](https://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html) -* [Existing issues](https://github.com/cakephp/cakephp/issues) -* [Development Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps) -* [General GitHub documentation](https://help.github.com/) -* [GitHub pull request documentation](https://help.github.com/send-pull-requests/) -* #cakephp IRC channel on freenode.org diff --git a/README.md b/README.md index de7a96c4a5..35494fa2a8 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ The original CakePHP 2.x branch [reached End of Life in June 2021](https://baker ## Installation +> [!IMPORTANT] +> This fork requires Composer for installation. Manual installation is not supported. + Install via Composer: ```json @@ -59,9 +62,22 @@ Then run: composer update ``` +After installation, copy dispatcher files from the package to your application: + +```bash +# Copy web dispatcher files +cp vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/webroot/index.php app/webroot/index.php +cp vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/webroot/test.php app/webroot/test.php + +# Copy console dispatcher +cp vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/Console/cake app/Console/cake +chmod +x app/Console/cake +``` + > [!NOTE] -> This package uses Composer's `replace` directive to replace `cakephp/cakephp`. -> This ensures that all plugins and packages that depend on `cakephp/cakephp:^2.x` will continue to work correctly with this fork. +> - This package uses Composer's `replace` directive to replace `cakephp/cakephp`. +> - This ensures that all plugins and packages that depend on `cakephp/cakephp:^2.x` will continue to work correctly with this fork. +> - Dispatcher files provide better error messages and simplified autoload handling. ## Security @@ -97,7 +113,31 @@ Before migrating to this fork, ensure: ### Breaking Changes -#### 1. Cache Engines Removed ([PR #4](https://github.com/friendsofcake2/cakephp/pull/4)) +#### 1. Composer-Only Installation Required ([PR #14](https://github.com/friendsofcake2/cakephp/pull/14)) + +**Breaking Change:** +- **Non-Composer installation is no longer supported** +- Dispatcher files (`app/webroot/index.php`, `app/webroot/test.php`, `app/Console/cake`) require Composer autoload +- Removed manual `CAKE_CORE_INCLUDE_PATH` detection from dispatcher files +- Removed `include_path` manipulation logic +- Removed legacy `app/Vendor/cakephp/cakephp` path detection +- Removed `app/Console/cake.bat` and `app/Console/cake.php` (Windows batch file and PHP wrapper no longer needed) + +**Migration:** +1. Ensure you're using Composer for dependency management +2. Copy updated dispatcher files from `vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/` to your application: + ```bash + cp vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/webroot/index.php app/webroot/index.php + cp vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/webroot/test.php app/webroot/test.php + cp vendors/friendsofcake2/cakephp/lib/Cake/Console/Templates/skel/Console/cake app/Console/cake + ``` +3. Remove old dispatcher files if present: + ```bash + rm -f app/Console/cake.bat app/Console/cake.php + ``` +4. Run `composer install` to ensure all dependencies are properly loaded + +#### 2. Cache Engines Removed ([PR #4](https://github.com/friendsofcake2/cakephp/pull/4)) **Breaking Change:** - **Xcache** support has been removed (not compatible with PHP 7.0+) @@ -106,7 +146,7 @@ Before migrating to this fork, ensure: **Migration:** - If using these cache engines, migrate to Redis, Memcached, or APCu -#### 2. Database Driver Methods Added ([PR #3](https://github.com/friendsofcake2/cakephp/pull/3)) +#### 3. Database Driver Methods Added ([PR #3](https://github.com/friendsofcake2/cakephp/pull/3)) **Breaking Change:** - New methods added to database drivers (may cause issues if you have custom driver implementations) @@ -123,7 +163,7 @@ Before migrating to this fork, ensure: **Migration:** - If you have custom database drivers extending these classes, implement these methods -#### 3. Database Charset Configuration Changes ([PR #11](https://github.com/friendsofcake2/cakephp/pull/11)) +#### 4. Database Charset Configuration Changes ([PR #11](https://github.com/friendsofcake2/cakephp/pull/11)) **Breaking Change:** - Character set configuration moved from `SET NAMES` to DSN connection options @@ -136,11 +176,11 @@ Before migrating to this fork, ensure: - `setEncoding()` methods still work for runtime changes - More efficient connection setup with charset in DSN -#### 4. SQL Server Driver Updates ([PR #9](https://github.com/friendsofcake2/cakephp/pull/9)) +#### 5. SQL Server Driver Updates ([PR #9](https://github.com/friendsofcake2/cakephp/pull/9)) **Breaking Changes:** -**4.1 Configuration Format** +**5.1 Configuration Format** - **Schema-based configuration**: Use schema mapping instead of multiple databases ```php // Old approach (still works) @@ -165,7 +205,7 @@ Before migrating to this fork, ensure: - **Port configuration**: Specify port separately (automatically appended to server) -**4.2 Method Signature Changes** +**5.2 Method Signature Changes** - `describe($model): array` - Now has explicit return type - `insertMulti()` - Now returns `bool` instead of `void` @@ -174,7 +214,7 @@ Before migrating to this fork, ensure: - Move SSL/TLS options to `options` array if using inline DSN - If extending Sqlserver class, update method signatures to match -#### 5. Mail Function Updates ([PR #10](https://github.com/friendsofcake2/cakephp/pull/10)) +#### 6. Mail Function Updates ([PR #10](https://github.com/friendsofcake2/cakephp/pull/10)) **Breaking Change:** - `MailTransport::_mail()` method signature changed with strict types @@ -185,7 +225,7 @@ Before migrating to this fork, ensure: - No action required unless you've extended `MailTransport` class - If extending, update method signature to match strict types -#### 6. CSRF Token Security Enhancement ([PR #5](https://github.com/friendsofcake2/cakephp/pull/5)) +#### 7. CSRF Token Security Enhancement ([PR #5](https://github.com/friendsofcake2/cakephp/pull/5)) **Breaking Change:** - New CSRF tokens use HMAC-SHA1 signatures (prevents CVE-2020-15400) @@ -196,7 +236,7 @@ Before migrating to this fork, ensure: - Existing tokens continue to work - New tokens generated with enhanced security -#### 7. strftime() Replacement +#### 8. strftime() Replacement **Breaking Change:** - `strftime()` deprecated in PHP 8.1, removed in PHP 8.2 @@ -208,9 +248,9 @@ Before migrating to this fork, ensure: - Edge cases may produce slightly different output - Test date formatting in your application -#### 8. Development Tools Updates +#### 9. Development Tools Updates -**8.1 PHP CodeSniffer ([PR #8](https://github.com/friendsofcake2/cakephp/pull/8))** +**9.1 PHP CodeSniffer ([PR #8](https://github.com/friendsofcake2/cakephp/pull/8))** - Updated from 1.0.0 to 5.3 - Applied automatic formatting fixes @@ -218,14 +258,14 @@ Before migrating to this fork, ensure: - Development-time change only - Update `phpcs.xml` if you have custom coding standards -**8.2 PHPUnit Compatibility** +**9.2 PHPUnit Compatibility** - Framework tests migrated to PHPUnit 9.6 - All deprecated PHPUnit features fixed **Migration:** - Update your tests if using deprecated PHPUnit features -#### 9. PHP 8 Syntax Modernization ([PR #7](https://github.com/friendsofcake2/cakephp/pull/7)) +#### 10. PHP 8 Syntax Modernization ([PR #7](https://github.com/friendsofcake2/cakephp/pull/7)) **Breaking Change:** - Codebase modernized to PHP 8 syntax @@ -241,7 +281,7 @@ Before migrating to this fork, ensure: **Migration:** - **No action required** - syntax changes only, no functionality changes -#### 10. CookieComponent 'cipher' Type - Insecure and Should Be Replaced +#### 11. CookieComponent 'cipher' Type - Insecure and Should Be Replaced **Breaking Change:** - The default `CookieComponent` encryption type `'cipher'` is horribly insecure diff --git a/app/.htaccess b/app/.htaccess deleted file mode 100644 index f7ab0332c3..0000000000 --- a/app/.htaccess +++ /dev/null @@ -1,8 +0,0 @@ - - RewriteEngine on - # Uncomment if you have a .well-known directory in the app folder, e.g. for the Let's Encrypt challenge - # https://tools.ietf.org/html/rfc5785 - #RewriteRule ^(\.well-known/.*)$ $1 [L] - RewriteRule ^$ webroot/ [L] - RewriteRule (.*) webroot/$1 [L] - \ No newline at end of file diff --git a/app/Console/cake b/app/Console/cake index fee8e35a31..0aa37d6a64 100755 --- a/app/Console/cake +++ b/app/Console/cake @@ -1,41 +1,54 @@ -#!/usr/bin/env bash -################################################################################ -# -# Bake is a shell script for running CakePHP bake script -# -# CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -# -# Licensed under The MIT License -# For full copyright and license information, please see the LICENSE.txt -# Redistributions of files must retain the above copyright notice. -# -# @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -# @link https://cakephp.org CakePHP(tm) Project -# @package app.Console -# @since CakePHP(tm) v 1.2.0.5012 -# @license https://opensource.org/licenses/mit-license.php MIT License -# -################################################################################ - -# Canonicalize by following every symlink of the given name recursively -canonicalize() { - NAME="$1" - if [ -f "$NAME" ] - then - DIR=$(dirname -- "$NAME") - NAME=$(cd -P "$DIR" && pwd -P)/$(basename -- "$NAME") - fi - while [ -h "$NAME" ]; do - DIR=$(dirname -- "$NAME") - SYM=$(readlink "$NAME") - NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") - done - echo "$NAME" +#!/usr/bin/env php +

- Html->link(__d('cake_dev', 'Read the changelog'), 'https://cakephp.org/changelogs/' . Configure::version()); ?> + Html->link(__d('cake_dev', 'Read the changelog'), 'https://github.com/friendsofcake2/cakephp/releases/tag/v' . Configure::version()); ?>

0): - Debugger::checkSecurityKeys(); + Debugger::checkSecurityKeys(); endif; ?> -

- - 1) Help me configure it - 2) I don't / can't use URL rewriting -

+

+ + 1) Help me configure it + 2) I don't / can't use URL rewriting +

-=')): - echo ''; - echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.'); - echo ''; -else: - echo ''; - echo __d('cake_dev', 'Your version of PHP is too low. You need PHP 5.2.8 or higher to use CakePHP.'); - echo ''; -endif; -?> + '; + echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.'); + echo ''; + ?>

- '; - echo __d('cake_dev', 'Your tmp directory is writable.'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your tmp directory is NOT writable.'); - echo ''; - endif; - ?> + '; + echo __d('cake_dev', 'Your tmp directory is writable.'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'Your tmp directory is NOT writable.'); + echo ''; + endif; + ?>

- '; - echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit %s', '' . $settings['engine'] . 'Engine', CONFIG . 'core.php'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in %s', CONFIG . 'core.php'); - echo ''; - endif; - ?> + '; + echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit %s', '' . $settings['engine'] . 'Engine', CONFIG . 'core.php'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in %s', CONFIG . 'core.php'); + echo ''; + endif; + ?>

- '; - echo __d('cake_dev', 'Your database configuration file is present.'); - $filePresent = true; - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your database configuration file is NOT present.'); - echo '
'; - echo __d('cake_dev', 'Rename %s to %s', CONFIG . 'database.php.default', CONFIG . 'database.php'); - echo '
'; - endif; - ?> + '; + echo __d('cake_dev', 'Your database configuration file is present.'); + $filePresent = true; + echo ''; + else: + echo ''; + echo __d('cake_dev', 'Your database configuration file is NOT present.'); + echo '
'; + echo __d('cake_dev', 'Rename %s to %s', CONFIG . 'database.php.default', CONFIG . 'database.php'); + echo '
'; + endif; + ?>

getMessage(); - if (method_exists($connectionError, 'getAttributes')): - $attributes = $connectionError->getAttributes(); - if (isset($attributes['message'])): - $errorMsg .= '
' . $attributes['message']; - endif; - endif; - } - ?> -

- isConnected()): - echo ''; - echo __d('cake_dev', 'CakePHP is able to connect to the database.'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'CakePHP is NOT able to connect to the database.'); - echo '

'; - echo $errorMsg; - echo '
'; - endif; - ?> -

+ App::uses('ConnectionManager', 'Model'); + try { + $connected = ConnectionManager::getDataSource('default'); + } catch (Exception $connectionError) { + $connected = false; + $errorMsg = $connectionError->getMessage(); + if (method_exists($connectionError, 'getAttributes')): + $attributes = $connectionError->getAttributes(); + if (isset($attributes['message'])): + $errorMsg .= '
' . $attributes['message']; + endif; + endif; + } + ?> +

+ isConnected()): + echo ''; + echo __d('cake_dev', 'CakePHP is able to connect to the database.'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'CakePHP is NOT able to connect to the database.'); + echo '

'; + echo $errorMsg; + echo '
'; + endif; + ?> +

'; - echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.'); - echo '
'; - echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring'); - echo '

'; + echo '

'; + echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.'); + echo '
'; + echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring'); + echo '

'; endif; ?>

- '; - echo __d('cake_dev', 'DebugKit plugin is present'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.'); - echo '
'; - echo __d('cake_dev', 'You can install it from %s', $this->Html->link('GitHub', 'https://github.com/cakephp/debug_kit/tree/2.2')); - echo '
'; - endif; - ?> + '; + echo __d('cake_dev', 'DebugKit plugin is present'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.'); + echo '
'; + echo __d('cake_dev', 'You can install it from %s', $this->Html->link('GitHub', 'https://github.com/friendsofcake2/debug_kit/tree/2.2')); + echo '
'; + endif; + ?>

@@ -150,41 +144,41 @@ endif; echo __d('cake_dev', 'To change the content of this page, edit: %s.
To change its layout, edit: %s.
You can also add some CSS styles for your pages at: %s.', - 'APP/View/Pages/home.ctp', 'APP/View/Layouts/default.ctp', 'APP/webroot/css'); + 'APP/View/Pages/home.ctp', 'APP/View/Layouts/default.ctp', 'APP/webroot/css'); ?>

- Html->link( - sprintf('%s %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')), - 'https://book.cakephp.org/2.0/en/', - array('target' => '_blank', 'escape' => false) - ); - ?> + Html->link( + sprintf('%s %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')), + 'https://book.cakephp.org/2.0/en/', + array('target' => '_blank', 'escape' => false) + ); + ?>

- Html->link( - __d('cake_dev', 'The 15 min Blog Tutorial'), - 'https://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html', - array('target' => '_blank', 'escape' => false) - ); - ?> + Html->link( + __d('cake_dev', 'The 15 min Blog Tutorial'), + 'https://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html', + array('target' => '_blank', 'escape' => false) + ); + ?>

@@ -197,34 +191,34 @@ You can also add some CSS styles for your pages at: %s.',

diff --git a/app/index.php b/app/index.php deleted file mode 100644 index 2a3902ccf0..0000000000 --- a/app/index.php +++ /dev/null @@ -1,17 +0,0 @@ -out(__d('cake_console', 'This command is available on %s or above', 'PHP5.4')); - - return; - } - $command = sprintf( 'php -S %s:%d -t %s %s', $this->_host, diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php index 4eb6a81ea9..d4043f5706 100644 --- a/lib/Cake/Console/Command/Task/ProjectTask.php +++ b/lib/Cake/Console/Command/Task/ProjectTask.php @@ -99,7 +99,7 @@ public function execute() } if ($this->consolePath($path) === true) { - $this->out(__d('cake_console', ' * app/Console/cake.php path set.')); + $this->out(__d('cake_console', ' * app/Console/cake path set.')); } else { $this->err(__d('cake_console', 'Unable to set console path for app/Console.')); $success = false; @@ -236,14 +236,14 @@ public function bake($path, $skel = null, $skip = ['empty']) /** * Generates the correct path to the CakePHP libs that are generating the project - * and points app/console/cake.php to the right place + * and points app/console/cake to the right place * * @param string $path Project path. * @return bool success */ public function consolePath($path) { - $File = new File($path . 'Console' . DS . 'cake.php'); + $File = new File($path . 'Console' . DS . 'cake'); $contents = $File->read(); if (preg_match('/(__CAKE_PATH__)/', $contents, $match)) { $root = str_starts_with(CAKE_CORE_INCLUDE_PATH, '/') ? " DS . '" : "'"; @@ -363,9 +363,9 @@ protected function _replaceCorePath($filename, $hardCode) $root = str_starts_with(CAKE_CORE_INCLUDE_PATH, '/') ? " DS . '" : "'"; $corePath = $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'"; - $composer = ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; + $composer = ROOT . DS . 'vendors' . DS . 'friendsofcake2' . DS . 'cakephp' . DS . 'lib'; if (file_exists($composer)) { - $corePath = " ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'"; + $corePath = " ROOT . DS . 'vendors' . DS . 'friendsofcake2' . DS . 'cakephp' . DS . 'lib'"; } $result = str_replace('__CAKE_PATH__', $corePath, $contents, $count); diff --git a/lib/Cake/Console/Command/TestShell.php b/lib/Cake/Console/Command/TestShell.php index 62c43e54d8..eaf71c323a 100644 --- a/lib/Cake/Console/Command/TestShell.php +++ b/lib/Cake/Console/Command/TestShell.php @@ -187,7 +187,7 @@ public function initialize() * * @return array|null Array of params for CakeTestDispatcher or null. */ - protected function _parseArgs() + protected function _parseArgs(): ?array { if (empty($this->args)) { return null; @@ -268,7 +268,9 @@ public function main() $args = $this->_parseArgs(); if (empty($args['case'])) { - return $this->available(); + $this->available(); + + return; } $this->_run($args, $this->_runnerOptions()); @@ -286,8 +288,8 @@ protected function _run($runnerArgs, $options = []) restore_error_handler(); restore_error_handler(); - $testCli = new CakeTestSuiteCommand('CakeTestLoader', $runnerArgs); - $testCli->run($options); + $testCli = new CakeTestSuiteCommand(CakeTestLoader::class, $runnerArgs); + $testCli->run($options, false); } /** @@ -314,8 +316,9 @@ public function available() if (empty($testCases)) { $this->out(__d('cake_console', "No test cases available \n\n")); + $this->out($this->OptionParser->help()); - return $this->out($this->OptionParser->help()); + return; } $this->out($title); diff --git a/lib/Cake/Console/Command/TestsuiteShell.php b/lib/Cake/Console/Command/TestsuiteShell.php index 81ddd3470c..2419eaf005 100644 --- a/lib/Cake/Console/Command/TestsuiteShell.php +++ b/lib/Cake/Console/Command/TestsuiteShell.php @@ -51,12 +51,12 @@ public function getOptionParser() /** * Parse the CLI options into an array CakeTestDispatcher can use. * - * @return array Array of params for CakeTestDispatcher + * @return array|null Array of params for CakeTestDispatcher */ - protected function _parseArgs() + protected function _parseArgs(): ?array { if (empty($this->args)) { - return; + return null; } $params = [ 'core' => false, @@ -95,7 +95,9 @@ public function main() $args = $this->_parseArgs(); if (empty($args['case'])) { - return $this->available(); + $this->available(); + + return; } $this->_run($args, $this->_runnerOptions()); diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index b8b26478af..da8a8d146b 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -15,6 +15,8 @@ * @license https://opensource.org/licenses/mit-license.php MIT License */ +use PHPUnit\Framework\TestCase; + App::uses('TaskCollection', 'Console'); App::uses('ConsoleOutput', 'Console'); App::uses('ConsoleInput', 'Console'); @@ -874,13 +876,7 @@ public function helper($name) */ protected function _checkUnitTest() { - if (class_exists('PHPUnit_Framework_TestCase')) { - return true; - //@codingStandardsIgnoreStart - } elseif (@include 'PHPUnit' . DS . 'Autoload.php') { - //@codingStandardsIgnoreEnd - return true; - } elseif (App::import('Vendor', 'phpunit', ['file' => 'PHPUnit' . DS . 'Autoload.php'])) { + if (class_exists(TestCase::class)) { return true; } diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php index 4ae10eeff2..dd43ce46b1 100644 --- a/lib/Cake/Console/ShellDispatcher.php +++ b/lib/Cake/Console/ShellDispatcher.php @@ -150,7 +150,7 @@ protected function _bootstrap() define('CONFIG', ROOT . DS . APP_DIR . DS . 'Config' . DS); } // $boot is used by Cake/bootstrap.php file - require CORE_PATH . 'Cake' . DS . 'bootstrap.php'; + require_once CORE_PATH . 'Cake' . DS . 'bootstrap.php'; if (!file_exists(CONFIG . 'core.php')) { include_once CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'Config' . DS . 'core.php'; @@ -419,7 +419,7 @@ public function help() * Stop execution of the current script * * @param string|int $status see http://php.net/exit for values - * @return void + * @return never */ protected function _stop($status = 0) { diff --git a/lib/Cake/Console/Templates/skel/.htaccess b/lib/Cake/Console/Templates/skel/.htaccess deleted file mode 100644 index 128e7871bc..0000000000 --- a/lib/Cake/Console/Templates/skel/.htaccess +++ /dev/null @@ -1,5 +0,0 @@ - - RewriteEngine on - RewriteRule ^$ webroot/ [L] - RewriteRule (.*) webroot/$1 [L] - \ No newline at end of file diff --git a/lib/Cake/Console/Templates/skel/Console/cake b/lib/Cake/Console/Templates/skel/Console/cake index fee8e35a31..a9207817ca 100644 --- a/lib/Cake/Console/Templates/skel/Console/cake +++ b/lib/Cake/Console/Templates/skel/Console/cake @@ -1,41 +1,53 @@ -#!/usr/bin/env bash -################################################################################ -# -# Bake is a shell script for running CakePHP bake script -# -# CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -# -# Licensed under The MIT License -# For full copyright and license information, please see the LICENSE.txt -# Redistributions of files must retain the above copyright notice. -# -# @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -# @link https://cakephp.org CakePHP(tm) Project -# @package app.Console -# @since CakePHP(tm) v 1.2.0.5012 -# @license https://opensource.org/licenses/mit-license.php MIT License -# -################################################################################ - -# Canonicalize by following every symlink of the given name recursively -canonicalize() { - NAME="$1" - if [ -f "$NAME" ] - then - DIR=$(dirname -- "$NAME") - NAME=$(cd -P "$DIR" && pwd -P)/$(basename -- "$NAME") - fi - while [ -h "$NAME" ]; do - DIR=$(dirname -- "$NAME") - SYM=$(readlink "$NAME") - NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") - done - echo "$NAME" +#!/usr/bin/env php +

- +

0): - Debugger::checkSecurityKeys(); + Debugger::checkSecurityKeys(); endif; ?>

- - 1) Help me configure it - 2) I don't / can't use URL rewriting + + 1) Help me configure it + 2) I don't / can't use URL rewriting

-=')): - echo ''; - echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your version of PHP is too low. You need PHP 5.2.8 or higher to use CakePHP.'); - echo ''; - endif; -?> + '; + echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.'); + echo ''; + ?>

- '; - echo __d('cake_dev', 'Your tmp directory is writable.'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your tmp directory is NOT writable.'); - echo ''; - endif; - ?> + '; + echo __d('cake_dev', 'Your tmp directory is writable.'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'Your tmp directory is NOT writable.'); + echo ''; + endif; + ?>

- '; - echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit %s', '' . $settings['engine'] . 'Engine', CONFIG . 'core.php'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in %s', CONFIG . 'core.php'); - echo ''; - endif; - ?> + '; + echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit %s', '' . $settings['engine'] . 'Engine', CONFIG . 'core.php'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in %s', CONFIG . 'core.php'); + echo ''; + endif; + ?>

- '; - echo __d('cake_dev', 'Your database configuration file is present.'); - $filePresent = true; - echo ''; - else: - echo ''; - echo __d('cake_dev', 'Your database configuration file is NOT present.'); - echo '
'; - echo __d('cake_dev', 'Rename %s to %s', CONFIG . 'database.php.default', CONFIG . 'database.php'); - echo '
'; - endif; - ?> + '; + echo __d('cake_dev', 'Your database configuration file is present.'); + $filePresent = true; + echo ''; + else: + echo ''; + echo __d('cake_dev', 'Your database configuration file is NOT present.'); + echo '
'; + echo __d('cake_dev', 'Rename %s to %s', CONFIG . 'database.php.default', CONFIG . 'database.php'); + echo '
'; + endif; + ?>

getMessage(); - if (method_exists($connectionError, 'getAttributes')): - $attributes = $connectionError->getAttributes(); - if (isset($errorMsg['message'])): - $errorMsg .= '
' . $attributes['message']; - endif; - endif; - } + App::uses('ConnectionManager', 'Model'); + try { + $connected = ConnectionManager::getDataSource('default'); + } catch (Exception $connectionError) { + $connected = false; + $errorMsg = $connectionError->getMessage(); + if (method_exists($connectionError, 'getAttributes')): + $attributes = $connectionError->getAttributes(); + if (isset($errorMsg['message'])): + $errorMsg .= '
' . $attributes['message']; + endif; + endif; + } ?>

- isConnected()): - echo ''; - echo __d('cake_dev', 'CakePHP is able to connect to the database.'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'CakePHP is NOT able to connect to the database.'); - echo '

'; - echo $errorMsg; - echo '
'; - endif; - ?> + isConnected()): + echo ''; + echo __d('cake_dev', 'CakePHP is able to connect to the database.'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'CakePHP is NOT able to connect to the database.'); + echo '

'; + echo $errorMsg; + echo '
'; + endif; + ?>

'; - echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.'); - echo '
'; - echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring'); - echo '

'; - endif; + App::uses('Validation', 'Utility'); + if (!Validation::alphaNumeric('cakephp')): + echo '

'; + echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.'); + echo '
'; + echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring'); + echo '

'; + endif; ?>

- '; - echo __d('cake_dev', 'DebugKit plugin is present'); - echo ''; - else: - echo ''; - echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.'); - echo '
'; - echo __d('cake_dev', 'You can install it from %s', $this->Html->link('GitHub', 'https://github.com/cakephp/debug_kit/tree/2.2')); - echo '
'; - endif; - ?> + '; + echo __d('cake_dev', 'DebugKit plugin is present'); + echo ''; + else: + echo ''; + echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.'); + echo '
'; + echo __d('cake_dev', 'You can install it from %s', $this->Html->link('GitHub', 'https://github.com/friendsofcake2/debug_kit/tree/2.2')); + echo '
'; + endif; + ?>

@@ -153,41 +147,41 @@ if (isset($filePresent)): echo __d('cake_dev', 'To change the content of this page, edit: %s.
To change its layout, edit: %s.
You can also add some CSS styles for your pages at: %s.', - 'APP/View/Pages/home.ctp', 'APP/View/Layouts/default.ctp', 'APP/webroot/css'); + 'APP/View/Pages/home.ctp', 'APP/View/Layouts/default.ctp', 'APP/webroot/css'); ?>

- Html->link( - sprintf('%s %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')), - 'https://book.cakephp.org/2.0/en/', - array('target' => '_blank', 'escape' => false) - ); - ?> + Html->link( + sprintf('%s %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')), + 'https://book.cakephp.org/2.0/en/', + array('target' => '_blank', 'escape' => false) + ); + ?>

- Html->link( - __d('cake_dev', 'The 15 min Blog Tutorial'), - 'https://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html', - array('target' => '_blank', 'escape' => false) - ); - ?> + Html->link( + __d('cake_dev', 'The 15 min Blog Tutorial'), + 'https://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html', + array('target' => '_blank', 'escape' => false) + ); + ?>

@@ -200,34 +194,34 @@ You can also add some CSS styles for your pages at: %s.',

diff --git a/lib/Cake/Console/Templates/skel/index.php b/lib/Cake/Console/Templates/skel/index.php deleted file mode 100644 index 952d34e9f6..0000000000 --- a/lib/Cake/Console/Templates/skel/index.php +++ /dev/null @@ -1,8 +0,0 @@ - /dev/null && pwd -P)/$(basename -- "$NAME") - fi - while [ -h "$NAME" ]; do - DIR=$(dirname -- "$NAME") - SYM=$(readlink "$NAME") - NAME=$(cd "$DIR" > /dev/null && cd $(dirname -- "$SYM") > /dev/null && pwd)/$(basename -- "$SYM") - done - echo "$NAME" +if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); } -CONSOLE=$(dirname -- "$(canonicalize "$0")") -APP=`pwd` +$rootInstall = dirname(__DIR__, 3) . DS . 'vendors' . DS . 'autoload.php'; +$composerInstall = dirname(__DIR__, 5) . DS . 'autoload.php'; -exec php -q "$CONSOLE"/cake.php -working "$APP" "$@" -exit +if (isset($GLOBALS['_composer_autoload_path'])) { + require_once $GLOBALS['_composer_autoload_path']; +} else { + if (file_exists($composerInstall)) { + require_once $composerInstall; + } elseif (file_exists($rootInstall)) { + require_once $rootInstall; + } else { + trigger_error('Composer autoload file not found. ' . + 'Please run "composer install" to generate the autoload file.', E_USER_ERROR); + } +} + +if (!require_once 'Cake' . DS . 'Console' . DS . 'ShellDispatcher.php') { + trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); +} + +return ShellDispatcher::run($argv); diff --git a/lib/Cake/Console/cake.bat b/lib/Cake/Console/cake.bat deleted file mode 100644 index 7aa9ad78f8..0000000000 --- a/lib/Cake/Console/cake.bat +++ /dev/null @@ -1,28 +0,0 @@ -:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -:: -:: Bake is a shell script for running CakePHP bake script -:: -:: CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -:: Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -:: -:: Licensed under The MIT License -:: Redistributions of files must retain the above copyright notice. -:: -:: @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -:: @link https://cakephp.org CakePHP(tm) Project -:: @package Cake.Console -:: @since CakePHP(tm) v 1.2.0.5012 -:: @license https://opensource.org/licenses/mit-license.php MIT License -:: -:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -@echo off - -SET app=%0 -SET lib=%~dp0 - -php -q "%lib%cake.php" -working "%CD% " %* - -echo. - -exit /B %ERRORLEVEL% diff --git a/lib/Cake/Console/cake.php b/lib/Cake/Console/cake.php deleted file mode 100644 index 7d47e4f912..0000000000 --- a/lib/Cake/Console/cake.php +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/php -q - [ '%s' . 'Vendor' . DS, + ROOT . DS . 'vendor' . DS, ROOT . DS . 'vendors' . DS, + dirname(CAKE, 2) . DS . 'vendor' . DS, dirname(CAKE, 2) . DS . 'vendors' . DS, ], 'Plugin' => [ diff --git a/lib/Cake/Core/Configure.php b/lib/Cake/Core/Configure.php index 5cb26d83b2..67a906f36d 100644 --- a/lib/Cake/Core/Configure.php +++ b/lib/Cake/Core/Configure.php @@ -439,7 +439,7 @@ protected static function _getReader($config) public static function version() { if (!isset(static::$_values['Cake']['version'])) { - require CAKE . 'Config' . DS . 'config.php'; + $config = require CAKE . 'Config' . DS . 'config.php'; static::write($config); } diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php index 279e5811f0..da5c8d100c 100644 --- a/lib/Cake/Error/ErrorHandler.php +++ b/lib/Cake/Error/ErrorHandler.php @@ -339,16 +339,6 @@ protected static function _getErrorMessage($error, $code, $description, $file, $ $errorConfig = Configure::read('Error'); $message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']'; if (!empty($errorConfig['trace'])) { - // https://bugs.php.net/bug.php?id=65322 - if (version_compare(PHP_VERSION, '5.4.21', '<')) { - if (!class_exists('Debugger')) { - App::load('Debugger'); - } - if (!class_exists('CakeText')) { - App::uses('CakeText', 'Utility'); - App::load('CakeText'); - } - } $trace = Debugger::trace(['start' => 1, 'format' => 'log']); $message .= "\nTrace:\n" . $trace . "\n"; } diff --git a/lib/Cake/Log/Engine/FileLog.php b/lib/Cake/Log/Engine/FileLog.php index 08cdeaafd8..06923e310c 100644 --- a/lib/Cake/Log/Engine/FileLog.php +++ b/lib/Cake/Log/Engine/FileLog.php @@ -195,11 +195,7 @@ protected function _getFilename($type) protected function _rotateFile($filename) { $filepath = $this->_path . $filename; - if (version_compare(PHP_VERSION, '5.3.0') >= 0) { - clearstatcache(true, $filepath); - } else { - clearstatcache(); - } + clearstatcache(true, $filepath); if ( !file_exists($filepath) || diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php index 1ff9d40932..8d26887f5f 100644 --- a/lib/Cake/Model/Datasource/CakeSession.php +++ b/lib/Cake/Model/Datasource/CakeSession.php @@ -589,9 +589,7 @@ protected static function _configureSession() // In PHP7.2.0+ session.save_handler can't be set to 'user' by the user. // https://github.com/php/php-src/commit/a93a51c3bf4ea1638ce0adc4a899cb93531b9f0d - if (version_compare(PHP_VERSION, '7.2.0', '>=')) { - unset($sessionConfig['ini']['session.save_handler']); - } + unset($sessionConfig['ini']['session.save_handler']); } elseif (!empty($sessionConfig['session.save_path']) && Configure::read('debug')) { if (!is_dir($sessionConfig['session.save_path'])) { mkdir($sessionConfig['session.save_path'], 0775, true); diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 37979b8fa1..6a9d23a2b5 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -179,9 +179,6 @@ protected function _processPost() $data = $this->_readInput(); parse_str($data, $this->data); } - if (ini_get('magic_quotes_gpc') === '1') { - $this->data = stripslashes_deep($this->data); - } $override = null; if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) { @@ -222,11 +219,7 @@ protected function _processPost() */ protected function _processGet() { - if (ini_get('magic_quotes_gpc') === '1') { - $query = stripslashes_deep($_GET); - } else { - $query = $_GET; - } + $query = $_GET; $unsetUrl = '/' . str_replace(['.', ' '], '_', urldecode($this->url)); unset($query[$unsetUrl]); diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php index 5fdade0c9b..a47a95b1bb 100644 --- a/lib/Cake/Network/CakeSocket.php +++ b/lib/Cake/Network/CakeSocket.php @@ -287,19 +287,11 @@ protected function _setSslContext($host) } unset($this->config[$key]); } - if (version_compare(PHP_VERSION, '5.3.2', '>=')) { - if (!isset($this->config['context']['ssl']['SNI_enabled'])) { - $this->config['context']['ssl']['SNI_enabled'] = true; - } - if (version_compare(PHP_VERSION, '5.6.0', '>=')) { - if (empty($this->config['context']['ssl']['peer_name'])) { - $this->config['context']['ssl']['peer_name'] = $host; - } - } else { - if (empty($this->config['context']['ssl']['SNI_server_name'])) { - $this->config['context']['ssl']['SNI_server_name'] = $host; - } - } + if (!isset($this->config['context']['ssl']['SNI_enabled'])) { + $this->config['context']['ssl']['SNI_enabled'] = true; + } + if (empty($this->config['context']['ssl']['peer_name'])) { + $this->config['context']['ssl']['peer_name'] = $host; } if (empty($this->config['context']['ssl']['cafile'])) { $this->config['context']['ssl']['cafile'] = CAKE . 'Config' . DS . 'cacert.pem'; diff --git a/lib/Cake/Test/Case/BasicsTest.php b/lib/Cake/Test/Case/BasicsTest.php index d2ac84ca75..4bfd913be5 100644 --- a/lib/Cake/Test/Case/BasicsTest.php +++ b/lib/Cake/Test/Case/BasicsTest.php @@ -1112,8 +1112,6 @@ public function testPrCli() */ public function testStripslashesDeep() { - $this->skipIf(ini_get('magic_quotes_sybase') === '1', 'magic_quotes_sybase is on.'); - $this->assertEquals(stripslashes_deep("tes\'t"), "tes't"); $this->assertEquals(stripslashes_deep('tes\\' . chr(0) . 't'), 'tes' . chr(0) . 't'); $this->assertEquals(stripslashes_deep('tes\"t'), 'tes"t'); @@ -1143,42 +1141,6 @@ public function testStripslashesDeep() $this->assertEquals($expected, stripslashes_deep($nested)); } - /** - * test stripslashes_deep() with magic_quotes_sybase on - * - * @return void - */ - public function testStripslashesDeepSybase() - { - if (!(ini_get('magic_quotes_sybase') === '1')) { - $this->markTestSkipped('magic_quotes_sybase is off'); - } - - $this->assertEquals(stripslashes_deep("tes\'t"), "tes\'t"); - - $nested = [ - 'a' => "tes't", - 'b' => "tes''t", - 'c' => [ - 'd' => "tes'''t", - 'e' => "tes''''t", - ['f' => "tes''t"], - ], - 'g' => "te'''''st", - ]; - $expected = [ - 'a' => "tes't", - 'b' => "tes't", - 'c' => [ - 'd' => "tes''t", - 'e' => "tes''t", - ['f' => "tes't"], - ], - 'g' => "te'''st", - ]; - $this->assertEquals($expected, stripslashes_deep($nested)); - } - /** * Tests that the stackTrace() method is a shortcut for Debugger::trace() * diff --git a/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php index 719829df50..8d5e301fe3 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php @@ -148,10 +148,10 @@ public function testExecuteWithAbsolutePath() $this->assertTrue(is_dir($this->Task->args[0]), 'No project dir'); $File = new File($path . DS . 'webroot' . DS . 'index.php'); $contents = $File->read(); - $this->assertMatchesRegularExpression('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents); + $this->assertMatchesRegularExpression('/define\(\'VENDORS\', .*?DS/', $contents); $File = new File($path . DS . 'webroot' . DS . 'test.php'); $contents = $File->read(); - $this->assertMatchesRegularExpression('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents); + $this->assertMatchesRegularExpression('/define\(\'VENDORS\', .*?DS/', $contents); } /** @@ -174,10 +174,10 @@ public function testExecuteWithCakeOnIncludePath() $this->assertTrue(is_dir($this->Task->args[0]), 'No project dir'); $contents = file_get_contents($path . DS . 'webroot' . DS . 'index.php'); - $this->assertMatchesRegularExpression('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents); + $this->assertMatchesRegularExpression('#define\(\'VENDORS#', $contents); $contents = file_get_contents($path . DS . 'webroot' . DS . 'test.php'); - $this->assertMatchesRegularExpression('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents); + $this->assertMatchesRegularExpression('#define\(\'VENDORS#', $contents); ini_set('include_path', $restore); } @@ -407,9 +407,9 @@ public function testConsolePath() $path = $this->Task->path . 'bake_test_app' . DS; $result = $this->Task->consolePath($path); - $this->assertTrue($result); + $this->assertFalse($result); - $File = new File($path . 'Console' . DS . 'cake.php'); + $File = new File($path . 'Console' . DS . 'cake'); $contents = $File->read(); $this->assertDoesNotMatchRegularExpression('/__CAKE_PATH__/', $contents, 'Console path placeholder left behind.'); } diff --git a/lib/Cake/Test/Case/Console/Command/TestShellTest.php b/lib/Cake/Test/Case/Console/Command/TestShellTest.php index ad51756fe4..8315f1ca08 100644 --- a/lib/Cake/Test/Case/Console/Command/TestShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/TestShellTest.php @@ -1,7 +1,5 @@ skipIf(version_compare(Version::id(), '9.0.0', '>='), 'This test can not be run with PHPUnit 9+'); parent::setUp(); $out = $this->getMock('ConsoleOutput', [], [], '', false); $in = $this->getMock('ConsoleInput', [], [], '', false); @@ -323,9 +320,12 @@ public function testAvailableWithEmptyList() $this->Shell->startup(); $this->Shell->args = ['unexistant-category']; - $this->Shell->expects($this->once()) + $this->Shell->expects($this->exactly(2)) ->method('out') - ->with(__d('cake_console', "No test cases available \n\n")); + ->withConsecutive( + [__d('cake_console', "No test cases available \n\n")], + [$this->anything()], + ); $this->Shell->OptionParser->expects($this->once())->method('help'); $this->Shell->available(); @@ -341,13 +341,12 @@ public function testAvailableCoreCategory() $this->Shell->startup(); $this->Shell->args = ['core']; - $this->Shell->expects($this->exactly(3)) + $outputs = []; + $this->Shell->expects($this->atLeast(3)) ->method('out') - ->withConsecutive( - ['Core Test Cases:'], - [$this->stringContains('[1]')], - [$this->stringContains('[2]')], - ); + ->willReturnCallback(function ($value) use (&$outputs) { + $outputs[] = $value; + }); $this->Shell->expects($this->once()) ->method('in') @@ -356,7 +355,11 @@ public function testAvailableCoreCategory() $this->Shell->expects($this->once())->method('_run'); $this->Shell->available(); + $this->assertEquals(['core', 'AllBehaviors'], $this->Shell->args); + $this->assertEquals('Core Test Cases:', $outputs[0]); + $this->assertStringContainsString('[1]', $outputs[1]); + $this->assertStringContainsString('[2]', $outputs[2]); } /** diff --git a/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php b/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php index ece9d6e2ae..226d38d60e 100644 --- a/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php +++ b/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php @@ -163,10 +163,6 @@ public function testError500Exception() */ public function testNonIntegerExceptionCode() { - if (PHP_VERSION_ID < 50300) { - $this->markTestSkipped('ReflectionProperty::setAccessible() is available since 5.3'); - } - $exception = new Exception('Non-integer exception code'); $class = new ReflectionClass('Exception'); diff --git a/lib/Cake/Test/Case/Core/CakeObjectTest.php b/lib/Cake/Test/Case/Core/CakeObjectTest.php index 32f829e751..858d8aacd3 100644 --- a/lib/Cake/Test/Case/Core/CakeObjectTest.php +++ b/lib/Cake/Test/Case/Core/CakeObjectTest.php @@ -723,16 +723,4 @@ public function testRequestActionPostWithData() ); $this->assertEquals($data, $result); } - - /** - * Test backward compatibility - * - * @return voind - */ - public function testBackwardCompatibility() - { - $this->skipIf(version_compare(PHP_VERSION, '7.0.0', '>=')); - - $this->assertInstanceOf('Object', new ObjectTestModel()); - } } diff --git a/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php b/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php index 5a16b87a2c..2a0ae800ef 100644 --- a/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php +++ b/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php @@ -1,7 +1,5 @@ skipIf(version_compare(Version::id(), '9.0.0', '>='), 'This test can not be run with PHPUnit 9+'); parent::setUp(); App::build([ 'Plugin' => [CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS], ], App::RESET); CakePlugin::load(['TestPlugin']); - $reporter = new CakeBaseReporter(); + $reporter = new CakeHtmlReporter(); $reporter->params = ['app' => false, 'plugin' => false, 'group' => false]; $coverage = []; $this->Coverage = new HtmlCoverageReport($coverage, $reporter); diff --git a/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/lib/Cake/Test/Case/Utility/CakeTimeTest.php index 9be39f4ba5..73d90f4b33 100644 --- a/lib/Cake/Test/Case/Utility/CakeTimeTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTimeTest.php @@ -1301,10 +1301,6 @@ public function testFormatNewSyntax() */ public function testListTimezones() { - $this->skipIf( - version_compare(PHP_VERSION, '5.4.0', '<='), - 'This test requires newer libicu which is in php5.4+', - ); $return = CakeTime::listTimezones(); $this->assertTrue(isset($return['Asia']['Asia/Bangkok'])); $this->assertEquals('Bangkok', $return['Asia']['Asia/Bangkok']); @@ -1335,15 +1331,13 @@ public function testListTimezones() $this->assertTrue(isset($return['America/Argentina/Buenos_Aires'])); $this->assertTrue(isset($return['Pacific/Tahiti'])); - if (!$this->skipIf(version_compare(PHP_VERSION, '5.3.0', '<'))) { - $return = CakeTime::listTimezones(DateTimeZone::ASIA); - $this->assertTrue(isset($return['Asia']['Asia/Bangkok'])); - $this->assertFalse(isset($return['Pacific'])); + $return = CakeTime::listTimezones(DateTimeZone::ASIA); + $this->assertTrue(isset($return['Asia']['Asia/Bangkok'])); + $this->assertFalse(isset($return['Pacific'])); - $return = CakeTime::listTimezones(DateTimeZone::PER_COUNTRY, 'US', false); - $this->assertTrue(isset($return['Pacific/Honolulu'])); - $this->assertFalse(isset($return['Asia/Bangkok'])); - } + $return = CakeTime::listTimezones(DateTimeZone::PER_COUNTRY, 'US', false); + $this->assertTrue(isset($return['Pacific/Honolulu'])); + $this->assertFalse(isset($return['Asia/Bangkok'])); } /** diff --git a/lib/Cake/Test/Case/Utility/DebuggerTest.php b/lib/Cake/Test/Case/Utility/DebuggerTest.php index bf3c9386b7..14622a8758 100644 --- a/lib/Cake/Test/Case/Utility/DebuggerTest.php +++ b/lib/Cake/Test/Case/Utility/DebuggerTest.php @@ -388,10 +388,6 @@ public function testExportVar() Form => object(FormHelper) {} int => (int) 2 float => (float) 1.333 - -TEXT; - if (version_compare(PHP_VERSION, '5.3.0') >= 0) { - $expected .= << array( (int) 0 => 'viewVars', (int) 1 => 'autoLayout', @@ -417,10 +413,6 @@ public function testExportVar() [protected] _stack => array() [protected] _eventManager => object(CakeEventManager) {} [protected] _eventManagerConfigured => false - -TEXT; - } - $expected .= <<delete($mv); $this->assertTrue($result); - $new = APP . 'index.php'; + $new = WWW_ROOT . 'index.php'; $result = $Folder->create($new); $this->assertFalse($result); diff --git a/lib/Cake/Test/Case/Utility/HashTest.php b/lib/Cake/Test/Case/Utility/HashTest.php index e3dcedf9d5..371a333d35 100644 --- a/lib/Cake/Test/Case/Utility/HashTest.php +++ b/lib/Cake/Test/Case/Utility/HashTest.php @@ -1332,9 +1332,6 @@ public function testSortNumeric() */ public function testSortNatural() { - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - $this->markTestSkipped('SORT_NATURAL is available since PHP 5.4.'); - } $items = [ ['Item' => ['image' => 'img1.jpg']], ['Item' => ['image' => 'img99.jpg']], @@ -1370,9 +1367,6 @@ public function testSortNatural() */ public function testSortNaturalIgnoreCase() { - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - $this->markTestSkipped('SORT_NATURAL is available since PHP 5.4.'); - } $items = [ ['Item' => ['image' => 'img1.jpg']], ['Item' => ['image' => 'img99.jpg']], @@ -1408,10 +1402,6 @@ public function testSortNaturalIgnoreCase() */ public function testSortNaturalFallbackToRegular() { - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - $this->markTestSkipped('Skipping SORT_NATURAL fallback test on PHP >= 5.4'); - } - $a = [ 0 => ['Person' => ['name' => 'Jeff']], 1 => ['Shirt' => ['color' => 'black']], diff --git a/lib/Cake/Test/Case/Utility/SecurityTest.php b/lib/Cake/Test/Case/Utility/SecurityTest.php index fd915caf38..950cd83ef1 100644 --- a/lib/Cake/Test/Case/Utility/SecurityTest.php +++ b/lib/Cake/Test/Case/Utility/SecurityTest.php @@ -523,7 +523,6 @@ public function testEncryptDecryptCompatibility($txt) { $this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed'); $this->skipIf(!extension_loaded('openssl'), 'This test requires openssl to be installed'); - $this->skipIf(version_compare(PHP_VERSION, '5.3.3', '<'), 'This test requires PHP 5.3.3 or greater'); $key = '12345678901234567890123456789012'; diff --git a/lib/Cake/Test/Case/View/Helper/RssHelperTest.php b/lib/Cake/Test/Case/View/Helper/RssHelperTest.php index b62070c74a..efd21b6050 100644 --- a/lib/Cake/Test/Case/View/Helper/RssHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/RssHelperTest.php @@ -600,11 +600,7 @@ public function testItemEnclosureLength() $this->assertTrue($File->write('123'), 'Could not write to ' . $tmpFile); - if (PHP_VERSION_ID >= 50300) { - clearstatcache(true, $tmpFile); - } else { - clearstatcache(); - } + clearstatcache(true, $tmpFile); $item = [ 'title' => [ diff --git a/lib/Cake/Test/Case/View/JsonViewTest.php b/lib/Cake/Test/Case/View/JsonViewTest.php index b877b4c4b8..bd657135f8 100644 --- a/lib/Cake/Test/Case/View/JsonViewTest.php +++ b/lib/Cake/Test/Case/View/JsonViewTest.php @@ -206,8 +206,6 @@ public function testRenderWithoutView($data, $serialize, $expected) */ public function testRenderWithoutViewJsonOptions() { - $this->skipIf(!version_compare(PHP_VERSION, '5.3.0', '>='), 'Needs PHP5.3+ for these constants to be tested'); - $Request = new CakeRequest(); $Response = new CakeResponse(); $Controller = new Controller($Request, $Response); diff --git a/lib/Cake/Test/Case/View/ViewTest.php b/lib/Cake/Test/Case/View/ViewTest.php index 44556fa5f5..fc99eafb42 100644 --- a/lib/Cake/Test/Case/View/ViewTest.php +++ b/lib/Cake/Test/Case/View/ViewTest.php @@ -1954,12 +1954,7 @@ public function testViewVarDefaultValue() protected function _checkException($message) { - if (version_compare(PHP_VERSION, '7.4', '>=')) { - $this->expectException(Error::class); - $this->expectExceptionMessage($message); - } else { - $this->expectError(); - $this->expectErrorMessage($message); - } + $this->expectException(Error::class); + $this->expectExceptionMessage($message); } } diff --git a/lib/Cake/Test/bootstrap/cake_dot_php.php b/lib/Cake/Test/bootstrap/cake_dot_php.php index 69c9c28082..2b3a01147f 100644 --- a/lib/Cake/Test/bootstrap/cake_dot_php.php +++ b/lib/Cake/Test/bootstrap/cake_dot_php.php @@ -1,37 +1,30 @@ loader = new StandardTestSuiteLoader(); + } + /** * Load a file and find the first test case / suite in that file. * - * @param string $filePath The file path to load - * @param string $params Additional parameters + * @param string $suiteClassFile The file path to load * @return ReflectionClass */ - public function load($filePath, $params = '') + public function load(string $suiteClassFile): ReflectionClass { - $file = $this->_resolveTestFile($filePath, $params); + $file = $this->_resolveTestFile($suiteClassFile, []); - return parent::load('', $file); + return $this->loader->load($file); } /** * Convert path fragments used by CakePHP's test runner to absolute paths that can be fed to PHPUnit. * * @param string $filePath The file path to load. - * @param string $params Additional parameters. + * @param array $params Additional parameters. * @return string Converted path fragments. */ - protected function _resolveTestFile($filePath, $params) + protected function _resolveTestFile(string $filePath, array $params): string { $basePath = static::_basePath($params) . DS . $filePath; $ending = 'Test.php'; - return strpos($basePath, $ending) === strlen($basePath) - strlen($ending) ? $basePath : $basePath . $ending; + return str_ends_with($basePath, $ending) ? $basePath : $basePath . $ending; } /** * Generates the base path to a set of tests based on the parameters. * - * @param array $params The path parameters. - * @return string The base path. + * @param array|null $params The path parameters. + * @return string|null The base path. */ - protected static function _basePath($params) + protected static function _basePath(?array $params): ?string { $result = null; if (!empty($params['core'])) { @@ -87,12 +99,16 @@ protected static function _basePath($params) /** * Get the list of files for the test listing. * - * @param string $params Path parameters + * @param array|null $params Path parameters * @return array */ - public static function generateTestList($params) + public static function generateTestList(?array $params): array { $directory = static::_basePath($params); + if (empty($directory)) { + return []; + } + $fileList = static::_getRecursiveFileList($directory); $testCases = []; @@ -113,7 +129,7 @@ public static function generateTestList($params) * @param string $directory The directory to scan for files. * @return array */ - protected static function _getRecursiveFileList($directory = '.') + protected static function _getRecursiveFileList(string $directory = '.'): array { $fileList = []; if (!is_dir($directory)) { @@ -131,4 +147,15 @@ protected static function _getRecursiveFileList($directory = '.') return $fileList; } + + /** + * Reload + * + * @param ReflectionClass $aClass + * @return ReflectionClass + */ + public function reload(ReflectionClass $aClass): ReflectionClass + { + return $this->loader->reload($aClass); + } } diff --git a/lib/Cake/TestSuite/CakeTestRunner.php b/lib/Cake/TestSuite/CakeTestRunner.php deleted file mode 100644 index bbb71de143..0000000000 --- a/lib/Cake/TestSuite/CakeTestRunner.php +++ /dev/null @@ -1,139 +0,0 @@ -_params = $params; - } - - /** - * Actually run a suite of tests. Cake initializes fixtures here using the chosen fixture manager - * - * @param PHPUnit_Framework_Test $suite The test suite to run - * @param array $arguments The CLI arguments - * @param bool $exit Exits by default or returns the results - * This argument is ignored if >PHPUnit5.2.0 - * @return void - */ - public function doRun(PHPUnit_Framework_Test $suite, array $arguments = [], $exit = true) - { - if (isset($arguments['printer'])) { - static::$versionStringPrinted = true; - } - - $fixture = $this->_getFixtureManager($arguments); - $iterator = $suite->getIterator(); - if ($iterator instanceof RecursiveIterator) { - $iterator = new RecursiveIteratorIterator($iterator); - } - foreach ($iterator as $test) { - if ($test instanceof CakeTestCase) { - $fixture->fixturize($test); - $test->fixtureManager = $fixture; - } - } - - $return = parent::doRun($suite, $arguments, $exit); - $fixture->shutdown(); - - return $return; - } - -// @codingStandardsIgnoreStart PHPUnit overrides don't match CakePHP - - /** - * Create the test result and splice on our code coverage reports. - * - * @return PHPUnit_Framework_TestResult - */ - protected function createTestResult() - { - $result = new PHPUnit_Framework_TestResult(); - if (!empty($this->_params['codeCoverage'])) { - if (method_exists($result, 'collectCodeCoverageInformation')) { - $result->collectCodeCoverageInformation(true); - } - if (method_exists($result, 'setCodeCoverage')) { - $result->setCodeCoverage(new PHP_CodeCoverage()); - } - } - - return $result; - } - -// @codingStandardsIgnoreEnd - - /** - * Get the fixture manager class specified or use the default one. - * - * @param array $arguments The CLI arguments. - * @return mixed instance of a fixture manager. - * @throws RuntimeException When fixture manager class cannot be loaded. - */ - protected function _getFixtureManager($arguments) - { - if (!empty($arguments['fixtureManager'])) { - App::uses($arguments['fixtureManager'], 'TestSuite'); - if (class_exists($arguments['fixtureManager'])) { - return new $arguments['fixtureManager'](); - } - throw new RuntimeException(__d('cake_dev', 'Could not find fixture manager %s.', $arguments['fixtureManager'])); - } - App::uses('AppFixtureManager', 'TestSuite'); - if (class_exists('AppFixtureManager')) { - return new AppFixtureManager(); - } - - return new CakeFixtureManager(); - } -} diff --git a/lib/Cake/TestSuite/CakeTestSuiteCommand.php b/lib/Cake/TestSuite/CakeTestSuiteCommand.php index c32014a214..3f698c38e3 100644 --- a/lib/Cake/TestSuite/CakeTestSuiteCommand.php +++ b/lib/Cake/TestSuite/CakeTestSuiteCommand.php @@ -19,7 +19,6 @@ * @license https://opensource.org/licenses/mit-license.php MIT License */ -App::uses('CakeTestRunner', 'TestSuite'); App::uses('CakeTestLoader', 'TestSuite'); App::uses('CakeTestSuite', 'TestSuite'); App::uses('CakeTestCase', 'TestSuite'); @@ -36,11 +35,11 @@ class CakeTestSuiteCommand extends Command /** * Construct method * - * @param mixed $loader The loader instance to use. + * @param string $loader The loader instance to use. * @param array $params list of options to be used for this run * @throws MissingTestLoaderException When a loader class could not be found. */ - public function __construct($loader, $params = []) + public function __construct(string $loader, array $params = []) { if ($loader && !class_exists($loader)) { throw new MissingTestLoaderException(['class' => $loader]); @@ -55,76 +54,18 @@ public function __construct($loader, $params = []) } /** - * Ugly hack to get around PHPUnit having a hard coded class name for the Runner. :( + * Run * - * @param array $argv The command arguments - * @param bool $exit The exit mode. - * @return void + * @param array $argv + * @param bool $exit + * @return int + * @throws Exception */ - public function run(array $argv, $exit = true): int + public function run(array $argv, bool $exit = true): int { - $this->handleArguments($argv); - - $runner = $this->getRunner($this->arguments['loader']); - - if ( - is_object($this->arguments['test']) && - $this->arguments['test'] instanceof PHPUnit_Framework_Test - ) { - $suite = $this->arguments['test']; - } else { - $suite = $runner->getTest( - $this->arguments['test'], - $this->arguments['testFile'], - ); - } - - if ($this->arguments['listGroups']) { - PHPUnit_TextUI_TestRunner::printVersionString(); - - print "Available test group(s):\n"; - - $groups = $suite->getGroups(); - sort($groups); - - foreach ($groups as $group) { - print " - $group\n"; - } - - exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); - } - - unset($this->arguments['test']); - unset($this->arguments['testFile']); - - try { - $result = $runner->doRun($suite, $this->arguments, false); - } catch (PHPUnit_Framework_Exception $e) { - print $e->getMessage() . "\n"; - } + $argv[] = $this->_resolveTestFile($this->_params['case'], $this->_params); - if ($exit) { - if (!isset($result) || $result->errorCount() > 0) { - exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); - } - if ($result->failureCount() > 0) { - exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); - } - - // Default to success even if there are warnings to match phpunit's behavior - exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); - } - } - - /** - * Create a runner for the command. - * - * @param mixed $loader The loader to be used for the test run. - * @return CakeTestRunner - */ - public function getRunner($loader) - { - return new CakeTestRunner($loader, $this->_params); + return parent::run($argv, $exit); } /** @@ -142,12 +83,10 @@ public function handleFixture($class) * Handles output flag used to change printing on webrunner. * * @param string $reporter The reporter class to use. - * @return void + * @return CakeBaseReporter */ public function handleReporter($reporter) { - $object = null; - $reporter = ucwords($reporter); $coreClass = 'Cake' . $reporter . 'Reporter'; App::uses($coreClass, 'TestSuite/Reporter'); @@ -163,4 +102,47 @@ public function handleReporter($reporter) return $this->arguments['printer'] = $object; } + + /** + * Convert path fragments used by CakePHP's test runner to absolute paths that can be fed to PHPUnit. + * + * @param string $filePath The file path to load. + * @param array $params Additional parameters. + * @return string Converted path fragments. + */ + protected function _resolveTestFile(string $filePath, array $params): string + { + $basePath = static::_basePath($params) . DS . $filePath; + $ending = 'Test.php'; + + return str_ends_with($basePath, $ending) ? $basePath : $basePath . $ending; + } + + /** + * Generates the base path to a set of tests based on the parameters. + * + * @param array|null $params The path parameters. + * @return string|null The base path. + */ + protected static function _basePath(?array $params): ?string + { + $result = null; + if (!empty($params['core'])) { + $result = CORE_TEST_CASES; + } elseif (!empty($params['plugin'])) { + if (!CakePlugin::loaded($params['plugin'])) { + try { + CakePlugin::load($params['plugin']); + $result = CakePlugin::path($params['plugin']) . 'Test' . DS . 'Case'; + } catch (MissingPluginException) { + } + } else { + $result = CakePlugin::path($params['plugin']) . 'Test' . DS . 'Case'; + } + } elseif (!empty($params['app'])) { + $result = APP_TEST_CASES; + } + + return $result; + } } diff --git a/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php b/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php index 2ab584133a..29d701fefb 100644 --- a/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php +++ b/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php @@ -19,6 +19,9 @@ /** * Path to the tests directory of the app. */ + +use PHPUnit\Framework\TestCase; + if (!defined('TESTS')) { define('TESTS', APP . 'Test' . DS); } @@ -154,38 +157,7 @@ protected function _checkPHPUnit() */ public function loadTestFramework() { - if (class_exists('PHPUnit_Framework_TestCase')) { - return true; - } - $phpunitPath = 'phpunit' . DS . 'phpunit'; - if (defined('PHP_WINDOWS_VERSION_MAJOR')) { - $composerGlobalDir[] = env('APPDATA') . DS . 'Composer' . DS . 'vendor' . DS; - } else { - $composerGlobalDir[] = env('HOME') . DS . '.composer' . DS . 'vendor' . DS; - } - $vendors = array_merge(App::path('vendors'), $composerGlobalDir); - foreach ($vendors as $vendor) { - $vendor = rtrim($vendor, DS); - if (is_dir($vendor . DS . $phpunitPath)) { - ini_set('include_path', $vendor . DS . $phpunitPath . PATH_SEPARATOR . ini_get('include_path')); - break; - } elseif (is_dir($vendor . DS . 'PHPUnit')) { - ini_set('include_path', $vendor . PATH_SEPARATOR . ini_get('include_path')); - break; - } elseif (is_file($vendor . DS . 'phpunit.phar')) { - $backup = $GLOBALS['_SERVER']['SCRIPT_NAME']; - $GLOBALS['_SERVER']['SCRIPT_NAME'] = '-'; - ob_start(); - $included = include_once $vendor . DS . 'phpunit.phar'; - ob_end_clean(); - $GLOBALS['_SERVER']['SCRIPT_NAME'] = $backup; - - return $included; - } - } - include 'PHPUnit' . DS . 'Autoload.php'; - - return class_exists('PHPUnit_Framework_TestCase'); + return class_exists(TestCase::class); } /** @@ -284,8 +256,8 @@ protected function _runTestCase() try { static::time(); - $command = new CakeTestSuiteCommand('CakeTestLoader', $commandArgs); - $command->run($options); + $command = new CakeTestSuiteCommand(CakeTestLoader::class, $commandArgs); + $command->run($options, false); } catch (MissingConnectionException $exception) { ob_end_clean(); include CAKE . 'TestSuite' . DS . 'templates' . DS . 'missing_connection.php'; diff --git a/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php b/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php index c27ed610a2..6b30c1a18d 100644 --- a/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php +++ b/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php @@ -15,16 +15,19 @@ * @license https://opensource.org/licenses/mit-license.php MIT License */ -if (!class_exists('PHPUnit_TextUI_ResultPrinter')) { - require_once 'PHPUnit/TextUI/ResultPrinter.php'; -} +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestResult; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; +use PHPUnit\TextUI\ResultPrinter; /** * CakeBaseReporter contains common reporting features used in the CakePHP Test suite * * @package Cake.TestSuite.Reporter */ -class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter +abstract class CakeBaseReporter implements ResultPrinter { /** * Headers sent @@ -47,6 +50,11 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter */ protected $_characterSet; + /** + * @var int + */ + protected int $numAssertions = 0; + /** * Does nothing yet. The first output will * be sent on the first test start. @@ -131,10 +139,10 @@ public function baseUrl() /** * Print result * - * @param PHPUnit_Framework_TestResult $result The result object + * @param TestResult $result The result object * @return void */ - public function printResult(PHPUnit_Framework_TestResult $result) + public function printResult(TestResult $result): void { $this->paintFooter($result); } @@ -142,10 +150,10 @@ public function printResult(PHPUnit_Framework_TestResult $result) /** * Paint result * - * @param PHPUnit_Framework_TestResult $result The result object + * @param TestResult $result The result object * @return void */ - public function paintResult(PHPUnit_Framework_TestResult $result) + public function paintResult(TestResult $result) { $this->paintFooter($result); } @@ -153,12 +161,12 @@ public function paintResult(PHPUnit_Framework_TestResult $result) /** * An error occurred. * - * @param PHPUnit_Framework_Test $test The test to add an error for. - * @param Exception $e The exception object to add. + * @param \PHPUnit\Framework\Test $test The test to add an error for. + * @param Exception|Throwable $e The exception object to add. * @param float $time The current time. * @return void */ - public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + public function addError(Test $test, Exception|Throwable $e, $time): void { $this->paintException($e, $test); } @@ -166,12 +174,12 @@ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) /** * A failure occurred. * - * @param PHPUnit_Framework_Test $test The test that failed - * @param PHPUnit_Framework_AssertionFailedError $e The assertion that failed. + * @param \PHPUnit\Framework\Test $test The test that failed + * @param AssertionFailedError $e The assertion that failed. * @param float $time The current time. * @return void */ - public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + public function addFailure(Test $test, AssertionFailedError $e, $time): void { $this->paintFail($e, $test); } @@ -179,12 +187,12 @@ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_Asser /** * Incomplete test. * - * @param PHPUnit_Framework_Test $test The test that was incomplete. - * @param Exception $e The incomplete exception + * @param \PHPUnit\Framework\Test $test The test that was incomplete. + * @param Exception|Throwable $e The incomplete exception * @param float $time The current time. * @return void */ - public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + public function addIncompleteTest(Test $test, Exception|Throwable $e, $time): void { $this->paintSkip($e, $test); } @@ -192,12 +200,12 @@ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $t /** * Skipped test. * - * @param PHPUnit_Framework_Test $test The test that failed. - * @param Exception $e The skip object. + * @param \PHPUnit\Framework\Test $test The test that failed. + * @param Exception|Throwable $e The skip object. * @param float $time The current time. * @return void */ - public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + public function addSkippedTest(Test $test, Exception|Throwable $e, $time): void { $this->paintSkip($e, $test); } @@ -205,10 +213,10 @@ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time /** * A test suite started. * - * @param PHPUnit_Framework_TestSuite $suite The suite to start + * @param TestSuite $suite The suite to start * @return void */ - public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + public function startTestSuite(TestSuite $suite): void { if (!$this->_headerSent) { echo $this->paintHeader(); @@ -219,31 +227,31 @@ public function startTestSuite(PHPUnit_Framework_TestSuite $suite) /** * A test suite ended. * - * @param PHPUnit_Framework_TestSuite $suite The suite that ended. + * @param TestSuite $suite The suite that ended. * @return void */ - public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + public function endTestSuite(TestSuite $suite): void { } /** * A test started. * - * @param PHPUnit_Framework_Test $test The test that started. + * @param \PHPUnit\Framework\Test $test The test that started. * @return void */ - public function startTest(PHPUnit_Framework_Test $test) + public function startTest(Test $test): void { } /** * A test ended. * - * @param PHPUnit_Framework_Test $test The test that ended + * @param \PHPUnit\Framework\Test $test The test that ended * @param float $time The current time. * @return void */ - public function endTest(PHPUnit_Framework_Test $test, $time) + public function endTest(Test $test, $time): void { $this->numAssertions += $test->getNumAssertions(); if ($test->hasFailed()) { @@ -251,4 +259,34 @@ public function endTest(PHPUnit_Framework_Test $test, $time) } $this->paintPass($test, $time); } + + /** + * @param string $buffer + * @return void + */ + public function write(string $buffer): void + { + echo $buffer; + } + + /** + * @param Test $test + * @param Warning $e + * @param float $time + * @return void + */ + public function addWarning(Test $test, Warning $e, float $time): void + { + $this->paintFail($e, $test); + } + + /** + * @param Test $test + * @param Throwable $t + * @param float $time + * @return void + */ + public function addRiskyTest(Test $test, Throwable $t, float $time): void + { + } } diff --git a/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php b/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php index 7cc912a829..f124f6dd7d 100644 --- a/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php +++ b/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php @@ -1,5 +1,9 @@ params['baseDir']; include CAKE . 'TestSuite' . DS . 'templates' . DS . 'header.php'; } @@ -85,6 +90,7 @@ public function paintTestMenu() { $plugins = App::objects('plugin', null, false); sort($plugins); + $cases = '?'; include CAKE . 'TestSuite' . DS . 'templates' . DS . 'menu.php'; } @@ -145,13 +151,12 @@ public function sendNoCacheHeaders() * Paints the end of the test with a summary of * the passes and failures. * - * @param PHPUnit_Framework_TestResult $result Result object + * @param TestResult $result Result object * @return void */ - public function paintFooter($result) + public function paintFooter(TestResult $result) { echo $this->_buffer; - ob_end_flush(); $colour = ($result->failureCount() + $result->errorCount() > 0 ? 'red' : 'green'); echo "\n"; @@ -205,21 +210,7 @@ public function paintCoverage(array $coverage) */ protected function _paintLinks() { - $show = $query = []; - if (!empty($this->params['case'])) { - $show['show'] = 'cases'; - } - - if (!empty($this->params['core'])) { - $show['core'] = $query['core'] = 'true'; - } - if (!empty($this->params['plugin'])) { - $show['plugin'] = $query['plugin'] = $this->params['plugin']; - } - if (!empty($this->params['case'])) { - $query['case'] = $this->params['case']; - } - [$show, $query] = str_split($this->_getQueryLink()); + [$show, $query] = $this->_getQueryLink(); echo "

Run more tests | Show Passes | \n"; echo "Enable Debug Output | \n"; @@ -252,6 +243,7 @@ protected function _queryString($url) */ public function paintDocumentEnd() { + $baseDir = $this->params['baseDir']; include CAKE . 'TestSuite' . DS . 'templates' . DS . 'footer.php'; if (ob_get_length()) { ob_end_flush(); @@ -303,7 +295,7 @@ public function paintFail($message, $test) echo "\n"; echo "

" . __d('cake_dev', 'Test case: %s', $testName) . "
\n"; if (!str_contains($className, 'PHPUnit_')) { - [, $query] = str_split($this->_getQueryLink()); + [, $query] = $this->_getQueryLink(); echo "\n"; } echo "
" . __d('cake_dev', 'Stack trace:') . '
' . $trace . "
\n"; @@ -316,11 +308,11 @@ public function paintFail($message, $test) * trail of the nesting test suites below the * top level test. * - * @param PHPUnit_Framework_Test $test Test method that just passed + * @param \PHPUnit\Framework\Test $test Test method that just passed * @param float $time time spent to run the test method * @return void */ - public function paintPass(PHPUnit_Framework_Test $test, $time = null) + public function paintPass(Test $test, $time = null) { ob_start(); if (isset($this->params['showPasses']) && $this->params['showPasses']) { @@ -360,10 +352,10 @@ public function paintException($message, $test) * Prints the message for skipping tests. * * @param string $message Text of skip condition. - * @param PHPUnit_Framework_TestCase $test the test method skipped + * @param TestCase $test the test method skipped * @return void */ - public function paintSkip($message, $test) + public function paintSkip($message, TestCase $test) { ob_start(); echo "
  • \n"; @@ -421,10 +413,10 @@ protected function _getStackTrace(Exception $e) /** * A test suite started. * - * @param PHPUnit_Framework_TestSuite $suite The test suite to start. + * @param TestSuite $suite The test suite to start. * @return void */ - public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + public function startTestSuite(TestSuite $suite): void { if (!$this->_headerSent) { $this->paintHeader(); @@ -435,9 +427,9 @@ public function startTestSuite(PHPUnit_Framework_TestSuite $suite) /** * Returns the query string formatted for ouput in links * - * @return string + * @return array{string, string} */ - protected function _getQueryLink() + protected function _getQueryLink(): array { $show = $query = []; if (!empty($this->params['case'])) { diff --git a/lib/Cake/TestSuite/Reporter/CakeTextReporter.php b/lib/Cake/TestSuite/Reporter/CakeTextReporter.php index cd53ef8d05..f0c1d4faf6 100644 --- a/lib/Cake/TestSuite/Reporter/CakeTextReporter.php +++ b/lib/Cake/TestSuite/Reporter/CakeTextReporter.php @@ -15,6 +15,8 @@ * @license https://opensource.org/licenses/mit-license.php MIT License */ +use PHPUnit\Framework\TestResult; + App::uses('CakeBaseReporter', 'TestSuite/Reporter'); App::uses('TextCoverageReport', 'TestSuite/Coverage'); @@ -73,10 +75,10 @@ public function paintFail($message) * Paints the end of the test with a summary of * the passes and failures. * - * @param PHPUnit_Framework_TestResult $result Result object + * @param TestResult $result Result object * @return void */ - public function paintFooter($result) + public function paintFooter(TestResult $result) { if ($result->failureCount() + $result->errorCount()) { echo "FAILURES!!!\n"; diff --git a/lib/Cake/TestSuite/templates/header.php b/lib/Cake/TestSuite/templates/header.php index 0504451d91..3655a7b315 100644 --- a/lib/Cake/TestSuite/templates/header.php +++ b/lib/Cake/TestSuite/templates/header.php @@ -1,26 +1,6 @@ - * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * - * Licensed under The MIT License - * For full copyright and license information, please see the LICENSE.txt - * Redistributions of files must retain the above copyright notice - * - * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) - * @link https://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests - * @package Cake.TestSuite.templates - * @since CakePHP(tm) v 1.2.0.4433 - * @license https://opensource.org/licenses/mit-license.php MIT License - */ -?> - - - - - CakePHP Test Suite <?php echo Configure::version(); ?> +use PHPUnit\Runner\Version; +?>