This large CakePHP 2.x reference page (cheat sheet) is something I use often and I hope it will be helpful to anybody developing with CakePHP. It is based on several CakePHP cheat sheets floating around on the Web: “A CakePHP Cheat Sheet”, which was originally published by Alvin Alexander. and then “A CakePHP 2.x Cheat Sheet” updated by Alberto Ponte. Since I am currently doing some development with CakePHP, I’ve been using it often. So, below is copy of the CakePHP Cheat Sheet!
CakePHP Default Directory Structure
This is what the CakePHP directory structure looks like by default:
/app /Config /Schema db_acl.php db_acl.sql i18n.php i18n.sql sessions.php sessions.sql acl.ini.php acl.php bootstrap.php core.php databases.php email.php routes.php /Controller /Component ErrorComponent.php YourComponentsHere.php AppController.php PagesController.php YourControllersGoHere.php /Lib /Locale /eng /LC_MESSAGES cake.pot cake_dev.pot default.pot /Model /Behavior YourBehaviorsHere.php /Datasource YourDatasourceHere.php YourModelsHere.php /Plugin /Test /Case /Controller /Component /Model /Behavior /View /Helper /Fixture /Vendor /View /Elements auth_error.ctp breadcrumb.ctp flash_fail.ctp flash_success.ctp your_elements_here.ctp /Emails /html default.ctp your_emails_here.ctp /text default.ctp your_emails_here.ctp /Errors error400.ctp error500.ctp your_errors_here.ctp /Helper AppHelper.ctp /Layouts /Emails /html default.ctp your_email_layouts_here.ctp /text default.ctp your_email_layouts_here.ctp /js default.ctp /rss default.ctp /xml default.ctp ajax.ctp default.ctp flash.ctp your_layouts_here.ctp /Pages home.ctp your_pages_here.ctp /Scaffolds /console /Command /Task AppShell.php /Templates cake cake.bat cake.php /tmp /cache /models /persistent /views /logs /sessions /tests /webroot /css /files /img /js /lib /Cake <span style="color:red;"><i class="icon-check"></i> All CakePHP 2.x Delivered Files are Here</span> /plugins /vendors
CakePHP Naming Conventions
There is a website that has the CakePHP 2.x Inflector up for public use. I used it all the time when I was new with CakePHP – you can find the CakePHP 2.x Inflector online here!
This is a list of the CakePHP naming conventions, specifically the CakePHP Model, View, and Controller naming conventions.
CakePHP Models
- class names are singular
- class names UpperCamelCased
- file names are UpperCamelCased
- database tables are plural underscored
- set var $name in your model definition (PHP4)
CakePHP Controllers
- class names are plural
- class names are UpperCamelCased
- class names also end with ‘Controller’
- file names are UpperCamelCased
- file names also end with ‘Controller.php’.
CakePHP Views
- views are in folders that match controller
- view folders are plural
- view folders are UpperCamelCased
- views are named after their corresponding actions {controller methods}
- file names are lowercased
CakePHP naming conventions – Examples
Assuming we have a database table named orders, the following standard CakePHP naming conventions should be used:
Model filename = Order.php classname = Order directory = app/Model View filename = (same as the action {class method} name in the controller) extension = .ctp (the filename extension) directory = app/View/Orders Controller filename = OrdersController.php classname = OrdersController directory = app/Controller
Assuming we have a database table named order_items, the following standard CakePHP naming conventions should be used:
Model filename = OrderItem.php classname = OrderItem directory = app/Model View filename = (same as the action {class method} name in the controller) extension = .ctp (the filename extension) directory = app/View/OrderItems Controller filename = OrderItemsController.php classname = OrderItemsController directory = app/Controller
CakePHP bake Command Examples
Here are some CakePHP bake examples (cake bake examples):
cake bake cake bake controller cake bake model cake bake view cake bake project
CakePHP Foreign Key Examples and Relationship Types
From the CakePHP Cookbook, there are four possible CakePHP relationship types:
<strong>Relationship</strong> <strong>Association Type</strong> <strong> Example</strong> one to one hasOne A user has one profile. one to many hasMany A user can have multiple recipes. many to one belongsTo Many recipes belong to a user. many to many hasAndBelongsToMany Recipes have, and belong to many tags.
Further details on these relationships can be found at the CakePHP Cookbook pages:
- hasOne relationship
- belongsTo relationship
- hasMany relationship
- hasAndBelongsToMany (HABTM) relationship
CakePHP relationship type examples:
# in a Post model class: # each Post belongs to a User var $belongsTo = array('User'); # TODO var $hasOne ... # in the User model var $hasMany = array('Post'); # TODO var $hasAndBelongsToMany
The CakePHP recursive attribute
The CakePHP recursive attribute affects how CakePHP retrieves data, in particular when there are associations between database tables. (I normally indicate these associations with foreign key relationships, but I’ve also seen applications not indicate foreign key relationships in the database, but just deal with them in the software that is written.)
For instance, the CakePHP Cookbook includes an example of a blog tutorial, and this database is built upon in the excellent book, Beginning CakePHP: From Novice to Professional. In this book, blog “posts” are associated with “tags” and “users”. As the author of the book explains, when a Post model runs a query that pulls posts from the database, it will (may) also retrieve associated rows from the tags and users database tables. This is where the CakePHP recursive attribute comes in:
The CakePHP recursive attribute tells the model how far to look when pulling associated rows.
The CakePHP recursive attribute can be set to the following integer values, with the following meanings:
<strong>Value</strong> <strong>Meaning</strong> -1 returns only the current model, and ignores all associations. 0 returns the current model, plus its owner(s). 1 returns the current model, its owner(s), plus their associated models. 2 returns the current model, its owner(s), their associated models, and the associated models of any associations.
In a simple controller index() method, the recursive attribute may be used like this:
function index() { $this->Post->recursive = 0; $this->set('posts', $this->paginate); }
TODO – add other recursive examples here
CakePHP find Conditions
One of the things you have to get used to when working with CakePHP is the CakePHP find method. This is a collection of CakePHP find examples.
First, a list of possible CakePHP find query parameters:
<strong>Name</strong> <strong>Default</strong> <strong>Description</strong> type 'first' can be 'all', 'first', or 'list'. determines what type of find operation to perform. (TODO - more info here) conditions null array containing the find (select) conditions as key/value pairs fields null array specifying which fields should be retrieved in the resulting select query order null sql 'order by conditions. field name must be followed by ASC or DESC page null page number, used for paged data limit null a limit on the number of results returned, like 'select * from orders limit 20'. offset null sql offset value (i haven't used this query much myself, but i think it refers to skipping X number of rows returned in a query) recursive 1 the cakephp recursive value, relating to associated model data
Next, a very simple CakePHP find query that retrieves all records from the Post model (probably not something you’ll want to do in a production application):
$this->Post->find('all');
A CakePHP find query with one condition:
$this->Post->find('all', array('conditions'=>array('User.id'=>5)));
A CakePHP find query with one “not equal to” condition:
$this->Post->find('all', array('conditions'=>array('User.id'=>'<> 5')));
A CakePHP find query with multiple conditions:
# this is a little lame, but i'm trying to avoid dates $this->Post->find('all', array('conditions'=>array('User.id'=>1, 'Post.id'=>'> 50')));
A CakePHP find query that uses all the find function parameters:
<strong>NOTE: Both 'fields' and 'order', shown below, can be arrays as well.</strong> $this->Post->find('all', array('conditions'=>array('User.id'=>5), 'fields'=>'Post.name', 'order'=>'Post.id ASC', 'limit'=>20, 'recursive'=>0));
A CakePHP find query using a date:
# note: you can search for date or datetime fields by enclosing the table's field name # in the SQL DATE() function. $this->Post->find('all', array('conditions'=>array('User.id'=>5, 'DATE(Post.date)'=>'CURDATE()'))); # TODO demonstrate "date >" and "date <" conditions
CakePHP find queries with ORDER BY examples:
array('order'=>'date ASC') array('order'=>'date DESC') array('order'=>'User.id DESC')
A collection of other CakePHP find query examples:
These CakePHP find examples are lines of code that would be used in an OrderController class: $this->Order->find('all'); $this->Order->find(null, null, 'date DESC'); $this->Order->find('all', array('conditions'=>array('User.id'=>1))); $this->Order->find('all', array('conditions'=>array('User.id'=>array(1,2,3,4)))); $this->Order->find('all', array('conditions'=>array('User.id'=>'<> 1'))); $this->Order->find('all', array('conditions'=>array('User.id'=>1, 'DATE(Post.date)'=>'CURDATE()'))); $this->Order->find('all', array('order'=>'date ASC', 'limit'=>20, 'recursive'=>0);
Here are some CakePHP find examples from the CakePHP retrieving your data book page:
$params can contain all these: array( 'conditions' => array('Model.field' => $thisValue), //array of conditions 'recursive' => 1, //int 'fields' => array('Model.field1', 'DISTINCT Model.field2'), //array of field names 'order' => array('Model.created', 'Model.field3 DESC'), //string or array defining order 'group' => array('Model.field'), //fields to GROUP BY 'limit' => n, //int 'page' => n, //int 'offset'=>n, //int 'callbacks' => true //other possible values are false, 'before', 'after' )
Here’s a CakePHP function showing several different CakePHP find examples:
# find('first', $params) syntax function some_function() { ... $this->Article->order = null; // resetting if it's set $semiRandomArticle = $this->Article->find(); $this->Article->order = 'Article.created DESC'; // simulating the model having a default order $lastCreated = $this->Article->find(); $alsoLastCreated = $this->Article->find('first', array('order' => array('Article.created DESC'))); $specificallyThisOne = $this->Article->find('first', array('conditions' => array('Article.id' => 1))); ... }
Here’s a CakePHP find count example:
# find('count', $params) function some_function() { ... $total = $this->Article->find('count'); $pending = $this->Article->find('count', array('conditions' => array('Article.status' => 'pending'))); $authors = $this->Article->User->find('count'); $publishedAuthors = $this->Article->find('count', array( 'fields' => 'DISTINCT Article.user_id', 'conditions' => array('Article.status !=' => 'pending') )); ... }
Some CakePHP find all examples:
# find('all', $params) syntax function some_function() { ... $allArticles = $this->Article->find('all'); $pending = $this->Article->find('all', array('conditions' => array('Article.status' => 'pending'))); $allAuthors = $this->Article->User->find('all'); $allPublishedAuthors = $this->Article->User->find('all', array('conditions' => array('Article.status !=' => 'pending'))); ... }
CakePHP find list examples, useful for creating select boxes:
# find('list', $params) syntax function some_function() { ... $allArticles = $this->Article->find('list'); $pending = $this->Article->find('list', array( 'conditions' => array('Article.status' => 'pending') )); $allAuthors = $this->Article->User->find('list'); $allPublishedAuthors = $this->Article->find('list', array( 'fields' => array('User.id', 'User.name'), 'conditions' => array('Article.status !=' => 'pending'), 'recursive' => 0 )); ... }
See the CakePHP 2.x retrieving your data book page for many more CakePHP find examples, including:
- find threaded
- find neighbors
- findAllBy
- findBy
- query
- field
- read
- More complex CakePHP find examples
CakePHP paginate Examples
Another important CakePHP method to know is the CakePHP paginate method. Here is a collection of CakePHP paginate examples.
A basic CakePHP paginate method in a controller: function index() { $this->Order->recursive = 0; $this->set('orders', $this->paginate()); }
You can also control CakePHP pagination with the CakePHP paginate variable in your CakePHP controllers, like this:
class RecipesController extends AppController { var $paginate = array( 'limit' => 25, 'order' => array( 'Post.title' => 'asc' ) ); }
or this:
class RecipesController extends AppController { var $paginate = array( 'fields' => array('Post.id', 'Post.created'), 'limit' => 25, 'order' => array( 'Post.title' => 'asc' ) ); }
For more information on CakePHP pagination, see the CakePHP 2.x pagination book page.
CakePHP logging
You can write to CakePHP log files using the CakeLog::write method:
CakeLog::write('debug', 'Something did not work');
Or you can use the CakePHP log function in any class that extends the CakePHP Object class:
$this->log("Something did not work!", 'debug');
You can also perform CakePHP error logging like this:
Configure::write('log', E_WARNING);
CakePHP Global Methods
These are names of some globally available CakePHP methods (assuming you extend the CakePHP Object class):
config uses vendor debug - use like <? debug($order); ?> in a view a aa am e - shortcut for echo() env ife low up r pr - shortcut for print_r() stripslashes_deep
CakePHP Global Constants
This is a list of CakePHP global constants. You can find the official list of CakePHP 2.x Global Constants and Functions here with definitions.
ACL_CLASSNAME ACL_FILENAME APP APP_DIR APP_PATH AUTO_SESSION CACHE CACHE_CHECK CAKE CAKE_CORE_INCLUDE_PATH CAKE_SECURITY CAKE_SESSION_COOKIE CAKE_SESSION_SAVE CAKE_SESSION_STRING CAKE_SESSION_TABLE CAKE_SESSION_TIMEOUT COMPONENTS COMPRESS_CSS CONFIGS CONTROLLER_TESTS CONTROLLERS CORE_PATH CSS DATASOURCE DAY DEBUG DS ELEMENTS HELPER_TESTS HELPERS HOUR INFLECTIONS JS LAYOUTS LIB_TESTS LIBS LOG_ERROR LOGS MAX_MD5SIZE MINUTE MODEL_TESTS MODELS MODULES MONTH ROOT SCRIPTS SECOND TAG_DIV TAG_FIELDSET TAG_LABEL TAG_P_CLASS TESTS TMP VENDORS VIEWS WEBROOT_DIR WEBSERVICES WEEK WWW_ROOT YEAR
CakePHP Controller properties, methods, callbacks
CakePHP controller properties:
$name = null $action = null $autoLayout = true $autoRender = true $base = null $beforeFilter = null $cacheAction = false $components = array() $data = array() $helpers = array('Html') $here = null $layout = 'default' $output = null $pageTitle = false $params = array() $persistModel = false $plugin = null $uses = false $view = 'View' $viewPath = null $webroot = null $_viewClass = null $_viewVars = array()
CakePHP controller methods
cleanUpFields () constructClasses () flash ($message, $url, $pause = 1) flashOut ($message, $url, $pause = 1) generateFieldNames ($data = null, $doCreateOptions = true) postConditions ($data, $operator = '', $bool = 'AND', $exclusive = false) redirect ($url, $status = null) referer ($default = null, $local = false) render ($action = null, $layout = null, $file = null) set ($one, $two = null) setAction ($action) validate () validateErrors ()
CakePHP controller callbacks
afterFilter () beforeFilter () beforeRender ()
CakePHP Model properties, methods, callbacks, and validation
CakePHP Model properties:
$belongsTo = array() $cacheQueries = true $data = array() $displayField = null $hasAndBelongsToMany = array() $hasMany = array() $hasOne = array() $id = false $logTransactions = false $name = null $primaryKey = null $recursive = 1 $useDbConfig = 'default' $useTable = null $validate = array() $validationErrors = array()
CakePHP Model methods:
bindModel ($params) create () delete ($id = null, $cascade = true) escapeField ($field) execute ($data) exists () field ($name, $conditions = null, $order = null) find ($conditions = null, $fields = null, $order = null, $recursive = null) findAll ($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) findAllThreaded ($conditions = null, $fields = null, $sort = null) findCount ($conditions = null, $recursive = 0) findNeighbours ($conditions = null, $field, $value) generateList ($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) getAffectedRows () getColumnType ($column) getColumnTypes () getDisplayField () getID ($list=0) getLastInsertID () getNumRows () hasAny ($conditions = null) hasField ($name) invalidate ($field) invalidFields ($data = array()) isForeignKey ($field) loadInfo () query () read ($fields = null, $id = null) remove ($id = null, $cascade = true) save ($data = null, $validate = true, $fieldList = array()) saveField ($name, $value, $validate = false) set ($one, $two = null) setDataSource ($dataSource = null) setSource ($tableName) unbindModel ($params) validates ($data=array()) setSource ($tableName)
CakePHP Model callbacks
afterDelete () afterFind ($results) afterSave () beforeDelete () beforeFind (&$queryData) beforeSave () beforeValidate ()
CakePHP Model validation
'VALID_EMAIL` 'VALID_NOT_EMPTY` 'VALID_NUMBER` 'VALID_YEAR`
CakePHP View properties and methods
CakePHP View properties
$action = null $autoLayout = true $autoRender = true $base = null $controller = null $ext = '.thtml' $hasRendered = null $helpers = array('Html') $here = null $layout = 'default' $loaded = array() $models = array() $name = null $pageTitle = false $params $parent = null $plugin = null $subDir = null $themeWeb = null $uses = false $viewPath
CakePHP View methods
element ($name) error ($code, $name, $message) pluginView ($action, $layout) render ($action = null, $layout = null, $file = null) renderCache ($filename, $timeStart) renderElement ($name, $params = array()) renderLayout ($content_for_layout) setLayout ($layout)
CakePHP Helpers
CakePHP Html Helper
addCrumb ($name, $link) charset ($charset, $return = false) checkbox ($fieldName, $title = null, $htmlAttributes = null, $return = false) css ($path, $rel = 'stylesheet', $htmlAttributes = null, $return = false) dateTimeOptionTag ($tagName, $dateFormat = 'DMY', $timeFormat = '12', $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) dayOptionTag ($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) file ($fieldName, $htmlAttributes = null, $return = false) formTag ($target = null, $type = 'post', $htmlAttributes = null) getCrumbs ($separator = '»', $startText = false, $return = false) guiListTree ($data, $htmlAttributes = null, $bodyKey = 'body', $childrenKey = 'children', $return = false) hidden ($fieldName, $htmlAttributes = null, $return = false) hourOptionTag ($tagName, $value = null, $format24Hours = false, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) image ($path, $htmlAttributes = null, $return = false) input ($fieldName, $htmlAttributes = null, $return = false) link ($title, $url = null, $htmlAttributes = null, $confirmMessage = false, $escapeTitle = true, $return = false) linkEmail ($title, $email = null, $options = null) meridianOptionTag ($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) minuteOptionTag ($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) monthOptionTag ($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) parseHtmlOptions ($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) password ($fieldName, $htmlAttributes = null, $return = false) radio ($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) selectTag ($fieldName, $optionElements, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true, $return = false) setFormTag ($tagValue) submit ($caption = 'Submit', $htmlAttributes = null, $return = false) tableCells ($data, $oddTrOptions = null, $evenTrOptions = null, $return = false) tableHeaders ($names, $trOptions = null, $thOptions = null, $return = false) tagErrorMsg ($field, $text) tagIsInvalid ($model, $field) tagValue ($fieldName) textarea ($fieldName, $htmlAttributes = null, $return = false) trim () url ($url = null, $return = false) validate () validateErrors () yearOptionTag ($tagName, $value = null, $minYear = null, $maxYear = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) _parseAttributes ($options, $exclude = null, $insertBefore = ' ', $insertAfter = null)
CakePHP Form Helper
button ($params, $type= 'button', $options=array()) create ($model=null, $options=array()) dateTime ($tagName, $dateFormat= 'DMY', $timeFormat= '12', $selected=null, $attributes=array(), $showEmpty=true) day ($fieldName, $selected=null, $attributes=array(), $showEmpty=true) end ($options=null) error ($field, $text=null, $options=array()) file ($fieldName, $options=array()) hidden ($fieldName, $options=array()) hour ($tagName, $format24Hours=false, $selected=null, $attributes=array(), $showEmpty=true) input ($tagName, $options=array()) inputs ($fields=null, $blacklist=null) isFieldError ($field) label ($tagName=null, $text=null, $attributes=array()) meridian ($tagName, $selected=null, $attributes=array(), $showEmpty=true) minute ($tagName, $selected=null, $attributes=array(), $showEmpty=true) month ($tagName, $selected=null, $attributes=array(), $showEmpty=true) password ($fieldName, $options=array()) secure ($fields) select ($fieldName, $options=array(), $selected=null, $attributes=array(), $showEmpty= '') submit ($caption= 'Submit', $options=array()) submitImage ($path, $options=array()) text ($fieldName, $options=array()) textarea ($fieldName, $options=array()) year ($fieldName, $minYear=null, $maxYear=null, $selected=null, $attributes=array(), $showEmpty=true)
CakePHP Ajax Helper
autoComplete ($field, $url="", $options=array()) div ($id, $options=array()) divEnd ($id) drag ($id, $options=array()) drop ($id, $options=array()) dropRemote ($id, $options=array(), $ajaxOptions=array()) editor ($id, $url, $options=array()) form ($params=null, $type= 'post', $options=array()) isAjax () link ($title, $href=null, $options=array(), $confirm=null, $escapeTitle=true) observeField ($field_id, $options=array()) observeForm ($field_id, $options=array()) remoteFunction ($options=null) remoteTimer ($options=null) slider ($id, $track_id, $options=array()) sortable ($id, $options=array()) submit ($title= 'Submit', $options=array())
CakePHP Text Helper
highlight ($text, $phrase, $highlighter= '< span class="highlight">\1</span >') stripLinks ($text) autoLinkUrls ($text, $htmlOptions = array()) autoLinkEmails ($text, $htmlOptions = array()) autoLink ($text, $htmlOptions = array()) truncate ($text, $length, $ending = '...', $exact = true) trim () excerpt ($text, $phrase, $radius = 100, $ending = "...") flay ($text, $allowHtml = false)
CakePHP Time Helper
dayAsSql ($date_string, $field_name, $return = false) daysAsSql ($begin, $end, $field_name, $return = false) fromString ($date_string) isThisYear ($date_string, $return = false) isToday ($date_string, $return = false) isTomorrow ($date_string, $return = false) nice ($date_string=null, $return = false) niceShort ($date_string=null, $return = false) relativeTime ($datetime_string, $format = 'j/n/y', $return = false) timeAgoInWords ($datetime_string, $format = 'j/n/y', $backwards = false, $return = false) toAtom ($date_string, $return = false) toRSS ($date_string, $return = false) toUnix ($date_string, $return = false) trim ($string, $length, $ending = '..') wasWithinLast ($timeInterval, $date_string, $return = false) wasYesterday ($date_string, $return = false)
CakePHP Number Helper
precision ($number, $precision = 3) toReadableSize ($size) toPercentage ($number, $precision = 2)
CakePHP Components
CakePHP Session Component
check ($name) del ($name) delete ($name) error () flash ($key) read ($name) renew () setFlash ($flashMessage, $layout = 'default', $param = null, $key = 'flash') valid () write($name, $value)
CakePHP RequestHandler Component
accepts ($types) getAjaxVersion () getClientIP () getReferer () isAjax () isAtom () isDelete () isGet () isMobile () isPost () isPut () isRss () isXml () setContent ($name, $type) stripAll ($string) stripImages ($string) stripScripts ($string)
CakePHP Security Component
requirePost ([$action1, $ action2, $action3, ...]) requireAuth ([$action1, $ action2, $action3, ...])
CakePHP ACL Component
check ($aro, $aco, $action="*") allow ($aro, $aco, $action="*") deny ($aro, $aco, $action="*") inherit ($aro, $aco, $action="*") grant ($aro, $aco, $action="*") revoke ($aro, $aco, $action="*") getAro ($id) getAco ($id)
CakePHP SQL Debug
To add CakePHP SQL debug output in CakePHP 1.3, change the CakePHP debug config parameter to ‘2’ in this line of the $app/config/core.php file:
Configure::write('debug', 2);
Then add this line to the bottom of your CakePHP view page:
echo $this->element('sql_dump');
CakePHP API Documentation
Links to some of the most important (common) CakePHP classes:
- The CakePHP API docs (main page)
- CakePHP Model class
- CakePHP Model::find
- CakePHP Controller class
- CakePHP String class
- CakePHP Validation class
- CakePHP AuthComponent
- NumberHelper
- TimeHelper
CakePHP support URLs
Here is a list of CakePHP support URLs:
- The main CakePHP website (cakephp.org)
- The CakePHP Bakery
- The CakePHP Cookbook
- CakePHP Google discussion group
As usual, great post, mifty