sentinel = new TreeNode(); } /** * Add a child node * * @param TreeNode $child * @param TreeNode $parent * * @return $this */ public function addChild(TreeNode $child, TreeNode $parent = null) { if ($parent === null) { $parent = $this->sentinel; } elseif (! isset($this->nodes[$parent->getId()])) { throw new LogicException(sprintf( 'Can\'t append child node %s to parent node %s: Parent node does not exist', $child->getId(), $parent->getId() )); } if (isset($this->nodes[$child->getId()])) { throw new LogicException(sprintf( 'Can\'t append child node %s to parent node %s: Child node does already exist', $child->getId(), $parent->getId() )); } $this->nodes[$child->getId()] = $child; $parent->appendChild($child); return $this; } /** * Get a node by its ID * * @param mixed $id * * @return TreeNode|null */ public function getNode($id) { if (! isset($this->nodes[$id])) { return null; } return $this->nodes[$id]; } /** * @return TreeNodeIterator */ public function getIterator(): Traversable { return new TreeNodeIterator($this->sentinel); } }