@@ -16,7 +16,7 @@ trait HierarchicalTrait
16
16
/**
17
17
* The object's parent, if any, in the hierarchy.
18
18
*
19
- * @var HierarchicalInterface |null
19
+ * @var string|integer |null
20
20
*/
21
21
protected $ master ;
22
22
@@ -41,6 +41,13 @@ trait HierarchicalTrait
41
41
*/
42
42
private $ siblings ;
43
43
44
+ /**
45
+ * The object's parent object, if any, in the hierarchy.
46
+ *
47
+ * @var HierarchicalInterface|null
48
+ */
49
+ private $ masterObject ;
50
+
44
51
/**
45
52
* A store of cached objects.
46
53
*
@@ -65,23 +72,11 @@ public function resetHierarchy()
65
72
/**
66
73
* Set this object's immediate parent.
67
74
*
68
- * @param mixed $master The object's parent (or master).
69
- * @throws UnexpectedValueException The current object cannot be its own parent.
75
+ * @param mixed $master The object's parent (or master).
70
76
* @return HierarchicalInterface Chainable
71
77
*/
72
78
public function setMaster ($ master )
73
79
{
74
- $ master = $ this ->objFromIdent ($ master );
75
-
76
- if ($ master instanceof ModelInterface) {
77
- if ($ master ->id () === $ this ->id ()) {
78
- throw new UnexpectedValueException (sprintf (
79
- 'Can not be ones own parent: %s ' ,
80
- $ master ->id ()
81
- ));
82
- }
83
- }
84
-
85
80
$ this ->master = $ master ;
86
81
87
82
$ this ->resetHierarchy ();
@@ -92,13 +87,38 @@ public function setMaster($master)
92
87
/**
93
88
* Retrieve this object's immediate parent.
94
89
*
95
- * @return HierarchicalInterface |null
90
+ * @return string |null
96
91
*/
97
92
public function getMaster ()
98
93
{
99
94
return $ this ->master ;
100
95
}
101
96
97
+ /**
98
+ * Retrieve this object's immediate parent as object.
99
+ * @return HierarchicalInterface|null
100
+ * @throws UnexpectedValueException The current object cannot be its own parent.
101
+ */
102
+ public function getMasterObject ()
103
+ {
104
+ if (!$ this ->masterObject && $ this ->hasMaster ()) {
105
+ $ master = $ this ->objFromIdent ($ this ->getMaster ());
106
+
107
+ if ($ master instanceof ModelInterface) {
108
+ if ($ master ->id () === $ this ->id ()) {
109
+ throw new UnexpectedValueException (sprintf (
110
+ 'Can not be ones own parent: %s ' ,
111
+ $ master ->id ()
112
+ ));
113
+ }
114
+ }
115
+
116
+ $ this ->masterObject = $ master ;
117
+ }
118
+
119
+ return $ this ->masterObject ;
120
+ }
121
+
102
122
/**
103
123
* Determine if this object has a direct parent.
104
124
*
@@ -145,7 +165,7 @@ public function isLastLevel()
145
165
public function hierarchyLevel ()
146
166
{
147
167
$ hierarchy = $ this ->hierarchy ();
148
- $ level = (count ($ hierarchy ) + 1 );
168
+ $ level = (count ($ hierarchy ) + 1 );
149
169
150
170
return $ level ;
151
171
}
@@ -184,10 +204,10 @@ public function hierarchy()
184
204
{
185
205
if (!isset ($ this ->hierarchy )) {
186
206
$ hierarchy = [];
187
- $ master = $ this ->getMaster ();
207
+ $ master = $ this ->getMasterObject ();
188
208
while ($ master ) {
189
209
$ hierarchy [] = $ master ;
190
- $ master = $ master ->getMaster ();
210
+ $ master = $ master ->getMasterObject ();
191
211
}
192
212
193
213
$ this ->hierarchy = $ hierarchy ;
@@ -204,6 +224,7 @@ public function hierarchy()
204
224
public function invertedHierarchy ()
205
225
{
206
226
$ hierarchy = $ this ->hierarchy ();
227
+
207
228
return array_reverse ($ hierarchy );
208
229
}
209
230
@@ -216,7 +237,8 @@ public function invertedHierarchy()
216
237
public function isMasterOf ($ child )
217
238
{
218
239
$ child = $ this ->objFromIdent ($ child );
219
- return ($ child ->getMaster () == $ this );
240
+
241
+ return ($ child ->getMaster () === $ this ->id ());
220
242
}
221
243
222
244
/**
@@ -240,6 +262,7 @@ public function recursiveIsMasterOf($child)
240
262
public function hasChildren ()
241
263
{
242
264
$ numChildren = $ this ->numChildren ();
265
+
243
266
return ($ numChildren > 0 );
244
267
}
245
268
@@ -250,6 +273,7 @@ public function hasChildren()
250
273
public function numChildren ()
251
274
{
252
275
$ children = $ this ->children ();
276
+
253
277
return count ($ children );
254
278
}
255
279
@@ -274,13 +298,14 @@ public function setChildren(array $children)
274
298
foreach ($ children as $ c ) {
275
299
$ this ->addChild ($ c );
276
300
}
301
+
277
302
return $ this ;
278
303
}
279
304
280
305
/**
281
306
* @param mixed $child The child object (or ident) to add.
282
- * @throws UnexpectedValueException The current object cannot be its own child.
283
307
* @return HierarchicalInterface Chainable
308
+ * @throws UnexpectedValueException The current object cannot be its own child.
284
309
*/
285
310
public function addChild ($ child )
286
311
{
@@ -311,6 +336,7 @@ public function children()
311
336
}
312
337
313
338
$ this ->children = $ this ->loadChildren ();
339
+
314
340
return $ this ->children ;
315
341
}
316
342
@@ -329,7 +355,8 @@ public function isChildOf($master)
329
355
if ($ master === null ) {
330
356
return false ;
331
357
}
332
- return ($ master == $ this ->getMaster ());
358
+
359
+ return ($ master ->id () === $ this ->getMaster ());
333
360
}
334
361
335
362
/**
@@ -342,7 +369,7 @@ public function recursiveIsChildOf($master)
342
369
return true ;
343
370
}
344
371
345
- if ($ this ->hasParents () && $ this ->getMaster ()->recursiveIsChildOf ($ master )) {
372
+ if ($ this ->hasParents () && $ this ->getMasterObject ()->recursiveIsChildOf ($ master )) {
346
373
return true ;
347
374
}
348
375
@@ -355,6 +382,7 @@ public function recursiveIsChildOf($master)
355
382
public function hasSiblings ()
356
383
{
357
384
$ numSiblings = $ this ->numSiblings ();
385
+
358
386
return ($ numSiblings > 1 );
359
387
}
360
388
@@ -364,6 +392,7 @@ public function hasSiblings()
364
392
public function numSiblings ()
365
393
{
366
394
$ siblings = $ this ->siblings ();
395
+
367
396
return count ($ siblings );
368
397
}
369
398
@@ -376,7 +405,7 @@ public function siblings()
376
405
if ($ this ->siblings !== null ) {
377
406
return $ this ->siblings ;
378
407
}
379
- $ master = $ this ->getMaster ();
408
+ $ master = $ this ->getMasterObject ();
380
409
if ($ master === null ) {
381
410
// Todo: return all top-level objects.
382
411
$ siblings = [];
@@ -385,6 +414,7 @@ public function siblings()
385
414
$ siblings = $ master ->children ();
386
415
}
387
416
$ this ->siblings = $ siblings ;
417
+
388
418
return $ this ->siblings ;
389
419
}
390
420
@@ -395,13 +425,14 @@ public function siblings()
395
425
public function isSiblingOf ($ sibling )
396
426
{
397
427
$ sibling = $ this ->objFromIdent ($ sibling );
398
- return ($ sibling ->getMaster () == $ this ->getMaster ());
428
+
429
+ return ($ sibling ->getMaster () === $ this ->getMaster ());
399
430
}
400
431
401
432
/**
402
433
* @param mixed $ident The ident.
403
- * @throws InvalidArgumentException If the identifier is not a scalar value.
404
434
* @return HierarchicalInterface|null
435
+ * @throws InvalidArgumentException If the identifier is not a scalar value.
405
436
*/
406
437
private function objFromIdent ($ ident )
407
438
{
0 commit comments