Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Topmenu.php
Go to the documentation of this file.
1 <?php
7 
11 
15 class Topmenu
16 {
22  protected $catalogCategory;
23 
27  private $collectionFactory;
28 
32  private $storeManager;
33 
37  private $layerResolver;
38 
47  public function __construct(
48  \Magento\Catalog\Helper\Category $catalogCategory,
49  \Magento\Catalog\Model\ResourceModel\Category\StateDependentCollectionFactory $categoryCollectionFactory,
50  \Magento\Store\Model\StoreManagerInterface $storeManager,
51  \Magento\Catalog\Model\Layer\Resolver $layerResolver
52  ) {
53  $this->catalogCategory = $catalogCategory;
54  $this->collectionFactory = $categoryCollectionFactory;
55  $this->storeManager = $storeManager;
56  $this->layerResolver = $layerResolver;
57  }
58 
69  public function beforeGetHtml(
70  \Magento\Theme\Block\Html\Topmenu $subject,
71  $outermostClass = '',
72  $childrenWrapClass = '',
73  $limit = 0
74  ) {
75  $rootId = $this->storeManager->getStore()->getRootCategoryId();
76  $storeId = $this->storeManager->getStore()->getId();
78  $collection = $this->getCategoryTree($storeId, $rootId);
79  $currentCategory = $this->getCurrentCategory();
80  $mapping = [$rootId => $subject->getMenu()]; // use nodes stack to avoid recursion
81  foreach ($collection as $category) {
82  $categoryParentId = $category->getParentId();
83  if (!isset($mapping[$categoryParentId])) {
84  $parentIds = $category->getParentIds();
85  foreach ($parentIds as $parentId) {
86  if (isset($mapping[$parentId])) {
87  $categoryParentId = $parentId;
88  }
89  }
90  }
91 
93  $parentCategoryNode = $mapping[$categoryParentId];
94 
95  $categoryNode = new Node(
96  $this->getCategoryAsArray(
97  $category,
98  $currentCategory,
99  $category->getParentId() == $categoryParentId
100  ),
101  'id',
102  $parentCategoryNode->getTree(),
103  $parentCategoryNode
104  );
105  $parentCategoryNode->addChild($categoryNode);
106 
107  $mapping[$category->getId()] = $categoryNode; //add node in stack
108  }
109  }
110 
117  public function beforeGetIdentities(\Magento\Theme\Block\Html\Topmenu $subject)
118  {
119  $subject->addIdentity(Category::CACHE_TAG);
120  $rootId = $this->storeManager->getStore()->getRootCategoryId();
121  $storeId = $this->storeManager->getStore()->getId();
123  $collection = $this->getCategoryTree($storeId, $rootId);
124  $mapping = [$rootId => $subject->getMenu()]; // use nodes stack to avoid recursion
125  foreach ($collection as $category) {
126  if (!isset($mapping[$category->getParentId()])) {
127  continue;
128  }
129  $subject->addIdentity(Category::CACHE_TAG . '_' . $category->getId());
130  }
131  }
132 
138  private function getCurrentCategory()
139  {
140  $catalogLayer = $this->layerResolver->get();
141 
142  if (!$catalogLayer) {
143  return null;
144  }
145 
146  return $catalogLayer->getCurrentCategory();
147  }
148 
157  private function getCategoryAsArray($category, $currentCategory, $isParentActive)
158  {
159  return [
160  'name' => $category->getName(),
161  'id' => 'category-node-' . $category->getId(),
162  'url' => $this->catalogCategory->getCategoryUrl($category),
163  'has_active' => in_array((string)$category->getId(), explode('/', $currentCategory->getPath()), true),
164  'is_active' => $category->getId() == $currentCategory->getId(),
165  'is_category' => true,
166  'is_parent_active' => $isParentActive
167  ];
168  }
169 
178  protected function getCategoryTree($storeId, $rootId)
179  {
181  $collection = $this->collectionFactory->create();
182  $collection->setStoreId($storeId);
183  $collection->addAttributeToSelect('name');
184  $collection->addFieldToFilter('path', ['like' => '1/' . $rootId . '/%']); //load only from store root
185  $collection->addAttributeToFilter('include_in_menu', 1);
186  $collection->addIsActiveFilter();
187  $collection->addNavigationMaxDepthFilter();
188  $collection->addUrlRewriteToResult();
189  $collection->addOrder('level', Collection::SORT_ORDER_ASC);
190  $collection->addOrder('position', Collection::SORT_ORDER_ASC);
191  $collection->addOrder('parent_id', Collection::SORT_ORDER_ASC);
192  $collection->addOrder('entity_id', Collection::SORT_ORDER_ASC);
193 
194  return $collection;
195  }
196 }
$storeManager
__construct(\Magento\Catalog\Helper\Category $catalogCategory, \Magento\Catalog\Model\ResourceModel\Category\StateDependentCollectionFactory $categoryCollectionFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Layer\Resolver $layerResolver)
Definition: Topmenu.php:47