Skip to content

Commit bdfc56d

Browse files
authored
Merge pull request #11 from locomotivemtl/joel/fix-hierarchical-master
fix hierarchical-trait master object loading BREAKING: the master method now returns the master ID and masterObject returns the actual object
2 parents bec134f + 517ad64 commit bdfc56d

File tree

6 files changed

+121
-74
lines changed

6 files changed

+121
-74
lines changed

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
language: php
22

33
php:
4-
- 5.6
5-
- 7.0
6-
- 7.1
7-
- 7.2
4+
- 7.3
5+
- 8.0
86
- nightly
97

108
env:

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
"prefer-stable": true,
1414
"extra": {
1515
"branch-alias": {
16-
"dev-master": "0.7.x-dev"
16+
"dev-master": "0.8.x-dev"
1717
}
1818
},
1919
"require": {
20-
"php": ">=5.6.0 || >=7.0",
20+
"php": "^7.3 || ^8.0",
2121
"psr/log": "^1.0",
2222
"locomotivemtl/charcoal-config": "~0.10",
2323
"locomotivemtl/charcoal-core": "~0.5",

src/Charcoal/Object/HierarchicalCollection.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,21 @@ public function sortTree()
7171

7272
foreach ($this->objects as $object) {
7373
// Repair bad hierarchy.
74-
if ($object->hasMaster() && $object->getMaster()->id() === $object->id()) {
74+
if ($object->hasMaster() && $object->getMaster() === $object->id()) {
7575
$object->setMaster(0);
7676
$object->update([ 'master' ]);
7777
}
7878

7979
if ($object->hasMaster()) {
80-
$childObjects[$object->getMaster()->id()][] = $object;
80+
$childObjects[$object->getMaster()][] = $object;
8181
} else {
8282
$rootObjects[] = $object;
8383
}
8484
}
8585

8686
if (empty($rootObjects) && !empty($childObjects)) {
8787
foreach ($childObjects as $parentId => $children) {
88-
$parentObj = $children[0]->getMaster();
88+
$parentObj = $children[0]->getMasterObject();
8989
$parentObj->auxiliary = true;
9090

9191
$rootObjects[] = $parentObj;
@@ -190,15 +190,15 @@ private function sortDescendantObjects(
190190
foreach ($childObjects[$parentObj->id()] as $object) {
191191
if ($count === 0 && $object->hasMaster()) {
192192
$myParents = [];
193-
$myParent = $object->getMaster();
193+
$myParent = $object->getMasterObject();
194194
while ($myParent) {
195195
$myParents[] = $myParent;
196196

197197
if (!$myParent->hasMaster()) {
198198
break;
199199
}
200200

201-
$myParent = $myParent->getMaster();
201+
$myParent = $myParent->getMasterObject();
202202
}
203203

204204
$numParents = count($myParents);
@@ -236,15 +236,15 @@ private function sortDescendantObjects(
236236
// If the page starts in a subtree, print the parents.
237237
if ($count === $start && $object->hasMaster()) {
238238
$myParents = [];
239-
$myParent = $object->getMaster();
239+
$myParent = $object->getMasterObject();
240240
while ($myParent) {
241241
$myParents[] = $myParent;
242242

243243
if (!$myParent->hasMaster()) {
244244
break;
245245
}
246246

247-
$myParent = $myParent->getMaster();
247+
$myParent = $myParent->getMasterObject();
248248
}
249249

250250
$numParents = count($myParents);

src/Charcoal/Object/HierarchicalInterface.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,17 @@ public function hierarchyLevel();
4444
/**
4545
* Retrieve this object's immediate parent.
4646
*
47-
* @return HierarchicalInterface|null
47+
* @return string|integer|null
4848
*/
4949
public function getMaster();
5050

51+
/**
52+
* Retrieve this object's immediate parent as object.
53+
*
54+
* @return HierarchicalInterface|null
55+
*/
56+
public function getMasterObject();
57+
5158
/**
5259
* Retrieve the top-level ancestor of this object.
5360
*

src/Charcoal/Object/HierarchicalTrait.php

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ trait HierarchicalTrait
1616
/**
1717
* The object's parent, if any, in the hierarchy.
1818
*
19-
* @var HierarchicalInterface|null
19+
* @var string|integer|null
2020
*/
2121
protected $master;
2222

@@ -41,6 +41,13 @@ trait HierarchicalTrait
4141
*/
4242
private $siblings;
4343

44+
/**
45+
* The object's parent object, if any, in the hierarchy.
46+
*
47+
* @var HierarchicalInterface|null
48+
*/
49+
private $masterObject;
50+
4451
/**
4552
* A store of cached objects.
4653
*
@@ -65,23 +72,11 @@ public function resetHierarchy()
6572
/**
6673
* Set this object's immediate parent.
6774
*
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).
7076
* @return HierarchicalInterface Chainable
7177
*/
7278
public function setMaster($master)
7379
{
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-
8580
$this->master = $master;
8681

8782
$this->resetHierarchy();
@@ -92,13 +87,38 @@ public function setMaster($master)
9287
/**
9388
* Retrieve this object's immediate parent.
9489
*
95-
* @return HierarchicalInterface|null
90+
* @return string|null
9691
*/
9792
public function getMaster()
9893
{
9994
return $this->master;
10095
}
10196

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+
102122
/**
103123
* Determine if this object has a direct parent.
104124
*
@@ -145,7 +165,7 @@ public function isLastLevel()
145165
public function hierarchyLevel()
146166
{
147167
$hierarchy = $this->hierarchy();
148-
$level = (count($hierarchy) + 1);
168+
$level = (count($hierarchy) + 1);
149169

150170
return $level;
151171
}
@@ -184,10 +204,10 @@ public function hierarchy()
184204
{
185205
if (!isset($this->hierarchy)) {
186206
$hierarchy = [];
187-
$master = $this->getMaster();
207+
$master = $this->getMasterObject();
188208
while ($master) {
189209
$hierarchy[] = $master;
190-
$master = $master->getMaster();
210+
$master = $master->getMasterObject();
191211
}
192212

193213
$this->hierarchy = $hierarchy;
@@ -204,6 +224,7 @@ public function hierarchy()
204224
public function invertedHierarchy()
205225
{
206226
$hierarchy = $this->hierarchy();
227+
207228
return array_reverse($hierarchy);
208229
}
209230

@@ -216,7 +237,8 @@ public function invertedHierarchy()
216237
public function isMasterOf($child)
217238
{
218239
$child = $this->objFromIdent($child);
219-
return ($child->getMaster() == $this);
240+
241+
return ($child->getMaster() === $this->id());
220242
}
221243

222244
/**
@@ -240,6 +262,7 @@ public function recursiveIsMasterOf($child)
240262
public function hasChildren()
241263
{
242264
$numChildren = $this->numChildren();
265+
243266
return ($numChildren > 0);
244267
}
245268

@@ -250,6 +273,7 @@ public function hasChildren()
250273
public function numChildren()
251274
{
252275
$children = $this->children();
276+
253277
return count($children);
254278
}
255279

@@ -274,13 +298,14 @@ public function setChildren(array $children)
274298
foreach ($children as $c) {
275299
$this->addChild($c);
276300
}
301+
277302
return $this;
278303
}
279304

280305
/**
281306
* @param mixed $child The child object (or ident) to add.
282-
* @throws UnexpectedValueException The current object cannot be its own child.
283307
* @return HierarchicalInterface Chainable
308+
* @throws UnexpectedValueException The current object cannot be its own child.
284309
*/
285310
public function addChild($child)
286311
{
@@ -311,6 +336,7 @@ public function children()
311336
}
312337

313338
$this->children = $this->loadChildren();
339+
314340
return $this->children;
315341
}
316342

@@ -329,7 +355,8 @@ public function isChildOf($master)
329355
if ($master === null) {
330356
return false;
331357
}
332-
return ($master == $this->getMaster());
358+
359+
return ($master->id() === $this->getMaster());
333360
}
334361

335362
/**
@@ -342,7 +369,7 @@ public function recursiveIsChildOf($master)
342369
return true;
343370
}
344371

345-
if ($this->hasParents() && $this->getMaster()->recursiveIsChildOf($master)) {
372+
if ($this->hasParents() && $this->getMasterObject()->recursiveIsChildOf($master)) {
346373
return true;
347374
}
348375

@@ -355,6 +382,7 @@ public function recursiveIsChildOf($master)
355382
public function hasSiblings()
356383
{
357384
$numSiblings = $this->numSiblings();
385+
358386
return ($numSiblings > 1);
359387
}
360388

@@ -364,6 +392,7 @@ public function hasSiblings()
364392
public function numSiblings()
365393
{
366394
$siblings = $this->siblings();
395+
367396
return count($siblings);
368397
}
369398

@@ -376,7 +405,7 @@ public function siblings()
376405
if ($this->siblings !== null) {
377406
return $this->siblings;
378407
}
379-
$master = $this->getMaster();
408+
$master = $this->getMasterObject();
380409
if ($master === null) {
381410
// Todo: return all top-level objects.
382411
$siblings = [];
@@ -385,6 +414,7 @@ public function siblings()
385414
$siblings = $master->children();
386415
}
387416
$this->siblings = $siblings;
417+
388418
return $this->siblings;
389419
}
390420

@@ -395,13 +425,14 @@ public function siblings()
395425
public function isSiblingOf($sibling)
396426
{
397427
$sibling = $this->objFromIdent($sibling);
398-
return ($sibling->getMaster() == $this->getMaster());
428+
429+
return ($sibling->getMaster() === $this->getMaster());
399430
}
400431

401432
/**
402433
* @param mixed $ident The ident.
403-
* @throws InvalidArgumentException If the identifier is not a scalar value.
404434
* @return HierarchicalInterface|null
435+
* @throws InvalidArgumentException If the identifier is not a scalar value.
405436
*/
406437
private function objFromIdent($ident)
407438
{

0 commit comments

Comments
 (0)