![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-catalog/Plugin/Block/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Catalog\Plugin\Block; use Magento\Catalog\Model\Category; use Magento\Framework\Data\Collection; use Magento\Framework\Data\Tree\Node; /** * Plugin for top menu block */ class Topmenu { /** * Catalog category * * @var \Magento\Catalog\Helper\Category */ protected $catalogCategory; /** * @var \Magento\Catalog\Model\ResourceModel\Category\StateDependentCollectionFactory */ private $collectionFactory; /** * @var \Magento\Store\Model\StoreManagerInterface */ private $storeManager; /** * @var \Magento\Catalog\Model\Layer\Resolver */ private $layerResolver; /** * Initialize dependencies. * * @param \Magento\Catalog\Helper\Category $catalogCategory * @param \Magento\Catalog\Model\ResourceModel\Category\StateDependentCollectionFactory $categoryCollectionFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver */ public function __construct( \Magento\Catalog\Helper\Category $catalogCategory, \Magento\Catalog\Model\ResourceModel\Category\StateDependentCollectionFactory $categoryCollectionFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Layer\Resolver $layerResolver ) { $this->catalogCategory = $catalogCategory; $this->collectionFactory = $categoryCollectionFactory; $this->storeManager = $storeManager; $this->layerResolver = $layerResolver; } /** * Build category tree for menu block. * * @param \Magento\Theme\Block\Html\Topmenu $subject * @param string $outermostClass * @param string $childrenWrapClass * @param int $limit * @return void * @SuppressWarnings("PMD.UnusedFormalParameter") */ public function beforeGetHtml( \Magento\Theme\Block\Html\Topmenu $subject, $outermostClass = '', $childrenWrapClass = '', $limit = 0 ) { $rootId = $this->storeManager->getStore()->getRootCategoryId(); $storeId = $this->storeManager->getStore()->getId(); /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ $collection = $this->getCategoryTree($storeId, $rootId); $currentCategory = $this->getCurrentCategory(); $mapping = [$rootId => $subject->getMenu()]; // use nodes stack to avoid recursion foreach ($collection as $category) { $categoryParentId = $category->getParentId(); if (!isset($mapping[$categoryParentId])) { $parentIds = $category->getParentIds(); foreach ($parentIds as $parentId) { if (isset($mapping[$parentId])) { $categoryParentId = $parentId; } } } /** @var Node $parentCategoryNode */ $parentCategoryNode = $mapping[$categoryParentId]; $categoryNode = new Node( $this->getCategoryAsArray( $category, $currentCategory, $category->getParentId() == $categoryParentId ), 'id', $parentCategoryNode->getTree(), $parentCategoryNode ); $parentCategoryNode->addChild($categoryNode); $mapping[$category->getId()] = $categoryNode; //add node in stack } } /** * Add list of associated identities to the top menu block for caching purposes. * * @param \Magento\Theme\Block\Html\Topmenu $subject * @return void */ public function beforeGetIdentities(\Magento\Theme\Block\Html\Topmenu $subject) { $subject->addIdentity(Category::CACHE_TAG); $rootId = $this->storeManager->getStore()->getRootCategoryId(); $storeId = $this->storeManager->getStore()->getId(); /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ $collection = $this->getCategoryTree($storeId, $rootId); $mapping = [$rootId => $subject->getMenu()]; // use nodes stack to avoid recursion foreach ($collection as $category) { if (!isset($mapping[$category->getParentId()])) { continue; } $subject->addIdentity(Category::CACHE_TAG . '_' . $category->getId()); } } /** * Get current Category from catalog layer * * @return \Magento\Catalog\Model\Category */ private function getCurrentCategory() { $catalogLayer = $this->layerResolver->get(); if (!$catalogLayer) { return null; } return $catalogLayer->getCurrentCategory(); } /** * Convert category to array * * @param \Magento\Catalog\Model\Category $category * @param \Magento\Catalog\Model\Category $currentCategory * @param bool $isParentActive * @return array */ private function getCategoryAsArray($category, $currentCategory, $isParentActive) { $categoryId = $category->getId(); return [ 'name' => $category->getName(), 'id' => 'category-node-' . $categoryId, 'url' => $this->catalogCategory->getCategoryUrl($category), 'has_active' => in_array((string)$categoryId, explode('/', (string)$currentCategory->getPath()), true), 'is_active' => $categoryId == $currentCategory->getId(), 'is_category' => true, 'is_parent_active' => $isParentActive ]; } /** * Get Category Tree * * @param int $storeId * @param int $rootId * @return \Magento\Catalog\Model\ResourceModel\Category\Collection * @throws \Magento\Framework\Exception\LocalizedException */ protected function getCategoryTree($storeId, $rootId) { /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ $collection = $this->collectionFactory->create(); $collection->setStoreId($storeId); $collection->addAttributeToSelect('name'); $collection->addFieldToFilter('path', ['like' => '1/' . $rootId . '/%']); //load only from store root $collection->addAttributeToFilter('include_in_menu', 1); $collection->addIsActiveFilter(); $collection->addNavigationMaxDepthFilter(); $collection->addUrlRewriteToResult(); $collection->addOrder('level', Collection::SORT_ORDER_ASC); $collection->addOrder('position', Collection::SORT_ORDER_ASC); $collection->addOrder('parent_id', Collection::SORT_ORDER_ASC); $collection->addOrder('entity_id', Collection::SORT_ORDER_ASC); return $collection; } /** * Add active * * @param \Magento\Theme\Block\Html\Topmenu $subject * @param string[] $result * @return string[] * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterGetCacheKeyInfo(\Magento\Theme\Block\Html\Topmenu $subject, array $result) { $activeCategory = $this->getCurrentCategory(); if ($activeCategory) { $result[] = Category::CACHE_TAG . '_' . $activeCategory->getId(); } return $result; } }