Welcome Guest, Not a member yet? Register   Sign In
MPTT - get_siblings
#1

[eluser]TheFuzzy0ne[/eluser]
Does anyone know the algorithm to obtaining all nodes at the same level as the specified node? I need the ability to move a node up or down in the tree within the confines of the parent node, and I just can't seem to figure it out.

Thanks in advance.
#2

[eluser]pistolPete[/eluser]
I use those two functions to get the next respectively the previous sibling of a given node, hope this helps:

Code:
function get_next_node($lft)
{
        $node = $this->mpttree->get_node($lft);
        $parent = $this->mpttree->get_parent($node['lft'], $node['rgt']);
        
        // is last node
        if ( ( $node['rgt'] + 1 ) ==  $parent['rgt'])
        {
            return FALSE;
        }
        
        return $this->mpttree->get_node($node['rgt'] + 1);
}
    
public function get_prev_node($lft)
{
        $node = $this->mpttree->get_node($lft);
        $parent = $this->mpttree->get_parent($node['lft'], $node['rgt']);
        
        // is first node
        if ( ( $node['lft'] - 1 ) == $parent['lft'])
        {
            return FALSE;
        }
        
        return $this->mpttree->get_node($node['lft'] - 2);
}
#3

[eluser]TheFuzzy0ne[/eluser]
You're a star! Thanks, Pete!

I knew I needed to get the parent node, but then I was going to start messing about with the get_children array, but clearly I don't need to.

Thanks again, Pete!
#4

[eluser]TheFuzzy0ne[/eluser]
Ugh, does anyone know of a way to achieve the above but in a fashion that works even when the node contains child nodes? I can't see it happening without more database queries. I was thinking of just parsing the results of the tree2array method.
#5

[eluser]Gaz[/eluser]
*bump*

I've got the same issue. I'd like to move a node with children up or down the tree, and move all the child nodes with it.

Cheers,
Gaz.
#6

[eluser]TheFuzzy0ne[/eluser]
I've been thinking about just loading the entire tree into an array, and having a library to work out things such as next sibling, previous sibling and so on. How big is your tree? Obviously, if it's massive, then loading the entire tree is not a good idea, but I'd imagine that with a small forum structure it might work well. Just my 2 pence. I haven't tested it yet, but it was the best idea I could come up with.

Another method might be to store the parent ID in the table, so you can then just select the row with the same parent value and the lowest/highest lft value.
#7

[eluser]theprodigy[/eluser]
Pardon my ignorance, but what is MPTT?
#8

[eluser]TheFuzzy0ne[/eluser]
[url="http://en.wikipedia.org/wiki/Tree_traversal"]Modified Preorder Tree Traversal[/url]
#9

[eluser]Gaz[/eluser]
That's not a bad idea.

Just get the parent node, get the tree with

Code:
$parent_node = $this->mptt->get_parent($node['lft']);
$tree = tree2array($parent_node['lft']);

walk the array until you find the node before / after the one you want to move, then use

Code:
$this->mptt->move_node($node['lft'], $prev_next_node['lft']);

to move it.
#10

[eluser]Gaz[/eluser]
OK, this works

Code:
function move_up($id) {
        $move_to_child = null;
        $node = $this->mptt->get_node_byid($id);
        $parent_node = $this->mptt->get_parent($node['lft'], $node['rgt']);
        $tree = $this->mptt->tree2array($parent_node['lft']);
        
        if(isset($tree[0]['children'])) {
            $children = $tree[0]['children'];

            foreach($children as $k=>$v) {
                if($v['id'] == $id) {
                    if($k-1 >= 0) {
                        $move_to_child = $children[$k-1];
                        continue;
                    }
                }
            }
        }

        if($move_to_child) {
            $move_to_lft = $move_to_child['lft'];
            $this->mptt->move_node_before($node['lft'], $move_to_child['lft']);
        }
    }

    function move_down($id) {
        $move_to_child = null;
        $node = $this->mptt->get_node_byid($id);
        $parent_node = $this->mptt->get_parent($node['lft'], $node['rgt']);
        $tree = $this->mptt->tree2array($parent_node['lft']);
        
        if(isset($tree[0]['children'])) {
            $children = $tree[0]['children'];

            foreach($children as $k=>$v) {
                if($v['id'] == $id) {
                    if($k < count($children)-1) {
                        $move_to_child = $children[$k+1];
                        continue;
                    }
                }
            }
        }

        if($move_to_child) {
            $move_to_lft = $move_to_child['lft'];
            $this->mptt->move_node_after($node['lft'], $move_to_child['lft']);
        }
    }




Theme © iAndrew 2016 - Forum software by © MyBB