Skip to content

Commit a3d7ad1

Browse files
authored
Merge pull request #1689 from iluuu1994/v2.4.x
[Tree] Fix positioning for rootless trees
2 parents a7f7243 + 4c8300c commit a3d7ad1

File tree

2 files changed

+113
-4
lines changed

2 files changed

+113
-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(

tests/Gedmo/Tree/NestedTreePositionTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,65 @@ public function testRootTreePositionedInserts()
333333
$this->assertTrue($repo->verify());
334334
}
335335

336+
public function testRootlessTreeTopLevelInserts()
337+
{
338+
$repo = $this->em->getRepository(self::CATEGORY);
339+
340+
// test top level positioned inserts
341+
$fruits = new Category();
342+
$fruits->setTitle('Fruits');
343+
344+
$vegetables = new Category();
345+
$vegetables->setTitle('Vegetables');
346+
347+
$milk = new Category();
348+
$milk->setTitle('Milk');
349+
350+
$meat = new Category();
351+
$meat->setTitle('Meat');
352+
353+
$repo
354+
->persistAsFirstChild($fruits)
355+
->persistAsFirstChild($vegetables)
356+
->persistAsLastChild($milk)
357+
->persistAsLastChild($meat);
358+
359+
$this->em->flush();
360+
361+
$this->assertEquals(3, $fruits->getLeft());
362+
$this->assertEquals(4, $fruits->getRight());
363+
364+
$this->assertEquals(1, $vegetables->getLeft());
365+
$this->assertEquals(2, $vegetables->getRight());
366+
367+
$this->assertEquals(5, $milk->getLeft());
368+
$this->assertEquals(6, $milk->getRight());
369+
370+
$this->assertEquals(7, $meat->getLeft());
371+
$this->assertEquals(8, $meat->getRight());
372+
373+
// test sibling positioned inserts
374+
$cookies = new Category();
375+
$cookies->setTitle('Cookies');
376+
377+
$drinks = new Category();
378+
$drinks->setTitle('Drinks');
379+
380+
$repo
381+
->persistAsNextSiblingOf($cookies, $milk)
382+
->persistAsPrevSiblingOf($drinks, $milk);
383+
384+
$this->em->flush();
385+
386+
$this->assertEquals(5, $drinks->getLeft());
387+
$this->assertEquals(6, $drinks->getRight());
388+
389+
$this->assertEquals(9, $cookies->getLeft());
390+
$this->assertEquals(10, $cookies->getRight());
391+
392+
$this->assertTrue($repo->verify());
393+
}
394+
336395
public function testSimpleTreePositionedInserts()
337396
{
338397
$repo = $this->em->getRepository(self::CATEGORY);

0 commit comments

Comments
 (0)