CakePHP TreeCounterCacheBehavior plugin
An extension to CakePHP’s core TreeBehavior that provides counterCache functionality for all children and/or direct children of each node in the tree. Packaged as a plugin with a fixture and unit tests with 100% code coverage.
Usage
- Install the plugin from my github account in your APP/plugins directory.
- Add `child_count` and/or `direct_child_count` integer fields to your database table (you can configure the field names in the settings when you attach the behavior to the model).
- Attach the TreeCounterCache Behavior to your model:
class MyTreeModel extends AppModel {
var $name = 'MyTreeModel';
var $actsAs = array('TreeCounterCache.TreeCounterCache');
}
?>
Why?
Useful if you ever need to know whether a node has child nodes, e.g. for adding a CSS class to alter the style of that node to indicate to the user there is something beneath it. Caching the count saves extra db queries. To be honest, it’s not that great really is it? Still, might be useful to someone.
Todo
- Add counterScope functionality
Filed under: CakePHP


5 Responses so far
January 11th, 2010
8:06 pm
[...] Neil Crookes » CakePHP TreeCounterCacheBehavior plugin [...]
January 15th, 2010
11:27 pm
You could also use some quick math to find out how many children the node has based on the left and right values:
$numberOfTotalChildren = ($result[$model][$right] – $result[$model][$left] – 1) / 2;
January 16th, 2010
9:24 am
@Ryan, you are absolutely right…
From twitter:
@AD7six: why have a (total)child_count field at all. no-of-children = (rght – lft -1)/2 .
@neilcrookes: ah, I remember now, it’s for when I add scope functionality
@neilcrookes: when I say remember, I mean, that’s the excuse I just came up with for being too dumb to realise no-of-children = (rght – lft -1)/2
February 21st, 2010
1:10 pm
Hi!
I have seen your HabtmCounterCache behaviour on github (https://gist.github.com/235652/d196add592288c8ce5d4bd9edf9b19c89bc6fee7).
I think there are some bugs in that code:
Line 246
$model->data[$habtmAlias][$habtmAlias] may be empty what causes warning on array_merge in the line 258. You should test for empty value in the line 246:
if (!isset($model->data[$habtmAlias][$habtmAlias]) || empty($model->data[$habtmAlias][$habtmAlias])) {
Line 357
By default, save method check for validation rules. But in line 357 we only want to save/update some model fields, so we should disable validation:
$model->{$habtmAlias}->save(array(
$habtmAlias => array(
‘id’ => $habtmId,
$settings['counterCache'] => $count,
),
),
false
);
Hope this helps.
Thanks for sharing your code!
February 21st, 2010
9:29 pm
@Jesús, thanks for the comment. I’ll check out your issues.
Leave a comment