The CakePHP team is thrilled to announce the immediate availability of 4.0.0. This is release begins a new chapter for CakePHP as 4.0 is now API stable. With this release, Cake 3.x moves into maintenance mode while 2.x moves into security release mode.
FormHelper now generates HTML5 datetime input elements.
Upgrading to 4.0
While 4.0 contains a number of breaking changes we have prepared an exhaustive migration guide covering all the deprecated, removed, and new features.
Additionally, we have put together an upgrade guide which gives a step-by-step guide and CLI tool to help you upgrade your application. These documents and companion tool will only improve as we collect more feedback from people upgrading.
Contributors to 4.0.0
CakePHP 4.0 would not have been possible without the hard work and contributions from the following folks:
CakePHP 4.0.0 is as tasty as other major CakePHP releases but will now require you to use PHP 7.2. With a refreshed application skeleton design, CakePHP 4.0.0 comes with a streamlined API making your development and application faster.
While 4.0 contains a number of breaking changes we have prepared an exhaustive migration guide covering all the deprecated and removed features as well as highlighting the shiny new features.
Command classes can implement the defaultName() method to overwrite the conventions based CLI name.
InstanceConfigTrait::getConfigOrFail() and StaticConfigTrait::getConfigOrFail() were added. Like other orFail methods these methods will raise an exception when the requested key doesn’t exist or has a nullvalue.
If your database’s timezone does not match PHP timezone then you can use DateTime::setDatabaseTimezone(). See DateTime Type for details.
DateTime::setKeepDatabaseTimezone() allows you to keep the database time zone in the DateTime objects created by queries.
Cake\Database\Log\LoggedQuery now implements JsonSerializable.
Cake\Database\Connection now allows using any PSR-3 logger. As a result those using the standalone database package are no longer forced to use the cakephp/log package for logging.
Cake\Database\Connection now allows using any PSR-16 cacher. As a result those using the standalone database package are no longer forced to use the cakephp/cache package for caching. New methods Cake\Database\Connection::setCache() and Cake\Database\Connection::getCache() have been added.
Cake\Database\ConstraintsInterface was extracted from Cake\Datasource\FixtureInterface. This interface should be implemented by fixture implementations that support constraints, which from our experience is generally relational databases.
The char abstract type was added. This type handles fixed length string columns.
The datetimefractional and timestampfractional abstract types were added. These types handle column data types with fractional seconds.
SqlServer schemas now support default values with functions in them like SYSDATETIME().
The datetimetimezone and timestamptimezone abstract types were added. These types handle column data types with time zone support.
If an error is raised by a controller action in a prefixed route, ErrorController will attempt to use a prefixed error template if one is available. This behavior is only applied when debug is off.
You can use cakephp/http without including the entire framework.
CakePHP now supports the PSR-15: HTTP Server Request Handlers specification. As a consequence the middlewares now implement Psr\Http\Server\MiddlewareInterface. CakePHP 3.x style invokable double pass middlewares are still supported for backwards compatibility.
Date and FrozenDate now respect the time zone parameter for various factory helpers like today('Asia/Tokyo').
Email message generation responsibility has now been transferred to Cake\Mailer\Renderer. This is mainly an architectural change and doesn’t impact how Email class is used. The only difference is that you now need to use Email::setViewVars() instead of Email::set() to set template variables.
Table::saveManyOrFail() method has been added that will throw PersistenceFailedException with the specific entity that failed in case of an error. The entities are saved transaction safe.
Table::deleteMany() and Table::deleteManyOrFail() methods have been added for removing many entities at once including callbacks. The entities are removed transaction safe.
Table::newEmptyEntity() has been added to create a new and empty entity object. This does not trigger any field validation. The entity can be persisted without validation error as an empty record.
Cake\ORM\RulesChecker::isLinkedTo() and isNotLinkedTo() were added. These new application rules allow you to ensure an association has or doesn’t have related records.
A new type class DateTimeFractionalType has been added for datetime types with microsecond precision. You can opt into using this type by adding it to the TypeFactory as the default datetime type or re-mapping individual columns. See the Database migration notes for how this type is automatically mapped to database types.
A new type class DateTimeTimezoneType has been added for datetime types with time zone support. You can opt into using this type by adding it to the TypeFactory as the default datetime type or re-mapping individual columns. See the Database migration notes for how this type is automatically mapped to database types.
Cake\Routing\Asset was added. This class exposes asset URL generation in a static interface similar to Router::url(). See Generating Asset URLs for more information.
TestSuite\EmailTrait::assertMailContainsAttachment() was added.
Validation::dateTime() now accepts values with microseconds.
FormHelper now generates HTML5 validation messages for fields marked as “notEmpty” in an entity’s ORM table class. This feature can be toggled with the autoSetCustomValidity class configuration option.
FormHelper now generates native HTML5 input tags for datetime fields. Check the Form Helper page for more details. If you need to retain the former markup, a shimmed FormHelper can be found in Shim plugin with the old behavior/generation (4.x branch).
FormHelper now sets the default step size to seconds for datetime widgets with a time component. The default is milliseconds if the field is from the new datetimefractional or timestampfractional database types.