First, I used Multi Tree Behaviour ( http://bakery.cakephp.org/articles/view/multitree-behavior ) as it allows several trees to be managed in one table.
My examples are perhaps a little complex and confused with application specific code, but I'm sure you can pick your way through it!
Pretty much anything you do with the tree is going to need a recursive 'tree-walker'. I wrote a task manager with sub-tasks etc. and this is an example of a method I used to walk the tree:
function _walkTasksTree($nodes, $model='Task')
{
foreach($nodes as $node)
{
$task = $node[$model];
$id = $task['id'];
$title = $task['name'];
$level = $task['level'];
$children = $this->_walkTasksTree($node['children'],$model);
if(empty($children))
{
$data[$id] = array('level'=>$level,'title'=>$title);
}
else
{
$data[$id] = array('level'=>$level,'title'=>$title,'children' => $children);
}
}
$data = (isset($data))?$data:array();
return $data;
}
My application has a 'repository' of common tasks which can be cloned into a project. The basic model is ProjectTask [1:1] ProjectTaskDescriptor - the descriptor holding the data, and the task holding the tree position. I use this method to traverse and clone trees and/or branches
function _saveTaskTree($subTasks,$parent_id,$root_id,$projId,$exclude=null)
{
foreach($subTasks as $node)
{
if(@$exclude!=$node['Task']['id'])
{
$node['Task']['id'] = null;
$node['Task']['root_id'] = $root_id;
$node['Task']['parent_id'] = $parent_id;
$node['Task']['project_id'] = $projId;
$this->ProjectTask->create();
$saved = $this->ProjectTask->save($node['Task']);
$this->ProjectTaskDescriptor->create();
$PTD = $node['TaskDescriptor'];
$PTD['project_task_id'] = $this->ProjectTask->id;
$this->ProjectTaskDescriptor->save($PTD);
}
else
{
$saved = true; //skip the first one - we've already done it.
}
if($saved)
{
if(@$node['children'])
$children = $this->_saveTaskTree($node['children'],$this->ProjectTask->id,$root_id,$projId);
}
}
}
It is a very hands on process and in terms of future understanding and maintenance of the code it is worthwhile fully understanding what is going on.