/** * Get slice of menu as another menu. * * If offset and/or length are numeric, it works like in array_slice function: * * If offset is non-negative, slice will start at the offset. * If offset is negative, slice will start that far from the end. * * If length is null, slice will have all elements. * If length is positive, slice will have that many elements. * If length is negative, slice will stop that far from the end. * * It's possible to mix names/object/numeric, for example: * slice("child1", 2); * slice(3, $child5); * Note: when using a child as limit, it will not be included in the returned menu. * the slice is done before this menu. * * @param ItemInterface $item * @param mixed $offset Name of child, child object, or numeric offset. * @param mixed $length Name of child, child object, or numeric length. * * @return ItemInterface */ public function slice(ItemInterface $item, $offset, $length = null) { $names = array_keys($item->getChildren()); if ($offset instanceof ItemInterface) { $offset = $offset->getName(); } if (!is_numeric($offset)) { $offset = array_search($offset, $names); } if (null !== $length) { if ($length instanceof ItemInterface) { $length = $length->getName(); } if (!is_numeric($length)) { $index = array_search($length, $names); $length = $index < $offset ? 0 : $index - $offset; } } $slicedItem = $item->copy(); $children = array_slice($slicedItem->getChildren(), $offset, $length); $slicedItem->setChildren($children); return $slicedItem; }