- 3.0 Migration Guide
- Requirements
- Upgrade Tool
- Application Directory Layout
- CakePHP should be installed with Composer
- Namespaces
- Removed Constants
- Configuration
- New ORM
- Basics
- Debugging
- Object settings/configuration
- Cache
- Core
- Console
- Shell / Task
- Event
- Log
- Routing
- Network
- Sessions
- Network\Http
- Network\Email
- Controller
- Controller\Components
- Model
- TestSuite
- View
- View\Helper
- I18n
- L10n
- Testing
- Utility
3.0 Migration Guide
This page summarizes the changes from CakePHP 2.x that will assist in migratinga project to 3.0, as well as a reference to get up to date with the changes madeto the core since the CakePHP 2.x branch. Be sure to read the other pages inthis 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 inCakePHP 3.0, we’ve also created a console application to help you complete someof the time consuming mechanical changes. You can get the upgrade tool fromgithub.
Application Directory Layout
The application directory layout has changed and now followsPSR-4. You should use theapp skeleton project as a reference pointwhen updating your application.
CakePHP should be installed with Composer
Since CakePHP can no longer be installed via PEAR, or in a shareddirectory, those options are no longer supported. Instead you should useComposer to install CakePHP into your application.
Namespaces
All of CakePHP’s core classes are now namespaced and follow PSR-4 autoloadingspecifications. For example src/Cache/Cache.php is namespaced asCake\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:
IMAGES
CSS
JS
IMAGES_URL
JS_URL
CSS_URL
DEFAULT_LANGUAGE
Configuration
Configuration in CakePHP 3.0 is significantly different than in previousversions. You should read the Configuration documentationfor 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. Seethe 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 fortemplates, plugins and locale files respectively.
The config key www_root
has been changed to wwwRoot
for consistency. Please adjustyour 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. Thenew ORM is significantly different and incompatible with the previous one.Upgrading to the new ORM will require extensive changes in any application thatis being upgraded. See the new Database Access & ORM documentation for information on howto 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 booleanis used instead to switch debug mode on or off.
Object settings/configuration
- Objects used in CakePHP now have a consistent instance-configuration storage/retrievalsystem. Code which previously accessed for example:
$object->settings
should insteadbe updated to use$object->config()
.
Cache
Memcache
engine has been removed, useCake\Cache\Cache\Engine\Memcached
instead.- 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.disable
configure 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 configurationyou must first drop the configuration and then re-create it. This preventssynchronization issues with configuration options.
Cache::set()
has been removed. It is recommended that you create multiplecache configurations to replace runtime configuration tweaks previouslypossible withCache::set()
.- All
CacheEngine
subclasses now implement aconfig()
method. Cake\Cache\Cache::readMany()
,Cake\Cache\Cache::deleteMany()
,andCake\Cache\Cache::writeMany()
were added.
AllCake\Cache\Cache\CacheEngine
methods now honor/are responsible for handling theconfigured key prefix. TheCake\Cache\CacheEngine::write()
no longer permits settingthe duration on write - the duration is taken from the cache engine’s runtime config. Calling acache method with an empty key will now throw anInvalidArgumentException
, insteadof returningfalse
.
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::RESET
has been removed.App::APPEND
has been removed.App::PREPEND
has been removed.App::REGISTER
has been removed.
Plugin
Cake\Core\Plugin::load()
does not setup an autoloader unlessyou set theautoload
option totrue
.- When loading plugins you can no longer provide a callable.
- When loading plugins you can no longer provide an array of config files toload.
Configure
Cake\Configure\PhpReader
renamed toCake\Core\Configure\EnginePhpConfig
Cake\Configure\IniReader
renamed toCake\Core\Configure\EngineIniConfig
Cake\Configure\ConfigReaderInterface
renamed toCake\Core\Configure\ConfigEngineInterface
Cake\Core\Configure::consume()
was added.Cake\Core\Configure::load()
now expects the file name withoutextension suffix as this can be derived from the engine. E.g. using PhpConfiguseapp
to load app.php.- Setting a
$config
variable in PHP config file is deprecated.Cake\Core\Configure\EnginePhpConfig
now expects the configfile to return an array. - A new config engine
Cake\Core\Configure\EngineJsonConfig
hasbeen added.
Object
The Object
class has been removed. It formerly contained a grab bag ofmethods that were used in various places across the framework. The most usefulof these methods have been extracted into traits. You can use theCake\Log\LogTrait
to access the log()
method. TheCake\Routing\RequestActionTrait
provides requestAction()
.
Console
The cake
executable has been moved from the app/Console directory to thebin directory within the application skeleton. You can now invoke CakePHP’sconsole with bin/cake
.
TaskCollection Replaced
This class has been renamed to Cake\Console\TaskRegistry
.See the section on Registry Objects for more informationon the features provided by the new class. You can use the cake upgrade
to assist in upgrading your code. Tasks no longer haveaccess to callbacks, as there were never any callbacks to use.
rename_collections
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 ahello_world()
method inside a shell and invoked itwithbin/cake my_shell hello_world
, you will need to rename the methodtohelloWorld
. 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
andConsole/Command/Task
to Shell
and Shell/Task
.
ApiShell Removed
The ApiShell was removed as it didn’t provide any benefit over the file sourceitself and the online documentation/API.
SchemaShell Removed
The SchemaShell was removed as it was never a complete database migration implementationand better tools such as Phinx have emerged. It has been replaced bythe CakePHP Migrations Plugin which acts as a wrapper betweenCakePHP and Phinx.
ExtractTask
bin/cake i18n extract
no longer includes untranslated validationmessages. If you want translated validation messages you should wrap thosemessages in __() calls like any other content.
BakeShell / TemplateTask
- Bake is no longer part of the core source and is superseded byCakePHP Bake Plugin
- Bake templates have been moved under src/Template/Bake.
- The syntax of Bake templates now uses erb-style tags (
<% %>
) to denotetemplating logic, allowing php code to be treated as plain text. - The
bake view
command has been renamedbake template
.
Event
The getEventManager()
method, was removed on all objects that had it. AneventManager()
method is now provided by the EventManagerTrait
. TheEventManagerTrait
contains the logic of instantiating and keepinga reference to a local event manager.
The Event subsystem has had a number of optional features removed. Whendispatching events you can no longer use the following options:
passParams
This option is now enabled always implicitly. Youcannot turn it off.break
This option has been removed. You must now stop events.breakOn
This option has been removed. You must now stop events.
Log
- Log configurations are now immutable. If you need to change configurationyou must first drop the configuration and then re-create it. This preventssynchronization 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 oflog levels. You should use logging scopes to create custom log files orspecific handling for different sections of your application. Usinga non-standard log level will now throw an exception.
Cake\Log\LogTrait
was added. You can use this trait in yourclasses to add thelog()
method.- The logging scope passed to
Cake\Log\Log::write()
is nowforwarded to the log engines’write()
method in order to provide bettercontext to the engines. - Log engines are now required to implement
Psr\Log\LogInterface
instead ofCake’s ownLogInterface
. In general, if you extendedCake\Log\Engine\BaseEngine
you just need to rename thewrite()
method tolog()
. Cake\Log\Engine\FileLog
now writes files inROOT/logs
instead ofROOT/tmp/logs
.
Routing
Named Parameters
Named parameters were removed in 3.0. Named parameters were added in 1.2.0 asa ‘pretty’ version of query string parameters. While the visual benefit isarguable, the problems named parameters created are not.
Named parameters required special handling in CakePHP as well as any PHP orJavaScript library that needed to interact with them, as named parameters arenot implemented or understood by any library except CakePHP. The additionalcomplexity and code required to support named parameters did not justify theirexistence, and they have been removed. In their place you should use standardquery string parameters or passed arguments. By default Router
will treatany additional parameters to Router::url()
as query string arguments.
Since many applications will still need to parse incoming URLs containing namedparameters. Cake\Routing\Router::parseNamedParams()
hasbeen added to allow backwards compatibility with existing URLs.
RequestActionTrait
Cake\Routing\RequestActionTrait::requestAction()
has hadsome 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_base
option has been replaced with the_full
option. - The
ext
option has been replaced with the_ext
option. _scheme
,_port
,_host
,_base
,_full
,_ext
options added.- String URLs are no longer modified by adding the plugin/controller/prefix names.
- The default fallback route handling was removed. If no routesmatch a parameter set
/
will be returned. - Route classes are responsible for all URL generation includingquery string parameters. This makes routes far more powerful and flexible.
- Persistent parameters were removed. They were replaced with
Cake\Routing\Router::urlFilter()
which allowsa more flexible way to mutate URLs being reverse routed. Router::parseExtensions()
has been removed.UseCake\Routing\Router::extensions()
instead. This methodmust be called before routes are connected. It won’t modify existingroutes.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 beenremoved. If you need to parse/match on arbitrary conditions consider usingcustom route classes. Router::promote()
has been removed.Router::parse()
will now raise an exception when a URL cannot be handledby any route.Router::url()
will now raise an exception when no route matches a set ofparameters.- Routing scopes have been introduced. Routing scopes allow you to keep yourroutes file DRY and give Router hints on how to optimize parsing & reverserouting URLs.
Route
CakeRoute
was 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
. Thismeans if your application used Dispatcher.filters
, you should now useCake\Routing\DispatcherFactory::add()
.
In addition to configuration changes, dispatcher filters have had someconventions updated, and features added. See theDispatcher Filters documentation for more information.
FilterAssetFilter
- Plugin & theme assets handled by the AssetFilter are no longer read via
include
instead they are treated as plain text files. This fixes a numberof issues with JavaScript libraries like TinyMCE and environments withshort_tags enabled. - Support for the
Asset.filter
configuration and hooks were removed. Thisfeature should be replaced with a plugin or dispatcher filter.
Network
Request
CakeRequest
has 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::$trustProxy
was added. This makes it easier to putCakePHP applications behind load balancers.Cake\Network\Request::$data
is no longer merged with the prefixed datakey, as that prefix has been removed.Cake\Network\Request::env()
was added.Cake\Network\Request::acceptLanguage()
was changed from static methodto non-static.- Request detector for “mobile” has been removed from the core. Instead the apptemplate adds detectors for “mobile” and “tablet” using
MobileDetect
lib. - 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/plain
to extensioncsv
has been removed.As a consequenceCake\Controller\Component\RequestHandlerComponent
doesn’t set extension tocsv
ifAccept
header contains mimetypetext/plain
which was a common annoyance when receiving a jQuery XHR request.
Sessions
The session class is no longer static, instead the session can be accessedthrough the request object. See the Sessions documentationfor using the session object.
Cake\Network\Session
and related session classes have beenmoved under theCake\Network
namespace.SessionHandlerInterface
has been removed in favor of the one provided byPHP itself.- The property
Session::$requestCountdown
has been removed. - The session checkAgent feature has been removed. It caused a number of bugswhen chrome frame, and flash player are involved.
- The conventional sessions database table name is now
sessions
instead ofcake_sessions
. - The session cookie timeout is automatically updated in tandem with the timeoutin the session data.
- The path for session cookie now defaults to app’s base path instead of “/”.A new configuration variable
Session.cookiePath
has been added tocustomize the cookie path. - A new convenience method
Cake\Network\Session::consume()
has been addedto allow reading and deleting session data in a single step. - The default value of
Cake\Network\Session::clear()
’s argument$renew
has been changedfromtrue
tofalse
.
Network\Http
HttpSocket
is nowCake\Network\Http\Client
.- HttpClient has been re-written from the ground up. It has a simpler/easier touse 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 theHttp Client documentation for more information.
Network\Email
Cake\Network\Email\Email::config()
is now used to defineconfiguration profiles. This replaces theEmailConfig
classes in previousversions.Cake\Network\Email\Email::profile()
replacesconfig()
asthe way to modify per instance configuration options.Cake\Network\Email\Email::drop()
has been added to allow theremoval of email configuration.Cake\Network\Email\Email::configTransport()
has been added to allow thedefinition of transport configurations. This change removes transport optionsfrom delivery profiles and allows you to re-use transports across emailprofiles.Cake\Network\Email\Email::dropTransport()
has been added to allow theremoval of transport configuration.
Controller
Controller
- The
$helpers
,$components
properties are now mergedwith all parent classes not justAppController
and the pluginAppController. The properties are merged differently now as well. Instead ofall settings in all classes being merged together, the configuration definedin the child class will be used. This means that if you have someconfiguration defined in your AppController, and some configuration defined ina 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 realapplications and served no purpose anymore.Controller::validate()
andController::validationErrors()
have beenremoved. They were left over methods from the 1.x days where the concerns ofmodels + controllers were far more intertwined.Controller::loadModel()
now loads table objects.- The
Controller::$scaffold
property has been removed. Dynamic scaffoldinghas been removed from CakePHP core. An improved scaffolding plugin, named CRUD, can be found here: https://github.com/FriendsOfCake/crud - The
Controller::$ext
property has been removed. You now have to extend andoverride theView::$_ext
property if you want to use a non-default view fileextension. - The
Controller::$methods
property has been removed. You should now useController::isAction()
to determine whether or not a method name is anaction. This change was made to allow easier customization of what is and isnot counted as an action. - The
Controller::$Components
property 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 beenchanged toController::redirect(string|array $url, int $status = null)
.The 3rd argument$exit
has been dropped. The method can no longer sendresponse and exit script, instead it returns aResponse
instance withappropriate headers set. - The
base
,webroot
,here
,data
,action
, andparams
magic properties have been removed. You should access all of these propertieson$this->request
instead. - Underscore prefixed controller methods like
_someMethod()
are no longertreated as private methods. Use proper visibility keywords instead. Onlypublic methods can be used as controller actions.
Scaffold Removed
The dynamic scaffolding in CakePHP has been removed from CakePHP core. It wasinfrequently used, and never intended for production use. An improvedscaffolding 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 informationon the features provided by the new class. You can use the cake upgrade
to assist in upgrading your code.
rename_collections
Component
- The
_Collection
property is now_registry
. It contains an instanceofCake\Controller\ComponentRegistry
now. - All components should now use the
config()
method to get/setconfiguration. - Default configuration for components should be defined in the
$_defaultConfig
property. This property is automatically merged with anyconfiguration 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 isbound to the same event thatComponent::initialize()
used to be. Theinitialize 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()
methodare now un-readable becauseSecurity::cipher()
has been removed. You willneed to re-encrypt cookies with therijndael()
oraes()
method before upgrading. CookieComponent::type()
has been removed and replaced with configurationdata accessed throughconfig()
.write()
no longer takesencryption
orexpires
parameters. Both ofthese are now managed through config data. SeeCookie for more information.- The path for cookies now defaults to app’s base path instead of “/”.
AuthComponent
Default
is now the default password hasher used by authentication classes.It uses exclusively the bcrypt hashing algorithm. If you want to continue usingSHA1 hashing used in 2.x use'passwordHasher' => 'Weak'
in your authenticator configuration.- A new
FallbackPasswordHasher
was added to help users migrate old passwordsfrom one algorithm to another. Check AuthComponent’s documentation for moreinfo. BlowfishAuthenticate
class has been removed. Just useFormAuthenticate
BlowfishPasswordHasher
class has been removed. UseDefaultPasswordHasher
instead.- 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 needto 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 uponsuccessful identification and then usesetUser()
to save the info tosession for persistence across requests. BaseAuthenticate::_password()
has been removed. Use aPasswordHasher
class instead.BaseAuthenticate::logout()
has been removed.AuthComponent
now triggers two eventsAuth.afterIdentify
andAuth.logout
after a user has been identified and before a user islogged out respectively. You can set callback functions for these events byreturning a mapping array fromimplementedEvents()
method of yourauthenticate class.
ACL related classes were moved to a separate plugin. Password hashers, Authentication andAuthorization providers where moved to the\Cake\Auth
namespace. You arerequired to move your providers and hashers to theApp\Auth
namespace aswell.
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 movedinto a separate CsrfComponent. This allows you to use CSRF protectionwithout 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 useFlash instead.
Error
Custom ExceptionRenderers are now expected to either returna Cake\Network\Response
object or string when rendering errors. This meansthat any methods handling specific exceptions must return a response or stringvalue.
Model
The Model layer in 2.x has been entirely re-written and replaced. You shouldreview the New ORM Upgrade Guide for information on how to use thenew ORM.
- The
Model
class has been removed. - The
BehaviorCollection
class has been removed. - The
DboSource
class has been removed. - The
Datasource
class has been removed. - The various datasource classes have been removed.
ConnectionManager
- ConnectionManager has been moved to the
Cake\Datasource
namespace. - ConnectionManager has had the following methods removed:
sourceList
getSourceName
loadDataSource
enumConnectionObjects
Database\ConnectionManager::config()
has been added and isnow the only way to configure connections.Database\ConnectionManager::get()
has been added. ItreplacesgetDataSource()
.Database\ConnectionManager::configured()
has been added. Itandconfig()
replacesourceList()
&enumConnectionObjects()
witha 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 longertreated as private methods. Use proper visibility keywords instead.
TreeBehavior
The TreeBehavior was completely re-written to use the new ORM. Although it worksthe 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 alloperation 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 bytheir 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 beassertEquals($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 APIwith$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 hasproven to be limited, and confusing. In CakePHP 3.0, themes no longer resideinside the application. Instead they are standalone plugins. This solvesa 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:
Layouts
is nowLayout
Elements
is nowElement
Errors
is nowError
Emails
is nowEmail
(same forEmail
insideLayout
)
HelperCollection Replaced
This class has been renamed to Cake\View\HelperRegistry
.See the section on Registry Objects for more informationon the features provided by the new class. You can use the cake upgrade
to assist in upgrading your code.
rename_collections
View Class
- The
plugin
key has been removed from$options
argument ofCake\View\View::element()
.Specify the element name asSomePlugin.element_name
instead. View::getVar()
has been removed, useCake\View\View::get()
instead.View::$ext
has been removed and instead a protected propertyView::$_ext
has been added.View::addScript()
has been removed. Use Using View Blocks instead.- The
base
,webroot
,here
,data
,action
, andparams
magic properties have been removed. You should access all of these propertieson$this->request
instead. View::start()
no longer appends to an existing block. Instead it willoverwrite the block content when end is called. If you need to combine blockcontents 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 overwritesstartIfEmpty serves no purpose.- The
View::$Helpers
property has been removed and replaced with_helpers
. If you need to load helpers at runtime you should use$this->addHelper()
in your view files. View
will now raiseCake\View\Exception\MissingTemplateException
whentemplates are missing instead ofMissingViewException
.
ViewBlock
ViewBlock::append()
has been removed, useCake\ViewViewBlock::concat()
instead. However,View::append()
still exists.
JsonView
- By default JSON data will have HTML entities encoded now. This preventspossible XSS issues when JSON view content is embedded in HTML files.
Cake\View\JsonView
now supports the_jsonOptions
viewvariable. This allows you to configure the bit-mask options used when generatingJSON.
XmlView
Cake\View\XmlView
now supports the_xmlOptions
viewvariable. This allows you to configure the options used when generatingXML.
View\Helper
- The
$settings
property is now called$_config
and should be accessedthrough theconfig()
method. - Configuration options are no longer set as public properties.
Helper::clean()
was removed. It was never robust enoughto fully prevent XSS. instead you should escape content withh
oruse a dedicated library like htmlPurifier.Helper::output()
was removed. This method wasdeprecated in 2.x.- Methods
Helper::webroot()
,Helper::url()
,Helper::assetUrl()
,Helper::assetTimestamp()
have been moved to newCake\View\Helper\UrlHelper
helper.Helper::url()
is now available asCake\View\Helper\UrlHelper::build()
. - Magic accessors to deprecated properties have been removed. The followingproperties 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 persistentfield features that have proven to be problematic over time. FormHelper nolonger relies on these methods and the complexity they provide is not necessaryanymore.
The following methods have been removed:
Helper::_parseAttributes()
Helper::_formatAttribute()
These methods can now be found on theStringTemplate
class that helpersfrequently use. See theStringTemplateTrait
for an easy way to integratestring 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 forintegrating with other ORMs or datasources.
- FormHelper features an extensible widget system that allows you to create newcustom input widgets and augment the built-in ones.
String templates are the foundation of the helper. Instead of munging arraystogether everywhere, most of the HTML FormHelper generates can be customizedin one central place using template sets.
In addition to these larger changes, some smaller breaking changes have beenmade as well. These changes should help streamline the HTML FormHelper generatesand 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 othersno longer generate id attributes. - The
inputDefaults
option has been removed fromcreate()
. - Options
default
andonsubmit
ofcreate()
have been removed. Insteadone 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
wrap
andclass
options have been removed from theerror()
method. - The
showParents
option has been removed from select(). - The
div
,before
,after
,between
anderrorMessage
optionshave been removed frominput()
. You can use templates to update thewrapping HTML. Thetemplates
option allows you to override the loadedtemplates for one input. - The
separator
,between
, andlegend
options have been removed fromradio()
. You can use templates to change the wrapping HTML now. - The
format24Hours
parameter has been removed fromhour()
.It has been replaced with theformat
option. - The
minYear
, andmaxYear
parameters have been removed fromyear()
.Both of these parameters can now be provided as options. - The
dateFormat
andtimeFormat
parameters have been removed fromdatetime()
. You can use the template to define the order the inputs shouldbe displayed in. - The
submit()
has had thediv
,before
andafter
optionsremoved. You can customize thesubmitContainer
template to modify thiscontent. - The
inputs()
method no longer acceptslegend
andfieldset
in the$fields
parameter, you must use the$options
parameter.It now also requires$fields
parameter to be an array. The$blacklist
parameter has been removed, the functionality has been replaced by specifying'field' => false
in the$fields
parameter. - The
inline
parameter has been removed from postLink() method.You should use theblock
option instead. Settingblock => true
willemulate the previous behavior. - The
timeFormat
parameter forhour()
,time()
anddateTime()
nowdefaults to 24, complying with ISO 8601. - The
$confirmMessage
argument ofCake\View\Helper\FormHelper::postLink()
has been removed. You should now use keyconfirm
in$options
to specifythe message. - Checkbox and radio input types are now rendered inside of label elementsby default. This helps increase compatibility with popular CSS libraries likeBootstrap andFoundation.
- Templates tags are now all camelBacked. Pre-3.0 tags
formstart
,formend
,hiddenblock
andinputsubmit
are nowformStart
,formEnd
,hiddenBlock
andinputSubmit
.Make sure you change them if they are customized in your app.
It is recommended that you review the Formdocumentation 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 bedone usingtemplates()
or thetemplates
setting.- The second parameter
$options
forHtmlHelper::css()
now always requires an array as documented. - The first parameter
$data
forHtmlHelper::style()
now always requires an array as documented. - The
inline
parameter has been removed from meta(), css(), script(), scriptBlock()methods. You should use theblock
option instead. Settingblock =>
will emulate the previous behavior.
true HtmlHelper::meta()
now requires$type
to be a string. Additional options canfurther on be passed as$options
.HtmlHelper::nestedList()
now requires$options
to be an array. The forth argument for the tag typehas been removed and included in the$options
array.- The
$confirmMessage
argument ofCake\View\Helper\HtmlHelper::link()
has been removed. You should now use keyconfirm
in$options
to specifythe 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 disabledarguments. Instead templates are used.prev()
no longer has ‘class’, or ‘tag’ options. It no longer has disabledarguments. 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 throughtemplates. It also requires the$options
parameter to be an array now.- The
%page%
style placeholders have been removed fromCake\View\Helper\PaginatorHelper::counter()
.Use{{page}}
style 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. Thishelps make CSS easier to write, and improves compatibility with popular CSSframeworks.
Instead of the various options in each method, you should use the templatesfeature. See the PaginatorHelper Templates documentation forinformation on how to use templates.
TimeHelper
TimeHelper::set()
,TimeHelper::
get()
, andTimeHelper::__isset()
wereremoved. 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$options
to be an array.
SessionHelper
- The
SessionHelper
has been deprecated. You can use$this->request->session()
directly,and the flash message functionality has been moved into Flash instead.
JsHelper
JsHelper
and all associated engines have been removed. It could onlygenerate a very small subset of JavaScript code for selected library andhence trying to generate all JavaScript code using just the helper oftenbecame an impediment. It’s now recommended to directly use JavaScript libraryof your choice.
CacheHelper Removed
CacheHelper has been removed. The caching functionality it provided wasnon-standard, limited and incompatible with non-HTML layouts and data views.These limitations meant a full rebuild would be necessary. Edge Side Includeshave become a standardized way to implement the functionality CacheHelper usedto provide. However, implementing Edge Side Includes in PHP has a number oflimitations and edge cases. Instead of building a sub-par solution, we recommendthat developers needing full response caching use Varnish or Squid instead.
I18n
The I18n subsystem was completely rewritten. In general, you can expect the samebehavior as in previous versions, specifically if you are using the __()
family of functions.
Internally, the I18n
class uses Aura\Intl
, and appropriate methods areexposed to access the specific features of this library. For this reason mostmethods inside I18n
were removed or renamed.
Due to the use of ext/intl
, the L10n class was completely removed. Itprovided outdated and incomplete data in comparison to the data available fromthe Locale
class in PHP.
The default application language will no longer be changed automatically by thebrowser accepted language nor by having the Config.language
value set in thebrowser session. You can, however, use a dispatcher filter to get automaticlanguage 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 bysetting a value in the user session.
The default formatting function for translated messages is no longersprintf
, 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 beused to control the current language of the application. Instead, you can usethe 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()
Since CakePHP now requires the mbstring extension, the
Multibyte
class has been removed.Error messages throughout CakePHP are no longer passed through I18nfunctions. This was done to simplify the internals of CakePHP and reduceoverhead. 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\Request
instance as argument.
Testing
The
TestShell
has been removed. CakePHP, the application skeleton andnewly baked plugins all usephpunit
to run tests.The webrunner (webroot/test.php) has been removed. CLI adoption has greatlyincreased since the initial release of 2.x. Additionaly, CLI runners offersuperior integration with IDE’s and other automated tooling.
If you find yourself in need of a way to run tests from a browser you shouldcheckout VisualPHPUnit. Itoffers many additional features over the old webrunner.
ControllerTestCase
is deprecated and will be removed for CakePHP 3.0.0.You should use the new Controller Integration Testing features instead.Fixtures should now be referenced using their plural form:
- // 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\File
renamed toCake\Filesystem\File
Cake\Utility\Folder
renamed toCake\Filesystem\Folder
Inflector
The default value for
$replacement
argument ofCake\Utility\Inflector::slug()
has been changed from underscore (_
) to dash (-
). Using dashes toseparate 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. Insteadof regular expressions, transliterations use simple string replacement. Thisyielded significant performance improvements:
- // 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 andsingularization 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$rules
argument array.
You can add / overwrite the list of uninflected and irregular rules usingCake\Utility\Inflector::rules()
by using values ‘uninflected’ and‘irregular’ for $type
argument.
Sanitize
Sanitize
class has been removed.
Security
Security::cipher()
has been removed. It is insecure and promoted badcryptographic practices. You should useSecurity::encrypt()
instead.- The Configure value
Security.cipherSeed
is no longer required. With theremoval ofSecurity::cipher()
it serves no use. - Backwards compatibility in
Cake\Utility\Security::rijndael()
for values encrypted priorto 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 compabilitylibrary ircmaxell/password-compatwhich is installed along with CakePHP provides these functions for PHP < 5.5. - OpenSSL is now used over mcrypt when encrypting/decrypting data. This changeprovides better performance and future proofs CakePHP against distros droppingsupport for mcrypt.
Security::rijndael()
is deprecated and only available when using mcrypt.
Warning
Data encrypted with Security::encrypt() in previous versions is notcompatible with the openssl implementation. You should set theimplementation to mcrypt when upgrading.
Time
CakeTime
has 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 toisYesterday
to match the restof the method naming.CakeTime::format()
Does not usesprintf
format strings anymore, you can usei18nFormat
instead.Time::timeAgoInWords()
now requires$options
to be an array.
Time is not a collection of static methods anymore, it extendsDateTime
toinherit all its methods and adds location aware formatting functions with thehelp of theintl
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.
CakeNumber
has been renamed toCake\I18n\Number
.Number::format()
now requires$options
to 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$lower
and$upper
are provided. Validation::ssn()
has been removed.
Xml
Xml::build()
now requires$options
to be an array.Xml::build()
no longer accepts a URL. If you need to create an XMLdocument from a URL, use Http\Client.