Skip to content

Instantly share code, notes, and snippets.

@damienwebdev
Last active April 8, 2023 18:48
Show Gist options
  • Save damienwebdev/34534765bb548bf6ea14dab28245846c to your computer and use it in GitHub Desktop.
Save damienwebdev/34534765bb548bf6ea14dab28245846c to your computer and use it in GitHub Desktop.
Patch for Magento Missing Root Store `catalog_category_product_index` v2.4.4
diff --git a/Model/Indexer/Category/Product/AbstractAction.php b/Model/Indexer/Category/Product/AbstractAction.php
index 020c195..955be66 100644
--- a/Model/Indexer/Category/Product/AbstractAction.php
+++ b/Model/Indexer/Category/Product/AbstractAction.php
@@ -169,7 +169,7 @@ abstract class AbstractAction
*/
protected function reindex()
{
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
if ($this->getPathFromCategoryId($store->getRootCategoryId())) {
$this->currentStoreId = $store->getId();
$this->reindexRootCategory($store);
@@ -246,7 +246,7 @@ abstract class AbstractAction
['path']
)->where(
'entity_id = ?',
- $categoryId
+ $categoryId == 0 ? 1 : $categoryId
)
);
}
@@ -283,10 +283,6 @@ abstract class AbstractAction
['ccp' => $this->getTable('catalog_category_product')],
'ccp.category_id = cc.entity_id',
[]
- )->joinInner(
- ['cpw' => $this->getTable('catalog_product_website')],
- 'cpw.product_id = ccp.product_id',
- []
)->joinInner(
['cpe' => $this->getTable('catalog_product_entity')],
'ccp.product_id = cpe.entity_id',
@@ -315,11 +311,6 @@ abstract class AbstractAction
' AND cpvs.store_id = ' .
$store->getId(),
[]
- )->where(
- 'cc.path LIKE ' . $this->connection->quote($rootPath . '/%')
- )->where(
- 'cpw.website_id = ?',
- $store->getWebsiteId()
)->where(
$this->connection->getIfNullSql('cpss.value', 'cpsd.value') . ' = ?',
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
@@ -343,6 +334,19 @@ abstract class AbstractAction
]
);
+ if ($store->getId() != 0) {
+ $select->joinInner(
+ ['cpw' => $this->getTable('catalog_product_website')],
+ 'cpw.product_id = ccp.product_id',
+ []
+ )->where(
+ 'cpw.website_id = ?',
+ $store->getWebsiteId()
+ )->where(
+ 'cc.path LIKE ' . $this->connection->quote($rootPath . '/%')
+ );
+ }
+
$this->addFilteringByChildProductsToSelect($select, $store);
$this->nonAnchorSelects[$store->getId()] = $select;
@@ -492,6 +496,7 @@ abstract class AbstractAction
$visibilityAttributeId = $this->config->getAttribute(Product::ENTITY, 'visibility')->getId();
$rootCatIds = explode('/', $this->getPathFromCategoryId($store->getRootCategoryId()));
array_pop($rootCatIds);
+ $rootCatIds = $rootCatIds ?: [1];
$temporaryTreeTable = $this->makeTempCategoryTreeIndex();
@@ -523,10 +528,6 @@ abstract class AbstractAction
['cpe' => $this->getTable('catalog_product_entity')],
'ccp.product_id = cpe.entity_id',
[]
- )->joinInner(
- ['cpw' => $this->getTable('catalog_product_website')],
- 'cpw.product_id = ccp.product_id',
- []
)->joinInner(
['cpsd' => $this->getTable('catalog_product_entity_int')],
'cpsd.' . $productLinkField . ' = cpe.' . $productLinkField . ' AND cpsd.store_id = 0'
@@ -561,9 +562,6 @@ abstract class AbstractAction
. ' AND ccas.attribute_id = ccad.attribute_id AND ccas.store_id = ' .
$store->getId(),
[]
- )->where(
- 'cpw.website_id = ?',
- $store->getWebsiteId()
)->where(
$this->connection->getIfNullSql('cpss.value', 'cpsd.value') . ' = ?',
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
@@ -590,6 +588,17 @@ abstract class AbstractAction
]
);
+ if ($store->getId() != 0) {
+ $select->joinInner(
+ ['cpw' => $this->getTable('catalog_product_website')],
+ 'cpw.product_id = ccp.product_id',
+ []
+ )->where(
+ 'cpw.website_id = ?',
+ $store->getWebsiteId()
+ );
+ }
+
$this->addFilteringByChildProductsToSelect($select, $store);
return $select;
@@ -771,10 +780,6 @@ abstract class AbstractAction
$select = $this->connection->select()->from(
['cp' => $this->getTable('catalog_product_entity')],
[]
- )->joinInner(
- ['cpw' => $this->getTable('catalog_product_website')],
- 'cpw.product_id = cp.entity_id',
- []
)->joinInner(
['cpsd' => $this->getTable('catalog_product_entity_int')],
'cpsd.' . $linkField . ' = cp.' . $linkField . ' AND cpsd.store_id = 0' .
@@ -803,9 +808,6 @@ abstract class AbstractAction
['ccp' => $this->getTable('catalog_category_product')],
'ccp.product_id = cp.entity_id',
[]
- )->where(
- 'cpw.website_id = ?',
- $store->getWebsiteId()
)->where(
$this->connection->getIfNullSql('cpss.value', 'cpsd.value') . ' = ?',
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
@@ -835,6 +837,17 @@ abstract class AbstractAction
]
);
+ if ($store->getId() != 0) {
+ $select->joinInner(
+ ['cpw' => $this->getTable('catalog_product_website')],
+ 'cpw.product_id = ccp.product_id',
+ []
+ )->where(
+ 'cpw.website_id = ?',
+ $store->getWebsiteId()
+ );
+ }
+
$this->productsSelects[$store->getId()] = $select;
}
diff --git a/Model/Indexer/Category/Product/Action/Full.php b/Model/Indexer/Category/Product/Action/Full.php
index e94c7a4..c6ca077 100644
--- a/Model/Indexer/Category/Product/Action/Full.php
+++ b/Model/Indexer/Category/Product/Action/Full.php
@@ -133,7 +133,7 @@ class Full extends AbstractAction
*/
private function createTables(): void
{
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$this->tableMaintainer->createTablesForStore((int)$store->getId());
}
}
@@ -145,7 +145,7 @@ class Full extends AbstractAction
*/
private function clearReplicaTables(): void
{
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$this->connection->truncateTable($this->tableMaintainer->getMainReplicaTable((int)$store->getId()));
}
}
@@ -158,7 +158,7 @@ class Full extends AbstractAction
private function switchTables(): void
{
$tablesToSwitch = [];
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$tablesToSwitch[] = $this->tableMaintainer->getMainTable((int)$store->getId());
}
$this->activeTableSwitcher->switchTable($this->connection, $tablesToSwitch);
@@ -188,7 +188,7 @@ class Full extends AbstractAction
{
$userFunctions = [];
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
if ($this->getPathFromCategoryId($store->getRootCategoryId())) {
$userFunctions[$store->getId()] = function () use ($store) {
$this->reindexStore($store);
diff --git a/Model/Indexer/Category/Product/Action/Rows.php b/Model/Indexer/Category/Product/Action/Rows.php
index c53277a..70c5c14 100644
--- a/Model/Indexer/Category/Product/Action/Rows.php
+++ b/Model/Indexer/Category/Product/Action/Rows.php
@@ -117,7 +117,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
|| ($indexer->isScheduled() && !$useTempTable)
|| ($indexer->isScheduled() && $useTempTable && !$workingState)) {
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$this->connection->truncateTable($this->getIndexTable($store->getId()));
}
} else {
@@ -130,7 +130,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
$workingState = $this->isWorkingState();
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$removalCategoryIds = array_diff($this->limitationByCategories, [$this->getRootCategoryId($store)]);
$this->connection->delete(
$this->tableMaintainer->getMainTable($store->getId()),
@@ -204,7 +204,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
*/
private function removeEntries()
{
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$removalCategoryIds = array_diff($this->limitationByCategories, [$this->getRootCategoryId($store)]);
$this->connection->delete(
$this->getIndexTable($store->getId()),
diff --git a/Model/Indexer/Category/Product/Plugin/StoreGroup.php b/Model/Indexer/Category/Product/Plugin/StoreGroup.php
index 12a9d85..05eb9df 100644
--- a/Model/Indexer/Category/Product/Plugin/StoreGroup.php
+++ b/Model/Indexer/Category/Product/Plugin/StoreGroup.php
@@ -78,7 +78,7 @@ class StoreGroup
*/
public function afterDelete(AbstractDb $subject, AbstractDb $objectResource, AbstractModel $storeGroup)
{
- foreach ($storeGroup->getStores() as $store) {
+ foreach ($storeGroup->getStores(true) as $store) {
$this->tableMaintainer->dropTablesForStore((int)$store->getId());
}
return $objectResource;
diff --git a/Model/Indexer/Product/Category/Action/Rows.php b/Model/Indexer/Product/Category/Action/Rows.php
index ab04f7c..53aa1eb 100644
--- a/Model/Indexer/Product/Category/Action/Rows.php
+++ b/Model/Indexer/Product/Category/Action/Rows.php
@@ -115,7 +115,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
$affectedCategories = $this->getCategoryIdsFromIndex($idsToBeReIndexed);
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$this->connection->truncateTable($this->getIndexTable($store->getId()));
}
} else {
@@ -127,7 +127,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
$workingState = $this->isWorkingState();
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$this->connection->delete(
$this->tableMaintainer->getMainTable($store->getId()),
['product_id IN (?)' => $this->limitationByProducts]
@@ -236,7 +236,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
*/
protected function removeEntries()
{
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$this->connection->delete(
$this->getIndexTable($store->getId()),
['product_id IN (?)' => $this->limitationByProducts]
@@ -299,7 +299,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
private function getCategoryIdsFromIndex(array $productIds): array
{
$categoryIds = [];
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->storeManager->getStores(true) as $store) {
$storeCategories = $this->connection->fetchCol(
$this->connection->select()
->from($this->getIndexTable($store->getId()), ['category_id'])
diff --git a/Model/ResourceModel/Category/Collection.php b/Model/ResourceModel/Category/Collection.php
index 351e331..efb701f 100644
--- a/Model/ResourceModel/Category/Collection.php
+++ b/Model/ResourceModel/Category/Collection.php
@@ -11,6 +11,7 @@ use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DB\Select;
use Magento\Store\Model\ScopeInterface;
+use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer;
/**
* Category resource collection
@@ -76,6 +77,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
*/
private $catalogProductVisibility;
+ /**
+ * @var TableMaintainer
+ */
+ private $tableMaintainer;
+
/**
* Constructor
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
@@ -125,6 +131,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
\Magento\Framework\App\ObjectManager::getInstance()->get(ScopeConfigInterface::class);
$this->catalogProductVisibility = $catalogProductVisibility ?:
\Magento\Framework\App\ObjectManager::getInstance()->get(Visibility::class);
+ $this->tableMaintainer = \Magento\Framework\App\ObjectManager::getInstance()->get(TableMaintainer::class);
}
/**
@@ -327,9 +334,9 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
$countSelect = $this->getProductsCountQuery($categoryIds, (bool)$websiteId);
$categoryProductsCount = $this->_conn->fetchPairs($countSelect);
foreach ($anchor as $item) {
- $productsCount = isset($categoriesProductsCount[$item->getId()])
+ $productsCount = isset($categoryProductsCount[$item->getId()])
? (int)$categoryProductsCount[$item->getId()]
- : $this->getProductsCountFromCategoryTable($item, $websiteId);
+ : 0;
$item->setProductCount($productsCount);
}
}
@@ -508,45 +515,6 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
return $this->_productTable;
}
- /**
- * Get products count using catalog_category_entity table
- *
- * @param Category $item
- * @param string $websiteId
- * @return int
- */
- private function getProductsCountFromCategoryTable(Category $item, string $websiteId): int
- {
- $productCount = 0;
-
- if ($item->getAllChildren()) {
- $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%'];
- $select = $this->_conn->select();
- $select->from(
- ['main_table' => $this->getProductTable()],
- new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)')
- )->joinInner(
- ['e' => $this->getTable('catalog_category_entity')],
- 'main_table.category_id=e.entity_id',
- []
- )->where(
- '(e.entity_id = :entity_id OR e.path LIKE :c_path)'
- );
- if ($websiteId) {
- $select->join(
- ['w' => $this->getProductWebsiteTable()],
- 'main_table.product_id = w.product_id',
- []
- )->where(
- 'w.website_id = ?',
- $websiteId
- );
- }
- $productCount = (int)$this->_conn->fetchOne($select, $bind);
- }
- return $productCount;
- }
-
/**
* Get query for retrieve count of products per category
*
@@ -556,7 +524,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
*/
private function getProductsCountQuery(array $categoryIds, $addVisibilityFilter = true): Select
{
- $categoryTable = $this->getTable('catalog_category_product_index');
+ $categoryTable = $this->tableMaintainer->getMainTable($this->getProductStoreId());
$select = $this->_conn->select()
->from(
['cat_index' => $categoryTable],
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment