11.1 Migrating from CakePHP 1.2 to 1.3
This guide summarizes many of the changes necessary when migrating from a 1.2 to 1.3 Cake core. Each section contains relevant information for the modifications made to existing methods as well as any methods that have been removed/renamed.
App File Replacements (important)
- webroot/index.php: Must be replaced due to changes in bootstrapping process.
- config/core.php: Additional settings have been put in place which are required for PHP 5.3.
- webroot/test.php: Replace if you want to run unit tests.
# Removed Constants
The following constants have been removed from CakePHP. If your
application depends on them you must define them in
app/config/bootstrap.php
CIPHER_SEED- It has been replaced with Configure class varSecurity.cipherSeedwhich should be changed inapp/config/core.phpPEARINFLECTIONSVALID_NOT_EMPTYVALID_EMAILVALID_NUMBERVALID_YEAR
# Configuration and application bootstrapping
Bootstrapping Additional Paths.
In your app/config/bootstrap.php you may have variables like
$pluginPaths or $controllerPaths.
There is a new way to add those paths. As of 1.3 RC1 the
$pluginPaths variables will no longer work. You must
use
App::build() to modify paths.
App::build(array(
'plugins' => array('/full/path/to/plugins/', '/next/full/path/to/plugins/'),
'models' => array('/full/path/to/models/', '/next/full/path/to/models/'),
'views' => array('/full/path/to/views/', '/next/full/path/to/views/'),
'controllers' => array('/full/path/to/controllers/', '/next/full/path/to/controllers/'),
'datasources' => array('/full/path/to/datasources/', '/next/full/path/to/datasources/'),
'behaviors' => array('/full/path/to/behaviors/', '/next/full/path/to/behaviors/'),
'components' => array('/full/path/to/components/', '/next/full/path/to/components/'),
'helpers' => array('/full/path/to/helpers/', '/next/full/path/to/helpers/'),
'vendors' => array('/full/path/to/vendors/', '/next/full/path/to/vendors/'),
'shells' => array('/full/path/to/shells/', '/next/full/path/to/shells/'),
'locales' => array('/full/path/to/locale/', '/next/full/path/to/locale/')
));
App::build(array('plugins' => array('/full/path/to/plugins/', '/next/full/path/to/plugins/'),'models' => array('/full/path/to/models/', '/next/full/path/to/models/'),'views' => array('/full/path/to/views/', '/next/full/path/to/views/'),'controllers' => array('/full/path/to/controllers/', '/next/full/path/to/controllers/'),'datasources' => array('/full/path/to/datasources/', '/next/full/path/to/datasources/'),'behaviors' => array('/full/path/to/behaviors/', '/next/full/path/to/behaviors/'),'components' => array('/full/path/to/components/', '/next/full/path/to/components/'),'helpers' => array('/full/path/to/helpers/', '/next/full/path/to/helpers/'),'vendors' => array('/full/path/to/vendors/', '/next/full/path/to/vendors/'),'shells' => array('/full/path/to/shells/', '/next/full/path/to/shells/'),'locales' => array('/full/path/to/locale/', '/next/full/path/to/locale/')));
Also changed is the order in which bootstrapping occurs. In the
past app/config/core.php was loaded
after app/config/bootstrap.php. This
caused any App::import() in an application bootstrap
to be un-cached and considerably slower than a cached include. In
1.3 core.php is loaded and the core cache configs are created
before bootstrap.php is loaded.
Loading custom inflections
inflections.php has been removed, it was an
unnecessary file hit, and the related features have been refactored
into a method to increase their flexibility. You now use
Inflector::rules() to load custom inflections.
Inflector::rules('singular', array(
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
'uninflected' => array('singulars'),
'irregular' => array('spins' => 'spinor')
));
Inflector::rules('singular', array('rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),'uninflected' => array('singulars'),'irregular' => array('spins' => 'spinor')));
Will merge the supplied rules into the infection sets, with the added rules taking precedence over the core rules.
# File renames and internal changes
Library Renames
Core libraries of libs/session.php, libs/socket.php, libs/model/schema.php and libs/model/behavior.php have been renamed so that there is a better mapping between filenames and main classes contained within (as well as dealing with some name-spacing issues):
-
session.php ⇒ cake_session.php
- App::import('Core', 'Session') ⇒ App::import('Core', 'CakeSession')
-
socket.php ⇒ cake_socket.php
- App::import('Core', 'Socket') ⇒ App::import('Core', 'CakeSocket')
-
schema.php ⇒ cake_schema.php
- App::import('Model', 'Schema') ⇒ App::import('Model', 'CakeSchema')
-
behavior.php ⇒ model_behavior.php
- App::import('Core', 'Behavior') ⇒ App::import('Core', 'ModelBehavior')
In most cases, the above renaming will not affect userland code.
Inheritance from Object
The following classes no longer extend Object:
- Router
- Set
- Inflector
- Cache
- CacheEngine
If you were using Object methods from these classes, you will need to not use those methods.
# Library Classes
CakeSession
delis deprecated usedelete
SessionComponent
SessionComponent::setFlash()now uses an element instead of a layout as its second parameter. Be sure to move any flash layouts from app/views/layouts to app/views/elements and change instances of $content_for_layout to $message.
Folder
mkdiris deprecated usecreatemvis deprecated usemovelsis deprecated usereadcpis deprecated usecopyrmis deprecated usedelete
Set
isEqualis deprecated. Use == or ===.
String
getInstanceis deprecated, call String methods statically.
Router
Routing.admin is deprecated. It provided an
inconsistent behavior with other prefix style routes in that it was
treated differently. Instead you should use
Routing.prefixes. Prefix routes in 1.3 do not require
additional routes to be declared manually. All prefix routes will
be generated automatically. To update simply change your
core.php.
//from:
Configure::write('Routing.admin', 'admin');
//to:
Configure::write('Routing.prefixes', array('admin'));
//from:Configure::write('Routing.admin', 'admin');//to:Configure::write('Routing.prefixes', array('admin'));
See the New features guide for more information on using prefix
routes. A small change has also been done to routing params. Routed
params should now only consist of alphanumeric chars, - and _ or
/[A-Z0-9-_+]+/.
Router::connect('/:$%@#param/:action/*', array(...)); // BAD
Router::connect('/:can/:anybody/:see/:m-3/*', array(...)); //Acceptable
Router::connect('/:$%@#param/:action/*', array(...)); // BADRouter::connect('/:can/:anybody/:see/:m-3/*', array(...)); //Acceptable
For 1.3 the internals of the Router were heavily refactored to increase performance and reduce code clutter. The side effect of this is two seldom used features were removed, as they were problematic and buggy even with the existing code base. First path segments using full regular expressions was removed. You can no longer create routes like
Router::connect('/([0-9]+)-p-(.*)/', array('controller' => 'products', 'action' => 'show'));
Router::connect('/([0-9]+)-p-(.*)/', array('controller' => 'products', 'action' => 'show'));
These routes complicated route compilation and impossible to reverse route. If you need routes like this, it is recommended that you use route parameters with capture patterns. Next mid-route greedy star support has been removed. It was previously possible to use a greedy star in the middle of a route.
Router::connect(
'/pages/*/:event',
array('controller' => 'pages', 'action' => 'display'),
array('event' => '[a-z0-9_-]+')
);
Router::connect('/pages/*/:event',array('controller' => 'pages', 'action' => 'display'),array('event' => '[a-z0-9_-]+'));
This is no longer supported as mid-route greedy stars behaved erratically, and complicated route compiling. Outside of these two edge-case features and the above changes the router behaves exactly as it did in 1.2
Also, people using the 'id' key in array-form URLs will notice that Router::url() now treats this as a named parameter. If you previously used this approach for passing the ID parameter to actions, you will need to rewrite all your $html->link() and $this->redirect() calls to reflect this change.
// old format:
$url = array('controller' => 'posts', 'action' => 'view', 'id' => $id);
// use cases:
Router::url($url);
$html->link($url);
$this->redirect($url);
// 1.2 result:
/posts/view/123
// 1.3 result:
/posts/view/id:123
// correct format:
$url = array('controller' => 'posts', 'action' => 'view', $id);
// old format:$url = array('controller' => 'posts', 'action' => 'view', 'id' => $id);// use cases:Router::url($url);$html->link($url);$this->redirect($url);// 1.2 result:/posts/view/123// 1.3 result:/posts/view/id:123// correct format:$url = array('controller' => 'posts', 'action' => 'view', $id);
Dispatcher
Dispatcher is no longer capable of setting a
controller's layout/viewPath with request parameters. Control of
these properties should be handled by the Controller, not the
Dispatcher. This feature was also undocumented, and untested.
Debugger
Debugger::checkSessionKey()has been renamed toDebugger::checkSecurityKeys()- Calling
Debugger::output("text")no longer works. UseDebugger::output("txt").
Object
Object::$_loghas been removed.CakeLog::writeis now called statically. See New Logging features for more information on changes made to logging.
Sanitize
Sanitize::html()now actually always returns escaped strings. In the past using the$removeparameter would skip entity encoding, returning possibly dangerous content.Sanitize::clean()now has aremove_htmloption. This will trigger thestrip_tagsfeature ofSanitize::html(), and must be used in conjunction with theencodeparameter.
Configure and App
- Configure::listObjects() replaced by App::objects()
- Configure::corePaths() replaced by App::core()
- Configure::buildPaths() replaced by App::build()
- Configure no longer manages paths.
- Configure::write('modelPaths', array...) replaced by App::build(array('models' => array...))
- Configure::read('modelPaths') replaced by App::path('models')
- There is no longer a debug = 3. The controller dumps generated
by this setting often caused memory consumption issues making it an
impractical and unusable setting. The
$cakeDebugvariable has also been removed fromView::renderLayoutYou should remove this variable reference to avoid errors. Configure::load()can now load configuration files from plugins. UseConfigure::load('plugin.file');to load configuration files from plugins. Any configuration files in your application that use.in the name should be updated to use_
Cache
In addition to being able to load CacheEngines from app/libs or plugins, Cache underwent some refactoring for CakePHP1.3. These refactorings focused around reducing the number and frequency of method calls. The end result was a significant performance improvement with only a few minor API changes which are detailed below.
The changes in Cache removed the singletons used for each Engine
type, and instead an engine instance is made for each unique key
created with Cache::config(). Since engines are not
singletons anymore, Cache::engine() was not needed and
was removed. In addition Cache::isInitialized() now
checks cache configuration names, not cache engine
names. You can still use Cache::set() or
Cache::engine() to modify cache configurations. Also
checkout the New features
guide for more information on the additional methods added to
Cache.
It should be noted that using an app/libs or plugin cache engine
for the default cache config can cause performance issues as the
import that loads these classes will always be uncached. It is
recommended that you either use one of the core cache engines for
your default configuration, or manually include the
cache engine class before configuring it. Furthermore any non-core
cache engine configurations should be done in
app/config/bootstrap.php for the same reasons detailed
above.
# View and Helpers
View
View::renderElementremoved. UseView::element()instead.- Automagic support for
.thtmlview file extension has been removed either declare$this->ext = 'thtml';in your controllers, or rename your views to use.ctp View::set('title', $var)no longer sets$title_for_layoutwhen rendering the layout.$title_for_layoutis still populated by default. But if you want to customize it, use$this->set('title_for_layout', $var).View::$pageTitlehas been removed. Use$this->set('title_for_layout', $var);instead.- The
$cakeDebuglayout variable associated with debug = 3 has been removed. Remove it from your layouts as it will cause errors. Also see the notes related to SQL log dumping and Configure for more information.
All core helpers no longer use Helper::output().
The method was inconsistently used and caused output issues with
many of FormHelper's methods. If you previously overrode
AppHelper::output() to force helpers to auto-echo you
will need to update your view files to manually echo helper
output.
TextHelper
TextHelper::trim()is deprecated, usedtruncate()instead.TextHelper::highlight()no longer has:- an
$highlighterparameter. Use$options['format']instead. - an
$considerHtmlparameter. Use$options['html']instead. TextHelper::truncate()no longer has:- an
$endingparameter. Use$options['ending']instead. - an
$exactparameter. Use$options['exact']instead. - an
$considerHtmlparameter. Use$options['html']instead.
PaginatorHelper
PaginatorHelper has had a number of enhancements applied to make
styling easier.
prev(), next(), first() and
last()
The disabled state of these methods now defaults to
<span> tags instead of <div>
tags.
passedArgs are now auto merged with url options in paginator.
sort(), prev(), next()
now add additional class names to the generated html.
prev() adds a class of prev. next() adds
a class of next. sort() will add the direction
currently being sorted, either asc or desc.
FormHelper
FormHelper::dateTime()no longer has a$showEmptyparameter. Use$attributes['empty']instead.FormHelper::year()no longer has a$showEmptyparameter. Use$attributes['empty']instead.FormHelper::month()no longer has a$showEmptyparameter. Use$attributes['empty']instead.FormHelper::day()no longer has a$showEmptyparameter. Use$attributes['empty']instead.FormHelper::minute()no longer has a$showEmptyparameter. Use$attributes['empty']instead.FormHelper::meridian()no longer has a$showEmptyparameter. Use$attributes['empty']instead.FormHelper::select()no longer has a$showEmptyparameter. Use$attributes['empty']instead.- Default urls generated by form helper no longer contain 'id' parameter. This makes default urls more consistent with documented userland routes. Also enables reverse routing to work in a more intuitive fashion with default FormHelper urls.
FormHelper::submit()Can now create other types of inputs other than type=submit. Use the type option to control the type of input generated.FormHelper::button()Now creates<button>elements instead of reset or clear inputs. If you want to generate those types of inputs useFormHelper::submit()with a'type' => 'reset'option for example.FormHelper::secure()andFormHelper::create()no longer create hidden fieldset elements. Instead they create hidden div elements. This improves validation with HTML4.
Also be sure to check the Form helper improvements for additional changes and new features in the FormHelper.
HtmlHelper
HtmlHelper::meta()no longer has an$inlineparameter. It has been merged with the$optionsarray.HtmlHelper::link()no longer has an$escapeTitleparameter. Use$options['escape']instead.HtmlHelper::para()no longer has an$escapeparameter. Use$options['escape']instead.HtmlHelper::div()no longer has an$escapeparameter. Use$options['escape']instead.HtmlHelper::tag()no longer has an$escapeparameter. Use$options['escape']instead.HtmlHelper::css()no longer has an$inlineparameter. Use$options['inline']instead.
SessionHelper
flash()no longer auto echos. You must add anecho $session->flash();to your session->flash() calls. flash() was the only helper method that auto outputted, and was changed to create consistency in helper methods.
CacheHelper
CacheHelper's interactions with
Controller::$cacheAction has changed slightly. In the
past if you used an array for $cacheAction you were
required to use the routed url as the keys, this caused caching to
break whenever routes were changed. You also could set different
cache durations for different passed argument values, but not
different named parameters or query string parameters. Both of
these limitations/inconsistencies have been removed. You now use
the controller's action names as the keys for
$cacheAction. This makes configuring
$cacheAction easier as its no longer coupled to the
routing, and allows cacheAction to work with all custom routing. If
you need to have custom cache durations for specific argument sets
you will need to detect and update cacheAction in your
controller.
TimeHelper
TimeHelper has been refactored to make it more i18n friendly. Internally almost all calls to date() have been replaced by strftime(). The new method TimeHelper::i18nFormat() has been added and will take localization data from a LC_TIME locale definition file in app/locale following the POSIX standard. These are the changes made in the TimeHelper API:
- TimeHelper::format() can now take a time string as first parameter and a format string as the second one, the format must be using the strftime() style. When called with this parameter order it will try to automatically convert the date format into the preferred one for the current locale. It will also take parameters as in 1.2.x version to be backwards compatible, but in this case format string must be compatible with date().
- TimeHelper::i18nFormat() has been added
Deprecated Helpers
Both the JavascriptHelper and the AjaxHelper are deprecated, and the JsHelper + HtmlHelper should be used in their place.
You should replace
$javascript->link()with$html->script()-
$javascript->codeBlock()with$html->scriptBlock()or$html->scriptStart()and$html->scriptEnd()depending on your usage.
# Console and shells
Shell
Shell::getAdmin() has been moved up to
ProjectTask::getAdmin()
Schema shell
cake schema run createhas been renamed tocake schema createcake schema run updatehas been renamed tocake schema update
Console Error Handling
The shell dispatcher has been modified to exit with a
1 status code if the method called on the shell
explicitly returns false. Returning anything else
results in a 0 status code. Before the value returned
from the method was used directly as the status code for exiting
the shell.
Shell methods which are returning 1 to indicate an
error should be updated to return false instead.
Shell::error() has been modified to exit with
status code 1 after printing the error message which now uses a
slightly different formatting.
$this->error('Invalid Foo', 'Please provide bar.');
// outputs:
Error: Invalid Foo
Please provide bar.
// exits with status code 1
$this->error('Invalid Foo', 'Please provide bar.');// outputs:Error: Invalid FooPlease provide bar.// exits with status code 1
ShellDispatcher::stderr() has been modified to not
prepend Error: to the message anymore. It's signature is now
similar to Shell::stdout().
ShellDispatcher::shiftArgs()
The method has been modified to return the shifted argument. Before if no arguments were available the method was returning false, it now returns null. Before if arguments were available the method was returning true, it now returns the shifted argument instead.
