CakePHP:轻松复制/深度复制树结构?

发布于 2024-09-10 08:40:29 字数 189 浏览 0 评论 0原文

我想知道是否有一种简单的方法来制作由一个模型组成的树结构的副本,该模型具有充当树的parent_id?

我在想应该很容易递归地遍历给定的树,删除所有 ids 和左、右字段;但是,当我添加新字段时,parent_id 将无法正确匹配。我想编写自己的函数来处理这个问题应该很容易,但我只是想知道是否已经有东西可以处理这个问题?

谢谢!!

I am wondering is there an easy way to make a copy of a tree structure that consists of one model with a parent_id that actsAs a tree?

I was thinking it should be easy to recursively go through a given tree, remove all ids and lft, rght fields; however, as I add the new fields parent_id won't match up correctly. I suppose it should be easy enough to write my own function to handle this, but I just wanted to know if there was already something to handle this?

Thanks!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不离久伴 2024-09-17 08:40:29

首先,我使用了多树行为( 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);
        }
    }
}

这是一个非常实用的过程,就未来对代码的理解和维护而言,完全理解正在发生的事情是值得的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文