Skip to content

Commit

Permalink
[Tree] Prevent setting integer value (root id) on an associated root …
Browse files Browse the repository at this point in the history
…property
  • Loading branch information
aramalipoor authored and l3pp4rd committed Jan 28, 2016
1 parent 20745a1 commit 1b5df40
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 45 deletions.
69 changes: 38 additions & 31 deletions lib/Gedmo/Tree/Strategy/ORM/Nested.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,12 @@ public function processPostRemove($em, $entity, AdapterInterface $ea)
public function updateNode(EntityManager $em, $node, $parent, $position = 'FirstChild')
{
$wrapped = AbstractWrapper::wrap($node, $em);

/** @var ClassMetadata $meta */
$meta = $wrapped->getMetadata();
$config = $this->listener->getConfiguration($em, $meta->name);

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

Expand All @@ -308,11 +310,11 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
}
$level = 0;
$treeSize = $right - $left + 1;
$newRootId = null;
$newRoot = null;
if ($parent) {
$wrappedParent = AbstractWrapper::wrap($parent, $em);

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

return;
}
if (!$isNewNode && $rootId === $parentRootId && $parentLeft >= $left && $parentRight <= $right) {
if (!$isNewNode && $root === $parentRoot && $parentLeft >= $left && $parentRight <= $right) {
throw new UnexpectedValueException("Cannot set child as parent to node: {$nodeId}");
}
if (isset($config['level'])) {
Expand Down Expand Up @@ -376,24 +378,29 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
$level++;
break;
}
$this->shiftRL($em, $config['useObjectClass'], $start, $treeSize, $parentRootId);
if (!$isNewNode && $rootId === $parentRootId && $left >= $start) {
$this->shiftRL($em, $config['useObjectClass'], $start, $treeSize, $parentRoot);
if (!$isNewNode && $root === $parentRoot && $left >= $start) {
$left += $treeSize;
$wrapped->setPropertyValue($config['left'], $left);
}
if (!$isNewNode && $rootId === $parentRootId && $right >= $start) {
if (!$isNewNode && $root === $parentRoot && $right >= $start) {
$right += $treeSize;
$wrapped->setPropertyValue($config['right'], $right);
}
$newRootId = $parentRootId;
$newRoot = $parentRoot;
} elseif (!isset($config['root'])) {
$start = isset($this->treeEdges[$meta->name]) ?
$this->treeEdges[$meta->name] : $this->max($em, $config['useObjectClass']);
$this->treeEdges[$meta->name] = $start + 2;
$start++;
} else {
$start = 1;
$newRootId = $nodeId;

if ($meta->isSingleValuedAssociation($config['root'])) {
$newRoot = $node;
} else {
$newRoot = $wrapped->getIdentifier();
}
}

$diff = $start - $left;
Expand All @@ -405,19 +412,19 @@ public function updateNode(EntityManager $em, $node, $parent, $position = 'First
$left,
$right,
$diff,
$rootId,
$newRootId,
$root,
$newRoot,
$levelDiff
);
$this->shiftRL($em, $config['useObjectClass'], $left, -$treeSize, $rootId);
$this->shiftRL($em, $config['useObjectClass'], $left, -$treeSize, $root);
} else {
$qb = $em->createQueryBuilder();
$qb->update($config['useObjectClass'], 'node');
if (isset($config['root'])) {
$qb->set('node.'.$config['root'], ':rid');
$qb->setParameter('rid', $newRootId);
$wrapped->setPropertyValue($config['root'], $newRootId);
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['root'], $newRootId);
$qb->setParameter('rid', $newRoot);
$wrapped->setPropertyValue($config['root'], $newRoot);
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['root'], $newRoot);
}
if (isset($config['level'])) {
$qb->set('node.'.$config['level'], $level);
Expand Down Expand Up @@ -485,9 +492,9 @@ public function max(EntityManager $em, $class, $rootId = 0)
* @param string $class
* @param integer $first
* @param integer $delta
* @param integer|string $rootId
* @param integer|string $root
*/
public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = null)
public function shiftRL(EntityManager $em, $class, $first, $delta, $root = null)
{
$meta = $em->getClassMetadata($class);
$config = $this->listener->getConfiguration($em, $class);
Expand All @@ -501,7 +508,7 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
;
if (isset($config['root'])) {
$qb->andWhere($qb->expr()->eq('node.'.$config['root'], ':rid'));
$qb->setParameter('rid', $rootId);
$qb->setParameter('rid', $root);
}
$qb->getQuery()->getSingleScalarResult();

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

$qb->getQuery()->getSingleScalarResult();
Expand All @@ -528,13 +535,13 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
}
$oid = spl_object_hash($node);
$left = $meta->getReflectionProperty($config['left'])->getValue($node);
$root = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
if ($root === $rootId && $left >= $first) {
$currentRoot = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
if ($currentRoot === $root && $left >= $first) {
$meta->getReflectionProperty($config['left'])->setValue($node, $left + $delta);
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['left'], $left + $delta);
}
$right = $meta->getReflectionProperty($config['right'])->getValue($node);
if ($root === $rootId && $right >= $first) {
if ($currentRoot === $root && $right >= $first) {
$meta->getReflectionProperty($config['right'])->setValue($node, $right + $delta);
$em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['right'], $right + $delta);
}
Expand All @@ -551,11 +558,11 @@ public function shiftRL(EntityManager $em, $class, $first, $delta, $rootId = nul
* @param integer $first
* @param integer $last
* @param integer $delta
* @param integer|string $rootId
* @param integer|string $destRootId
* @param integer|string $root
* @param integer|string $destRoot
* @param integer $levelDelta
*/
public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $rootId = null, $destRootId = null, $levelDelta = null)
public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $root = null, $destRoot = null, $levelDelta = null)
{
$meta = $em->getClassMetadata($class);
$config = $this->listener->getConfiguration($em, $class);
Expand All @@ -574,9 +581,9 @@ public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $
;
if (isset($config['root'])) {
$qb->set('node.'.$config['root'], ':drid');
$qb->setParameter('drid', $destRootId);
$qb->setParameter('drid', $destRoot);
$qb->andWhere($qb->expr()->eq('node.'.$config['root'], ':rid'));
$qb->setParameter('rid', $rootId);
$qb->setParameter('rid', $root);
}
if (isset($config['level'])) {
$qb->set('node.'.$config['level'], "node.{$config['level']} {$levelSign} {$absLevelDelta}");
Expand All @@ -594,8 +601,8 @@ public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $
}
$left = $meta->getReflectionProperty($config['left'])->getValue($node);
$right = $meta->getReflectionProperty($config['right'])->getValue($node);
$root = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
if ($root === $rootId && $left >= $first && $right <= $last) {
$currentRoot = isset($config['root']) ? $meta->getReflectionProperty($config['root'])->getValue($node) : null;
if ($currentRoot === $root && $left >= $first && $right <= $last) {
$oid = spl_object_hash($node);
$uow = $em->getUnitOfWork();

Expand All @@ -604,8 +611,8 @@ public function shiftRangeRL(EntityManager $em, $class, $first, $last, $delta, $
$meta->getReflectionProperty($config['right'])->setValue($node, $right + $delta);
$uow->setOriginalEntityProperty($oid, $config['right'], $right + $delta);
if (isset($config['root'])) {
$meta->getReflectionProperty($config['root'])->setValue($node, $destRootId);
$uow->setOriginalEntityProperty($oid, $config['root'], $destRootId);
$meta->getReflectionProperty($config['root'])->setValue($node, $destRoot);
$uow->setOriginalEntityProperty($oid, $config['root'], $destRoot);
}
if (isset($config['level'])) {
$level = $meta->getReflectionProperty($config['level'])->getValue($node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
* @Gedmo\Tree(type="nested")
*/
class RootRelationCategory
class RootAssociationCategory
{
/**
* @ORM\Column(name="id", type="integer")
Expand Down Expand Up @@ -37,7 +37,7 @@ class RootRelationCategory

/**
* @Gedmo\TreeParent
* @ORM\ManyToOne(targetEntity="RootRelationCategory", inversedBy="children")
* @ORM\ManyToOne(targetEntity="RootAssociationCategory", inversedBy="children")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
* })
Expand All @@ -46,7 +46,7 @@ class RootRelationCategory

/**
* @Gedmo\TreeRoot
* @ORM\ManyToOne(targetEntity="RootRelationCategory")
* @ORM\ManyToOne(targetEntity="RootAssociationCategory")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="tree_root", referencedColumnName="id", onDelete="CASCADE")
* })
Expand All @@ -60,7 +60,7 @@ class RootRelationCategory
private $level;

/**
* @ORM\OneToMany(targetEntity="RootRelationCategory", mappedBy="parent")
* @ORM\OneToMany(targetEntity="RootAssociationCategory", mappedBy="parent")
*/
private $children;

Expand All @@ -79,7 +79,7 @@ public function getTitle()
return $this->title;
}

public function setParent(RootRelationCategory $parent = null)
public function setParent(RootAssociationCategory $parent = null)
{
$this->parent = $parent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Doctrine\Common\EventManager;
use Tool\BaseTestCaseORM;
use Tree\Fixture\RootRelationCategory;
use Tree\Fixture\RootAssociationCategory;

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

protected function setUp()
{
Expand Down Expand Up @@ -62,25 +62,25 @@ protected function getUsedEntityFixtures()

private function populate()
{
$root = new RootRelationCategory();
$root = new RootAssociationCategory();
$root->setTitle("Food");

$root2 = new RootRelationCategory();
$root2 = new RootAssociationCategory();
$root2->setTitle("Sports");

$child = new RootRelationCategory();
$child = new RootAssociationCategory();
$child->setTitle("Fruits");
$child->setParent($root);

$child2 = new RootRelationCategory();
$child2 = new RootAssociationCategory();
$child2->setTitle("Vegetables");
$child2->setParent($root);

$childsChild = new RootRelationCategory();
$childsChild = new RootAssociationCategory();
$childsChild->setTitle("Carrots");
$childsChild->setParent($child2);

$potatoes = new RootRelationCategory();
$potatoes = new RootAssociationCategory();
$potatoes->setTitle("Potatoes");
$potatoes->setParent($child2);

Expand Down

0 comments on commit 1b5df40

Please sign in to comment.