/** * Attempts to get an ancestor node by the given id. * * @param int $id * @return null|AbstractNode */ public function getAncestor($id) { if (!is_null($this->parent)) { if ($this->parent->id() == $id) { return $this->parent; } return $this->parent->getAncestor($id); } return null; }
/** * Adds a child node to this node and returns the id of the child for this * parent. * * @param AbstractNode $child * @return bool * @throws CircularExceptionException */ public function addChild(AbstractNode $child) { $key = null; $newKey = 0; // check integrity if ($this->isAncestor($child->id())) { throw new CircularException('Can not add child. It is my ancestor.'); } // check if child is itself if ($child->id() == $this->id) { throw new CircularException('Can not set itself as a child.'); } if ($this->hasChildren()) { if (isset($this->children[$child->id()])) { // we already have this child return false; } $sibling = $this->lastChild(); $key = $sibling->id(); $this->children[$key]['next'] = $child->id(); } // add the child $this->children[$child->id()] = array('node' => $child, 'next' => null, 'prev' => $key); // tell child I am the new parent $child->setParent($this); //clear any cache $this->clear(); return true; }
/** * Removes the child with id $childId and replace it with the new child * $newChild. * * @param int $childId * @param AbstractNode $newChild * @throws ChildNotFoundException */ public function replaceChild($childId, AbstractNode $newChild) { $oldChild = $this->getChild($childId); $keys = array_keys($this->children); $index = array_search($childId, $keys, true); $keys[$index] = $newChild->id(); $this->children = array_combine($keys, $this->children); $this->children[$newChild->id()] = $newChild; unset($oldChild); }