Skip to content

Commit 151a48e

Browse files
committed
Make sure 'last' class is set on top menu
Previously the 'last' class was not set on the last visible top menu item when one of the top level categories was disabled. Also improved: + Split up the _getHtml() method to removed the @SuppressWarnings + Removed unneeded variables (moved the content of the variables to the place where they are actually are being used). + Removed unused $itemPosition variable in _getHtml method + Optimized imports
1 parent 2bca2aa commit 151a48e

File tree

1 file changed

+75
-41
lines changed

1 file changed

+75
-41
lines changed

app/code/Magento/Theme/Block/Html/Topmenu.php

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
*/
66
namespace Magento\Theme\Block\Html;
77

8+
use Magento\Backend\Model\Menu;
89
use Magento\Framework\Data\Tree\Node;
10+
use Magento\Framework\Data\Tree\Node\Collection;
911
use Magento\Framework\Data\Tree\NodeFactory;
1012
use Magento\Framework\Data\TreeFactory;
13+
use Magento\Framework\DataObject;
1114
use Magento\Framework\DataObject\IdentityInterface;
1215
use Magento\Framework\View\Element\Template;
1316

@@ -29,7 +32,7 @@ class Topmenu extends Template implements IdentityInterface
2932
/**
3033
* Top menu data tree
3134
*
32-
* @var \Magento\Framework\Data\Tree\Node
35+
* @var Node
3336
*/
3437
protected $_menu;
3538

@@ -89,28 +92,29 @@ public function getHtml($outermostClass = '', $childrenWrapClass = '', $limit =
8992
$this->getMenu()->setOutermostClass($outermostClass);
9093
$this->getMenu()->setChildrenWrapClass($childrenWrapClass);
9194

92-
$html = $this->_getHtml($this->getMenu(), $childrenWrapClass, $limit);
95+
$transportObject = new DataObject([
96+
'html' => $this->_getHtml($this->getMenu(), $childrenWrapClass, $limit)
97+
]);
9398

94-
$transportObject = new \Magento\Framework\DataObject(['html' => $html]);
9599
$this->_eventManager->dispatch(
96100
'page_block_html_topmenu_gethtml_after',
97101
['menu' => $this->getMenu(), 'transportObject' => $transportObject]
98102
);
99-
$html = $transportObject->getHtml();
100-
return $html;
103+
104+
return $transportObject->getHtml();
101105
}
102106

