From c137752b7fa9e2e357b511d68e7bca45b19e9f03 Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Tue, 5 Nov 2024 15:19:37 +0200 Subject: [PATCH 1/5] 12171-Auto-Related-Magento-Indexing-Implementation --- Model/AutoRelatedProductAction.php | 11 ++-- Model/Indexer/Rule.php | 87 ++++++++++++++++++++++++++++++ etc/indexer.xml | 7 +++ etc/mview.xml | 8 +++ 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 Model/Indexer/Rule.php create mode 100644 etc/indexer.xml create mode 100644 etc/mview.xml diff --git a/Model/AutoRelatedProductAction.php b/Model/AutoRelatedProductAction.php index 0ffea48..420906d 100644 --- a/Model/AutoRelatedProductAction.php +++ b/Model/AutoRelatedProductAction.php @@ -133,7 +133,7 @@ public function __construct( } } - public function execute() + public function execute(array $ids = []) { $productIdsToCleanCache = []; $oldProductToRuleData = []; @@ -141,8 +141,13 @@ public function execute() $connection = $this->resourceConnection->getConnection(); $tableNameArpIndex = $this->resourceConnection->getTableName('magefan_autorp_index'); - $ruleCollection = $this->ruleCollectionFactory->create() - ->addFieldToFilter('status', 1); + if (!empty($ids) && is_array($ids)) { + $ruleCollection = $this->ruleCollectionFactory->create() + ->addFieldToFilter('id',['in' => $ids]); + } else { + $ruleCollection = $this->ruleCollectionFactory->create() + ->addFieldToFilter('status', 1); + } if ($ruleCollection) { $oldProductToRuleCollection = $this->connection->fetchAll($this->connection->select()->from($tableNameArpIndex)); diff --git a/Model/Indexer/Rule.php b/Model/Indexer/Rule.php new file mode 100644 index 0000000..9d4e531 --- /dev/null +++ b/Model/Indexer/Rule.php @@ -0,0 +1,87 @@ +indexerRegistry = $indexerRegistry; + $this->autoRelatedProductAction = $autoRelatedProductAction; + $this->indexMutex = $indexMutex ?? ObjectManager::getInstance()->get(IndexMutexInterface::class); + } + + + public function execute($ids) + { + $this->executeList($ids); + } + + public function executeFull() + { + $this->executeAction([]); + } + + public function executeList(array $ids){ + $this->executeAction($ids); + } + + + public function executeRow($id) + { + $this->executeAction([$id]); + } + + protected function executeAction($ids) + { + $ids = array_unique($ids); + $indexer = $this->indexerRegistry->get(static::INDEXER_ID); + + if ($indexer->isScheduled()) { + $this->indexMutex->execute( + static::INDEXER_ID, + function () use ($ids) { + $this->autoRelatedProductAction->execute($ids); + } + ); + } else { + $this->autoRelatedProductAction->execute($ids); + } + + return $this; + } +} \ No newline at end of file diff --git a/etc/indexer.xml b/etc/indexer.xml new file mode 100644 index 0000000..70ce005 --- /dev/null +++ b/etc/indexer.xml @@ -0,0 +1,7 @@ + + + + AutoRelatedProduct Indexer + Magefan AutoRelatedProduct indexer + + \ No newline at end of file diff --git a/etc/mview.xml b/etc/mview.xml new file mode 100644 index 0000000..5fbeb74 --- /dev/null +++ b/etc/mview.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From 06cccd7196f0d5df69e64f70478e8d8f706cd7a5 Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Wed, 6 Nov 2024 14:01:08 +0200 Subject: [PATCH 2/5] 12171-Auto-Related-Magento-Indexing-Implementation --- Model/AutoRelatedProductAction.php | 9 +-- Model/Indexer/Rule.php | 119 +++++++++++++++++++++++++---- Observer/Product/SaveAfter.php | 39 ++++++++++ etc/adminhtml/events.xml | 12 +++ etc/indexer.xml | 2 +- 5 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 Observer/Product/SaveAfter.php create mode 100644 etc/adminhtml/events.xml diff --git a/Model/AutoRelatedProductAction.php b/Model/AutoRelatedProductAction.php index 420906d..ae067d6 100644 --- a/Model/AutoRelatedProductAction.php +++ b/Model/AutoRelatedProductAction.php @@ -141,12 +141,11 @@ public function execute(array $ids = []) $connection = $this->resourceConnection->getConnection(); $tableNameArpIndex = $this->resourceConnection->getTableName('magefan_autorp_index'); + $ruleCollection = $this->ruleCollectionFactory->create() + ->addFieldToFilter('status', 1); + if (!empty($ids) && is_array($ids)) { - $ruleCollection = $this->ruleCollectionFactory->create() - ->addFieldToFilter('id',['in' => $ids]); - } else { - $ruleCollection = $this->ruleCollectionFactory->create() - ->addFieldToFilter('status', 1); + $ruleCollection->addFieldToFilter('id', ['in' => $ids]); } if ($ruleCollection) { diff --git a/Model/Indexer/Rule.php b/Model/Indexer/Rule.php index 9d4e531..8af24e4 100644 --- a/Model/Indexer/Rule.php +++ b/Model/Indexer/Rule.php @@ -8,8 +8,14 @@ namespace Magefan\AutoRelatedProduct\Model\Indexer; +use Magefan\AutoRelatedProduct\Api\RelatedCollectionInterface; +use Magefan\AutoRelatedProduct\Model\AutoRelatedProductAction; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\CatalogRule\Model\RuleFactory; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Indexer\CacheContext; +use Magento\Framework\Indexer\IndexerRegistry; use Magento\Framework\Indexer\IndexMutexInterface; class Rule implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface @@ -17,8 +23,7 @@ class Rule implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame const INDEXER_ID = 'magefan_autorelatedproduct_indexer'; /** - * @var \Magento\Framework\Indexer\IndexerRegistry - * php bin/magento indexer:reindex magefan_autorelatedproduct_indexer + * @var IndexerRegistry */ protected $indexerRegistry; @@ -30,42 +35,102 @@ class Rule implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame private $autoRelatedProductAction; /** - * @var \Magento\Framework\Indexer\CacheContext + * @var CacheContext * @since 100.0.11 */ protected $cacheContext; + /** + * @var RelatedCollectionInterface + */ + private $relatedCollection; + + /** + * @var RuleFactory + */ + private $ruleFactory; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param IndexerRegistry $indexerRegistry + * @param AutoRelatedProductAction $autoRelatedProductAction + * @param RelatedCollectionInterface $relatedCollection + * @param RuleFactory $ruleFactory + * @param ProductRepositoryInterface $productRepository + * @param IndexMutexInterface|null $indexMutex + */ public function __construct( - \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, - \Magefan\AutoRelatedProduct\Model\AutoRelatedProductAction $autoRelatedProductAction, - ?IndexMutexInterface $indexMutex = null - ) { + IndexerRegistry $indexerRegistry, + AutoRelatedProductAction $autoRelatedProductAction, + RelatedCollectionInterface $relatedCollection, + RuleFactory $ruleFactory, + ProductRepositoryInterface $productRepository, + ?IndexMutexInterface $indexMutex = null + ) + { $this->indexerRegistry = $indexerRegistry; $this->autoRelatedProductAction = $autoRelatedProductAction; + $this->relatedCollection = $relatedCollection; + $this->ruleFactory = $ruleFactory; + $this->productRepository = $productRepository; $this->indexMutex = $indexMutex ?? ObjectManager::getInstance()->get(IndexMutexInterface::class); } - + /** + * @param $ids + * @return void + * @throws NoSuchEntityException + */ public function execute($ids) { - $this->executeList($ids); + $this->getIndexRuleByProduct($ids); + /* + * ???? + $this->executeAction([]) + */ } + /** + * @return void + */ public function executeFull() { $this->executeAction([]); } - public function executeList(array $ids){ - $this->executeAction($ids); + /** + * @param array $ids + * @return void + * @throws NoSuchEntityException + */ + public function executeList(array $ids) + { + var_dump('dgjksgj');exit(); + $this->getIndexRuleByProduct($ids); + /* + * ???? + $this->executeAction([]) + */ } - + /** + * @param $id + * @return void + * @throws NoSuchEntityException + */ public function executeRow($id) { - $this->executeAction([$id]); + $this->getIndexRuleByProduct([$id]); } + /** + * @param $ids + * @return $this + */ protected function executeAction($ids) { $ids = array_unique($ids); @@ -84,4 +149,32 @@ function () use ($ids) { return $this; } + + /** + * @param array $ids + * @return void + * @throws NoSuchEntityException + */ + public function getIndexRuleByProduct(array $ids) + { + $ruleIdFoIndex = []; + $autoRelatedProductRules = $this->relatedCollection->addFieldToFilter('status', 1); + $ids = array_unique($ids); + foreach ($ids as $id) { + $product = $this->productRepository->getById($id); + + foreach ($autoRelatedProductRules as $autoRelatedProductRule) { + if (in_array($autoRelatedProductRule->getId(), $ruleIdFoIndex)) { + continue; + } + $rule = $this->ruleFactory->create(); + $rule->setData('conditions_serialized', $autoRelatedProductRule->getConditions()); + $rule->setData('store_ids', $autoRelatedProductRule->getStoreIds()); + if ($rule->getConditions()->validate($product)) { + $ruleIdFoIndex[] = $autoRelatedProductRule->getId(); + } + } + } + $this->executeAction($ruleIdFoIndex); + } } \ No newline at end of file diff --git a/Observer/Product/SaveAfter.php b/Observer/Product/SaveAfter.php new file mode 100644 index 0000000..6d03146 --- /dev/null +++ b/Observer/Product/SaveAfter.php @@ -0,0 +1,39 @@ +ruleIndexer = $ruleIndexer; + } + + /** + * @param Observer $observer + * @return void + */ + public function execute(Observer $observer) + { + $productId = $observer->getEvent()->getProduct()->getId(); + $this->ruleIndexer->executeRow($productId); + } +} \ No newline at end of file diff --git a/etc/adminhtml/events.xml b/etc/adminhtml/events.xml new file mode 100644 index 0000000..8f00b93 --- /dev/null +++ b/etc/adminhtml/events.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/etc/indexer.xml b/etc/indexer.xml index 70ce005..7966dc8 100644 --- a/etc/indexer.xml +++ b/etc/indexer.xml @@ -1,6 +1,6 @@ - + AutoRelatedProduct Indexer Magefan AutoRelatedProduct indexer From 58014ef3e62fffd87d5f4f3c22fe0cf38246ad84 Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Wed, 6 Nov 2024 17:34:00 +0200 Subject: [PATCH 3/5] 12171-Auto-Related-Magento-Indexing-Implementation [in progress] --- Model/Indexer/Rule.php | 52 +++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/Model/Indexer/Rule.php b/Model/Indexer/Rule.php index 8af24e4..1f19c3e 100644 --- a/Model/Indexer/Rule.php +++ b/Model/Indexer/Rule.php @@ -64,12 +64,12 @@ class Rule implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame * @param IndexMutexInterface|null $indexMutex */ public function __construct( - IndexerRegistry $indexerRegistry, - AutoRelatedProductAction $autoRelatedProductAction, + IndexerRegistry $indexerRegistry, + AutoRelatedProductAction $autoRelatedProductAction, RelatedCollectionInterface $relatedCollection, - RuleFactory $ruleFactory, - ProductRepositoryInterface $productRepository, - ?IndexMutexInterface $indexMutex = null + RuleFactory $ruleFactory, + ProductRepositoryInterface $productRepository, + ?IndexMutexInterface $indexMutex = null ) { $this->indexerRegistry = $indexerRegistry; @@ -87,11 +87,7 @@ public function __construct( */ public function execute($ids) { - $this->getIndexRuleByProduct($ids); - /* - * ???? - $this->executeAction([]) - */ + $this->executeAction($ids); } /** @@ -109,12 +105,7 @@ public function executeFull() */ public function executeList(array $ids) { - var_dump('dgjksgj');exit(); - $this->getIndexRuleByProduct($ids); - /* - * ???? - $this->executeAction([]) - */ + $this->executeAction($ids); } /** @@ -124,7 +115,7 @@ public function executeList(array $ids) */ public function executeRow($id) { - $this->getIndexRuleByProduct([$id]); + $this->getIndexRuleByProduct($id); } /** @@ -155,26 +146,25 @@ function () use ($ids) { * @return void * @throws NoSuchEntityException */ - public function getIndexRuleByProduct(array $ids) + public function getIndexRuleByProduct($id) { $ruleIdFoIndex = []; $autoRelatedProductRules = $this->relatedCollection->addFieldToFilter('status', 1); - $ids = array_unique($ids); - foreach ($ids as $id) { - $product = $this->productRepository->getById($id); - foreach ($autoRelatedProductRules as $autoRelatedProductRule) { - if (in_array($autoRelatedProductRule->getId(), $ruleIdFoIndex)) { - continue; - } - $rule = $this->ruleFactory->create(); - $rule->setData('conditions_serialized', $autoRelatedProductRule->getConditions()); - $rule->setData('store_ids', $autoRelatedProductRule->getStoreIds()); - if ($rule->getConditions()->validate($product)) { - $ruleIdFoIndex[] = $autoRelatedProductRule->getId(); - } + $product = $this->productRepository->getById($id); + + foreach ($autoRelatedProductRules as $autoRelatedProductRule) { + if (in_array($autoRelatedProductRule->getId(), $ruleIdFoIndex)) { + continue; + } + $rule = $this->ruleFactory->create(); + $rule->setData('conditions_serialized', $autoRelatedProductRule->getConditions()); + $rule->setData('store_ids', $autoRelatedProductRule->getStoreIds()); + if ($rule->getConditions()->validate($product)) { + $ruleIdFoIndex[] = $autoRelatedProductRule->getId(); } } + $this->executeAction($ruleIdFoIndex); } } \ No newline at end of file From 1fe7773ad3d419113dba34ad08c0310b0f3f3045 Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Mon, 11 Nov 2024 11:42:19 +0200 Subject: [PATCH 4/5] 12171-Auto-Related-Magento-Indexing-Implementation [in progress] --- Model/AutoRelatedProductAction.php | 6 ------ etc/indexer.xml | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Model/AutoRelatedProductAction.php b/Model/AutoRelatedProductAction.php index ae067d6..0b94544 100644 --- a/Model/AutoRelatedProductAction.php +++ b/Model/AutoRelatedProductAction.php @@ -206,15 +206,9 @@ public function execute(array $ids = []) /** * @param $rule - * @param null $params * @return array * @throws LocalizedException */ - /** - * @param $rule - * @param null $params - * @return array - */ public function getListProductIds($rule) { $this->productIds = []; diff --git a/etc/indexer.xml b/etc/indexer.xml index 7966dc8..cae1bb0 100644 --- a/etc/indexer.xml +++ b/etc/indexer.xml @@ -2,6 +2,6 @@ AutoRelatedProduct Indexer - Magefan AutoRelatedProduct indexer + Magefan AutoRelatedProductRule/Product indexer \ No newline at end of file From 015dde61f51220e43e894093d2ffa7f13dbe7080 Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Tue, 12 Nov 2024 13:08:33 +0200 Subject: [PATCH 5/5] changed validation --- Model/AutoRelatedProductAction.php | 6 ++++- Model/Indexer/Rule.php | 43 +++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/Model/AutoRelatedProductAction.php b/Model/AutoRelatedProductAction.php index 0b94544..1a5fcab 100644 --- a/Model/AutoRelatedProductAction.php +++ b/Model/AutoRelatedProductAction.php @@ -209,7 +209,7 @@ public function execute(array $ids = []) * @return array * @throws LocalizedException */ - public function getListProductIds($rule) + public function getListProductIds($rule, $productId = null) { $this->productIds = []; $conditions = $rule->getConditions(); @@ -244,6 +244,10 @@ public function getListProductIds($rule) $productCollection->setStoreId($storeId); } + if ($productId) { + $productCollection->addFieldToFilter('entity_id', $productId); + } + $conditions = $rule->getConditions(); $conditions->collectValidatedAttributes($productCollection); diff --git a/Model/Indexer/Rule.php b/Model/Indexer/Rule.php index 1f19c3e..5f57711 100644 --- a/Model/Indexer/Rule.php +++ b/Model/Indexer/Rule.php @@ -13,6 +13,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\CatalogRule\Model\RuleFactory; use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Indexer\CacheContext; use Magento\Framework\Indexer\IndexerRegistry; @@ -55,12 +56,18 @@ class Rule implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame */ private $productRepository; + /** + * @var ResourceConnection + */ + private $resourceConnection; + /** * @param IndexerRegistry $indexerRegistry * @param AutoRelatedProductAction $autoRelatedProductAction * @param RelatedCollectionInterface $relatedCollection * @param RuleFactory $ruleFactory * @param ProductRepositoryInterface $productRepository + * @param ResourceConnection $resourceConnection * @param IndexMutexInterface|null $indexMutex */ public function __construct( @@ -69,6 +76,7 @@ public function __construct( RelatedCollectionInterface $relatedCollection, RuleFactory $ruleFactory, ProductRepositoryInterface $productRepository, + ResourceConnection $resourceConnection, ?IndexMutexInterface $indexMutex = null ) { @@ -77,6 +85,7 @@ public function __construct( $this->relatedCollection = $relatedCollection; $this->ruleFactory = $ruleFactory; $this->productRepository = $productRepository; + $this->resourceConnection = $resourceConnection; $this->indexMutex = $indexMutex ?? ObjectManager::getInstance()->get(IndexMutexInterface::class); } @@ -142,29 +151,39 @@ function () use ($ids) { } /** - * @param array $ids + * @param $id * @return void - * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException */ public function getIndexRuleByProduct($id) { - $ruleIdFoIndex = []; $autoRelatedProductRules = $this->relatedCollection->addFieldToFilter('status', 1); - $product = $this->productRepository->getById($id); - foreach ($autoRelatedProductRules as $autoRelatedProductRule) { - if (in_array($autoRelatedProductRule->getId(), $ruleIdFoIndex)) { - continue; - } + $rule = $this->ruleFactory->create(); $rule->setData('conditions_serialized', $autoRelatedProductRule->getConditions()); $rule->setData('store_ids', $autoRelatedProductRule->getStoreIds()); - if ($rule->getConditions()->validate($product)) { - $ruleIdFoIndex[] = $autoRelatedProductRule->getId(); + $relatedProductId = $this->autoRelatedProductAction->getListProductIds($rule, $id); + + $connection = $this->resourceConnection->getConnection(); + $tableNameArpIndex = $this->resourceConnection->getTableName('magefan_autorp_index'); + + $oldIndexRule = $connection->select()->from($tableNameArpIndex)->where( + 'rule_id = ?' , $autoRelatedProductRule->getId()); + $oldRelatedIds = explode(',', $connection->fetchRow($oldIndexRule)['related_ids']); + + if (in_array($relatedProductId[0],$oldRelatedIds)){ + continue; } - } - $this->executeAction($ruleIdFoIndex); + $relatedIds = array_merge($oldRelatedIds,$relatedProductId); + $relatedIds = array_unique($relatedIds); + $connection->update( + $tableNameArpIndex, + ['related_ids' => implode(',', $relatedIds)], + ['rule_id = ?' => $autoRelatedProductRule->getId()] + ); + } } } \ No newline at end of file