2.1 Migration Guide

CakePHP 2.1 is a fully API compatible upgrade from 2.0. This page outlines the changes and improvements made for 2.1.

AppController, AppHelper, AppModel and AppShell

These classes are now required to be part of the app directory, as they were removed from the CakePHP core. If you do not already have these classes, you can use the following while upgrading:

// app/View/Helper/AppHelper.php
App::uses('Helper', 'View');
class AppHelper extends Helper {

// app/Model/AppModel.php
App::uses('Model', 'Model');
class AppModel extends Model {

// app/Controller/AppController.php
App::uses('Controller', 'Controller');
class AppController extends Controller {

// app/Console/Command/AppShell.php
App::uses('Shell', 'Console');
class AppShell extends Shell {

If your application already has these files/classes you don’t need to do anything. Additionally if you were using the core PagesController, you would need to copy this to your app/Controller directory as well.

.htaccess files

The default .htaccess files have changed, you should remember to update them or update your webservers URL re-writing scheme to match the changes done in .htaccess


  • The beforeDelete callback will be fired before behaviors beforeDelete callbacks. This makes it consistent with the rest of the events triggered in the model layer.

  • Model::find('threaded') now accepts $options['parent'] if using other field then parent_id. Also if the model has TreeBehavior attached and set up with other parent field, the threaded find will by default use that.

  • Parameters for queries using prepared statements will now be part of the SQL dump.

  • Validation arrays can now be more specific with when a field is required. The required key now accepts create and update. These values will make a field required when creating or updating.

  • Model now has a schemaName property. If your application switches datasources by modifying Model::$useDbConfig you should also modify schemaName or use Model::setDataSource() method which handles this for you.


Changed in version 2.1.1: CakeSession no longer sets the P3P header, as this is the responsibility of your application.



  • I18nModel has been moved into a separate file.


The default exception rendering now includes more detailed stack traces including file excerpts and argument dumps for all functions in the stack.




debug() now uses Debugger internally. This makes it consistent with Debugger, and takes advantage of improvements made there.


  • Set::nest() has been added. It takes in a flat array and returns a nested array





  • App::build() now has the ability to register new packages using App::REGISTER. See Add new packages to an application for more information.

  • Classes that could not be found on configured paths will be searched inside APP as a fallback path. This makes autoloading nested directories in app/Vendor easier.


Test Shell

A new TestShell has been added. It reduces the typing required to run unit tests, and offers a file path based UI:

./Console/cake test app Model/Post
./Console/cake test app Controller/PostsController
./Console/cake test Plugin View/Helper/MyHelper

The old testsuite shell and its syntax are still available.


  • Generated files no longer contain timestamps with the generation datetime.



  • Routes can now use a special /** syntax to include all trailing arguments as a single passed argument. See the section on Connecting Routes for more information.

  • Router::resourceMap() was added.

  • Router::defaultRouteClass() was added. This method allows you to set the default route class used for all future routes that are connected.



  • Added is('requested') and isRequested() for detecting requestAction.




  • Controller::$uses was modified the default value is now true instead of false. Additionally different values are handled slightly differently, but will behave the same in most cases.

    • true Will load the default model and merge with AppController.

    • An array will load those models and merge with AppController.

    • An empty array will not load any models other than those declared in the base class.

    • false will not load any models, and will not merge with the base class either.



  • AuthComponent::allow() no longer accepts allow('*') as a wildcard for all actions. Just use allow(). This unifies the API between allow() and deny().

  • recursive option was added to all authentication adapters. Allows you to more easily control the associations stored in the session.


  • AclComponent no longer lowercases and inflects the class name used for Acl.classname. Instead it uses the provided value as is.

  • Acl backend implementations should now be put in Controller/Component/Acl.

  • Acl implementations should be moved into the Component/Acl directory from Component. For example if your Acl class was called CustomAclComponent, and was in Controller/Component/CustomAclComponent.php. It should be moved into Controller/Component/Acl/CustomAcl.php, and be named CustomAcl.

  • DbAcl has been moved into a separate file.

  • IniAcl has been moved into a separate file.

  • AclInterface has been moved into a separate file.





  • View::$output is deprecated.

  • $content_for_layout is deprecated. Use $this->fetch('content'); instead.

  • $scripts_for_layout is deprecated. Use the following instead:

    echo $this->fetch('meta');
    echo $this->fetch('css');
    echo $this->fetch('script');

    $scripts_for_layout is still available, but the view blocks API gives a more extensible & flexible replacement.

  • The Plugin.view syntax is now available everywhere. You can use this syntax anywhere you reference the name of a view, layout or element.

  • The $options['plugin'] option for element() is deprecated. You should use Plugin.element_name instead.

Content type views

Two new view classes have been added to CakePHP. A new JsonView and XmlView allow you to easily generate XML and JSON views. You can learn more about these classes in the section on JSON and XML views

Extending views

View has a new method allowing you to wrap or ‘extend’ a view/element/layout with another file. See the section on Extending Views for more information on this feature.


The ThemeView class is deprecated in favor of the View class. Simply setting $this->theme = 'MyTheme' will enable theme support, and all custom View classes which extend from ThemeView should extend View.

View blocks

View blocks are a flexible way to create slots or blocks in your views. Blocks replace $scripts_for_layout with a more robust and flexible API. See the section on Using view blocks for more information.


New callbacks

Two new callbacks have been added to Helpers. Helper::beforeRenderFile() and Helper::afterRenderFile() these new callbacks are fired before/after every view fragment is rendered. This includes elements, layouts and views.


  • <!--nocache--> tags now work inside elements correctly.


  • FormHelper now omits disabled fields from the secured fields hash. This makes working with SecurityComponent and disabled inputs easier.

  • The between option when used in conjunction with radio inputs, now behaves differently. The between value is now placed between the legend and first input elements.

  • The hiddenField option with checkbox inputs can now be set to a specific value such as ‘N’ rather than just 0.

  • The for attribute for date + time inputs now reflects the first generated input. This may result in the for attribute changing for generated datetime inputs.

  • The type attribute for FormHelper::button() can be removed now. It still defaults to ‘submit’.

  • FormHelper::radio() now allows you to disable all options. You can do this by setting either 'disabled' => true or 'disabled' => 'disabled' in the $attributes array.



  • Web test runner now displays the PHPUnit version number.

  • Web test runner now defaults to displaying app tests.

  • Fixtures can be created in different datasources other than $test.

  • Models loaded using the ClassRegistry and using another datasource will get their datasource name prepended with test_ (e.g datasource master will try to use test_master in the testsuite)

  • Test cases are generated with class specific setup methods.


  • A new generic events system has been built and it replaced the way callbacks were dispatched. This should not represent any change to your code.

  • You can dispatch your own events and attach callbacks to them at will, useful for inter-plugin communication and easier decoupling of your classes.