Last active
April 8, 2023 18:48
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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