Skip to content

Commit

Permalink
Merge 49dcb5d into bec134f
Browse files Browse the repository at this point in the history
  • Loading branch information
JoelAlphonso committed Nov 5, 2020
2 parents bec134f + 49dcb5d commit 9c4abce
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 68 deletions.
14 changes: 7 additions & 7 deletions src/Charcoal/Object/HierarchicalCollection.php
Expand Up @@ -71,21 +71,21 @@ public function sortTree()

foreach ($this->objects as $object) {
// Repair bad hierarchy.
if ($object->hasMaster() && $object->getMaster()->id() === $object->id()) {
if ($object->hasMaster() && $object->getMaster() === $object->id()) {
$object->setMaster(0);
$object->update([ 'master' ]);
}

if ($object->hasMaster()) {
$childObjects[$object->getMaster()->id()][] = $object;
$childObjects[$object->getMaster()][] = $object;
} else {
$rootObjects[] = $object;
}
}

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

$rootObjects[] = $parentObj;
Expand Down Expand Up @@ -190,15 +190,15 @@ private function sortDescendantObjects(
foreach ($childObjects[$parentObj->id()] as $object) {
if ($count === 0 && $object->hasMaster()) {
$myParents = [];
$myParent = $object->getMaster();
$myParent = $object->getMasterObject();
while ($myParent) {
$myParents[] = $myParent;

if (!$myParent->hasMaster()) {
break;
}

$myParent = $myParent->getMaster();
$myParent = $myParent->getMasterObject();
}

$numParents = count($myParents);
Expand Down Expand Up @@ -236,15 +236,15 @@ private function sortDescendantObjects(
// If the page starts in a subtree, print the parents.
if ($count === $start && $object->hasMaster()) {
$myParents = [];
$myParent = $object->getMaster();
$myParent = $object->getMasterObject();
while ($myParent) {
$myParents[] = $myParent;

if (!$myParent->hasMaster()) {
break;
}

$myParent = $myParent->getMaster();
$myParent = $myParent->getMasterObject();
}

$numParents = count($myParents);
Expand Down
9 changes: 8 additions & 1 deletion src/Charcoal/Object/HierarchicalInterface.php
Expand Up @@ -44,10 +44,17 @@ public function hierarchyLevel();
/**
* Retrieve this object's immediate parent.
*
* @return HierarchicalInterface|null
* @return string|integer|null
*/
public function getMaster();

/**
* Retrieve this object's immediate parent as object.
*
* @return HierarchicalInterface|null
*/
public function getMasterObject();

/**
* Retrieve the top-level ancestor of this object.
*
Expand Down
81 changes: 56 additions & 25 deletions src/Charcoal/Object/HierarchicalTrait.php
Expand Up @@ -16,7 +16,7 @@ trait HierarchicalTrait
/**
* The object's parent, if any, in the hierarchy.
*
* @var HierarchicalInterface|null
* @var string|integer|null
*/
protected $master;

Expand All @@ -41,6 +41,13 @@ trait HierarchicalTrait
*/
private $siblings;

/**
* The object's parent object, if any, in the hierarchy.
*
* @var HierarchicalInterface|null
*/
private $masterObject;

/**
* A store of cached objects.
*
Expand All @@ -65,23 +72,11 @@ public function resetHierarchy()
/**
* Set this object's immediate parent.
*
* @param mixed $master The object's parent (or master).
* @throws UnexpectedValueException The current object cannot be its own parent.
* @param mixed $master The object's parent (or master).
* @return HierarchicalInterface Chainable
*/
public function setMaster($master)
{
$master = $this->objFromIdent($master);

if ($master instanceof ModelInterface) {
if ($master->id() === $this->id()) {
throw new UnexpectedValueException(sprintf(
'Can not be ones own parent: %s',
$master->id()
));
}
}

$this->master = $master;

$this->resetHierarchy();
Expand All @@ -92,13 +87,38 @@ public function setMaster($master)
/**
* Retrieve this object's immediate parent.
*
* @return HierarchicalInterface|null
* @return string|null
*/
public function getMaster()
{
return $this->master;
}

/**
* Retrieve this object's immediate parent as object.
* @return HierarchicalInterface|null
* @throws UnexpectedValueException The current object cannot be its own parent.
*/
public function getMasterObject()
{
if (!$this->masterObject && $this->hasMaster()) {
$master = $this->objFromIdent($this->getMaster());

if ($master instanceof ModelInterface) {
if ($master->id() === $this->id()) {
throw new UnexpectedValueException(sprintf(
'Can not be ones own parent: %s',
$master->id()
));
}
}

$this->masterObject = $master;
}

return $this->masterObject;
}

/**
* Determine if this object has a direct parent.
*
Expand Down Expand Up @@ -145,7 +165,7 @@ public function isLastLevel()
public function hierarchyLevel()
{
$hierarchy = $this->hierarchy();
$level = (count($hierarchy) + 1);
$level = (count($hierarchy) + 1);

return $level;
}
Expand Down Expand Up @@ -184,10 +204,10 @@ public function hierarchy()
{
if (!isset($this->hierarchy)) {
$hierarchy = [];
$master = $this->getMaster();
$master = $this->getMasterObject();
while ($master) {
$hierarchy[] = $master;
$master = $master->getMaster();
$master = $master->getMasterObject();
}

$this->hierarchy = $hierarchy;
Expand All @@ -204,6 +224,7 @@ public function hierarchy()
public function invertedHierarchy()
{
$hierarchy = $this->hierarchy();

return array_reverse($hierarchy);
}

Expand All @@ -216,7 +237,8 @@ public function invertedHierarchy()
public function isMasterOf($child)
{
$child = $this->objFromIdent($child);
return ($child->getMaster() == $this);

return ($child->getMaster() === $this->id());
}

/**
Expand All @@ -240,6 +262,7 @@ public function recursiveIsMasterOf($child)
public function hasChildren()
{
$numChildren = $this->numChildren();

return ($numChildren > 0);
}

Expand All @@ -250,6 +273,7 @@ public function hasChildren()
public function numChildren()
{
$children = $this->children();

return count($children);
}

Expand All @@ -274,13 +298,14 @@ public function setChildren(array $children)
foreach ($children as $c) {
$this->addChild($c);
}

return $this;
}

/**
* @param mixed $child The child object (or ident) to add.
* @throws UnexpectedValueException The current object cannot be its own child.
* @return HierarchicalInterface Chainable
* @throws UnexpectedValueException The current object cannot be its own child.
*/
public function addChild($child)
{
Expand Down Expand Up @@ -311,6 +336,7 @@ public function children()
}

$this->children = $this->loadChildren();

return $this->children;
}

Expand All @@ -329,7 +355,8 @@ public function isChildOf($master)
if ($master === null) {
return false;
}
return ($master == $this->getMaster());

return ($master->id() === $this->getMaster());
}

/**
Expand All @@ -342,7 +369,7 @@ public function recursiveIsChildOf($master)
return true;
}

if ($this->hasParents() && $this->getMaster()->recursiveIsChildOf($master)) {
if ($this->hasParents() && $this->getMasterObject()->recursiveIsChildOf($master)) {
return true;
}

Expand All @@ -355,6 +382,7 @@ public function recursiveIsChildOf($master)
public function hasSiblings()
{
$numSiblings = $this->numSiblings();

return ($numSiblings > 1);
}

Expand All @@ -364,6 +392,7 @@ public function hasSiblings()
public function numSiblings()
{
$siblings = $this->siblings();

return count($siblings);
}

Expand All @@ -376,7 +405,7 @@ public function siblings()
if ($this->siblings !== null) {
return $this->siblings;
}
$master = $this->getMaster();
$master = $this->getMasterObject();
if ($master === null) {
// Todo: return all top-level objects.
$siblings = [];
Expand All @@ -385,6 +414,7 @@ public function siblings()
$siblings = $master->children();
}
$this->siblings = $siblings;

return $this->siblings;
}

Expand All @@ -395,13 +425,14 @@ public function siblings()
public function isSiblingOf($sibling)
{
$sibling = $this->objFromIdent($sibling);
return ($sibling->getMaster() == $this->getMaster());

return ($sibling->getMaster() === $this->getMaster());
}

/**
* @param mixed $ident The ident.
* @throws InvalidArgumentException If the identifier is not a scalar value.
* @return HierarchicalInterface|null
* @throws InvalidArgumentException If the identifier is not a scalar value.
*/
private function objFromIdent($ident)
{
Expand Down

0 comments on commit 9c4abce

Please sign in to comment.