CakePHP: легко копировать / глубоко копировать древовидную структуру? - PullRequest
0 голосов
/ 20 июля 2010

Мне интересно, есть ли простой способ сделать копию древовидной структуры, которая состоит из одной модели с parent_id, который действует как дерево?

Я думал, что должно быть легко рекурсивно пройти через данное дерево, удалить все идентификаторы и левые, правые поля; однако, как я добавляю новые поля parent_id не будет соответствовать правильно. Я полагаю, что было бы достаточно легко написать свою собственную функцию, чтобы справиться с этим, но я просто хотел знать, есть ли уже что-то, чтобы справиться с этим?

Спасибо !!

1 Ответ

1 голос
/ 21 июля 2010

Во-первых, я использовал Multi Tree Behavior (http://bakery.cakephp.org/articles/view/multitree-behavior), поскольку он позволяет управлять несколькими деревьями в одной таблице.

Мои примеры, возможно, немного сложны и перепутаны с кодом приложенияно я уверен, что вы можете пройти через это!

Почти все, что вы делаете с деревом, будет нуждаться в рекурсивном "обходчике дерева".Я написал диспетчер задач с подзадачами и т. Д., И это пример метода, который я использовал для обхода дерева:

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;
}

В моем приложении есть «хранилище» общих задач, которые можно клонировать впроект.Базовая модель - ProjectTask [1: 1] ProjectTaskDescriptor - дескриптор, содержащий данные, и задача, содержащая позицию дерева.Я использую этот метод для обхода и клонирования деревьев и / или ветвей

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);
        }
    }
}

Это является очень практичным процессом, и с точки зрения будущего понимания и обслуживания кода он полностью оправданпонимание происходящего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...