Skip to content

Commit

Permalink
SMM-5 add dynamic menu improvements
Browse files Browse the repository at this point in the history
See #317
  • Loading branch information
Adam Wacławczyk committed Jan 7, 2025
1 parent 02d1a1f commit bb0971f
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 20 deletions.
38 changes: 29 additions & 9 deletions Block/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
class Menu extends Template implements DataObject\IdentityInterface
{
const XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS = 'snowmenu/general/customer_groups';
const XML_SNOWMENU_GENERAL_CACHE_TAGS = 'snowmenu/general/cache_tags';

/**
* @var MenuRepositoryInterface
Expand Down Expand Up @@ -84,6 +85,11 @@ class Menu extends Template implements DataObject\IdentityInterface
*/
private $httpContext;

/**
* @var array
*/
private $nodeTypeCaches = [];

/**
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
Expand All @@ -97,6 +103,7 @@ public function __construct(
ImageFile $imageFile,
Escaper $escaper,
Context $httpContext,
array $nodeTypeCaches = [],
array $data = []
) {
parent::__construct($context, $data);
Expand All @@ -110,6 +117,7 @@ public function __construct(
$this->setTemplate($this->getMenuTemplate($this->_template));
$this->submenuTemplate = $this->getSubmenuTemplate();
$this->httpContext = $httpContext;
$this->nodeTypeCaches = $nodeTypeCaches;
}

/**
Expand All @@ -119,11 +127,22 @@ public function __construct(
*/
public function getIdentities()
{
return [
$tags = [
\Snowdog\Menu\Model\Menu::CACHE_TAG . '_' . $this->loadMenu()->getId(),
Block::CACHE_TAG,
\Snowdog\Menu\Model\Menu::CACHE_TAG
];
if (!$this->canGatherEntityCacheTags()) {
return $tags;
}
foreach ($this->nodeTypeCaches as $provider) {
$entityCacheTags = $this->nodeTypeProvider->getProvider($provider)->getEntityCacheTags();
if (!empty($entityCacheTags)) {
$tags = array_merge($tags, $entityCacheTags);
}
}

return $tags;
}

protected function getCacheLifetime()
Expand Down Expand Up @@ -481,19 +500,11 @@ private function fetchData()
}

foreach ($types['category'] as $nodes) {
if ($nodes['node']->getContent() == 20) {
$nodes['node']->setHideCategoryIfEmpty(true);
}
/** @var \Snowdog\Menu\Block\NodeType\Category $categoryProvider */
if (!$nodes['node']->getHideCategoryIfEmpty()) {
continue;
}
$categoryProvider = $this->nodeTypeProvider->getProvider('category');
$productCount = $categoryProvider->getCategoryProductCount($nodes['node']->getNodeId());
if (empty($productCount)) {
[$level, $parent, $idx] = $nodes['path'];
unset ($this->nodes[$level][$parent][$idx]);
//todo unset children
}
}
}
Expand Down Expand Up @@ -530,6 +541,15 @@ private function getSubmenuTemplate()
return $this->getMenuTemplate($baseSubmenuTemplate);
}

private function canGatherEntityCacheTags()
{
if (!$this->_scopeConfig->isSetFlag(self::XML_SNOWMENU_GENERAL_CACHE_TAGS)) {
return false;
}

return !empty($this->nodeTypeCaches);
}

public function getCustomerGroupId()
{
return $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_GROUP);
Expand Down
12 changes: 11 additions & 1 deletion Block/NodeType/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class Category extends AbstractNode
* @var array
*/
private $categories;
/**
* @var array
*/
private $cacheTags;

/**
* @var array
Expand Down Expand Up @@ -112,7 +116,8 @@ public function fetchData(array $nodes)
$this->nodes,
$this->categoryUrls,
$this->categories,
$this->categoryProductCounts
$this->categoryProductCounts,
$this->cacheTags
] = $this->_categoryModel->fetchData($nodes, $storeId);

}
Expand Down Expand Up @@ -226,4 +231,9 @@ public function getLabel()
{
return __("Category");
}

public function getEntityCacheTags()
{
return $this->cacheTags;
}
}
3 changes: 2 additions & 1 deletion Model/NodeType/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,11 @@ public function fetchData(array $nodes, $storeId)
$categoryUrls = $this->getResource()->fetchData($storeId, $categoryIds);
$categories = $this->getCategories($storeId, $categoryIds);
$categoryProductCounts = $this->getResource()->getCategoriesProductCount($categoryIds);
$cacheTags = preg_filter('/^/', 'cat_c_p' . '_', $categoryIds);

$this->profiler->stop(__METHOD__);

return [$localNodes, $categoryUrls, $categories, $categoryProductCounts];
return [$localNodes, $categoryUrls, $categories, $categoryProductCounts, $cacheTags];
}

/**
Expand Down
16 changes: 7 additions & 9 deletions Model/ResourceModel/NodeType/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Model\Store;
use Zend_Db_Expr;

class Category extends AbstractNode
{
Expand Down Expand Up @@ -111,15 +112,12 @@ public function getCategoriesProductCount($categoryIds = [])
{
$productTable = $this->getConnection()->getTableName('catalog_category_product');

$select = $this->getConnection()->select()->from(
['main_table' => $productTable],
['main_table.category_id', new \Zend_Db_Expr('COUNT(main_table.product_id)')]
)->where(
'main_table.category_id IN (?)', $categoryIds
)->group('main_table.category_id');

$counts = $this->getConnection()->fetchPairs($select);
$select = $this->getConnection()
->select()
->from($productTable, ['category_id', new Zend_Db_Expr('COUNT(product_id)')])
->where('category_id IN (?)', $categoryIds)
->group('category_id');

return $counts;
return $this->getConnection()->fetchPairs($select);
}
}
5 changes: 5 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
<comment>Controls serving different menus to different customer groups</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="cache_tags" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Gather node entities cache tags</label>
<comment>Controls menu caching mechanisms. Enabling this will allow for gathering cache tags from menu nodes, which allows handling menus that are heavily dependent on e.g. category contents - see https://github.com/SnowdogApps/magento2-menu/discussions/317</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
Expand Down
8 changes: 8 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,12 @@
<argument name="validator" xsi:type="object">Snowdog\Menu\Model\ImportExport\Processor\Import\Node\Validator\Proxy</argument>
</arguments>
</type>

<type name="Snowdog\Menu\Block\Menu">
<arguments>
<argument name="nodeTypeCaches" xsi:type="array">
<item name="category" xsi:type="string">category</item>
</argument>
</arguments>
</type>
</config>

0 comments on commit bb0971f

Please sign in to comment.