mmmm
mmmm

Reputation: 3938

Doctrine Tree getting disorganized after changing child position

When I create three-levels nested tree ( with only three entities ) that looks like this:

1 (lft 1, rgt:6)
 -2 (lft 2, rgt:5)
   -3 (lft 3, rgt:4)

and then I try to move node ( with id=3, i.e. ) from the third level to the second level as, let's say second child with this piece of code:

/* this line can be commented - it doesn't work with it either */ $chapter->setParent($parentEntity);
$repo->persistAsFirstChildOf($chapter, $parentEntity);
$repo->moveDown($chapter, 1);

As a result I got the tree that goes like this:

1 ( lft:-4, rgt:6 )
 -3 (lft: 5, rgt:6)
 -2 (lft 7, rgt:5)

instead of this:

1 (lft 1, rgt:6)
 -2 (lft 2, rgt:5)
 -3 (lft 3, rgt:4)

and child which should become second in order becomes first. As You can see, lft values aren't proper. Am I missing something?

Upvotes: 1

Views: 1148

Answers (3)

mmmm
mmmm

Reputation: 3938

Actually guys, I've chosen bad tree type. Don't use nested when You want to change children position often.

Upvotes: 0

vcrproszek
vcrproszek

Reputation: 11

You should update node and set new parent by gedmo TreeListener (get it by NestedTreeRepository->listener) :

<?php
class YourNestedTreeRepository extends NestedTreeRepository

    .......

    /**
     * @param Node $node
     * @param Node $newParent
     *
     * @return void
     */
    public function setNewParent($node, $newParent)
    {
        $meta = $this->getClassMetadata();
        $this->listener
            ->getStrategy($this->_em, $meta->name)
            ->updateNode($this->_em, $node, $newParent)
        ;
    }

and then, anywhere in your code:

//set as first child of a new parent - Tree hierarchy, it doesn't touch ORM relation
$repo->setNewParent($node, $newParent);
//set new parent and save. It updates ORM relation only, doesn't touch Tree hierarchy
$node->setParent($newParent);
$entityProvider->save($node); // or $entityManager->flush()
//additionaly move it down
if ($yourCondition) {
    $result = $repo->moveDown($node, $position);
}

Upvotes: 1

Gr&#233;gory Elhaimer
Gr&#233;gory Elhaimer

Reputation: 2801

You actually are OK there.

I think left/right values does not matter there since your order is still ok.

Your probleme is that you call

$repo->moveDown($chapter, 1);

This function will make your $chapter to move at next position (second one in your case).

Delete the call to moveDown and try it again.

As far as lft and rgt attributes are concerned, adding/removing node may recompute them.

If it's a real matter to you, then try calling (i'm not sur about this):

$repo->recover();
$em->flush(); // ensures cache clean

Upvotes: 0

Related Questions