Skip to content

Commit 2044516

Browse files
authored
Merge pull request #1754 from bbc/materializedpath-treeroot
Add TreeRoot support to MaterializedPath trees
2 parents 7ec4b4c + a48fa1e commit 2044516

File tree

7 files changed

+314
-0
lines changed

7 files changed

+314
-0
lines changed

lib/Gedmo/Tree/Strategy/AbstractMaterializedPath.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,27 @@ public function updateNode(ObjectManager $om, $node, AdapterInterface $ea)
313313
$changes[$config['path_hash']] = array(null, $pathHash);
314314
}
315315

316+
if (isset($config['root'])) {
317+
$root = null;
318+
319+
// Define the root value by grabbing the top of the current path
320+
$rootFinderPath = explode($config['path_separator'], $path);
321+
$rootIndex = $config['path_starts_with_separator'] ? 1 : 0;
322+
$root = $rootFinderPath[$rootIndex];
323+
324+
// If it is an association, then make it an reference
325+
// to the entity
326+
if ($meta->hasAssociation($config['root'])) {
327+
$rootClass = $meta->getAssociationTargetClass($config['root']);
328+
$root = $om->getReference($rootClass, $root);
329+
}
330+
331+
$rootProp = $meta->getReflectionProperty($config['root']);
332+
$rootProp->setAccessible(true);
333+
$rootProp->setValue($node, $root);
334+
$changes[$config['root']] = array(null, $root);
335+
}
336+
316337
if (isset($config['level'])) {
317338
$level = substr_count($path, $config['path_separator']);
318339
$levelProp = $meta->getReflectionProperty($config['level']);

tests/Gedmo/Tree/Fixture/MPCategory.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ class MPCategory
4545
*/
4646
private $level;
4747

48+
/**
49+
* @Gedmo\TreeRoot
50+
* @ORM\Column(name="tree_root_value", type="string", nullable=true)
51+
*/
52+
private $treeRootValue;
53+
4854
/**
4955
* @ORM\OneToMany(targetEntity="MPCategory", mappedBy="parent")
5056
*/
@@ -94,4 +100,9 @@ public function getLevel()
94100
{
95101
return $this->level;
96102
}
103+
104+
public function getTreeRootValue()
105+
{
106+
return $this->treeRootValue;
107+
}
97108
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
namespace Tree\Fixture;
4+
5+
use Gedmo\Mapping\Annotation as Gedmo;
6+
use Doctrine\ORM\Mapping as ORM;
7+
8+
/**
9+
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\MaterializedPathRepository")
10+
* @Gedmo\Tree(type="materializedPath")
11+
*/
12+
class MPCategoryWithRootAssociation
13+
{
14+
/**
15+
* @Gedmo\TreePathSource
16+
* @ORM\Column(name="id", type="integer")
17+
* @ORM\Id
18+
* @ORM\GeneratedValue
19+
*/
20+
private $id;
21+
22+
/**
23+
* @Gedmo\TreePath
24+
* @ORM\Column(name="path", type="string", length=3000, nullable=true)
25+
*/
26+
private $path;
27+
28+
/**
29+
* @ORM\Column(name="title", type="string", length=64)
30+
*/
31+
private $title;
32+
33+
/**
34+
* @Gedmo\TreeParent
35+
* @ORM\ManyToOne(targetEntity="MPCategoryWithRootAssociation", inversedBy="children")
36+
* @ORM\JoinColumns({
37+
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
38+
* })
39+
*/
40+
private $parentId;
41+
42+
/**
43+
* @Gedmo\TreeLevel
44+
* @ORM\Column(name="lvl", type="integer", nullable=true)
45+
*/
46+
private $level;
47+
48+
/**
49+
* @Gedmo\TreeRoot
50+
* @ORM\ManyToOne(targetEntity="MPCategoryWithRootAssociation")
51+
* @ORM\JoinColumns({
52+
* @ORM\JoinColumn(name="tree_root_entity", referencedColumnName="id", onDelete="CASCADE")
53+
* })
54+
*/
55+
private $treeRootEntity;
56+
57+
/**
58+
* @ORM\OneToMany(targetEntity="MPCategory", mappedBy="parent")
59+
*/
60+
private $children;
61+
62+
/**
63+
* @ORM\OneToMany(targetEntity="Article", mappedBy="category")
64+
*/
65+
private $comments;
66+
67+
public function getId()
68+
{
69+
return $this->id;
70+
}
71+
72+
public function setTitle($title)
73+
{
74+
$this->title = $title;
75+
}
76+
77+
public function getTitle()
78+
{
79+
return $this->title;
80+
}
81+
82+
public function setParent(MPCategoryWithRootAssociation $parent = null)
83+
{
84+
$this->parentId = $parent;
85+
}
86+
87+
public function getParent()
88+
{
89+
return $this->parentId;
90+
}
91+
92+
public function setPath($path)
93+
{
94+
$this->path = $path;
95+
}
96+
97+
public function getPath()
98+
{
99+
return $this->path;
100+
}
101+
102+
public function getLevel()
103+
{
104+
return $this->level;
105+
}
106+
107+
public function getTreeRootEntity()
108+
{
109+
return $this->treeRootEntity;
110+
}
111+
}

tests/Gedmo/Tree/Fixture/MPFeaturesCategory.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ class MPFeaturesCategory
5151
*/
5252
private $level;
5353

54+
55+
/**
56+
* @Gedmo\TreeRoot
57+
* @ORM\Column(name="tree_root_value", type="string", nullable=true)
58+
*/
59+
private $treeRootValue;
60+
5461
/**
5562
* @ORM\OneToMany(targetEntity="MPFeaturesCategory", mappedBy="parent")
5663
*/
@@ -101,6 +108,11 @@ public function getLevel()
101108
return $this->level;
102109
}
103110

