2.2 Migration Guide
CakePHP 2.2 is a fully API compatible upgrade from 2.0/2.1. This page outlines the changes and improvements made for 2.2.
Required steps to upgrade
When upgrading to CakePHP 2.2 its important to add a few new configuration values to app/Config/bootstrap.php. Adding these will ensure consistent behavior with 2.1.x:
// Enable the Dispatcher filters for plugin assets, and
// CacheHelper.
Configure::write('Dispatcher.filters', array(
'AssetDispatcher',
'CacheDispatcher'
));
// Add logging configuration.
CakeLog::config('debug', array(
'engine' => 'FileLog',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'FileLog',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));You will also need to modify app/Config/core.php. Change the value of LOG_ERROR to LOG_ERR:
define('LOG_ERROR', LOG_ERR);When using Model::validateAssociated() or Model::saveAssociated() and primary model validation fails, the validation errors of associated models are no longer wiped out. Model::$validationErrors will now always show all the errors. You might need to update your test cases to reflect this change.
Console
I18N extract shell
An option was added to overwrite existing POT files by default:
./Console/cake i18n extract --overwrite
Models
Model::find('count')will now call the custom find methods with$state = 'before'and$queryData['operation'] = 'count'. In many cases custom finds already return correct counts for pagination, but'operation'key allows more flexibility to build other queries, or drop joins which are required for the custom finder itself. As the pagination of custom find methods never worked quite well it required workarounds for this in the model level, which are now no longer needed.Model::find('first')will now return an empty array when no records are found.
Datasources
- Dbo datasources now supports real nested transactions. If you need to use this feature in your application, enable it using
ConnectionManager::getDataSource('default')->useNestedTransactions = true;
Testing
- The webrunner now includes links to re-run a test with debug output.
- Generated test cases for Controller now subclass
ControllerTestCase.
Error Handling
- When repeat exceptions, or exception are raised when rendering error pages, the new
errorlayout will be used. It's recommended to not use additional helpers in this layout as its intended for development level errors only. This fixes issues with fatal errors in rendering error pages due to helper usage in thedefaultlayout. - It is important to copy the
app/View/Layouts/error.ctpinto your app directory. Failing to do so will make error page rendering fail. - You can now configure application specific console error handling. By setting
Error.consoleHandler, andException.consoleHandleryou can define the callback that will handle errors/exceptions raised in console applications. - The handler configured in
Error.handlerandError.consoleHandlerwill receive fatal error codes (ie.E_ERROR,E_PARSE,E_USER_ERROR).
Exceptions
- The
NotImplementedExceptionwas added.
Core
Configure
Configure::dump()was added. It is used to persist configuration data in durable storage like files. BothPhpReaderandIniReaderwork with it.- A new config parameter 'Config.timezone' is available in which you can set users' timezone string. eg. You can do
Configure::write('Config.timezone', 'Europe/Paris'). If a method ofCakeTimeclass is called with$timezoneparameter as null and 'Config.timezone' is set, then the value of 'Config.timezone' will be used. This feature allows you to set users' timezone just once instead of passing it each time in function calls.
Controller
AuthComponent
- The options for adapters defined in
AuthComponent::$authenticatenow accepts acontainoption. This is used to set containable options for when user records are loaded.
CookieComponent
- You can now encrypt cookie values with the rijndael cipher. This requires the mcrypt extension to be installed. Using rijndael gives cookie values actual encryption, and is recommended in place of the XOR cipher available in previous releases. The XOR cipher is still the default cipher scheme to maintain compatibility with previous releases. You can read more in the
Security::rijndael()documentation.
Pagination
- Paginating custom finders will now return correct counts, see Model changes for more info.
Network
CakeEmail
CakeEmail::charset()andCakeEmail::headerCharset()were added.- Legacy Japanese encodings are now handled correctly.
ISO-2202-JPis used when the encoding isISO-2202-JP-MSwhich works around a number of issues in mail clients when dealing with the CP932 and Shift_JIS encodings. CakeEmail::theme()was added.CakeEmail::domain()was added. You can use this method to set the domain name used when sending email from a CLI script or if you want to control the hostname used to send email.- You can now define
themeandhelpersin your EmailConfig class.
CakeRequest
- CakeRequest will now automatically decode
application/x-www-form-urlencodedrequest bodies onPUTandDELETErequests. This data will be available as$this->datajust like POST data is.
Utility
Set
- The
Setclass is now deprecated, and replaced by theHashclass. Set will not be removed until 3.0. Set::expand()was added.
Hash
The Hash class was added in 2.2. It replaced Set providing a more consistent, reliable and performant API to doing many of the same tasks Set does. See the Hash page for more detail.
CakeTime
- The
$userOffsetparameter has been replaced with$timezoneparameter in all relevant functions. So instead of numeric offset you can now pass in a timezone string or DateTimeZone object. Passing numeric offsets for$timezoneparameter is still possible for backwards compatibility. CakeTime::timeAgoInWords()had theaccuracyoption added. This option allows you to specify how accurate formatted times should be.- New methods added:
CakeTime::toServer()CakeTime::timezone()CakeTime::listTimezones()
- The
$dateStringparameter in all methods now accepts a DateTime object.
Helpers
FormHelper
- FormHelper now better handles adding required classes to inputs. It now honors the
onkey. FormHelper::radio()now supports anemptywhich works similar to the empty option onselect().- Added
FormHelper::inputDefaults()to set common properties for each of the inputs generated by the helper
TimeHelper
- Since 2.1, TimeHelper uses the CakeTime class for all its relevant methods. The
$userOffsetparameter has been replaced with$timezoneparameter. TimeHelper::timeAgoInWords()has theelementoption added. This allows you to specify an HTML element to wrap the formatted time.
HtmlHelper
HtmlHelper::tableHeaders()now supports setting attributes per table cell.
Routing
Dispatcher
- Event listeners can now be attached to the dispatcher calls, those will have the ability to change the request information or the response before it is sent to the client. Check the full documentation for this new features in Dispatcher Filters
- With the addition of Dispatcher Filters you'll need to update
app/Config/bootstrap.php. See Required Steps To Upgrade 2 2.
Router
Router::setExtensions()has been added. With the new method you can now add more extensions to be parsed, for example within a plugin routes file.
Cache
Redis Engine
A new caching engine was added using the phpredis extension it is configured similarly to the Memcache engine.
Cache groups
It is now possible to tag or label cache keys under groups. This makes it simpler to mass-delete cache entries associated to the same label. Groups are declared at configuration time when creating the cache engine:
Cache::config(array(
'engine' => 'Redis',
...
'groups' => array('post', 'comment', 'user')
));You can have as many groups as you like, but keep in mind they cannot be dynamically modified.
The Cache::clearGroup() class method was added. It takes the group name and deletes all entries labeled with the same string.
Log
Changes in CakeLog now require, some additional configuration in your app/Config/bootstrap.php. See Required Steps To Upgrade 2 2, and Logging.
- The
CakeLogclass now accepts the same log levels as defined in RFC 5424. Several convenience methods have also been added:CakeLog::emergency($message, $scope = array())CakeLog::alert($message, $scope = array())CakeLog::critical($message, $scope = array())CakeLog::error($message, $scope = array())CakeLog::warning($message, $scope = array())CakeLog::notice($message, $scope = array())CakeLog::info($message, $scope = array())CakeLog::debug($message, $scope = array())
- A third argument
$scopehas been added toCakeLog::write. See Logging Scopes. - A new log engine:
ConsoleLoghas been added.
Model Validation
- A new object
ModelValidatorwas added to delegate the work of validating model data, it should be transparent to the application and fully backwards compatible. It also exposes a rich API to add, modify and remove validation rules. Check docs for this object in Data Validation. - Custom validation functions in your models need to have "public" visibility so that they are accessible by
ModelValidator. - New validation rules added:
Validation::naturalNumber()Validation::mimeType()Validation::uploadError()