103107
/**
104108
* Count All Subnavigation Items
105109
*
106-
* @param \Magento\Backend\Model\Menu $items
110+
* @param Menu $items
107111
* @return int
108112
*/
109113
protected function _countItems($items)
110114
{
111115
$total = $items->count();
112116
foreach ($items as $item) {
113-
/** @var $item \Magento\Backend\Model\Menu\Item */
117+
/** @var $item Menu\Item */
114118
if ($item->hasChildren()) {
115119
$total += $this->_countItems($item->getChildren());
116120
}
@@ -121,7 +125,7 @@ protected function _countItems($items)
121125
/**
122126
* Building Array with Column Brake Stops
123127
*
124-
* @param \Magento\Backend\Model\Menu $items
128+
* @param Menu $items
125129
* @param int $limit
126130
* @return array|void
127131
*
@@ -164,7 +168,7 @@ protected function _columnBrake($items, $limit)
164168
/**
165169
* Add sub menu HTML code for current menu item
166170
*
167-
* @param \Magento\Framework\Data\Tree\Node $child
171+
* @param Node $child
168172
* @param string $childLevel
169173
* @param string $childrenWrapClass
170174
* @param int $limit
@@ -192,48 +196,41 @@ protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
192196
/**
193197
* Recursively generates top menu html from data that is specified in $menuTree
194198
*
195-
* @param \Magento\Framework\Data\Tree\Node $menuTree
199+
* @param Node $menuTree
196200
* @param string $childrenWrapClass
197201
* @param int $limit
198202
* @param array $colBrakes
199203
* @return string
200-
*
201-
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
202-
* @SuppressWarnings(PHPMD.NPathComplexity)
203204
*/
204205
protected function _getHtml(
205-
\Magento\Framework\Data\Tree\Node $menuTree,
206+
Node $menuTree,
206207
$childrenWrapClass,
207208
$limit,
208209
array $colBrakes = []
209210
) {
210211
$html = '';
211212

212213
$children = $menuTree->getChildren();
213-
$parentLevel = $menuTree->getLevel();
214-
$childLevel = $parentLevel === null ? 0 : $parentLevel + 1;
214+
$this->removeChildrenWithoutActiveParent($children);
215+
$childLevel = $this->getChildLevel($menuTree->getLevel());
215216

216217
$counter = 1;
217-
$itemPosition = 1;
218218
$childrenCount = $children->count();
219219

220220
$parentPositionClass = $menuTree->getPositionClass();
221221
$itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass . '-' : 'nav-';
222222

223-
/** @var \Magento\Framework\Data\Tree\Node $child */
223+
/** @var Node $child */
224224
foreach ($children as $child) {
225-
if ($childLevel === 0 && $child->getData('is_parent_active') === false) {
226-
continue;
227-
}
228225
$child->setLevel($childLevel);
229-
$child->setIsFirst($counter == 1);
230-
$child->setIsLast($counter == $childrenCount);
226+
$child->setIsFirst($counter === 1);
227+
$child->setIsLast($counter === $childrenCount);
231228
$child->setPositionClass($itemPositionClassPrefix . $counter);
232229

233230
$outermostClassCode = '';
234231
$outermostClass = $menuTree->getOutermostClass();
235232

236-
if ($childLevel == 0 && $outermostClass) {
233+
if ($childLevel === 0 && $outermostClass) {
237234
$outermostClassCode = ' class="' . $outermostClass . '" ';
238235
$currentClass = $child->getClass();
239236

@@ -244,7 +241,7 @@ protected function _getHtml(
244241
}
245242
}
246243

247-
if (is_array($colBrakes) && count($colBrakes) && $colBrakes[$counter]['colbrake']) {
244+
if ($this->shouldAddNewColumn($colBrakes, $counter)) {
248245
$html .= '</ul></li><li class="column"><ul>';
249246
}
250247

@@ -257,7 +254,6 @@ protected function _getHtml(
257254
$childrenWrapClass,
258255
$limit
259256
) . '</li>';
260-
$itemPosition++;
261257
$counter++;
262258
}
263259

@@ -271,14 +267,13 @@ protected function _getHtml(
271267
/**
272268
* Generates string with all attributes that should be present in menu item element
273269
*
274-
* @param \Magento\Framework\Data\Tree\Node $item
270+
* @param Node $item
275271
* @return string
276272
*/
277-
protected function _getRenderedMenuItemAttributes(\Magento\Framework\Data\Tree\Node $item)
273+
protected function _getRenderedMenuItemAttributes(Node $item)
278274
{
279275
$html = '';
280-
$attributes = $this->_getMenuItemAttributes($item);
281-
foreach ($attributes as $attributeName => $attributeValue) {
276+
foreach ($this->_getMenuItemAttributes($item) as $attributeName => $attributeValue) {
282277
$html .= ' ' . $attributeName . '="' . str_replace('"', '\"', $attributeValue) . '"';
283278
}
284279
return $html;
@@ -287,27 +282,26 @@ protected function _getRenderedMenuItemAttributes(\Magento\Framework\Data\Tree\N
287282
/**
288283
* Returns array of menu item's attributes
289284
*
290-
* @param \Magento\Framework\Data\Tree\Node $item
285+
* @param Node $item
291286
* @return array
292287
*/
293-
protected function _getMenuItemAttributes(\Magento\Framework\Data\Tree\Node $item)
288+
protected function _getMenuItemAttributes(Node $item)
294289
{
295-
$menuItemClasses = $this->_getMenuItemClasses($item);
296-
return ['class' => implode(' ', $menuItemClasses)];
290+
return ['class' => implode(' ', $this->_getMenuItemClasses($item))];
297291
}
298292

299293
/**
300294
* Returns array of menu item's classes
301295
*
302-
* @param \Magento\Framework\Data\Tree\Node $item
296+
* @param Node $item
303297
* @return array
304298
*/
305-
protected function _getMenuItemClasses(\Magento\Framework\Data\Tree\Node $item)
299+
protected function _getMenuItemClasses(Node $item)
306300
{
307-
$classes = [];
308-
309-
$classes[] = 'level' . $item->getLevel();
310-
$classes[] = $item->getPositionClass();
301+
$classes = [
302+
'level' . $item->getLevel(),
303+
$item->getPositionClass(),
304+
];
311305

312306
if ($item->getIsCategory()) {
313307
$classes[] = 'category-item';
@@ -375,7 +369,7 @@ protected function getCacheTags()
375369
/**
376370
* Get menu object.
377371
*
378-
* Creates \Magento\Framework\Data\Tree\Node root node object.
372+
* Creates Tree root node object.
379373
* The creation logic was moved from class constructor into separate method.
380374
*
381375
* @return Node
@@ -394,4 +388,44 @@ public function getMenu()
394388
}
395389
return $this->_menu;
396390
}
391+
392+
/**
393+
* Remove children from collection when the parent is not active
394+
*
395+
* @param Collection $children
396+
*
397+
* @return void
398+
*/
399+
private function removeChildrenWithoutActiveParent(Collection $children)
400+
{
401+
/** @var Node $child */
402+
foreach ($children as $child) {
403+
if ($child->getData('is_parent_active') === false) {
404+
$children->delete($child);
405+
}
406+
}
407+
}
408+
409+
/**
410+
* Retrieve child level based on parent level
411+
*
412+
* @param int $parentLevel
413+
*
414+
* @return int
415+
*/
416+
private function getChildLevel($parentLevel)
417+
{
418+
return $parentLevel === null ? 0 : $parentLevel + 1;
419+
}
420+
421+
/**
422+
* @param array $colBrakes
423+
* @param $counter
424+
*
425+
* @return bool
426+
*/
427+
private function shouldAddNewColumn(array $colBrakes, int $counter)
428+
{
429+
return count($colBrakes) && $colBrakes[$counter]['colbrake'];
430+
}
397431
}

0 commit comments

Comments
 (0)