diff --git a/Block/Menu.php b/Block/Menu.php
index 4b03b964..4bb20e0a 100644
--- a/Block/Menu.php
+++ b/Block/Menu.php
@@ -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
@@ -84,6 +85,11 @@ class Menu extends Template implements DataObject\IdentityInterface
*/
private $httpContext;
+ /**
+ * @var array
+ */
+ private $nodeTypeCaches = [];
+
/**
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
@@ -97,6 +103,7 @@ public function __construct(
ImageFile $imageFile,
Escaper $escaper,
Context $httpContext,
+ array $nodeTypeCaches = [],
array $data = []
) {
parent::__construct($context, $data);
@@ -110,6 +117,7 @@ public function __construct(
$this->setTemplate($this->getMenuTemplate($this->_template));
$this->submenuTemplate = $this->getSubmenuTemplate();
$this->httpContext = $httpContext;
+ $this->nodeTypeCaches = $nodeTypeCaches;
}
/**
@@ -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()
@@ -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
}
}
}
@@ -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);
diff --git a/Block/NodeType/Category.php b/Block/NodeType/Category.php
index 5d94aefa..5722ecb7 100644
--- a/Block/NodeType/Category.php
+++ b/Block/NodeType/Category.php
@@ -43,6 +43,10 @@ class Category extends AbstractNode
* @var array
*/
private $categories;
+ /**
+ * @var array
+ */
+ private $cacheTags;
/**
* @var array
@@ -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);
}
@@ -226,4 +231,9 @@ public function getLabel()
{
return __("Category");
}
+
+ public function getEntityCacheTags()
+ {
+ return $this->cacheTags;
+ }
}
diff --git a/Model/NodeType/Category.php b/Model/NodeType/Category.php
index 5c0193f4..e80ab876 100644
--- a/Model/NodeType/Category.php
+++ b/Model/NodeType/Category.php
@@ -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];
}
/**
diff --git a/Model/ResourceModel/NodeType/Category.php b/Model/ResourceModel/NodeType/Category.php
index bb6d4fb9..e269401c 100644
--- a/Model/ResourceModel/NodeType/Category.php
+++ b/Model/ResourceModel/NodeType/Category.php
@@ -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
{
@@ -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);
}
}
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 0cd14336..543dfb41 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -15,6 +15,11 @@
Controls serving different menus to different customer groups
Magento\Config\Model\Config\Source\Yesno
+
+
+ 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
+ Magento\Config\Model\Config\Source\Yesno
+
diff --git a/etc/di.xml b/etc/di.xml
index bf2f437f..c46b4223 100644
--- a/etc/di.xml
+++ b/etc/di.xml
@@ -74,4 +74,12 @@
Snowdog\Menu\Model\ImportExport\Processor\Import\Node\Validator\Proxy
+
+
+
+
+ - category
+
+
+