Skip to content

Commit 1b5df40

Browse files
aramalipoorl3pp4rd
authored andcommitted
[Tree] Prevent setting integer value (root id) on an associated root property
1 parent 20745a1 commit 1b5df40

File tree

3 files changed

+52
-45
lines changed

3 files changed

+52
-45
lines changed

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

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,12 @@ public function processPostRemove($em, $entity, AdapterInterface $ea)
286286
public function updateNode(EntityManager $em, $node, $parent, $position = 'FirstChild')
287287
{
288288
$wrapped = AbstractWrapper::wrap($node, $em);
289+
290+
/** @var ClassMetadata $meta */
289291
$meta = $wrapped->getMetadata();
290292
$config = $this->listener->getConfiguration($em, $meta->name);
291293

292-
$rootId = isset($config['root']) ? $wrapped->getPropertyValue($config['root']) : null;
294+
$root = isset($config['root']) ? $wrapped->getPropertyValue($config['root']) : null;
293295
$identifierField = $meta->getSingleIdentifierFieldName();
294296
$nodeId = $wrapped->getIdentifier();
295297

@@ -308,11 +310,11 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
308310
}
309311
$level = 0;
310312
$treeSize = $right - $left + 1;
311-
$newRootId = null;
313+
$newRoot = null;
312314
if ($parent) {
313315
$wrappedParent = AbstractWrapper::wrap($parent, $em);
314316

315-
$parentRootId = isset($config['root']) ? $wrappedParent->getPropertyValue($config['root']) : null;
317+
$parentRoot = isset($config['root']) ? $wrappedParent->getPropertyValue($config['root']) : null;
316318
$parentOid = spl_object_hash($parent);
317319
$parentLeft = $wrappedParent->getPropertyValue($config['left']);
318320
$parentRight = $wrappedParent->getPropertyValue($config['right']);
@@ -326,7 +328,7 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
326328

327329
return;
328330
}
329-
if (!$isNewNode && $rootId === $parentRootId && $parentLeft >= $left && $parentRight <= $right) {
331+
if (!$isNewNode && $root === $parentRoot && $parentLeft >= $left && $parentRight <= $right) {
330332
throw new UnexpectedValueException("Cannot set child as parent to node: {$nodeId}");
331333
}
332334
if (isset($config['level'])) {
@@ -376,24 +378,29 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
376378
$level++;
377379
break;
378380
}
379-
$this->shiftRL($em, $config['useObjectClass'], $start, $treeSize, $parentRootId);
380-
if (!$isNewNode && $rootId === $parentRootId && $left >= $start) {
381+
$this->shiftRL($em, $config['useObjectClass'], $start, $treeSize, $parentRoot);
382+
if (!$isNewNode && $root === $parentRoot && $left >= $start) {
381383
$left += $treeSize;
382384
$wrapped->setPropertyValue($config['left'], $left);
383385
}
384-
if (!$isNewNode && $rootId === $parentRootId && $right >= $start) {
386+
if (!$isNewNode && $root === $parentRoot && $right >= $start) {
385387
$right += $treeSize;
386388
$wrapped->setPropertyValue($config['right'], $right);
387389
}
388-
$newRootId = $parentRootId;
390+
$newRoot = $parentRoot;
389391
} elseif (!isset($config['root'])) {
390392
$start = isset($this->treeEdges[$meta->name]) ?
391393
$this->treeEdges[$meta->name] : $this->max($em, $config['useObjectClass']);
392394
$this->treeEdges[$meta->name] = $start + 2;
393395
$start++;
394396
} else {
395397
$start = 1;
396-
$newRootId = $nodeId;
398+
399+
if ($meta->isSingleValuedAssociation($config['root'])) {
400+
$newRoot = $node;
401+
} else {
402+
$newRoot = $wrapped->getIdentifier();
403+
}
397404
}
398405

399406
$diff = $start - $left;
@@ -405,19 +412,19 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
405412
$left,
406413
$right,
407414
$diff,
408-
$rootId,
409-
$newRootId,
415+
$root,
416+
$newRoot,
410417
$levelDiff
411418
);
412-
$this->shiftRL($em, $config['useObjectClass'], $left, -$treeSize, $rootId);
419+
$this->shiftRL($em, $config['useObjectClass'], $left, -$treeSize, $root);
413420
} else {
414421
$qb = $em->createQueryBuilder();
415422
$qb->update($config['useObjectClass'], 'node');
416423
if (isset($config['root'])) {
417424
$qb->set('node.'.$config['root'], ':rid');
418-
$qb->setParameter('rid', $newRootId);
419-
$wrapped->setPropertyValue($config['root'], $newRootId);
420-
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['root'], $newRootId);
425+
$qb->setParameter('rid', $newRoot);
426+
$wrapped->setPropertyValue($config['root'], $newRoot);
427+
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['root'], $newRoot);
421428
}
422429
if (isset($config['level'])) {
423430
$qb->set('node.'.$config['level'], $level);
@@ -485,9 +492,9 @@ public function max(EntityManager $em, $class, $rootId = 0)
485492
* @param string $class
486493
* @param integer $first
487494
* @param integer $delta
488-
* @param integer|string $rootId
495+
* @param integer|string $root
489496
*/
490-
public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = null)
497+
public function shiftRL(EntityManager $em, $class, $first, $delta, $root = null)
491498
{
492499
$meta = $em->getClassMetadata($class);
493500
$config = $this->listener->getConfiguration($em, $class);
@@ -501,7 +508,7 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
501508
;
502509
if (isset($config['root'])) {
503510
$qb->andWhere($qb->expr()->eq('node.'.$config['root'], ':rid'));
504-
$qb->setParameter('rid', $rootId);
511+
$qb->setParameter('rid', $root);
505512
}
506513
$qb->getQuery()->getSingleScalarResult();
507514

@@ -512,7 +519,7 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
512519
;
513520
if (isset($config['root'])) {
514521
$qb->andWhere($qb->expr()->eq('node.'.$config['root'], ':rid'));
515-
$qb->setParameter('rid', $rootId);
522+
$qb->setParameter('rid', $root);
516523
}
517524

518525
$qb->getQuery()->getSingleScalarResult();
@@ -528,13 +535,13 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
528535
}
529536
$oid = spl_object_hash($node);
530537
$left = $meta->getReflectionProperty($config['left'])->getValue($node);
531-
$root = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
532-
if ($root === $rootId && $left >= $first) {
538+
$currentRoot = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
539+
if ($currentRoot === $root && $left >= $first) {
533540
$meta->getReflectionProperty($config['left'])->setValue($node, $left + $delta);
534541
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['left'], $left + $delta);
535542
}
536543
$right = $meta->getReflectionProperty($config['right'])->getValue($node);
537-
if ($root === $rootId && $right >= $first) {
544+
if ($currentRoot === $root && $right >= $first) {
538545
$meta->getReflectionProperty($config['right'])->setValue($node, $right + $delta);
539546
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['right'], $right + $delta);
540547
}
@@ -551,11 +558,11 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
551558
* @param integer $first
552559
* @param integer $last
553560
* @param integer $delta
554-
* @param integer|string $rootId
555-
* @param integer|string $destRootId
561+
* @param integer|string $root
562+
* @param integer|string $destRoot
556563
* @param integer $levelDelta
557564
*/
558-
public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $rootId = null, $destRootId = null, $levelDelta = null)
565+
public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $root = null, $destRoot = null, $levelDelta = null)
559566
{
560567
$meta = $em->getClassMetadata($class);
561568
$config = $this->listener->getConfiguration($em, $class);
@@ -574,9 +581,9 @@ public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $
574581
;
575582
if (isset($config['root'])) {
576583
$qb->set('node.'.$config['root'], ':drid');
577-
$qb->setParameter('drid', $destRootId);
584+
$qb->setParameter('drid', $destRoot);
578585
$qb->andWhere($qb->expr()->eq('node.'.$config['root'], ':rid'));
579-
$qb->setParameter('rid', $rootId);
586+
$qb->setParameter('rid', $root);
580587
}
581588
if (isset($config['level'])) {
582589
$qb->set('node.'.$config['level'], "node.{$config['level']} {$levelSign} {$absLevelDelta}");
@@ -594,8 +601,8 @@ public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $
594601
}
595602
$left = $meta->getReflectionProperty($config['left'])->getValue($node);
596603
$right = $meta->getReflectionProperty($config['right'])->getValue($node);
597-
$root = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
598-
if ($root === $rootId && $left >= $first && $right <= $last) {
604+
$currentRoot = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
605+
if ($currentRoot === $root && $left >= $first && $right <= $last) {
599606
$oid = spl_object_hash($node);
600607
$uow = $em->getUnitOfWork();
601608

@@ -604,8 +611,8 @@ public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $
604611
$meta->getReflectionProperty($config['right'])->setValue($node, $right + $delta);
605612
$uow->setOriginalEntityProperty($oid, $config['right'], $right + $delta);
606613
if (isset($config['root'])) {
607-
$meta->getReflectionProperty($config['root'])->setValue($node, $destRootId);
608-
$uow->setOriginalEntityProperty($oid, $config['root'], $destRootId);
614+
$meta->getReflectionProperty($config['root'])->setValue($node, $destRoot);
615+
$uow->setOriginalEntityProperty($oid, $config['root'], $destRoot);
609616
}
610617
if (isset($config['level'])) {
611618
$level = $meta->getReflectionProperty($config['level'])->getValue($node);

tests/Gedmo/Tree/Fixture/RootRelationCategory.php renamed to tests/Gedmo/Tree/Fixture/RootAssociationCategory.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
1010
* @Gedmo\Tree(type="nested")
1111
*/
12-
class RootRelationCategory
12+
class RootAssociationCategory
1313
{
1414
/**
1515
* @ORM\Column(name="id", type="integer")
@@ -37,7 +37,7 @@ class RootRelationCategory
3737

3838
/**
3939
* @Gedmo\TreeParent
40-
* @ORM\ManyToOne(targetEntity="RootRelationCategory", inversedBy="children")
40+
* @ORM\ManyToOne(targetEntity="RootAssociationCategory", inversedBy="children")
4141
* @ORM\JoinColumns({
4242
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
4343
* })
@@ -46,7 +46,7 @@ class RootRelationCategory
4646

4747
/**
4848
* @Gedmo\TreeRoot
49-
* @ORM\ManyToOne(targetEntity="RootRelationCategory")
49+
* @ORM\ManyToOne(targetEntity="RootAssociationCategory")
5050
* @ORM\JoinColumns({
5151
* @ORM\JoinColumn(name="tree_root", referencedColumnName="id", onDelete="CASCADE")
5252
* })
@@ -60,7 +60,7 @@ class RootRelationCategory
6060
private $level;
6161

6262
/**
63-
* @ORM\OneToMany(targetEntity="RootRelationCategory", mappedBy="parent")
63+
* @ORM\OneToMany(targetEntity="RootAssociationCategory", mappedBy="parent")
6464
*/
6565
private $children;
6666

@@ -79,7 +79,7 @@ public function getTitle()
7979
return $this->title;
8080
}
8181

82-
public function setParent(RootRelationCategory $parent = null)
82+
public function setParent(RootAssociationCategory $parent = null)
8383
{
8484
$this->parent = $parent;
8585
}

tests/Gedmo/Tree/NestedTreeRootRelationTest.php renamed to tests/Gedmo/Tree/NestedTreeRootAssociationTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Doctrine\Common\EventManager;
66
use Tool\BaseTestCaseORM;
7-
use Tree\Fixture\RootRelationCategory;
7+
use Tree\Fixture\RootAssociationCategory;
88

99
/**
1010
* These are tests for Tree behavior
@@ -13,9 +13,9 @@
1313
* @link http://www.gediminasm.org
1414
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
1515
*/
16-
class NestedTreeRootRelationTest extends BaseTestCaseORM
16+
class NestedTreeRootAssociationTest extends BaseTestCaseORM
1717
{
18-
const CATEGORY = "Tree\\Fixture\\RootRelationCategory";
18+
const CATEGORY = "Tree\\Fixture\\RootAssociationCategory";
1919

2020
protected function setUp()
2121
{
@@ -62,25 +62,25 @@ protected function getUsedEntityFixtures()
6262

6363
private function populate()
6464
{
65-
$root = new RootRelationCategory();
65+
$root = new RootAssociationCategory();
6666
$root->setTitle("Food");
6767

68-
$root2 = new RootRelationCategory();
68+
$root2 = new RootAssociationCategory();
6969
$root2->setTitle("Sports");
7070

71-
$child = new RootRelationCategory();
71+
$child = new RootAssociationCategory();
7272
$child->setTitle("Fruits");
7373
$child->setParent($root);
7474

75-
$child2 = new RootRelationCategory();
75+
$child2 = new RootAssociationCategory();
7676
$child2->setTitle("Vegetables");
7777
$child2->setParent($root);
7878

79-
$childsChild = new RootRelationCategory();
79+
$childsChild = new RootAssociationCategory();
8080
$childsChild->setTitle("Carrots");
8181
$childsChild->setParent($child2);
8282

83-
$potatoes = new RootRelationCategory();
83+
$potatoes = new RootAssociationCategory();
8484
$potatoes->setTitle("Potatoes");
8585
$potatoes->setParent($child2);
8686

0 commit comments

Comments
 (0)