The 5.3.0 release is a backwards compatible with 5.0. It adds new functionality and introduces new deprecations. Any functionality deprecated in 5.x will be removed in 6.0.0.
If you are not running on PHP 8.2 or higher, you will need to upgrade PHP before updating CakePHP.
Note
CakePHP 5.3 requires a minimum of PHP 8.2.
InstanceConfigTrait::deleteConfig()was added. For classes using this- trait, you can now use
$this->deleteConfig('key')instead of$this->setConfig('key', null)
Query::with()now accepts an array of expressions to align with other query clauses. This also- allows clearing the expressions with an empty array.
joinWith()now asserts when the association conflicts with an existing join and will overwrite it. Because existing code might harmlessly ignore the join or accidentally rely on that behavior, this change is not breaking in production for CakePHP 5.
- The signature of
Validator::validate(array $data, bool $newRecord = true, array $context = [])has now a additional third parameter$context. It can be used to pass necessary context into the validation when marshalling.
- The
format()andcurrency()methods ofNumberHelpernow accept also null as input and can return any default string here. This allows for easier templates, in particular baked ones. Make sure to adjust any extending helper (plugin or app level) by adding that type.
Query::newExpr()is deprecated. UseQuery::expr()instead.
Form::_execute()is deprecated. You should rename your_executemethods toprocess()which accepts the same parameters and has the same return type.
- Using
$request->getParam('?')to get the query params is deprecated. Use$request->getQueryParams()instead.
- Calling behavior methods on table instances is now deprecated. To call
a method of an attached behavior you need to use
$table->getBehavior('Sluggable')->slugify()instead of$table->slugify(). EntityTrait::isEmpty()is deprecated. UsehasValue()instead.
- Loading of plugins without a plugin class is deprecated. For your existing plugins
which don't have one, you can use the
bin/cake bake plugin MyPlugin --class-onlycommand, which will create the fileplugins/MyPlugin/src/MyPlugin.php.
- Passing an array as the first argument to
BreadcrumbsHelper::add()andBreadcrumbsHelper::prepend()is deprecated. UseaddMany()andprependMany()instead.
- Added Redis Cluster support to
RedisEngine. Configure theclusteroption with an array of server addresses to enable cluster mode. - Several :ref:`cache-events` were added to allow monitoring the caching behavior.
Collection::any()was added to replaceCollection::some()with a more familiar name.
cake plugin assets symlinkcommand now supports a--relativeoption to create relative path symlinks. This is useful when creating symlinks within containers that use volume mounts.cake servernow supports a--frankenphpoption that will start the development server with FrankenPHP.
- Added
TreeHelperwhich outputs an array as a tree such as an array of filesystem directories as array keys and files as lists under each directory. - Commands can now implement
getGroup()to customize how commands are grouped inbin/cake -houtput. CommandCollection::replace()was added. This method allows you to replace an existing command in the collection without needing to remove and re-add it. This is particularly useful when usingautoDiscoverand you want to replace a command with a customized version.
- Added
Configureattribute to support injectingConfigurevalues into constructor arguments. See ref:configure-dependency-injection.
- Added support for Entra authentication to SqlServer driver.
- Added
Query::optimizerHint()which accepts engine-specific optimizer hints. - Added
Query::getDriver()helper which returns theDriverfor the current connection role by default. - Added support for
yearcolumn types in MySQL. - Added support for
inet,cidrandmacaddrnetwork column types to postgres driver. - Added
TypeFactory::getMapped()to retrieve the mapped class name for a specific type. This provides a cleaner API compared to usingTypeFactory::getMap()with a type argument.
Debuggernow replaces :php:const:ROOT` with ` the ``Debugger.editorBasePathConfigure value if defined. This improves debugging workflows within containerized environments.
- Added
DateTimePeriodwhich wraps a phpDatePeriodand returnsDateTimeinstances when iterating. - Added
DatePeriodwhich wraps a phpDatePeriodand returnsDateinstances when iterating. - Added
toQuarterRange()method toDateTimeandFrozenTimeclasses which returns an array containing the start and end dates of the quarter for the given date. - Added
Date::getTimestamp(). This method returns an int of the date's timestamp.
- Added
Message::addAttachment()for adding attachments to a message. Like other message methods, it can be accessed via theMailerinstance as$mailer->addAttachment().
Table::patchEntity(),Table::newEntity(),Marshaller::one()andMarshaller::many()now accept astrictFieldsoption that only applies validation to the fields listed in thefieldsoption.- Added
TableContainerthat you can register in your Application::services() to add dependency injection for your Tables. Cake\ORM\Locator\TableContainerwas added. By adding this container delegate to your application, ORM Tables can be injected by the DI container.
- Added
SortableFieldsBuilderclass enabling fluent configuration of sortable fields with advanced features. ThesortableFieldsoption now accepts a callable that receives aSortableFieldsBuilderinstance, allowing you to map friendly sort keys to database fields with multi-column sorting and direction control. - Added
SortFieldclass for defining sort field configurations with customizable default directions and locked directions (e.g.,SortField::asc('price')orSortField::desc('created', locked: true)). - Added support for combined sorting keys in URLs (e.g.,
?sort=title-ascor?sort=price-desc) in addition to the traditional?sort=field&direction=ascformat.
- Added
RouteBuilder::setOptions()method to set default route options at the scope level. This allows you to apply options like_host,_https, and_portto all routes within a scope without repeating them on each route. Options set at the scope level are inherited by nested scopes and can be overridden on individual routes. EntityRoutenow handles enum value conversions. This enables you to use enum backed properties as route parameters. When an enum backed property is used in routing, the enum'svalueornamewill be used.- Added
RedirectTrait. This trait can be used to create custom redirect route classes.
assertRedirectBack()added to assert a successful redirect has been made to the same previous URL.assertRedirectBackToReferer()added to assert a successful redirect has been made to the referer URL.assertFlashMessageContains()andassertFlashMessageContainsAt()were added. These methods enable substring matching of flash message content.TestFixture::$tableAliaswas added. This property lets you define the table alias that will be used to load anORM\Tableinstance for a fixture. This improves compatibility for schemas that do not closely follow naming conventions.
Text::uuid()now supports configurable UUID generation. You can set a custom UUID generator usingConfigure::write('Text.uuidGenerator', $closure)to integrate your own UUID generation strategy or third-party libraries.
ipOrRange()validation has has been added to check for an IP or a range (subnet).- When validating within CakePHP marshalling context, the entity will be passed into the
contextargument for use inside custom validation rules. This can be useful when patching partially and then needing to get that data from the entity instead of the passed data. existsInNullable()rule has been added. This rule allowsnullvalues in nullable composite foreign keys, which is semantically correct for optional relationships. Use$rules->existsInNullable(['author_id', 'site_id'], 'SiteAuthors')instead ofexistsIn()when you want to permit null values in foreign keys.
- :php:meth:`HtmlHelper::scriptStart()` and
scriptEnd()now allow simple wrapping script tags (<script>...</script>) around inline JavaScript. This enables syntax highlighting in many editors to work. The wrapping script tag will be removed and replaced with a script tag generated by the helper. - :php:class:`FormHelper` now supports a new option
nestedCheckboxAndRadio. By default, the helper generates inputs of type checkbox and radio nested inside their label. Setting thenestedCheckboxAndRadiooption tofalsewill turn off the nesting. ViewBuilder::setConfigMergeStrategy()was added to control how view options are merged with the View class's default configuration. Available strategies areViewBuilder::MERGE_DEEP(recursive merge, default) andViewBuilder::MERGE_SHALLOW(simple array merge). This is useful when you want to replace array values in view options rather than deep merging them.ViewBuilder::getConfigMergeStrategy()was added to retrieve the current merge strategy setting.- :php:meth:`PaginatorHelper::limitControl()` now automatically respects the
maxLimitconfiguration from the paginator, filtering out any limit options that exceed it. A newstepsoption was added to automatically generate limit options in multiples of a specific value (e.g.,['steps' => 10]generates 10, 20, 30... up to maxLimit). - :php:meth:`BreadcrumbsHelper::addMany()` and :php:meth:`BreadcrumbsHelper::prependMany()` were added. These methods allow adding multiple breadcrumbs at once with support for shared options that apply to all crumbs.