@@ -18,7 +18,7 @@ trait HierarchicalTrait
18
18
*
19
19
* @var string|integer|null
20
20
*/
21
- protected $ master ;
21
+ protected $ master = null ;
22
22
23
23
/**
24
24
* Store a copy of the object's ancestry.
@@ -32,21 +32,21 @@ trait HierarchicalTrait
32
32
*
33
33
* @var HierarchicalInterface[]|null
34
34
*/
35
- private $ children ;
35
+ private $ children = null ;
36
36
37
37
/**
38
38
* Store a copy of the object's siblings.
39
39
*
40
40
* @var HierarchicalInterface[]|null
41
41
*/
42
- private $ siblings ;
42
+ private $ siblings = null ;
43
43
44
44
/**
45
45
* The object's parent object, if any, in the hierarchy.
46
46
*
47
47
* @var HierarchicalInterface|null
48
48
*/
49
- private $ masterObject ;
49
+ private $ masterObject = null ;
50
50
51
51
/**
52
52
* A store of cached objects.
@@ -128,14 +128,24 @@ public function getMasterObject()
128
128
return $ this ->masterObject ;
129
129
}
130
130
131
+ /**
132
+ * Determine if this object's immediate parent exists.
133
+ *
134
+ * @return boolean
135
+ */
136
+ public function hasMasterObject ()
137
+ {
138
+ return (bool )$ this ->getMasterObject ();
139
+ }
140
+
131
141
/**
132
142
* Determine if this object has a direct parent.
133
143
*
134
144
* @return boolean
135
145
*/
136
146
public function hasMaster ()
137
147
{
138
- return ($ this ->getMaster () !== null );
148
+ return (bool ) $ this ->getMaster ();
139
149
}
140
150
141
151
/**
@@ -147,7 +157,7 @@ public function hasMaster()
147
157
*/
148
158
public function isTopLevel ()
149
159
{
150
- return ( $ this ->getMaster () === null );
160
+ return ! $ this ->getMaster ();
151
161
}
152
162
153
163
/**
@@ -201,34 +211,44 @@ public function toplevelMaster()
201
211
*/
202
212
public function hasParents ()
203
213
{
204
- return !! count ($ this ->hierarchy ());
214
+ return count ($ this ->hierarchy ()) > 0 ;
205
215
}
206
216
207
217
/**
208
218
* Retrieve this object's ancestors (from immediate parent to top-level).
209
219
*
210
- * @return array
220
+ * @return HierarchicalInterface[]
211
221
*/
212
222
public function hierarchy ()
213
223
{
214
- if (!isset ($ this ->hierarchy )) {
215
- $ hierarchy = [];
216
- $ master = $ this ->getMasterObject ();
217
- while ($ master ) {
218
- $ hierarchy [] = $ master ;
219
- $ master = $ master ->getMasterObject ();
220
- }
221
-
222
- $ this ->hierarchy = $ hierarchy ;
224
+ if ($ this ->hierarchy === null ) {
225
+ $ this ->hierarchy = $ this ->loadHierarchy ();
223
226
}
224
227
225
228
return $ this ->hierarchy ;
226
229
}
227
230
231
+ /**
232
+ * Build this object's ancestors (from immediate parent to top-level).
233
+ *
234
+ * @return HierarchicalInterface[]
235
+ */
236
+ public function loadHierarchy ()
237
+ {
238
+ $ hierarchy = [];
239
+ $ master = $ this ->getMasterObject ();
240
+ while ($ master ) {
241
+ $ hierarchy [] = $ master ;
242
+ $ master = $ master ->getMasterObject ();
243
+ }
244
+
245
+ return $ hierarchy ;
246
+ }
247
+
228
248
/**
229
249
* Retrieve this object's ancestors, inverted from top-level to immediate.
230
250
*
231
- * @return array
251
+ * @return HierarchicalInterface[]
232
252
*/
233
253
public function invertedHierarchy ()
234
254
{
@@ -290,15 +310,15 @@ public function numChildren()
290
310
* Get the total number of children in the entire hierarchy.
291
311
* This method counts all children and sub-children, unlike `numChildren()` which only count 1 level.
292
312
* @return integer
313
+ * @todo Implementation needed.
293
314
*/
294
315
public function recursiveNumChildren ()
295
316
{
296
- // TODO
297
317
return 0 ;
298
318
}
299
319
300
320
/**
301
- * @param array $children The children to set.
321
+ * @param mixed[] $children The children to set.
302
322
* @return HierarchicalInterface Chainable
303
323
*/
304
324
public function setChildren (array $ children )
@@ -336,7 +356,7 @@ public function addChild($child)
336
356
337
357
/**
338
358
* Get the children directly under this object.
339
- * @return array
359
+ * @return ModelInterface[]
340
360
*/
341
361
public function children ()
342
362
{
@@ -361,11 +381,8 @@ abstract public function loadChildren();
361
381
public function isChildOf ($ master )
362
382
{
363
383
$ master = $ this ->objFromIdent ($ master );
364
- if ($ master === null ) {
365
- return false ;
366
- }
367
384
368
- return ($ master ->id () === $ this ->getMaster ());
385
+ return ($ master && $ master ->id () === $ this ->getMaster ());
369
386
}
370
387
371
388
/**
@@ -378,8 +395,8 @@ public function recursiveIsChildOf($master)
378
395
return true ;
379
396
}
380
397
381
- if ($ this ->hasParents () && $ this ->getMasterObject ()-> recursiveIsChildOf ( $ master )) {
382
- return true ;
398
+ if ($ this ->hasParents () && $ this ->hasMasterObject ( )) {
399
+ return $ this -> getMasterObject ()-> recursiveIsChildOf ( $ master ) ;
383
400
}
384
401
385
402
return false ;
@@ -407,24 +424,32 @@ public function numSiblings()
407
424
408
425
/**
409
426
* Get all the objects on the same level as this one.
410
- * @return array
427
+ * @return ModelInterface[]
411
428
*/
412
429
public function siblings ()
413
430
{
414
- if ($ this ->siblings ! == null ) {
415
- return $ this ->siblings ;
431
+ if ($ this ->siblings = == null ) {
432
+ $ this ->siblings = $ this -> loadSiblings () ;
416
433
}
434
+
435
+ return $ this ->siblings ;
436
+ }
437
+
438
+ /**
439
+ * Get all the objects on the same level as this one.
440
+ * @return ModelInterface[]
441
+ * @todo Implementation needed.
442
+ */
443
+ public function loadSiblings ()
444
+ {
417
445
$ master = $ this ->getMasterObject ();
418
- if ($ master === null ) {
419
- // Todo: return all top-level objects.
420
- $ siblings = [];
421
- } else {
446
+ if ($ master ) {
422
447
// Todo: Remove "current" object from siblings
423
- $ siblings = $ master ->children ();
448
+ return $ master ->children ();
424
449
}
425
- $ this ->siblings = $ siblings ;
426
450
427
- return $ this ->siblings ;
451
+ // TODO: return all top-level objects.
452
+ return [];
428
453
}
429
454
430
455
/**
@@ -440,7 +465,7 @@ public function isSiblingOf($sibling)
440
465
441
466
/**
442
467
* @param mixed $ident The ident.
443
- * @return HierarchicalInterface|null
468
+ * @return ( HierarchicalInterface&ModelInterface) |null
444
469
* @throws InvalidArgumentException If the identifier is not a scalar value.
445
470
*/
446
471
private function objFromIdent ($ ident )
@@ -472,7 +497,6 @@ private function objFromIdent($ident)
472
497
}
473
498
474
499
$ obj = $ this ->loadObjectFromSource ($ ident );
475
-
476
500
if ($ obj !== null ) {
477
501
$ this ->addObjectToCache ($ obj );
478
502
}
@@ -484,7 +508,7 @@ private function objFromIdent($ident)
484
508
* Retrieve an object from the storage source by its ID.
485
509
*
486
510
* @param mixed $id The object id.
487
- * @return null| HierarchicalInterface
511
+ * @return ( HierarchicalInterface&ModelInterface)|null
488
512
*/
489
513
private function loadObjectFromSource ($ id )
490
514
{
@@ -493,25 +517,25 @@ private function loadObjectFromSource($id)
493
517
494
518
if ($ obj ->id ()) {
495
519
return $ obj ;
496
- } else {
497
- return null ;
498
520
}
521
+
522
+ return null ;
499
523
}
500
524
501
525
/**
502
526
* Retrieve an object from the cache store by its ID.
503
527
*
504
528
* @param mixed $id The object id.
505
- * @return null| HierarchicalInterface
529
+ * @return ( HierarchicalInterface&ModelInterface)|null
506
530
*/
507
531
private function loadObjectFromCache ($ id )
508
532
{
509
533
$ objType = $ this ->objType ();
510
534
if (isset (static ::$ objectCache [$ objType ][$ id ])) {
511
535
return static ::$ objectCache [$ objType ][$ id ];
512
- } else {
513
- return null ;
514
536
}
537
+
538
+ return null ;
515
539
}
516
540
517
541
/**
0 commit comments