/** * Reorder menu based on position attribute * * @param ItemInterface $menu */ protected function sort(ItemInterface $menu) { if ($menu->hasChildren() && $menu->getDisplayChildren()) { $orderedChildren = []; $unorderedChildren = []; $hasOrdering = false; $children = $menu->getChildren(); foreach ($children as &$child) { if ($child->hasChildren() && $child->getDisplayChildren()) { $this->sort($child); } $position = $child->getExtra('position'); if ($position !== null) { $orderedChildren[$child->getName()] = (int) $position; $hasOrdering = true; } else { $unorderedChildren[] = $child->getName(); } } if ($hasOrdering) { asort($orderedChildren); $menu->reorderChildren(array_merge(array_keys($orderedChildren), $unorderedChildren)); } } }
/** * Рекурсивный метод для удаления фабрики, что позволяет кешировать объект меню. * * @param ItemInterface $menu */ protected function removeFactory(ItemInterface $menu) { $menu->setFactory(new DummyFactory()); foreach ($menu->getChildren() as $subMenu) { $this->removeFactory($subMenu); } }
/** * Get a flattened array containing references to all of the items * * @param ItemInterface $item The menu item * @param bool $isTop Is the initial menu item starting at the top-level? * @return array */ public static function flattenMenuItems(ItemInterface $item, $isTop = true) { $arr = $isTop ? [] : [$item]; foreach ($item->getChildren() as $child) { $arr = array_merge($arr, self::flattenMenuItems($child, false)); } return $arr; }
/** * Reorder the menu * * @param \Knp\Menu\ItemInterface $menu * * @return MenuItem */ private function reorderMenu($menu) { $menuItems = $menu->getChildren(); usort($menuItems, array($this, 'menuSort')); $newMenuOrder = array(); foreach ($menuItems as $menuItem) { $newMenuOrder[] = $menuItem->getName(); } $menu->reorderChildren($newMenuOrder); return $menu; }
/** * Convert Menu children to be a Bootstrap menu. * * The options array expect a key "automenu" * set to a string of possibleNavs * * Additional options may be specified and code tightened. * * @param ItemInterface $item * @param array $options */ public function convertChildren(ItemInterface $item, array $options) { foreach ($item->getChildren() as $child) { $autoChildOptions = $this->getChildOptions($child, $options); $childOptions = $this->decorator->buildOptions($autoChildOptions); $this->decorator->buildItem($child, $childOptions); if (isset($option['autochilds']) && $option['autochilds']) { $this->convertChildren($child, $options); } } }
/** * {@inheritdoc} */ public function matchItem(ItemInterface $item) { $children = $item->getChildren(); $match = null; foreach ($children as $child) { if ($this->matcher->isCurrent($child)) { $match = true; break; } } return $match; }
/** * Renders all of the children of this menu. * * This calls ->renderItem() on each menu item, which instructs each * menu item to render themselves as an <li> tag (with nested ul if it * has children). * This method updates the depth for the children. * * @param \Knp\Menu\ItemInterface $item * @param array $options The options to render the item. * @return string */ protected function renderChildren(ItemInterface $item, array $options) { // render children with a depth - 1 if (null !== $options['depth']) { $options['depth'] = $options['depth'] - 1; } $html = ''; foreach ($item->getChildren() as $child) { $html .= $this->renderItem($child, $options); } return $html; }
public function isAncestor(ItemInterface $item, $depth = null) { if (0 === $depth) { return false; } $childDepth = null === $depth ? null : $depth - 1; foreach ($item->getChildren() as $child) { if ($this->isCurrent($child) || $this->isAncestor($child, $childDepth)) { return true; } } return false; }
/** * Get current item * * @param ItemInterface $item * * @return ItemInterface|null */ private function getCurrentItem(ItemInterface $item) { foreach ($item->getChildren() as $child) { if ($this->matcher->isCurrent($child)) { return $child; } else { $child = $this->getCurrentItem($child); if ($child) { return $child; } } } return null; }
/** * Specifies, whether the children of an item are displayed when rendering the menu * * @param ItemInterface $item * * @return bool */ public function hasChildrenHelper(ItemInterface $item) { if (!$item->isDisplayed()) { return false; } foreach ($item->getChildren() as $child) { /** @var ItemInterface $child */ if (!$child->getExtra("pageTree:hidden", false)) { // if we find a child which is not hidden, we need to render the menu return true; } } return false; }
public function filterMenu(ItemInterface $menu) { foreach ($menu->getChildren() as $child) { /** @var \Knp\Menu\MenuItem $child */ $routes = $child->getExtra('routes'); if ($routes !== null) { $route = current(current($routes)); if ($route && !$this->hasRouteAccess($route)) { $menu->removeChild($child); } } $this->filterMenu($child); } return $menu; }
/** * Reorder Menus items * * @param ItemInterface $menu */ protected function reorderMenuItems(ItemInterface $menu) { $menuOrderArray = array(); $addLast = array(); $alreadyTaken = array(); foreach ($menu->getChildren() as $key => $menuItem) { if ($menuItem->hasChildren()) { $this->reorderMenuItems($menuItem); } $orderNumber = $menuItem->getExtra('orderNumber'); if ($orderNumber != null) { if (!isset($menuOrderArray[$orderNumber])) { $menuOrderArray[$orderNumber] = $menuItem->getName(); } else { $alreadyTaken[$orderNumber] = $menuItem->getName(); // $alreadyTaken[] = array('orderNumber' => $orderNumber, 'name' => $menuItem->getName()); } } else { $addLast[] = $menuItem->getName(); } } // sort them after first pass ksort($menuOrderArray); // handle position duplicates if (count($alreadyTaken)) { foreach ($alreadyTaken as $key => $value) { // the ever shifting target $keysArray = array_keys($menuOrderArray); $position = array_search($key, $keysArray); if ($position === false) { continue; } $menuOrderArray = array_merge(array_slice($menuOrderArray, 0, $position), array($value), array_slice($menuOrderArray, $position)); } } // sort them after second pass ksort($menuOrderArray); // add items without ordernumber to the end if (count($addLast)) { foreach ($addLast as $key => $value) { $menuOrderArray[] = $value; } } if (count($menuOrderArray)) { $menu->reorderChildren($menuOrderArray); } }
protected function renderLabel(ItemInterface $item, array $options) { $html = '<i class="' . $item->getIcon() . '"></i> '; $html .= '<span>' . $item->getLabel() . '</span>'; if ($item->hasChildren()) { $drop = false; foreach ($item->getChildren() as $child) { if (\App::isGranted($child->getPermissions())) { $drop = true; } } if ($drop) { $html .= '<i class="fa fa-angle-left pull-right"></i>'; } } return $html; }
public function render(ItemInterface $item, array $options = array()) { $o = '<ul class="level1menu nav nav-sidebar">'; foreach ($item->getChildren() as $item) { $o .= '<li'; $current = false; if ($this->matcher->isCurrent($item)) { $current = true; } if ($this->matcher->isAncestor($item, 10)) { $current = true; } if ($current) { $o .= ' class="current"'; } $o .= '>'; $o .= '<a href="' . $this->urlGenerator->generate($item->getUri()) . '">'; $o .= $item->getLabel(); $o .= '</a>'; if ($current) { foreach ($item->getChildren() as $subItem) { $o .= '<ul>'; $current = false; if ($this->matcher->isCurrent($subItem)) { $current = true; } if ($this->matcher->isAncestor($subItem, 10)) { $current = true; } $o .= '<li'; if ($current) { $o .= ' class="current"'; } $o .= '>'; $o .= '<a href="' . $this->urlGenerator->generate($subItem->getUri()) . '">'; $o .= $subItem->getLabel(); $o .= '</a>'; $o .= '</li>'; $o .= '</ul>'; } } $o .= '</li>'; } $o .= '</ul>'; return $o; }
/** * Renders all of the children of this menu. * * This calls ->renderItem() on each menu item, which instructs each * menu item to render themselves as an <li> tag (with nested ul if it * has children). * This method updates the depth for the children. * * @param Item $item * @param array $options The options to render the item. * * @return string */ protected function renderChildren(Item $item, array $options) { // render children with a depth - 1 if (null !== $options['depth']) { $options['depth'] = $options['depth'] - 1; } $html = ''; foreach ($item->getChildren() as $child) { /* @var \CSBill\CoreBundle\Menu\MenuItem $child */ if ($child->isDivider()) { $html .= $this->renderDivider($child, $options); } else { $html .= $this->renderItem($child, $options); } } return $html; }
/** * Reorderd the items in the menu based on the extra data * * @param ItemInterface $menu */ protected function reorderMenuItems(ItemInterface $menu) { $menuOrderArray = array(); $addLast = array(); $alreadyTaken = array(); foreach ($menu->getChildren() as $menuItem) { if ($menuItem->hasChildren()) { $this->reorderMenuItems($menuItem); } $orderNumber = $menuItem->getExtra('orderNumber'); if ($orderNumber != null) { if (!isset($menuOrderArray[$orderNumber])) { $menuOrderArray[$orderNumber] = $menuItem->getName(); } else { $alreadyTaken[$orderNumber] = $menuItem->getName(); } } else { $addLast[] = $menuItem->getName(); } } ksort($menuOrderArray); if (!empty($alreadyTaken)) { foreach ($alreadyTaken as $key => $value) { $keysArray = array_keys($menuOrderArray); $position = array_search($key, $keysArray); if ($position === false) { continue; } $menuOrderArray = array_merge(array_slice($menuOrderArray, 0, $position), array($value), array_slice($menuOrderArray, $position)); } } ksort($menuOrderArray); if (!empty($addLast)) { foreach ($addLast as $value) { $menuOrderArray[] = $value; } } if (!empty($menuOrderArray)) { $menu->reorderChildren($menuOrderArray); } }
/** * @param ItemInterface $menu * @param array $data * @param array $itemList * @param array $options * * @return \Knp\Menu\ItemInterface */ private function createFromArray(ItemInterface $menu, array $data, array &$itemList, array $options = array()) { $isAllowed = false; foreach ($data as $itemCode => $itemData) { if (!empty($itemList[$itemCode])) { $itemOptions = $itemList[$itemCode]; if (empty($itemOptions['name'])) { $itemOptions['name'] = $itemCode; } if (empty($itemOptions['route']) && empty($itemOptions['uri'])) { $itemOptions['route'] = $itemCode; } if (!empty($itemData['position'])) { $itemOptions['extras']['position'] = $itemData['position']; } $this->moveToExtras($itemOptions, 'translateDomain'); $this->moveToExtras($itemOptions, 'translateParameters'); $newMenuItem = $menu->addChild($itemOptions['name'], array_merge($itemOptions, $options)); if (!empty($itemData['children'])) { $this->createFromArray($newMenuItem, $itemData['children'], $itemList, $options); } $isAllowed = $isAllowed || $newMenuItem->getExtra('isAllowed'); } } $menu->setExtra('isAllowed', $isAllowed); if ($menu->getExtra('hideIfEmpty') && $menu->hasChildren()) { $willDisplaySomeChildren = false; foreach ($menu->getChildren() as $child) { if ($child->isDisplayed() && $child->getExtra('isAllowed')) { $willDisplaySomeChildren = true; break; } } if (!$willDisplaySomeChildren) { $menu->setDisplay(false); } } }
protected function renderChildren(ItemInterface $item, array $options) { // render children with a depth - 1 if (null !== $options['depth']) { $options['depth'] = $options['depth'] - 1; } if (null !== $options['matchingDepth'] && $options['matchingDepth'] > 0) { $options['matchingDepth'] = $options['matchingDepth'] - 1; } $html = ''; $children = $item->getChildren(); $childrenCount = count($children); $lastIndex = $childrenCount - 1; $index = 0; foreach ($children as $child) { $html .= $this->renderItem($child, $options); if ($index !== $lastIndex) { $html .= $this->renderSeparator($options); } ++$index; } return $html; }
/** * @param \Knp\Menu\ItemInterface $item * @param array $options * @return array */ protected function getChildren(ItemInterface $item, array $options) { if (null !== $options['depth']) { $options['depth'] = $options['depth'] - 1; } if (null !== $options['ancestorCurrencyDepth']) { $options['ancestorCurrencyDepth'] = max(0, $options['ancestorCurrencyDepth'] - 1); } $items = array(); foreach ($item->getChildren() as $child) { if (($item = $this->getItem($child, $options)) !== null) { $items[] = $item; } } return $items; }
/** * resolveAdminIcons. * * @param ItemInterface $menu */ protected function resolveAdminIcons(ItemInterface $menu) { foreach ($menu->getChildren() as $child) { if (!$child->getExtra('icon') && $child->hasChildren()) { $child->setExtra('icon', 'fa fa-folder'); } if ($child->hasChildren()) { foreach ($child->getChildren() as $subChild) { if (!$subChild->getExtra('icon') && ($admin = $subChild->getExtra('admin'))) { if ($admin instanceof AbstractAdmin) { $subChild->setExtra('icon', $admin->getIcon()); } } } } } }
/** * @param ItemInterface $item * @param integer|null $depth the depth until which children should be exported (null means unlimited) * * @return array */ public function toArray(ItemInterface $item, $depth = null) { $array = array('name' => $item->getName(), 'label' => $item->getLabel(), 'uri' => $item->getUri(), 'attributes' => $item->getAttributes(), 'labelAttributes' => $item->getLabelAttributes(), 'linkAttributes' => $item->getLinkAttributes(), 'childrenAttributes' => $item->getChildrenAttributes(), 'extras' => $item->getExtras(), 'display' => $item->isDisplayed(), 'displayChildren' => $item->getDisplayChildren(), 'current' => $item->isCurrent()); // export the children as well, unless explicitly disabled if (0 !== $depth) { $childDepth = null === $depth ? null : $depth - 1; $array['children'] = array(); foreach ($item->getChildren() as $key => $child) { $array['children'][$key] = $this->toArray($child, $childDepth); } } return $array; }