3.0 Migration Guide
This page summarizes the changes from CakePHP 2.x that will assist in migrating a project to 3.0, as well as a reference to get up to date with the changes made to the core since the CakePHP 2.x branch. Be sure to read the other pages in this guide for all the new features and API changes.
Requirements
- CakePHP 3.x supports PHP Version 5.4.16 and above.
- CakePHP 3.x requires the mbstring extension.
- CakePHP 3.x requires the intl extension.
WARNING
CakePHP 3.0 will not work if you do not meet the above requirements.
Upgrade Tool
While this document covers all the breaking changes and improvements made in CakePHP 3.0, we've also created a console application to help you complete some of the time consuming mechanical changes. You can get the upgrade tool from github.
Application Directory Layout
The application directory layout has changed and now follows PSR-4. You should use the app skeleton project as a reference point when updating your application.
CakePHP should be installed with Composer
Since CakePHP can no longer be installed via PEAR, or in a shared directory, those options are no longer supported. Instead you should use Composer to install CakePHP into your application.
Namespaces
All of CakePHP's core classes are now namespaced and follow PSR-4 autoloading specifications. For example src/Cache/Cache.php is namespaced as Cake\Cache\Cache. Global constants and helper methods like __() and debug() are not namespaced for convenience sake.
Removed Constants
The following deprecated constants have been removed:
IMAGESCSSJSIMAGES_URLJS_URLCSS_URLDEFAULT_LANGUAGE
Configuration
Configuration in CakePHP 3.0 is significantly different than in previous versions. You should read the Configuration documentation for how configuration is done in 3.0.
You can no longer use App::build() to configure additional class paths. Instead you should map additional paths using your application's autoloader. See the section on Additional Class Paths for more information.
Three new configure variables provide the path configuration for plugins, views and locale files. You can add multiple paths to App.paths.templates, App.paths.plugins, App.paths.locales to configure multiple paths for templates, plugins and locale files respectively.
The config key www_root has been changed to wwwRoot for consistency. Please adjust your app.php config file as well as any usage of Configure::read('App.wwwRoot').
New ORM
CakePHP 3.0 features a new ORM that has been re-built from the ground up. The new ORM is significantly different and incompatible with the previous one. Upgrading to the new ORM will require extensive changes in any application that is being upgraded. See the new Database Access & ORM documentation for information on how to use the new ORM.
Basics
LogError()was removed, it provided no benefit and is rarely/never used.- The following global functions have been removed:
config(),cache(),clearCache(),convertSlashes(),am(),fileExistsInPath(),sortByKey().
Debugging
Configure::write('debug', $bool)does not support 0/1/2 anymore. A simple boolean is used instead to switch debug mode on or off.
Object settings/configuration
- Objects used in CakePHP now have a consistent instance-configuration storage/retrieval system. Code which previously accessed for example:
$object->settingsshould instead be updated to use$object->config().
Cache
Memcacheengine has been removed, useCake\Cache\Cache\Engine\Memcachedinstead.- Cache engines are now lazy loaded upon first use.
Cake\Cache\Cache::engine()has been added.Cake\Cache\Cache::enabled()has been added. This replaced theCache.disableconfigure option.Cake\Cache\Cache::enable()has been added.Cake\Cache\Cache::disable()has been added.- Cache configurations are now immutable. If you need to change configuration you must first drop the configuration and then re-create it. This prevents synchronization issues with configuration options.
Cache::set()has been removed. It is recommended that you create multiple cache configurations to replace runtime configuration tweaks previously possible withCache::set().- All
CacheEnginesubclasses now implement aconfig()method. Cake\Cache\Cache::readMany(),Cake\Cache\Cache::deleteMany(), andCake\Cache\Cache::writeMany()were added.
All Cake\Cache\Cache\CacheEngine methods now honor/are responsible for handling the configured key prefix. The Cake\Cache\CacheEngine::write() no longer permits setting the duration on write - the duration is taken from the cache engine's runtime config. Calling a cache method with an empty key will now throw an InvalidArgumentException, instead of returning false.
Core
App
App::pluginPath()has been removed. UseCakePlugin::path()instead.App::build()has been removed.App::location()has been removed.App::paths()has been removed.App::load()has been removed.App::objects()has been removed.App::RESEThas been removed.App::APPENDhas been removed.App::PREPENDhas been removed.App::REGISTERhas been removed.
Plugin
Cake\Core\Plugin::load()does not setup an autoloader unless you set theautoloadoption totrue.- When loading plugins you can no longer provide a callable.
- When loading plugins you can no longer provide an array of config files to load.
Configure
Cake\Configure\PhpReaderrenamed toCake\Core\Configure\Engine\PhpConfigCake\Configure\IniReaderrenamed toCake\Core\Configure\Engine\IniConfigCake\Configure\ConfigReaderInterfacerenamed toCake\Core\Configure\ConfigEngineInterfaceCake\Core\Configure::consume()was added.Cake\Core\Configure::load()now expects the file name without extension suffix as this can be derived from the engine. E.g. using PhpConfig useappto load app.php.- Setting a
$configvariable in PHP config file is deprecated.Cake\Core\Configure\Engine\PhpConfignow expects the config file to return an array. - A new config engine
Cake\Core\Configure\Engine\JsonConfighas been added.
Object
The Object class has been removed. It formerly contained a grab bag of methods that were used in various places across the framework. The most useful of these methods have been extracted into traits. You can use the Cake\Log\LogTrait to access the log() method. The Cake\Routing\RequestActionTrait provides requestAction().
Console
The cake executable has been moved from the app/Console directory to the bin directory within the application skeleton. You can now invoke CakePHP's console with bin/cake.
TaskCollection Replaced
This class has been renamed to Cake\Console\TaskRegistry. See the section on Registry Objects for more information on the features provided by the new class. You can use the cake upgrade rename_collections to assist in upgrading your code. Tasks no longer have access to callbacks, as there were never any callbacks to use.
Shell
Shell::__construct()has changed. It now takes an instance ofCake\Console\ConsoleIo.Shell::param()has been added as convenience access to the parameters.
Additionally all shell methods will be transformed to camel case when invoked. For example, if you had a hello_world() method inside a shell and invoked it with bin/cake my_shell hello_world, you will need to rename the method to helloWorld. There are no changes required in the way you invoke commands.
ConsoleOptionParser
ConsoleOptionParser::merge()has been added to merge parsers.
ConsoleInputArgument
ConsoleInputArgument::isEqualTo()has been added to compare two arguments.
Shell / Task
Shells and Tasks have been moved from Console/Command and Console/Command/Task to Shell and Shell/Task.
ApiShell Removed
The ApiShell was removed as it didn't provide any benefit over the file source itself and the online documentation/API.
SchemaShell Removed
The SchemaShell was removed as it was never a complete database migration implementation and better tools such as Phinx have emerged. It has been replaced by the CakePHP Migrations Plugin which acts as a wrapper between CakePHP and Phinx.
ExtractTask
bin/cake i18n extractno longer includes untranslated validation messages. If you want translated validation messages you should wrap those messages in __() calls like any other content.
BakeShell / TemplateTask
- Bake is no longer part of the core source and is superseded by CakePHP Bake Plugin
- Bake templates have been moved under src/Template/Bake.
- The syntax of Bake templates now uses erb-style tags (
<% %>) to denote templating logic, allowing php code to be treated as plain text. - The
bake viewcommand has been renamedbake template.
Event
The getEventManager() method, was removed on all objects that had it. An eventManager() method is now provided by the EventManagerTrait. The EventManagerTrait contains the logic of instantiating and keeping a reference to a local event manager.
The Event subsystem has had a number of optional features removed. When dispatching events you can no longer use the following options:
passParamsThis option is now enabled always implicitly. You cannot turn it off.breakThis option has been removed. You must now stop events.breakOnThis option has been removed. You must now stop events.
Log
- Log configurations are now immutable. If you need to change configuration you must first drop the configuration and then re-create it. This prevents synchronization issues with configuration options.
- Log engines are now lazily loaded upon the first write to the logs.
Cake\Log\Log::engine()has been added.- The following methods have been removed from
Cake\Log\Log::defaultLevels(),enabled(),enable(),disable(). - You can no longer create custom levels using
Log::levels(). - When configuring loggers you should use
'levels'instead of'types'. - You can no longer specify custom log levels. You must use the default set of log levels. You should use logging scopes to create custom log files or specific handling for different sections of your application. Using a non-standard log level will now throw an exception.
Cake\Log\LogTraitwas added. You can use this trait in your classes to add thelog()method.- The logging scope passed to
Cake\Log\Log::write()is now forwarded to the log engines'write()method in order to provide better context to the engines. - Log engines are now required to implement
Psr\Log\LogInterfaceinstead of CakePHP's ownLogInterface. In general, if you extendedCake\Log\Engine\BaseEngineyou just need to rename thewrite()method tolog(). Cake\Log\Engine\FileLognow writes files inROOT/logsinstead ofROOT/tmp/logs.
Routing
Named Parameters
Named parameters were removed in 3.0. Named parameters were added in 1.2.0 as a 'pretty' version of query string parameters. While the visual benefit is arguable, the problems named parameters created are not.
Named parameters required special handling in CakePHP as well as any PHP or JavaScript library that needed to interact with them, as named parameters are not implemented or understood by any library except CakePHP. The additional complexity and code required to support named parameters did not justify their existence, and they have been removed. In their place you should use standard query string parameters or passed arguments. By default Router will treat any additional parameters to Router::url() as query string arguments.
Since many applications will still need to parse incoming URLs containing named parameters. Cake\Routing\Router::parseNamedParams() has been added to allow backwards compatibility with existing URLs.
RequestActionTrait
Cake\Routing\RequestActionTrait::requestAction()has had some of the extra options changed:options[url]is nowoptions[query].options[data]is nowoptions[post].- Named parameters are no longer supported.
Router
- Named parameters have been removed, see above for more information.
- The
full_baseoption has been replaced with the_fulloption. - The
extoption has been replaced with the_extoption. _scheme,_port,_host,_base,_full,_extoptions added.- String URLs are no longer modified by adding the plugin/controller/prefix names.
- The default fallback route handling was removed. If no routes match a parameter set
/will be returned. - Route classes are responsible for all URL generation including query string parameters. This makes routes far more powerful and flexible.
- Persistent parameters were removed. They were replaced with
Cake\Routing\Router::urlFilter()which allows a more flexible way to mutate URLs being reverse routed. Router::parseExtensions()has been removed. UseCake\Routing\Router::extensions()instead. This method must be called before routes are connected. It won't modify existing routes.Router::setExtensions()has been removed. UseCake\Routing\Router::extensions()instead.Router::resourceMap()has been removed.- The
[method]option has been renamed to_method. - The ability to match arbitrary headers with
[]style parameters has been removed. If you need to parse/match on arbitrary conditions consider using custom route classes. Router::promote()has been removed.Router::parse()will now raise an exception when a URL cannot be handled by any route.Router::url()will now raise an exception when no route matches a set of parameters.- Routing scopes have been introduced. Routing scopes allow you to keep your routes file DRY and give Router hints on how to optimize parsing & reverse routing URLs.
Route
CakeRoutewas re-named toRoute.- The signature of
match()has changed tomatch($url, $context = [])SeeCake\Routing\Route::match()for information on the new signature.
Dispatcher Filters Configuration Changed
Dispatcher filters are no longer added to your application using Configure. You now append them with Cake\Routing\DispatcherFactory. This means if your application used Dispatcher.filters, you should now use Cake\Routing\DispatcherFactory::add().
In addition to configuration changes, dispatcher filters have had some conventions updated, and features added. See the Dispatcher Filters documentation for more information.
FilterAssetFilter
- Plugin & theme assets handled by the AssetFilter are no longer read via
includeinstead they are treated as plain text files. This fixes a number of issues with JavaScript libraries like TinyMCE and environments with short_tags enabled. - Support for the
Asset.filterconfiguration and hooks were removed. This feature should be replaced with a plugin or dispatcher filter.
Network
Request
CakeRequesthas been renamed toCake\Network\Request.Cake\Network\Request::port()was added.Cake\Network\Request::scheme()was added.Cake\Network\Request::cookie()was added.Cake\Network\Request::$trustProxywas added. This makes it easier to put CakePHP applications behind load balancers.Cake\Network\Request::$datais no longer merged with the prefixed data key, as that prefix has been removed.Cake\Network\Request::env()was added.Cake\Network\Request::acceptLanguage()was changed from static method to non-static.- Request detector for "mobile" has been removed from the core. Instead the app template adds detectors for "mobile" and "tablet" using
MobileDetectlib. - The method
onlyAllow()has been renamed toallowMethod()and no longer accepts "var args". All method names need to be passed as first argument, either as string or array of strings.
Response
- The mapping of mimetype
text/plainto extensioncsvhas been removed. As a consequenceCake\Controller\Component\RequestHandlerComponentdoesn't set extension tocsvifAcceptheader contains mimetypetext/plainwhich was a common annoyance when receiving a jQuery XHR request.
Sessions
The session class is no longer static, instead the session can be accessed through the request object. See the Sessions documentation for using the session object.
Cake\Network\Sessionand related session classes have been moved under theCake\Networknamespace.SessionHandlerInterfacehas been removed in favor of the one provided by PHP itself.- The property
Session::$requestCountdownhas been removed. - The session checkAgent feature has been removed. It caused a number of bugs when chrome frame, and flash player are involved.
- The conventional sessions database table name is now
sessionsinstead ofcake_sessions. - The session cookie timeout is automatically updated in tandem with the timeout in the session data.
- The path for session cookie now defaults to app's base path instead of "/". A new configuration variable
Session.cookiePathhas been added to customize the cookie path. - A new convenience method
Cake\Network\Session::consume()has been added to allow reading and deleting session data in a single step. - The default value of
Cake\Network\Session::clear()'s argument$renewhas been changed fromtruetofalse.
Network\Http
HttpSocketis nowCake\Network\Http\Client.- HttpClient has been re-written from the ground up. It has a simpler/easier to use API, support for new authentication systems like OAuth, and file uploads. It uses PHP's stream APIs so there is no requirement for cURL. See the Http Client documentation for more information.
Network\Email
Cake\Network\Email\Email::config()is now used to define configuration profiles. This replaces theEmailConfigclasses in previous versions.Cake\Network\Email\Email::profile()replacesconfig()as the way to modify per instance configuration options.Cake\Network\Email\Email::drop()has been added to allow the removal of email configuration.Cake\Network\Email\Email::configTransport()has been added to allow the definition of transport configurations. This change removes transport options from delivery profiles and allows you to re-use transports across email profiles.Cake\Network\Email\Email::dropTransport()has been added to allow the removal of transport configuration.
Controller
Controller
- The
$helpers,$componentsproperties are now merged with all parent classes not justAppControllerand the plugin AppController. The properties are merged differently now as well. Instead of all settings in all classes being merged together, the configuration defined in the child class will be used. This means that if you have some configuration defined in your AppController, and some configuration defined in a subclass, only the configuration in the subclass will be used. Controller::httpCodes()has been removed, useCake\Network\Response::httpCodes()instead.Controller::disableCache()has been removed, useCake\Network\Response::disableCache()instead.Controller::flash()has been removed. This method was rarely used in real applications and served no purpose anymore.Controller::validate()andController::validationErrors()have been removed. They were left over methods from the 1.x days where the concerns of models + controllers were far more intertwined.Controller::loadModel()now loads table objects.- The
Controller::$scaffoldproperty has been removed. Dynamic scaffolding has been removed from CakePHP core. An improved scaffolding plugin, named CRUD, can be found here: https://github.com/FriendsOfCake/crud - The
Controller::$extproperty has been removed. You now have to extend and override theView::$_extproperty if you want to use a non-default view file extension. - The
Controller::$methodsproperty has been removed. You should now useController::isAction()to determine whether or not a method name is an action. This change was made to allow easier customization of what is and is not counted as an action. - The
Controller::$Componentsproperty has been removed and replaced with_components. If you need to load components at runtime you should use$this->loadComponent()on your controller. - The signature of
Cake\Controller\Controller::redirect()has been changed toController::redirect(string|array $url, int $status = null). The 3rd argument$exithas been dropped. The method can no longer send response and exit script, instead it returns aResponseinstance with appropriate headers set. - The
base,webroot,here,data,action, andparamsmagic properties have been removed. You should access all of these properties on$this->requestinstead. - Underscore prefixed controller methods like
_someMethod()are no longer treated as private methods. Use proper visibility keywords instead. Only public methods can be used as controller actions.
Scaffold Removed
The dynamic scaffolding in CakePHP has been removed from CakePHP core. It was infrequently used, and never intended for production use. An improved scaffolding plugin, named CRUD, can be found here: https://github.com/FriendsOfCake/crud
ComponentCollection Replaced
This class has been renamed to Cake\Controller\ComponentRegistry. See the section on Registry Objects for more information on the features provided by the new class. You can use the cake upgrade rename_collections to assist in upgrading your code.
Component
- The
_Collectionproperty is now_registry. It contains an instance ofCake\Controller\ComponentRegistrynow. - All components should now use the
config()method to get/set configuration. - Default configuration for components should be defined in the
$_defaultConfigproperty. This property is automatically merged with any configuration provided to the constructor. - Configuration options are no longer set as public properties.
- The
Component::initialize()method is no longer an event listener. Instead, it is a post-constructor hook likeTable::initialize()andController::initialize(). The newComponent::beforeFilter()method is bound to the same event thatComponent::initialize()used to be. The initialize method should have the following signatureinitialize(array $config).
Controller\Components
CookieComponent
- Uses
Cake\Network\Request::cookie()to read cookie data, this eases testing, and allows for ControllerTestCase to set cookies. - Cookies encrypted in previous versions of CakePHP using the
cipher()method are now un-readable becauseSecurity::cipher()has been removed. You will need to re-encrypt cookies with therijndael()oraes()method before upgrading. CookieComponent::type()has been removed and replaced with configuration data accessed throughconfig().write()no longer takesencryptionorexpiresparameters. Both of these are now managed through config data. See Cookie for more information.- The path for cookies now defaults to app's base path instead of "/".
AuthComponent
Defaultis now the default password hasher used by authentication classes. It uses exclusively the bcrypt hashing algorithm. If you want to continue using SHA1 hashing used in 2.x use'passwordHasher' => 'Weak'in your authenticator configuration.- A new
FallbackPasswordHasherwas added to help users migrate old passwords from one algorithm to another. Check AuthComponent's documentation for more info. BlowfishAuthenticateclass has been removed. Just useFormAuthenticateBlowfishPasswordHasherclass has been removed. UseDefaultPasswordHasherinstead.- The
loggedIn()method has been removed. Useuser()instead. - Configuration options are no longer set as public properties.
- The methods
allow()anddeny()no longer accept "var args". All method names need to be passed as first argument, either as string or array of strings. - The method
login()has been removed and replaced bysetUser()instead. To login a user you now have to callidentify()which returns user info upon successful identification and then usesetUser()to save the info to session for persistence across requests. BaseAuthenticate::_password()has been removed. Use aPasswordHasherclass instead.BaseAuthenticate::logout()has been removed.AuthComponentnow triggers two eventsAuth.afterIdentifyandAuth.logoutafter a user has been identified and before a user is logged out respectively. You can set callback functions for these events by returning a mapping array fromimplementedEvents()method of your authenticate class.
ACL related classes were moved to a separate plugin. Password hashers, Authentication and Authorization providers where moved to the \Cake\Auth namespace. You are required to move your providers and hashers to the App\Auth namespace as well.
RequestHandlerComponent
- The following methods have been removed from RequestHandler component::
isAjax(),isFlash(),isSSL(),isPut(),isPost(),isGet(),isDelete(). Use theCake\Network\Request::is()method instead with relevant argument. RequestHandler::setContent()was removed, useCake\Network\Response::type()instead.RequestHandler::getReferer()was removed, useCake\Network\Request::referer()instead.RequestHandler::getClientIP()was removed, useCake\Network\Request::clientIp()instead.RequestHandler::getAjaxVersion()was removed.RequestHandler::mapType()was removed, useCake\Network\Response::mapType()instead.- Configuration options are no longer set as public properties.
SecurityComponent
- The following methods and their related properties have been removed from Security component:
requirePost(),requireGet(),requirePut(),requireDelete(). Use theCake\Network\Request::allowMethod()instead. SecurityComponent::$disabledFields()has been removed, useSecurityComponent::$unlockedFields().- The CSRF related features in SecurityComponent have been extracted and moved into a separate CsrfComponent. This allows you to use CSRF protection without having to use form tampering prevention.
- Configuration options are no longer set as public properties.
- The methods
requireAuth()andrequireSecure()no longer accept "var args". All method names need to be passed as first argument, either as string or array of strings.
SessionComponent
SessionComponent::setFlash()is deprecated. You should use Flash instead.
Error
Custom ExceptionRenderers are now expected to either return a Cake\Network\Response object or string when rendering errors. This means that any methods handling specific exceptions must return a response or string value.
Model
The Model layer in 2.x has been entirely re-written and replaced. You should review the New ORM Upgrade Guide for information on how to use the new ORM.
- The
Modelclass has been removed. - The
BehaviorCollectionclass has been removed. - The
DboSourceclass has been removed. - The
Datasourceclass has been removed. - The various datasource classes have been removed.
ConnectionManager
- ConnectionManager has been moved to the
Cake\Datasourcenamespace. - ConnectionManager has had the following methods removed:
sourceListgetSourceNameloadDataSourceenumConnectionObjects
Cake\Database\ConnectionManager::config()has been added and is now the only way to configure connections.Cake\Database\ConnectionManager::get()has been added. It replacesgetDataSource().Cake\Database\ConnectionManager::configured()has been added. It andconfig()replacesourceList()&enumConnectionObjects()with a more standard and consistent API.ConnectionManager::create()has been removed. It can be replaced byconfig($name, $config)andget($name).
Behaviors
- Underscore prefixed behavior methods like
_someMethod()are no longer treated as private methods. Use proper visibility keywords instead.
TreeBehavior
The TreeBehavior was completely re-written to use the new ORM. Although it works the same as in 2.x, a few methods were renamed or removed:
TreeBehavior::children()is now a custom finderfind('children').TreeBehavior::generateTreeList()is now a custom finderfind('treeList').TreeBehavior::getParentNode()was removed.TreeBehavior::getPath()is now a custom finderfind('path').TreeBehavior::reorder()was removed.TreeBehavior::verify()was removed.
TestSuite
TestCase
_normalizePath()has been added to allow path comparison tests to run across all operation systems regarding their DS settings (\in Windows vs/in UNIX, for example).
The following assertion methods have been removed as they have long been deprecated and replaced by their new PHPUnit counterpart:
assertEqual()in favor ofassertEquals()assertNotEqual()in favor ofassertNotEquals()assertIdentical()in favor ofassertSame()assertNotIdentical()in favor ofassertNotSame()assertPattern()in favor ofassertRegExp()assertNoPattern()in favor ofassertNotRegExp()assertReference()if favor ofassertSame()assertIsA()in favor ofassertInstanceOf()
Note that some methods have switched the argument order, e.g. assertEqual($is, $expected) should now be assertEquals($expected, $is).
The following assertion methods have been deprecated and will be removed in the future:
assertWithinMargin()in favor ofassertWithinRange()assertTags()in favor ofassertHtml()
Both method replacements also switched the argument order for a consistent assert method API with $expected as first argument.
The following assertion methods have been added:
assertNotWithinRange()as counter part toassertWithinRange()
View
Themes are now Basic Plugins
Having themes and plugins as ways to create modular application components has proven to be limited, and confusing. In CakePHP 3.0, themes no longer reside inside the application. Instead they are standalone plugins. This solves a few problems with themes:
- You could not put themes in plugins.
- Themes could not provide helpers, or custom view classes.
Both these issues are solved by converting themes into plugins.
View Folders Renamed
The folders containing view files now go under src/Template instead of src/View. This was done to separate the view files from files containing php classes (eg. Helpers, View classes).
The following View folders have been renamed to avoid naming collisions with controller names:
Layoutsis nowLayoutElementsis nowElementErrorsis nowErrorEmailsis nowEmail(same forEmailinsideLayout)
HelperCollection Replaced
This class has been renamed to Cake\View\HelperRegistry. See the section on Registry Objects for more information on the features provided by the new class. You can use the cake upgrade rename_collections to assist in upgrading your code.
View Class
- The
pluginkey has been removed from$optionsargument ofCake\View\View::element(). Specify the element name asSomePlugin.element_nameinstead. View::getVar()has been removed, useCake\View\View::get()instead.View::$exthas been removed and instead a protected propertyView::$_exthas been added.View::addScript()has been removed. Use View Blocks instead.- The
base,webroot,here,data,action, andparamsmagic properties have been removed. You should access all of these properties on$this->requestinstead. View::start()no longer appends to an existing block. Instead it will overwrite the block content when end is called. If you need to combine block contents you should fetch the block content when calling start a second time, or use the capturing mode ofappend().View::prepend()no longer has a capturing mode.View::startIfEmpty()has been removed. Now that start() always overwrites startIfEmpty serves no purpose.- The
View::$Helpersproperty has been removed and replaced with_helpers. If you need to load helpers at runtime you should use$this->addHelper()in your view files. Viewwill now raiseCake\View\Exception\MissingTemplateExceptionwhen templates are missing instead ofMissingViewException.
ViewBlock
ViewBlock::append()has been removed, useCake\View\ViewBlock::concat()instead. However,View::append()still exists.
JsonView
- By default JSON data will have HTML entities encoded now. This prevents possible XSS issues when JSON view content is embedded in HTML files.
Cake\View\JsonViewnow supports the_jsonOptionsview variable. This allows you to configure the bit-mask options used when generating JSON.
XmlView
Cake\View\XmlViewnow supports the_xmlOptionsview variable. This allows you to configure the options used when generating XML.
View\Helper
- The
$settingsproperty is now called$_configand should be accessed through theconfig()method. - Configuration options are no longer set as public properties.
Helper::clean()was removed. It was never robust enough to fully prevent XSS. instead you should escape content withhor use a dedicated library like htmlPurifier.Helper::output()was removed. This method was deprecated in 2.x.- Methods
Helper::webroot(),Helper::url(),Helper::assetUrl(),Helper::assetTimestamp()have been moved to newCake\View\Helper\UrlHelperhelper.Helper::url()is now available asCake\View\Helper\UrlHelper::build(). - Magic accessors to deprecated properties have been removed. The following properties now need to be accessed from the request object:
- base
- here
- webroot
- data
- action
- params
Helper
Helper has had the following methods removed:
Helper::setEntity()Helper::entity()Helper::model()Helper::field()Helper::value()Helper::_name()Helper::_initInputField()Helper::_selectedArray()
These methods were part used only by FormHelper, and part of the persistent field features that have proven to be problematic over time. FormHelper no longer relies on these methods and the complexity they provide is not necessary anymore.
The following methods have been removed:
Helper::_parseAttributes()Helper::_formatAttribute()
These methods can now be found on the StringTemplate class that helpers frequently use. See the StringTemplateTrait for an easy way to integrate string templates into your own helpers.
FormHelper
FormHelper has been entirely rewritten for 3.0. It features a few large changes:
- FormHelper works with the new ORM. But has an extensible system for integrating with other ORMs or datasources.
- FormHelper features an extensible widget system that allows you to create new custom input widgets and augment the built-in ones.
- String templates are the foundation of the helper. Instead of munging arrays together everywhere, most of the HTML FormHelper generates can be customized in one central place using template sets.
In addition to these larger changes, some smaller breaking changes have been made as well. These changes should help streamline the HTML FormHelper generates and reduce the problems people had in the past:
- The
data[prefix was removed from all generated inputs. The prefix serves no real purpose anymore. - The various standalone input methods like
text(),select()and others no longer generate id attributes. - The
inputDefaultsoption has been removed fromcreate(). - Options
defaultandonsubmitofcreate()have been removed. Instead one should use JavaScript event binding or set all required js code foronsubmit. end()can no longer make buttons. You should create buttons withbutton()orsubmit().FormHelper::tagIsInvalid()has been removed. UseisFieldError()instead.FormHelper::inputDefaults()has been removed. You can usetemplates()to define/augment the templates FormHelper uses.- The
wrapandclassoptions have been removed from theerror()method. - The
showParentsoption has been removed from select(). - The
div,before,after,betweenanderrorMessageoptions have been removed frominput(). You can use templates to update the wrapping HTML. Thetemplatesoption allows you to override the loaded templates for one input. - The
separator,between, andlegendoptions have been removed fromradio(). You can use templates to change the wrapping HTML now. - The
format24Hoursparameter has been removed fromhour(). It has been replaced with theformatoption. - The
minYear, andmaxYearparameters have been removed fromyear(). Both of these parameters can now be provided as options. - The
dateFormatandtimeFormatparameters have been removed fromdatetime(). You can use the template to define the order the inputs should be displayed in. - The
submit()has had thediv,beforeandafteroptions removed. You can customize thesubmitContainertemplate to modify this content. - The
inputs()method no longer acceptslegendandfieldsetin the$fieldsparameter, you must use the$optionsparameter. It now also requires$fieldsparameter to be an array. The$blacklistparameter has been removed, the functionality has been replaced by specifying'field' => falsein the$fieldsparameter. - The
inlineparameter has been removed from postLink() method. You should use theblockoption instead. Settingblock => truewill emulate the previous behavior. - The
timeFormatparameter forhour(),time()anddateTime()now defaults to 24, complying with ISO 8601. - The
$confirmMessageargument ofCake\View\Helper\FormHelper::postLink()has been removed. You should now use keyconfirmin$optionsto specify the message. - Checkbox and radio input types are now rendered inside of label elements by default. This helps increase compatibility with popular CSS libraries like Bootstrap and Foundation.
- Templates tags are now all camelBacked. Pre-3.0 tags
formstart,formend,hiddenblockandinputsubmitare nowformStart,formEnd,hiddenBlockandinputSubmit. Make sure you change them if they are customized in your app.
It is recommended that you review the Form documentation for more details on how to use the FormHelper in 3.0.
HtmlHelper
HtmlHelper::useTag()has been removed, usetag()instead.HtmlHelper::loadConfig()has been removed. Customizing the tags can now be done usingtemplates()or thetemplatessetting.- The second parameter
$optionsforHtmlHelper::css()now always requires an array as documented. - The first parameter
$dataforHtmlHelper::style()now always requires an array as documented. - The
inlineparameter has been removed from meta(), css(), script(), scriptBlock() methods. You should use theblockoption instead. Settingblock => truewill emulate the previous behavior. HtmlHelper::meta()now requires$typeto be a string. Additional options can further on be passed as$options.HtmlHelper::nestedList()now requires$optionsto be an array. The forth argument for the tag type has been removed and included in the$optionsarray.- The
$confirmMessageargument ofCake\View\Helper\HtmlHelper::link()has been removed. You should now use keyconfirmin$optionsto specify the message.
PaginatorHelper
link()has been removed. It was no longer used by the helper internally. It had low usage in user land code, and no longer fit the goals of the helper.next()no longer has 'class', or 'tag' options. It no longer has disabled arguments. Instead templates are used.prev()no longer has 'class', or 'tag' options. It no longer has disabled arguments. Instead templates are used.first()no longer has 'after', 'ellipsis', 'separator', 'class', or 'tag' options.last()no longer has 'after', 'ellipsis', 'separator', 'class', or 'tag' options.numbers()no longer has 'separator', 'tag', 'currentTag', 'currentClass', 'class', 'tag', 'ellipsis' options. These options are now facilitated through templates. It also requires the$optionsparameter to be an array now.- The
%page%style placeholders have been removed fromCake\View\Helper\PaginatorHelper::counter(). Usestyle placeholders instead. url()has been renamed togenerateUrl()to avoid method declaration clashes withHelper::url().
By default all links and inactive texts are wrapped in <li> elements. This helps make CSS easier to write, and improves compatibility with popular CSS frameworks.
Instead of the various options in each method, you should use the templates feature. See the Paginator Templates documentation for information on how to use templates.
TimeHelper
TimeHelper::__set(),TimeHelper::__get(), andTimeHelper::__isset()were removed. These were magic methods for deprecated attributes.TimeHelper::serverOffset()has been removed. It promoted incorrect time math practices.TimeHelper::niceShort()has been removed.
NumberHelper
NumberHelper::format()now requires$optionsto be an array.
SessionHelper
- The
SessionHelperhas been deprecated. You can use$this->request->session()directly, and the flash message functionality has been moved into Flash instead.
JsHelper
JsHelperand all associated engines have been removed. It could only generate a very small subset of JavaScript code for selected library and hence trying to generate all JavaScript code using just the helper often became an impediment. It's now recommended to directly use JavaScript library of your choice.
CacheHelper Removed
CacheHelper has been removed. The caching functionality it provided was non-standard, limited and incompatible with non-HTML layouts and data views. These limitations meant a full rebuild would be necessary. Edge Side Includes have become a standardized way to implement the functionality CacheHelper used to provide. However, implementing Edge Side Includes in PHP has a number of limitations and edge cases. Instead of building a sub-par solution, we recommend that developers needing full response caching use Varnish or Squid instead.
I18n
The I18n subsystem was completely rewritten. In general, you can expect the same behavior as in previous versions, specifically if you are using the __() family of functions.
Internally, the I18n class uses Aura\Intl, and appropriate methods are exposed to access the specific features of this library. For this reason most methods inside I18n were removed or renamed.
Due to the use of ext/intl, the L10n class was completely removed. It provided outdated and incomplete data in comparison to the data available from the Locale class in PHP.
The default application language will no longer be changed automatically by the browser accepted language nor by having the Config.language value set in the browser session. You can, however, use a dispatcher filter to get automatic language switching from the Accept-Language header sent by the browser:
// In config/bootstrap.php
DispatcherFactory::addFilter('LocaleSelector');There is no built-in replacement for automatically selecting the language by setting a value in the user session.
The default formatting function for translated messages is no longer sprintf, but the more advanced and feature rich MessageFormatter class. In general you can rewrite placeholders in messages as follows:
// Before:
__('Today is a %s day in %s', 'Sunny', 'Spain');
// After:
__('Today is a {0} day in {1}', 'Sunny', 'Spain');You can avoid rewriting your messages by using the old sprintf formatter:
I18n::defaultFormatter('sprintf');Additionally, the Config.language value was removed and it can no longer be used to control the current language of the application. Instead, you can use the I18n class:
// Before
Configure::write('Config.language', 'fr_FR');
// Now
I18n::setLocale('en_US');The methods below have been moved:
- From
Cake\I18n\Multibyte::utf8()toCake\Utility\Text::utf8() - From
Cake\I18n\Multibyte::ascii()toCake\Utility\Text::ascii() - From
Cake\I18n\Multibyte::checkMultibyte()toCake\Utility\Text::isMultibyte()
- From
Since CakePHP now requires the mbstring extension, the
Multibyteclass has been removed.Error messages throughout CakePHP are no longer passed through I18n functions. This was done to simplify the internals of CakePHP and reduce overhead. The developer facing messages are rarely, if ever, actually translated -so the additional overhead reaps very little benefit.
L10n
Cake\I18n\L10n's constructor now takes aCake\Network\Requestinstance as argument.
Testing
The
TestShellhas been removed. CakePHP, the application skeleton and newly baked plugins all usephpunitto run tests.The webrunner (webroot/test.php) has been removed. CLI adoption has greatly increased since the initial release of 2.x. Additionaly, CLI runners offer superior integration with IDE's and other automated tooling.
If you find yourself in need of a way to run tests from a browser you should checkout VisualPHPUnit. It offers many additional features over the old webrunner.
ControllerTestCaseis deprecated and will be removed for CakePHP 3.0.0. You should use the new Integration Testing features instead.Fixtures should now be referenced using their plural form:
php// Instead of $fixtures = ['app.article']; // You should use $fixtures = ['app.articles'];
Utility
Set Class Removed
The Set class has been removed, you should use the Hash class instead now.
Folder & File
The folder and file classes have been renamed:
Cake\Utility\Filerenamed toCake\Filesystem\FileCake\Utility\Folderrenamed toCake\Filesystem\Folder
Inflector
The default value for
$replacementargument ofCake\Utility\Inflector::slug()has been changed from underscore (_) to dash (-). Using dashes to separate words in URLs is the popular choice and also recommended by Google.Transliterations for
Cake\Utility\Inflector::slug()have changed. If you use custom transliterations you will need to update your code. Instead of regular expressions, transliterations use simple string replacement. This yielded significant performance improvements:php// Instead of Inflector::rules('transliteration', [ '/ä|æ/' => 'ae', '/å/' => 'aa' ]); // You should use Inflector::rules('transliteration', [ 'ä' => 'ae', 'æ' => 'ae', 'å' => 'aa' ]);Separate set of uninflected and irregular rules for pluralization and singularization have been removed. Instead we now have a common list for each. When using
Cake\Utility\Inflector::rules()with type 'singular' and 'plural' you can no longer use keys like 'uninflected', 'irregular' in$rulesargument array.You can add / overwrite the list of uninflected and irregular rules using
Cake\Utility\Inflector::rules()by using values 'uninflected' and 'irregular' for$typeargument.
Sanitize
Sanitizeclass has been removed.
Security
Security::cipher()has been removed. It is insecure and promoted bad cryptographic practices. You should useSecurity::encrypt()instead.- The Configure value
Security.cipherSeedis no longer required. With the removal ofSecurity::cipher()it serves no use. - Backwards compatibility in
Cake\Utility\Security::rijndael()for values encrypted prior to CakePHP 2.3.1 has been removed. You should re-encrypt values usingSecurity::encrypt()and a recent version of CakePHP 2.x before migrating. - The ability to generate a blowfish hash has been removed. You can no longer use type "blowfish" for
Security::hash(). One should just use PHP's password_hash() and password_verify() to generate and verify blowfish hashes. The compability library ircmaxell/password-compat which is installed along with CakePHP provides these functions for PHP < 5.5. - OpenSSL is now used over mcrypt when encrypting/decrypting data. This change provides better performance and future proofs CakePHP against distros dropping support for mcrypt.
Security::rijndael()is deprecated and only available when using mcrypt.
WARNING
Data encrypted with Security::encrypt() in previous versions is not compatible with the openssl implementation. You should set the implementation to mcrypt when upgrading.
Time
CakeTimehas been renamed toCake\I18n\Time.CakeTime::serverOffset()has been removed. It promoted incorrect time math practises.CakeTime::niceShort()has been removed.CakeTime::convert()has been removed.CakeTime::convertSpecifiers()has been removed.CakeTime::dayAsSql()has been removed.CakeTime::daysAsSql()has been removed.CakeTime::fromString()has been removed.CakeTime::gmt()has been removed.CakeTime::toATOM()has been renamed totoAtomString.CakeTime::toRSS()has been renamed totoRssString.CakeTime::toUnix()has been renamed totoUnixString.CakeTime::wasYesterday()has been renamed toisYesterdayto match the rest of the method naming.CakeTime::format()Does not usesprintfformat strings anymore, you can usei18nFormatinstead.Time::timeAgoInWords()now requires$optionsto be an array.
Time is not a collection of static methods anymore, it extends DateTime to inherit all its methods and adds location aware formatting functions with the help of the intl extension.
In general, expressions looking like this:
CakeTime::aMethod($date);Can be migrated by rewriting it to:
(new Time($date))->aMethod();Number
The Number library was rewritten to internally use the NumberFormatter class.
CakeNumberhas been renamed toCake\I18n\Number.Number::format()now requires$optionsto be an array.Number::addFormat()was removed.Number::fromReadableSize()has been moved toCake\Utility\Text::parseFileSize().
Validation
- The range for
Validation::range()now is inclusive if$lowerand$upperare provided. Validation::ssn()has been removed.
Xml
Xml::build()now requires$optionsto be an array.Xml::build()no longer accepts a URL. If you need to create an XML document from a URL, use Http\Client.