/** * Constructor. * * @param PartInterface[] $components compound parts */ public function __construct(array $components) { $this->componentCollection = new ObjectCollection($components); $this->componentCollection->onChange([$this, 'requireTreeUpdate']); $this->componentCollection->onItemRemove(function (PartInterface $item) { $item->detach(); }); $this->componentCollection->onItemAdd(function (PartInterface $part) { if ($this->hasComponent($part->getId())) { $this->removeComponent($part->getId()); } }); $this->initializeCollection([]); $this->childrenInternal()->onItemAdd(function ($item) { if ($item instanceof PartInterface && !$this->componentCollection->contains($item)) { $this->componentCollection->add($item); } }); }
/** * Returns collection containing all descendant nodes. * * @return CollectionInterface|ObjectCollection|ChildNodeInterface[] */ public function getChildrenRecursive() { $res = new ObjectCollection(); foreach ($this->children() as $child) { $res->add($child); if ($child instanceof ParentNodeInterface) { $res->addMany($child->getChildrenRecursive()); } } return $res; }
/** * @return ObjectCollection */ public function parents() { $parents = new ObjectCollection(); $current = $this->parent(); while ($current instanceof ParentNodeInterface) { $parents->add($current); if (!$current instanceof ChildNodeInterface) { break; } $current = $current->parent(); } return $parents; }
/** * Adds component to collection. * * If component is already in collection, it will not be added twice. * * @param ChildNodeInterface $item * @param bool $prepend Pass true to add component to the beginning of an array. * * @return $this */ public function add($item, $prepend = false) { if (!$item instanceof ChildNodeInterface) { $details = is_object($item) ? get_class($item) : gettype($item); throw new InvalidArgumentException("NodeCollection accepts only objects implementing ChildNodeInterface, {$details} given."); } $old = $item->parent(); if ($old === $this->parentNode) { return $this; } elseif ($old !== null) { $item->detach(); } $this->checkUnlocked($item); parent::add($item, $prepend); $item->internalSetParent($this->parentNode); return $this; }