Skip to content

Commit 4c8300c

Browse files
committed
Fix positioning for rootless trees - solves #1688
The desired position (first, last, before/after sibling) was not properly handeled when adding top level nodes to a tree with no root property. See `NestedTreePositionTest::testRootlessTreeTopLevelInserts`
1 parent 908eaee commit 4c8300c

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

lib/Gedmo/Tree/Strategy/ORM/Nested.php

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,59 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
389389
}
390390
$newRoot = $parentRoot;
391391
} elseif (!isset($config['root'])) {
392-
$start = isset($this->treeEdges[$meta->name]) ?
393-
$this->treeEdges[$meta->name] : $this->max($em, $config['useObjectClass']);
394-
$this->treeEdges[$meta->name] = $start + 2;
395-
$start++;
392+
393+
if (!isset($this->treeEdges[$meta->name])) {
394+
$this->treeEdges[$meta->name] = $this->max($em, $config['useObjectClass']) + 1;
395+
}
396+
397+
$level = 0;
398+
$parentLeft = 0;
399+
$parentRight = $this->treeEdges[$meta->name];
400+
$this->treeEdges[$meta->name] += 2;
401+
402+
switch ($position) {
403+
case self::PREV_SIBLING:
404+
if (property_exists($node, 'sibling')) {
405+
$wrappedSibling = AbstractWrapper::wrap($node->sibling, $em);
406+
$start = $wrappedSibling->getPropertyValue($config['left']);
407+
} else {
408+
$wrapped->setPropertyValue($config['parent'], null);
409+
$em->getUnitOfWork()->recomputeSingleEntityChangeSet($meta, $node);
410+
$start = $parentLeft + 1;
411+
}
412+
break;
413+
414+
case self::NEXT_SIBLING:
415+
if (property_exists($node, 'sibling')) {
416+
$wrappedSibling = AbstractWrapper::wrap($node->sibling, $em);
417+
$start = $wrappedSibling->getPropertyValue($config['right']) + 1;
418+
} else {
419+
$wrapped->setPropertyValue($config['parent'], null);
420+
$em->getUnitOfWork()->recomputeSingleEntityChangeSet($meta, $node);
421+
$start = $parentRight;
422+
}
423+
break;
424+
425+
case self::LAST_CHILD:
426+
$start = $parentRight;
427+
break;
428+
429+
case self::FIRST_CHILD:
430+
default:
431+
$start = $parentLeft + 1;
432+
break;
433+
}
434+
435+
$this->shiftRL($em, $config['useObjectClass'], $start, $treeSize, null);
436+
437+
if (!$isNewNode && $left >= $start) {
438+
$left += $treeSize;
439+
$wrapped->setPropertyValue($config['left'], $left);
440+
}
441+
if (!$isNewNode && $right >= $start) {
442+
$right += $treeSize;
443+
$wrapped->setPropertyValue($config['right'], $right);
444+
}
396445
} else {
397446
$start = 1;
398447

@@ -404,6 +453,7 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
404453
}
405454

406455
$diff = $start - $left;
456+
407457
if (!$isNewNode) {
408458
$levelDiff = isset($config['level']) ? $level - $wrapped->getPropertyValue($config['level']) : null;
409459
$this->shiftRangeRL(

0 commit comments

Comments
 (0)