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


(1 votes, average: 4.00 out of 5)
7 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.
November 17th, 2010
1:53 pm
Hi,
and first of all thanks for posting your work, it’s been really useful!
about the code HabtmCounterCache behaviour on github (https://gist.github.com/235652/d196add592288c8ce5d4bd9edf9b19c89bc6fee7).
I fixed one infinite loop that was happening in my app.
I post here it for if someone has the same problem….
on line 357:
$model->{$habtmAlias}->save(array(
$habtmAlias => array(
‘id’ => $habtmId,
$settings['counterCache'] => $count,
),
));
was creating an infinite loop in my app. using cake 3.5
if someone has the same problem can fix it changing it for this:
$model->{$habtmAlias}->id = $habtmId;
$model->{$habtmAlias}->saveField($settings['counterCache'], $count, array(
‘validate’ => false,
‘callbacks’ => false
));
July 23rd, 2011
3:54 pm
[...] each node in the tree. Packaged as a plugin with a fixture and unit tests with 100% code coverage. 6 Comments Filed under: CakePHP (1 votes, average: 4.00 out of 5, [...]
Leave a comment