Skip to content

Commit 81d7146

Browse files
committed
[Tree] Improve tree object hydrator
1 parent 32bc087 commit 81d7146

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

lib/Gedmo/Tree/Hydrator/ORM/ObjectHydrator.php renamed to lib/Gedmo/Tree/Hydrator/ORM/TreeObjectHydrator.php

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,32 @@
22

33
namespace Gedmo\Tree\Hydrator\ORM;
44

5-
use Doctrine\ORM\Internal\Hydration\ObjectHydrator as BaseObjectHydrator;
5+
use Doctrine\Common\Collections\AbstractLazyCollection;
6+
use Doctrine\Common\Collections\ArrayCollection;
67
use Doctrine\ORM\EntityManagerInterface;
8+
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
79
use Gedmo\Tool\Wrapper\EntityWrapper;
810
use Gedmo\Tree\TreeListener;
911

10-
class ObjectHydrator extends BaseObjectHydrator
12+
/**
13+
* Automatically maps the parent and children properties of Tree nodes
14+
*
15+
* @author Ilija Tovilo <[email protected]>
16+
* @link http://www.gediminasm.org
17+
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
18+
*/
19+
class TreeObjectHydrator extends ObjectHydrator
1120
{
1221
/**
1322
* @var array
1423
*/
1524
private $config;
1625

26+
/**
27+
* @var string
28+
*/
29+
private $idField;
30+
1731
/**
1832
* @var string
1933
*/
@@ -40,6 +54,7 @@ protected function hydrateAllData()
4054
$listener = $this->getTreeListener($this->_em);
4155
$entityClass = $this->getEntityClassFromHydratedData($data);
4256
$this->config = $listener->getConfiguration($this->_em, $entityClass);
57+
$this->idField = $this->getIdField($entityClass);
4358
$this->parentField = $this->getParentField();
4459
$this->childrenField = $this->getChildrenField($entityClass);
4560

@@ -70,10 +85,12 @@ protected function buildChildrenHashmap($nodes)
7085
foreach ($nodes as $node) {
7186
$wrapper = new EntityWrapper($node, $this->_em);
7287
$parentProxy = $wrapper->getPropertyValue($this->config['parent']);
88+
$parentId = null;
7389

74-
$parentId = $parentProxy !== null
75-
? $parentProxy->getId()
76-
: null;
90+
if ($parentProxy !== null) {
91+
$parentWrapper = new EntityWrapper($parentProxy, $this->_em);
92+
$parentId = $parentWrapper->getPropertyValue($this->idField);
93+
}
7794

7895
$r[$parentId][] = $node;
7996
}
@@ -89,21 +106,40 @@ protected function populateChildrenArray($nodes, $childrenHashmap)
89106
{
90107
foreach ($nodes as $node) {
91108
$wrapper = new EntityWrapper($node, $this->_em);
109+
$nodeId = $wrapper->getPropertyValue($this->idField);
92110
$childrenCollection = $wrapper->getPropertyValue($this->childrenField);
93111

112+
if ($childrenCollection === null) {
113+
$childrenCollection = new ArrayCollection();
114+
$wrapper->setPropertyValue($this->childrenField, $childrenCollection);
115+
}
116+
94117
// Mark all children collections as initialized to avoid select queries
95-
$childrenCollection->setInitialized(true);
118+
if ($childrenCollection instanceof AbstractLazyCollection) {
119+
$childrenCollection->setInitialized(true);
120+
}
96121

97-
if (!isset($childrenHashmap[$node->getId()])) { continue; }
122+
if (!isset($childrenHashmap[$nodeId])) {
123+
continue;
124+
}
98125

99126
$childrenCollection->clear();
100127

101-
foreach ($childrenHashmap[$node->getId()] as $child) {
128+
foreach ($childrenHashmap[$nodeId] as $child) {
102129
$childrenCollection->add($child);
103130
}
104131
}
105132
}
106133

134+
/**
135+
* @return string
136+
*/
137+
protected function getIdField($entityClass)
138+
{
139+
$meta = $this->getClassMetadata($entityClass);
140+
return $meta->getSingleIdentifierFieldName();
141+
}
142+
107143
/**
108144
* @return string
109145
*/
@@ -126,11 +162,16 @@ protected function getChildrenField($entityClass)
126162
foreach ($meta->getReflectionProperties() as $property) {
127163

128164
// Skip properties that have no association
129-
if (!$meta->hasAssociation($property->getName())) { continue; }
165+
if (!$meta->hasAssociation($property->getName())) {
166+
continue;
167+
}
168+
130169
$associationMapping = $meta->getAssociationMapping($property->getName());
131170

132171
// Make sure the association is mapped by the parent property
133-
if ($associationMapping['mappedBy'] !== $this->parentField) { continue; }
172+
if ($associationMapping['mappedBy'] !== $this->parentField) {
173+
continue;
174+
}
134175

135176
return $associationMapping['fieldName'];
136177
}

0 commit comments

Comments
 (0)