Repository navigation
v2.12.6
Note
Code that triggered an E_USER_ERROR (deprecated as of PHP 8.4) now throws an exception with the same message, and ConsoleLog decides colored output by its own stream. See UPGRADE.md.
Important
The 'cipher' encryption (Security::cipher(), the default CookieComponent type) is deprecated and now logs a warning once per process. New Configure values Cookie.type and Cookie.key set the default CookieComponent type and key; set them to 'aes' and a random key of at least 32 bytes. See UPGRADE.md and the security advisory GHSA-65v5-h65v-8pgg.
PHPStan Level 5 (docblocks only) (PR #56)
- PHPStan:
src/Cake(includingTestSuite) now passes PHPStan level 5 withpieceofcake2/phpstan-cakephp2^0.2.4, without a baseline. CI runs PHPStan on every pull request - No signature changes: Only docblocks were corrected (
@param,@return,@var,@property,@method,@param-out,@phpstan-impure). No native parameter, return or property types were added, and no public or protected method or property signature changed, so subclasses in applications and plugins keep working. The only declaration changes are the properties listed below, which were previously created dynamically - Internal clean-ups without behavior change:
extract()calls were replaced by explicit variables, variables that were only set on some code paths are initialised,return voidMethod()statements were split, always-true/false conditions were removed, and internal functions receive values of the documented type (e.g.ini_set()values as strings)
Bug Fixes (PR #56)
- Dynamic properties: Declare
ConsoleOptionParser::$_tokens,HelpFormatter::$_parser,Scaffold::$redirect/$modelClass/$modelKey/$ScaffoldModel/$scaffoldActions,MemcachedEngine::$_compiledGroupNames,CakeFixtureManager::$_processed,CakeTestFixture::$Schema,CakeTestSuiteCommand::$_paramsandControllerTestDispatcher::$response, which were created dynamically (deprecated as of PHP 8.2).CakeFixtureInjectorno longer adds$fixtureManagerto plain PHPUnit test cases, andSqlserver::_execute()throwsPDOExceptionWithQueryStringinstead of adding$queryStringto aPDOException - Null arguments:
ConsoleLog,CakeText::toList()andShell::shortPath()no longer passnullto internal functions (deprecated as of PHP 8.1) - HttpSocketResponse: Trailer headers after a chunked body no longer cause a fatal error (call to the undefined
_buildHeader()); they are merged into the response headers - App:
App::import()with several search paths no longer stops looking after the first path (it could include a directory instead of the file) - ExtractTask: A literal count argument of
__dcn()/__dxcn()no longer overwrites the parser position, which skipped the following calls - PaginatorComponent:
mergeOptions()ignores the request parameters for an unknownparamTypeinstead of throwing aTypeError - FlashComponent: The constructor calls
Component::__construct(), so$settingsis set - PrivateActionException: The previous exception passed to the constructor is kept
- AclNode: The "Model class not found" exception of
node()has a formatted message - CakeNumber:
fromReadableSize()treats a non-numeric value with a unit (e.g.'XMB') as invalid (returns$defaultor throws) instead of throwing aTypeError - Validation: The deep
luhn()check returnsfalsefor values with non-digit characters instead of throwing aTypeError, and accepts integers - Mysql / Sqlserver:
listSources()andMysql::listDetailedSources()return an empty list when the query fails instead of callingcloseCursor()onfalse - TestSuite:
assertTags()prints the$fullDebugoutput before the assertion fails;ConsoleOutputStub::write()returns the number of bytes written likeConsoleOutput::write();CakeHtmlReporter/CakeTextReportercode coverage output works with php-code-coverage 9
Console Without an Application core.php (PR #59)
- ShellDispatcher: When the application has no
Config/core.php, the console no longer stops with the fatal error "Can't find application core file"._bootstrap()again tellsCake/bootstrap.phpto skipConfigure::bootstrap()in that case and loads the defaultcore.php, as it was meant to, so the console starts and commands that do not need the application settings can run. Applications with aConfig/core.phpare not affected
Bug Fixes (PR #58)
- E_USER_ERROR:
Configure::bootstrap()throwsConfigureExceptionwhen the applicationcore.phporbootstrap.phpis missing, andTranslateBehaviorthrowsCakeExceptionwhen its datasource is not connected or the translation association is already bound to the model, instead of triggeringE_USER_ERROR(deprecated as of PHP 8.4). The messages are unchanged - ShellDispatcher: A
ConfigureExceptionfrom bootstrapping the application (missingcore.phporbootstrap.php) is printed asError: ...with exit code 1 instead of an uncaught exception or a stack trace - bin/cake: A missing Composer autoloader is printed to STDERR with exit code 1 instead of triggering
E_USER_ERROR - ConsoleLog: Colored or plain output is decided by the configured
streaminstead of STDIN, so logging to a file or pipe from a terminal no longer writes ANSI escape codes. Plain output is still forced on Windows consoles without ANSI support, and an explicitoutputAssetting is kept - ConsoleOutput: Uses
stream_isatty()to detect a terminal, so streams that cannot be checked (e.g.php://memory,php://temp) get plain output without aposix_isatty()warning - Tests:
AllTestSuiteTestincludes theTestSuite/FixtureandTestSuite/Stubtests, which never ran before;CakeFixtureManagerTestpasses when run on its own
Enhancements: CookieComponent Cookie.key and Cookie.type (PR #62)
- CookieComponent: Without a
'key'setting, the key defaults to ConfigureCookie.keywhen it is a non-empty string, otherwise toSecurity.saltas before. Without a'type'setting, the type defaults to ConfigureCookie.typewhen it is set (validated bytype(), so an invalid value triggers the usualE_USER_WARNINGand falls back to'cipher'), otherwise to'cipher'as before. An explicit'key'/'type'setting,$this->Cookie->key = ...or$this->Cookie->type(...)always wins. Nothing changes for applications that do not setCookie.keyorCookie.type - IntegrationTestTrait:
cookieEncrypted()/assertCookieEncrypted()use the same default key (Cookie.key, elseSecurity.salt)
Deprecation: 'cipher' encryption (PR #62)
- Security::cipher() / CookieComponent
'cipher'type: Deprecated. It is not secure with anySecurity.cipherSeed. The first call in a process writes awarningto the log, also with debug off, and with debug on also triggersE_USER_DEPRECATED. The message names the source (CookieComponent (type 'cipher')orSecurity::cipher() (called from Class::method())) and the fix: set Configure 'Cookie.type' to 'aes' and 'Cookie.key' to a random value of at least 32 bytes, with Security.useOpenSsl enabled. Thecipher()output, cookie values and return values are unchanged, and nothing throws - Security.cipherSeed range:
mt_srand()keeps 32 bits, soSecurity::cipher()uses the seed as given only when it is a digits-only number from 1 to 4294967295. Other values are reduced: empty,0, non-numeric values, values of 27 or more digits and most 26-digit values (including the former default76859309657453542496749683645) become seed 0. The firstSecurity::cipher()call with such a seed logs awarningonce per process; the seed value is never logged - Debugger::checkSecurityKeys(): With debug on (called by
AuthComponent), also triggers anE_USER_NOTICEwhenSecurity.cipherSeedis set but outside 1 to 4294967295. The "Please change the value of 'Security.cipherSeed'" notice now fires for both the former default and the new default'2659758734' - Core config: The fallback
config/core.php(used when the application has nocore.php) setsSecurity.cipherSeedto'2659758734'(the same default as the application skeleton) and enablesSecurity.useOpenSsl - Security::isCipherSeedInRange(): New internal helper for the range check
Enhancements: Validation::utf8() (backport from CakePHP 5) (PR #64)
- Validation::utf8(): New validation rule, a backport of
Cake\Validation\Validation::utf8()from CakePHP 5 (added in CakePHP 3.1). Returnstruefor a string that is valid UTF-8 and has no characters above the Basic Multilingual Plane (4-byte characters such as emoji), which MySQL'sutf8(utf8mb3) columns cannot store. With['extended' => true], characters above the BMP are allowed (forutf8mb4). Non-string values (including arrays, integers andnull) and invalid UTF-8 byte sequences (e.g. truncated sequences, overlong encodings and encoded surrogates) are rejected in both modes. Usable in model validation as'rule' => 'utf8'or'rule' => ['utf8', ['extended' => true]]
Bug Fixes (PR #63)
- Folder:
Folder::isAbsolute()/isRegisteredStreamWrapper()recognize registered stream wrapper schemes that contain digits,+,-or.(for examples3://), soFolderandFileno longer treat such paths as relative
Debug Error Pages in the CakePHP 5 Style (PR #60)
- Error pages: In debug mode (
debug> 0) the core error templates (missing_controller,missing_action,missing_view,missing_layout,missing_component,missing_helper,missing_behavior,missing_plugin,missing_table,missing_connection,missing_database,missing_datasource,missing_datasource_config,pdo_error,private_action,scaffold_error,fatal_error,error400,error500) are rendered in the newdev_errorlayout ported from CakePHP 5: a header with the error title and exception class, the suggested fix with the real file path of the application layout (src/Controller/...orapp/Controller/...; the suggested class has noApp::uses()in the modern layout, where the Composer classmap autoloads the classes, except for plugin classes), and a stack trace of the exception and its previous exceptions with code excerpts, collapsible frames, arguments and(edit)links that open the file in your editor. The layout has inline CSS and JavaScript and uses no helpers - Unchanged: Production mode (
debug= 0), error templates provided by the application, plugin or theme, AJAX requests and the console.Layouts/dev_error.ctpin the application or theme overrides the core layout, and theexception_stack_traceelement is kept for application templates - ExceptionRenderer: When an error page fails to render, the fallback still renders the template with the
errorlayout, but lets the core templates switch todev_errorin debug mode - Debugger: New
Debugger.editorconfigure value (defaultphpstorm; alsoatom,emacs,macvim,sublime,textmate,vscode,vscodium) andDebugger.editorBasePath, plusDebugger::editorUrl(),Debugger::setEditor()andDebugger::addEditor()as in CakePHP 5, used by the(edit)links of the debug error pages - Debugger:
Debugger::excerpt()no longer shows<?phpat the start of every line on PHP 8.3+ - fatal_error.ctp: The Xdebug function stack is only printed when Xdebug runs in
developmode; in other modes Xdebug 3 triggered a warning that broke the page