22
33namespace 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 ;
67use Doctrine \ORM \EntityManagerInterface ;
8+ use Doctrine \ORM \Internal \Hydration \ObjectHydrator ;
79use Gedmo \Tool \Wrapper \EntityWrapper ;
810use 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