111+
public function getTreeRootValue()
112+
{
113+
return $this->treeRootValue;
114+
}
115+
104116
public function getPathHash()
105117
{
106118
return $this->pathHash;

tests/Gedmo/Tree/MaterializedPathORMFeaturesTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ public function checkPathsAndHash()
7272
$this->assertEquals($this->generatePathHash(array('1' => $category->getId(), '2' => $category2->getId())), $category2->getPathHash());
7373
$this->assertEquals($this->generatePathHash(array('1' => $category->getId(), '2' => $category2->getId(), '3' => $category3->getId())), $category3->getPathHash());
7474
$this->assertEquals($this->generatePathHash(array('4' => $category4->getId())), $category4->getPathHash());
75+
76+
$this->assertEquals($category->getTitle(), $category->getTreeRootValue());
77+
$this->assertEquals($category->getTitle(), $category2->getTreeRootValue());
78+
$this->assertEquals($category->getTitle(), $category3->getTreeRootValue());
79+
$this->assertEquals($category4->getTitle(), $category4->getTreeRootValue());
7580
}
7681

7782
public function createCategory()
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
namespace Gedmo\Tree;
4+
5+
use Doctrine\Common\EventManager;
6+
use Tool\BaseTestCaseORM;
7+
8+
/**
9+
* These are tests for Tree behavior
10+
*
11+
* @author Gustavo Falco <[email protected]>
12+
* @author Gediminas Morkevicius <[email protected]>
13+
* @link http://www.gediminasm.org
14+
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
15+
*/
16+
class MaterializedPathORMRootAssociationTest extends BaseTestCaseORM
17+
{
18+
const CATEGORY = "Tree\\Fixture\\MPCategoryWithRootAssociation";
19+
20+
protected $config;
21+
protected $listener;
22+
23+
protected function setUp()
24+
{
25+
parent::setUp();
26+
27+
$this->listener = new TreeListener();
28+
29+
$evm = new EventManager();
30+
$evm->addEventSubscriber($this->listener);
31+
32+
$this->getMockSqliteEntityManager($evm);
33+
34+
$meta = $this->em->getClassMetadata(self::CATEGORY);
35+
$this->config = $this->listener->getConfiguration($this->em, $meta->name);
36+
}
37+
38+
/**
39+
* @test
40+
*/
41+
public function insertUpdateAndRemove()
42+
{
43+
// Insert
44+
$category = $this->createCategory();
45+
$category->setTitle('1');
46+
$category2 = $this->createCategory();
47+
$category2->setTitle('2');
48+
$category3 = $this->createCategory();
49+
$category3->setTitle('3');
50+
$category4 = $this->createCategory();
51+
$category4->setTitle('4');
52+
53+
$category2->setParent($category);
54+
$category3->setParent($category2);
55+
56+
$this->em->persist($category4);
57+
$this->em->persist($category3);
58+
$this->em->persist($category2);
59+
$this->em->persist($category);
60+
$this->em->flush();
61+
62+
$this->em->refresh($category);
63+
$this->em->refresh($category2);
64+
$this->em->refresh($category3);
65+
$this->em->refresh($category4);
66+
67+
$this->assertEquals($this->generatePath(array($category->getId())), $category->getPath());
68+
$this->assertEquals($this->generatePath(array($category->getId(), $category2->getId())), $category2->getPath());
69+
$this->assertEquals($this->generatePath(array($category->getId(), $category2->getId(), $category3->getId())), $category3->getPath());
70+
$this->assertEquals($this->generatePath(array($category4->getId())), $category4->getPath());
71+
$this->assertEquals(1, $category->getLevel());
72+
$this->assertEquals(2, $category2->getLevel());
73+
$this->assertEquals(3, $category3->getLevel());
74+
$this->assertEquals(1, $category4->getLevel());
75+
76+
$this->assertEquals($category, $category->getTreeRootEntity());
77+
$this->assertEquals($category, $category2->getTreeRootEntity());
78+
$this->assertEquals($category, $category3->getTreeRootEntity());
79+
$this->assertEquals($category4, $category4->getTreeRootEntity());
80+
81+
// Update
82+
$category2->setParent(null);
83+
84+
$this->em->persist($category2);
85+
$this->em->flush();
86+
87+
$this->em->refresh($category);
88+
$this->em->refresh($category2);
89+
$this->em->refresh($category3);
90+
91+
$this->assertEquals($this->generatePath(array($category->getId())), $category->getPath());
92+
$this->assertEquals($this->generatePath(array($category2->getId())), $category2->getPath());
93+
$this->assertEquals($this->generatePath(array($category2->getId(), $category3->getId())), $category3->getPath());
94+
$this->assertEquals(1, $category->getLevel());
95+
$this->assertEquals(1, $category2->getLevel());
96+
$this->assertEquals(2, $category3->getLevel());
97+
$this->assertEquals(1, $category4->getLevel());
98+
99+
$this->assertEquals($category, $category->getTreeRootEntity());
100+
$this->assertEquals($category2, $category2->getTreeRootEntity());
101+
$this->assertEquals($category2, $category3->getTreeRootEntity());
102+
$this->assertEquals($category4, $category4->getTreeRootEntity());
103+
104+
// Remove
105+
$this->em->remove($category);
106+
$this->em->remove($category2);
107+
$this->em->flush();
108+
109+
$result = $this->em->createQueryBuilder()->select('c')->from(self::CATEGORY, 'c')->getQuery()->execute();
110+
111+
$firstResult = $result[0];
112+
113+
$this->assertCount(1, $result);
114+
$this->assertEquals('4', $firstResult->getTitle());
115+
$this->assertEquals(1, $firstResult->getLevel());
116+
$this->assertEquals($category4, $firstResult->getTreeRootEntity());
117+
}
118+
119+
public function createCategory()
120+
{
121+
$class = self::CATEGORY;
122+
123+
return new $class();
124+
}
125+
126+
protected function getUsedEntityFixtures()
127+
{
128+
return array(
129+
self::CATEGORY,
130+
);
131+
}
132+
133+
public function generatePath(array $sources)
134+
{
135+
$path = '';
136+
137+
foreach ($sources as $id) {
138+
$path .= $id.$this->config['path_separator'];
139+
}
140+
141+
return $path;
142+
}
143+
}

