RSS

Neil Crookes

Learnings and Teachings on Web Application Development & CakePHP

Jan

9

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.

Share and Enjoy:

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot

Usage

  1. Install the plugin from my github account in your APP/plugins directory.
  2. 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).
  3. 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
Share and Enjoy:

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot

Be the first to rate this post
Loading ... Loading ...

5 Responses so far

[...] Neil Crookes » CakePHP TreeCounterCacheBehavior plugin [...]

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;

@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

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!

@Jesús, thanks for the comment. I’ll check out your issues.

Leave a comment