nodeFactory = $nodeFactory; $this->treeFactory = $treeFactory; } /** * Get block cache life time * * @return int * @since 100.1.0 */ protected function getCacheLifetime() { return parent::getCacheLifetime() ?: 3600; } /** * Get top menu html * * @param string $outermostClass * @param string $childrenWrapClass * @param int $limit * @return string */ public function getHtml($outermostClass = '', $childrenWrapClass = '', $limit = 0) { $this->_eventManager->dispatch( 'page_block_html_topmenu_gethtml_before', ['menu' => $this->getMenu(), 'block' => $this, 'request' => $this->getRequest()] ); $this->getMenu()->setOutermostClass($outermostClass); $this->getMenu()->setChildrenWrapClass($childrenWrapClass); $html = $this->_getHtml($this->getMenu(), $childrenWrapClass, $limit); $transportObject = new \Magento\Framework\DataObject(['html' => $html]); $this->_eventManager->dispatch( 'page_block_html_topmenu_gethtml_after', ['menu' => $this->getMenu(), 'transportObject' => $transportObject] ); $html = $transportObject->getHtml(); return $html; } /** * Count All Subnavigation Items * * @param \Magento\Backend\Model\Menu $items * @return int */ protected function _countItems($items) { $total = $items->count(); foreach ($items as $item) { /** @var $item \Magento\Backend\Model\Menu\Item */ if ($item->hasChildren()) { $total += $this->_countItems($item->getChildren()); } } return $total; } /** * Building Array with Column Brake Stops * * @param \Magento\Backend\Model\Menu $items * @param int $limit * @return array|void * * @todo: Add Depth Level limit, and better logic for columns */ protected function _columnBrake($items, $limit) { $total = $this->_countItems($items); if ($total <= $limit) { return; } $result[] = ['total' => $total, 'max' => (int)ceil($total / ceil($total / $limit))]; $count = 0; $firstCol = true; foreach ($items as $item) { $place = $this->_countItems($item->getChildren()) + 1; $count += $place; if ($place >= $limit) { $colbrake = !$firstCol; $count = 0; } elseif ($count >= $limit) { $colbrake = !$firstCol; $count = $place; } else { $colbrake = false; } $result[] = ['place' => $place, 'colbrake' => $colbrake]; $firstCol = false; } return $result; } /** * Add sub menu HTML code for current menu item * * @param \Magento\Framework\Data\Tree\Node $child * @param string $childLevel * @param string $childrenWrapClass * @param int $limit * @return string HTML code */ protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit) { $html = ''; if (!$child->hasChildren()) { return $html; } $colStops = []; if ($childLevel == 0 && $limit) { $colStops = $this->_columnBrake($child->getChildren(), $limit); } $html .= ''; return $html; } /** * Recursively generates top menu html from data that is specified in $menuTree * * @param \Magento\Framework\Data\Tree\Node $menuTree * @param string $childrenWrapClass * @param int $limit * @param array $colBrakes * @return string * * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _getHtml( \Magento\Framework\Data\Tree\Node $menuTree, $childrenWrapClass, $limit, array $colBrakes = [] ) { $html = ''; $children = $menuTree->getChildren(); $parentLevel = $menuTree->getLevel(); $childLevel = $parentLevel === null ? 0 : $parentLevel + 1; $counter = 1; $itemPosition = 1; $childrenCount = $children->count(); $parentPositionClass = $menuTree->getPositionClass(); $itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass . '-' : 'nav-'; /** @var \Magento\Framework\Data\Tree\Node $child */ foreach ($children as $child) { if ($childLevel === 0 && $child->getData('is_parent_active') === false) { continue; } $child->setLevel($childLevel); $child->setIsFirst($counter == 1); $child->setIsLast($counter == $childrenCount); $child->setPositionClass($itemPositionClassPrefix . $counter); $outermostClassCode = ''; $outermostClass = $menuTree->getOutermostClass(); if ($childLevel == 0 && $outermostClass) { $outermostClassCode = ' class="' . $outermostClass . '" '; $currentClass = $child->getClass(); if (empty($currentClass)) { $child->setClass($outermostClass); } else { $child->setClass($currentClass . ' ' . $outermostClass); } } if (is_array($colBrakes) && count($colBrakes) && $colBrakes[$counter]['colbrake']) { $html .= '