tests/Gedmo/Tree/MaterializedPathORMTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ public function insertUpdateAndRemove()
7373
$this->assertEquals(3, $category3->getLevel());
7474
$this->assertEquals(1, $category4->getLevel());
7575

76+
$this->assertEquals('1-4', $category->getTreeRootValue());
77+
$this->assertEquals('1-4', $category2->getTreeRootValue());
78+
$this->assertEquals('1-4', $category3->getTreeRootValue());
79+
$this->assertEquals('4-1', $category4->getTreeRootValue());
80+
7681
// Update
7782
$category2->setParent(null);
7883

@@ -91,6 +96,11 @@ public function insertUpdateAndRemove()
9196
$this->assertEquals(2, $category3->getLevel());
9297
$this->assertEquals(1, $category4->getLevel());
9398

99+
$this->assertEquals('1-4', $category->getTreeRootValue());
100+
$this->assertEquals('2-3', $category2->getTreeRootValue());
101+
$this->assertEquals('2-3', $category3->getTreeRootValue());
102+
$this->assertEquals('4-1', $category4->getTreeRootValue());
103+
94104
// Remove
95105
$this->em->remove($category);
96106
$this->em->remove($category2);
@@ -103,6 +113,7 @@ public function insertUpdateAndRemove()
103113
$this->assertCount(1, $result);
104114
$this->assertEquals('4', $firstResult->getTitle());
105115
$this->assertEquals(1, $firstResult->getLevel());
116+
$this->assertEquals('4-1', $firstResult->getTreeRootValue());
106117
}
107118

108119
/**

0 commit comments

Comments
 (0)