diff --git a/vendor/magento/module-catalog/Model/Indexer/Category/Product.php b/vendor/magento/module-catalog/Model/Indexer/Category/Product.php index af1cda41d8c..c18404bda1f 100644 --- a/vendor/magento/module-catalog/Model/Indexer/Category/Product.php +++ b/vendor/magento/module-catalog/Model/Indexer/Category/Product.php @@ -137,10 +137,11 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr /** @var Product\Action\Rows $action */ $action = $this->rowsActionFactory->create(); - if ($indexer->isWorking()) { + if ($indexer->isScheduled()) { $action->execute($ids, true); + } else { + $action->execute($ids); } - $action->execute($ids); return $this; } diff --git a/vendor/magento/module-catalog/Model/Indexer/Category/Product/Action/Rows.php b/vendor/magento/module-catalog/Model/Indexer/Category/Product/Action/Rows.php index 581def6ea36..217b0feb81a 100644 --- a/vendor/magento/module-catalog/Model/Indexer/Category/Product/Action/Rows.php +++ b/vendor/magento/module-catalog/Model/Indexer/Category/Product/Action/Rows.php @@ -5,10 +5,23 @@ */ namespace Magento\Catalog\Model\Indexer\Category\Product\Action; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Indexer\CacheContext; +use Magento\Framework\Event\ManagerInterface as EventManagerInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\ResourceConnection; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\DB\Query\Generator as QueryGenerator; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Catalog\Model\Config; +use Magento\Catalog\Model\Category; +use Magento\Framework\Indexer\IndexerRegistry; +use Magento\Catalog\Model\Indexer\Product\Category as ProductCategoryIndexer; + /** - * Reindex multiple rows action. + * Action for partial reindex * - * @package Magento\Catalog\Model\Indexer\Category\Product\Action + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractAction { @@ -19,6 +32,47 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio */ protected $limitationByCategories; + /** + * @var CacheContext + */ + private $cacheContext; + + /** + * @var EventManagerInterface|null + */ + private $eventManager; + + /** + * @var IndexerRegistry + */ + private $indexerRegistry; + + /** + * @param ResourceConnection $resource + * @param StoreManagerInterface $storeManager + * @param Config $config + * @param QueryGenerator|null $queryGenerator + * @param MetadataPool|null $metadataPool + * @param CacheContext|null $cacheContext + * @param EventManagerInterface|null $eventManager + * @param IndexerRegistry|null $indexerRegistry + */ + public function __construct( + ResourceConnection $resource, + StoreManagerInterface $storeManager, + Config $config, + QueryGenerator $queryGenerator = null, + MetadataPool $metadataPool = null, + CacheContext $cacheContext = null, + EventManagerInterface $eventManager = null, + IndexerRegistry $indexerRegistry = null + ) { + parent::__construct($resource, $storeManager, $config, $queryGenerator, $metadataPool); + $this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class); + $this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManagerInterface::class); + $this->indexerRegistry = $indexerRegistry ?: ObjectManager::getInstance()->get(IndexerRegistry::class); + } + /** * Refresh entities index * @@ -40,12 +94,58 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio } $this->limitationByCategories = array_unique($this->limitationByCategories); $this->useTempTable = $useTempTable; - $this->removeEntries(); + $indexer = $this->indexerRegistry->get(ProductCategoryIndexer::INDEXER_ID); + $workingState = $indexer->isWorking(); + + if ($useTempTable && !$workingState && $indexer->isScheduled()) { + foreach ($this->storeManager->getStores() as $store) { + $this->connection->truncateTable($this->getIndexTable($store->getId())); + } + } else { + $this->removeEntries(); + } + $this->reindex(); + if ($useTempTable && !$workingState && $indexer->isScheduled()) { + foreach ($this->storeManager->getStores() as $store) { + $removalCategoryIds = array_diff($this->limitationByCategories, [$this->getRootCategoryId($store)]); + $this->connection->delete( + $this->tableMaintainer->getMainTable($store->getId()), + ['category_id IN (?)' => $removalCategoryIds] + ); + $select = $this->connection->select() + ->from($this->tableMaintainer->getMainReplicaTable($store->getId())); + $this->connection->query( + $this->connection->insertFromSelect( + $select, + $this->tableMaintainer->getMainTable($store->getId()), + [], + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + } + } + + $this->registerCategories($entityIds); + $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]); + return $this; } + /** + * Register categories assigned to products + * + * @param array $categoryIds + * @return void + */ + private function registerCategories(array $categoryIds) + { + if ($categoryIds) { + $this->cacheContext->registerEntities(Category::CACHE_TAG, $categoryIds); + } + } + /** * Return array of all category root IDs + tree root ID * diff --git a/vendor/magento/module-catalog/Model/Indexer/Product/Category/Action/Rows.php b/vendor/magento/module-catalog/Model/Indexer/Product/Category/Action/Rows.php index 15ba6c8f375..ec3d0d57330 100644 --- a/vendor/magento/module-catalog/Model/Indexer/Product/Category/Action/Rows.php +++ b/vendor/magento/module-catalog/Model/Indexer/Product/Category/Action/Rows.php @@ -15,6 +15,9 @@ use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Event\ManagerInterface as EventManagerInterface; use Magento\Framework\Indexer\CacheContext; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Indexer\IndexerRegistry; +use Magento\Catalog\Model\Indexer\Category\Product as CategoryProductIndexer; /** * Category rows indexer. @@ -40,6 +43,11 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio */ private $eventManager; + /** + * @var IndexerRegistry + */ + private $indexerRegistry; + /** * @param ResourceConnection $resource * @param StoreManagerInterface $storeManager @@ -48,6 +56,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio * @param MetadataPool|null $metadataPool * @param CacheContext|null $cacheContext * @param EventManagerInterface|null $eventManager + * @param IndexerRegistry|null $indexerRegistry */ public function __construct( ResourceConnection $resource, @@ -56,11 +65,13 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio QueryGenerator $queryGenerator = null, MetadataPool $metadataPool = null, CacheContext $cacheContext = null, - EventManagerInterface $eventManager = null + EventManagerInterface $eventManager = null, + IndexerRegistry $indexerRegistry = null ) { parent::__construct($resource, $storeManager, $config, $queryGenerator, $metadataPool); $this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class); $this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManagerInterface::class); + $this->indexerRegistry = $indexerRegistry ?: ObjectManager::getInstance()->get(IndexerRegistry::class); } /** @@ -78,12 +89,37 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio $this->limitationByProducts = $idsToBeReIndexed; $this->useTempTable = $useTempTable; + $indexer = $this->indexerRegistry->get(CategoryProductIndexer::INDEXER_ID); + $workingState = $indexer->isWorking(); $affectedCategories = $this->getCategoryIdsFromIndex($idsToBeReIndexed); - $this->removeEntries(); - + if ($useTempTable && !$workingState && $indexer->isScheduled()) { + foreach ($this->storeManager->getStores() as $store) { + $this->connection->truncateTable($this->getIndexTable($store->getId())); + } + } else { + $this->removeEntries(); + } $this->reindex(); + if ($useTempTable && !$workingState && $indexer->isScheduled()) { + foreach ($this->storeManager->getStores() as $store) { + $this->connection->delete( + $this->tableMaintainer->getMainTable($store->getId()), + ['product_id IN (?)' => $this->limitationByProducts] + ); + $select = $this->connection->select() + ->from($this->tableMaintainer->getMainReplicaTable($store->getId())); + $this->connection->query( + $this->connection->insertFromSelect( + $select, + $this->tableMaintainer->getMainTable($store->getId()), + [], + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + } + } $affectedCategories = array_merge($affectedCategories, $this->getCategoryIdsFromIndex($idsToBeReIndexed)); diff --git a/vendor/magento/module-catalog/Observer/CategoryProductIndexer.php b/vendor/magento/module-catalog/Observer/CategoryProductIndexer.php index ca87efaa874..bdee84762ca 100644 --- a/vendor/magento/module-catalog/Observer/CategoryProductIndexer.php +++ b/vendor/magento/module-catalog/Observer/CategoryProductIndexer.php @@ -8,6 +8,7 @@ declare(strict_types=1); namespace Magento\Catalog\Observer; use Magento\Catalog\Model\Indexer\Category\Product\Processor; +use Magento\Catalog\Model\Indexer\Category\Flat\State as FlatState; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; @@ -21,12 +22,21 @@ class CategoryProductIndexer implements ObserverInterface */ private $processor; + /** + * @var FlatState + */ + private $flatState; + /** * @param Processor $processor + * @param FlatState $flatState */ - public function __construct(Processor $processor) - { + public function __construct( + Processor $processor, + FlatState $flatState + ) { $this->processor = $processor; + $this->flatState = $flatState; } /** @@ -35,7 +45,7 @@ class CategoryProductIndexer implements ObserverInterface public function execute(Observer $observer): void { $productIds = $observer->getEvent()->getProductIds(); - if (!empty($productIds) && $this->processor->isIndexerScheduled()) { + if (!empty($productIds) && $this->processor->isIndexerScheduled() && $this->flatState->isFlatEnabled()) { $this->processor->markIndexerAsInvalid(); } } diff --git a/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product/Category/Action/Rows.php b/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product/Category/Action/Rows.php new file mode 100644 index 00000000000..2b1844deb11 --- /dev/null +++ b/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product/Category/Action/Rows.php @@ -0,0 +1,52 @@ +indexerRegistry = $indexerRegistry; + } + + /** + * Reindex after catalog category product reindex + * + * @param ActionRows $subject + * @param ActionRows $result + * @param array $entityIds + * @return ActionRows + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterExecute(ActionRows $subject, ActionRows $result, array $entityIds): ActionRows + { + if (!empty($entityIds)) { + $indexer = $this->indexerRegistry->get(FulltextIndexer::INDEXER_ID); + if ($indexer->isScheduled()) { + $indexer->reindexList($entityIds); + } + } + return $result; + } +} diff --git a/vendor/magento/module-catalog-search/etc/di.xml b/vendor/magento/module-catalog-search/etc/di.xml index 372b389c545..4e5b38878ee 100644 --- a/vendor/magento/module-catalog-search/etc/di.xml +++ b/vendor/magento/module-catalog-search/etc/di.xml @@ -75,6 +75,9 @@ + + + diff --git a/vendor/magento/module-elasticsearch/Observer/CategoryProductIndexer.php b/vendor/magento/module-elasticsearch/Observer/CategoryProductIndexer.php index fd2734bb713..e2b3e18a0ff 100644 --- a/vendor/magento/module-elasticsearch/Observer/CategoryProductIndexer.php +++ b/vendor/magento/module-elasticsearch/Observer/CategoryProductIndexer.php @@ -11,6 +11,7 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor; use Magento\Elasticsearch\Model\Config; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; +use Magento\Catalog\Model\Indexer\Category\Flat\State as FlatState; /** * Checks if a category has changed products and depends on indexer configuration. @@ -27,14 +28,24 @@ class CategoryProductIndexer implements ObserverInterface */ private $processor; + /** + * @var FlatState + */ + private $flatState; + /** * @param Config $config * @param Processor $processor + * @param FlatState $flatState */ - public function __construct(Config $config, Processor $processor) - { + public function __construct( + Config $config, + Processor $processor, + FlatState $flatState + ) { $this->processor = $processor; $this->config = $config; + $this->flatState = $flatState; } /** @@ -47,7 +58,7 @@ class CategoryProductIndexer implements ObserverInterface } $productIds = $observer->getEvent()->getProductIds(); - if (!empty($productIds) && $this->processor->isIndexerScheduled()) { + if (!empty($productIds) && $this->processor->isIndexerScheduled() && $this->flatState->isFlatEnabled()) { $this->processor->markIndexerAsInvalid(); } }