diff --git a/app/code/Magento/CatalogExport/etc/di.xml b/app/code/Magento/CatalogExport/etc/di.xml
index f47d80e14..d8154d560 100644
--- a/app/code/Magento/CatalogExport/etc/di.xml
+++ b/app/code/Magento/CatalogExport/etc/di.xml
@@ -11,7 +11,6 @@
-
@@ -33,16 +32,6 @@
-
-
- Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantFeedIndexMetadata
- catalog.export.product.variants.data
- product_variants_updated
- product_variants_deleted
-
-
-
diff --git a/app/code/Magento/CatalogExport/etc/module.xml b/app/code/Magento/CatalogExport/etc/module.xml
index 2d50f0efc..ea9727a2c 100644
--- a/app/code/Magento/CatalogExport/etc/module.xml
+++ b/app/code/Magento/CatalogExport/etc/module.xml
@@ -6,10 +6,5 @@
*/
-->
-
-
-
-
-
-
+
diff --git a/app/code/Magento/ConfigurableProductDataExporter/Plugin/ReindexVariants.php b/app/code/Magento/ConfigurableProductDataExporter/Plugin/ReindexVariantsAfterSave.php
similarity index 67%
rename from app/code/Magento/ConfigurableProductDataExporter/Plugin/ReindexVariants.php
rename to app/code/Magento/ConfigurableProductDataExporter/Plugin/ReindexVariantsAfterSave.php
index e8b2c2774..6da3b94f4 100644
--- a/app/code/Magento/ConfigurableProductDataExporter/Plugin/ReindexVariants.php
+++ b/app/code/Magento/ConfigurableProductDataExporter/Plugin/ReindexVariantsAfterSave.php
@@ -11,13 +11,15 @@
use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct;
use Magento\ConfigurableProductDataExporter\Model\Query\LinkedAttributesQuery;
use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Indexer\IndexerRegistry;
use Magento\Framework\Model\AbstractModel;
use Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantFeedIndexer;
+use Magento\ProductVariantDataExporter\Model\Indexer\UpdateChangeLog;
/**
* Plugin to trigger reindex on parent products, when a super attribute value is changed on a child product
*/
-class ReindexVariants
+class ReindexVariantsAfterSave
{
/**
* @var ResourceConnection
@@ -30,27 +32,35 @@ class ReindexVariants
private $linkedAttributesQuery;
/**
- * @var ProductVariantFeedIndexer
+ * @var IndexerRegistry
*/
- private $feedIndexer;
+ private $indexerRegistry;
+
+ /**
+ * @var UpdateChangeLog
+ */
+ private $updateChangeLog;
/**
* @param ResourceConnection $resourceConnection
* @param LinkedAttributesQuery $linkedAttributesQuery
- * @param ProductVariantFeedIndexer $feedIndexer
+ * @param IndexerRegistry $indexerRegistry
+ * @param UpdateChangeLog $updateChangeLog
*/
public function __construct(
ResourceConnection $resourceConnection,
LinkedAttributesQuery $linkedAttributesQuery,
- ProductVariantFeedIndexer $feedIndexer
+ IndexerRegistry $indexerRegistry,
+ UpdateChangeLog $updateChangeLog
) {
$this->resourceConnection = $resourceConnection;
$this->linkedAttributesQuery = $linkedAttributesQuery;
- $this->feedIndexer = $feedIndexer;
+ $this->indexerRegistry = $indexerRegistry;
+ $this->updateChangeLog = $updateChangeLog;
}
/**
- * Reindex parent product on change of super attribute value.
+ * Reindex parent products on change of child product attribute value
*
* @param ResourceProduct $subject
* @param ResourceProduct $result
@@ -75,9 +85,26 @@ public function afterSave(
}
}
if (!empty($changedConfigurableIds)) {
- $this->feedIndexer->executeList(array_filter($changedConfigurableIds));
+ $this->reindexVariants($changedConfigurableIds);
}
}
return $result;
}
+
+ /**
+ * Reindex product variants
+ *
+ * @param int[] $ids
+ * @return void
+ */
+ private function reindexVariants(array $ids): void
+ {
+ $indexer = $this->indexerRegistry->get(ProductVariantFeedIndexer::INDEXER_ID);
+
+ if ($indexer->isScheduled()) {
+ $this->updateChangeLog->execute($indexer->getViewId(), $ids);
+ } else {
+ $indexer->reindexList($ids);
+ }
+ }
}
diff --git a/app/code/Magento/ConfigurableProductDataExporter/etc/di.xml b/app/code/Magento/ConfigurableProductDataExporter/etc/di.xml
index 4a40b3b93..c6e1e33e3 100755
--- a/app/code/Magento/ConfigurableProductDataExporter/etc/di.xml
+++ b/app/code/Magento/ConfigurableProductDataExporter/etc/di.xml
@@ -48,7 +48,7 @@
-
+
diff --git a/app/code/Magento/ProductVariantDataExporter/Model/Indexer/ProductVariantFeedIndexer.php b/app/code/Magento/ProductVariantDataExporter/Model/Indexer/ProductVariantFeedIndexer.php
index 65aba3ecc..8b62c4f91 100644
--- a/app/code/Magento/ProductVariantDataExporter/Model/Indexer/ProductVariantFeedIndexer.php
+++ b/app/code/Magento/ProductVariantDataExporter/Model/Indexer/ProductVariantFeedIndexer.php
@@ -15,6 +15,11 @@
*/
class ProductVariantFeedIndexer extends FeedIndexer
{
+ /**
+ * Product variant feed indexer id
+ */
+ public const INDEXER_ID = 'catalog_data_exporter_product_variants';
+
/**
* Get Ids select
*
@@ -122,8 +127,6 @@ public function execute($ids): void
/**
* Indexer feed data processor
*
- * TODO: currently reindexAll is going reindex all the products, should base that on catalog_product_relation
- *
* @param array $indexData
* @return void
*/
diff --git a/app/code/Magento/ProductVariantDataExporter/Model/Indexer/UpdateChangeLog.php b/app/code/Magento/ProductVariantDataExporter/Model/Indexer/UpdateChangeLog.php
new file mode 100644
index 000000000..8c59d2ae4
--- /dev/null
+++ b/app/code/Magento/ProductVariantDataExporter/Model/Indexer/UpdateChangeLog.php
@@ -0,0 +1,66 @@
+resourceConnection = $resourceConnection;
+ $this->logger = $logger;
+ }
+
+ /**
+ * Update indexer change log
+ *
+ * @param string $viewId
+ * @param array $ids
+ */
+ public function execute(string $viewId, array $ids): void
+ {
+ $connection = $this->resourceConnection->getConnection();
+ $connection->beginTransaction();
+ try {
+ foreach ($ids as $id) {
+ $connection->insert($viewId . '_cl', ['entity_id' => $id]);
+ }
+ $connection->commit();
+ } catch (\Exception $e) {
+ $connection->rollBack();
+ $this->logger->error(
+ sprintf(
+ 'Failed to update change log of indexer %s. %s',
+ $viewId,
+ $e->getMessage()
+ )
+ );
+ }
+ }
+}
diff --git a/app/code/Magento/ProductVariantDataExporter/Model/Query/ProductRelationsQuery.php b/app/code/Magento/ProductVariantDataExporter/Model/Query/ProductRelationsQuery.php
new file mode 100644
index 000000000..7347dd7c9
--- /dev/null
+++ b/app/code/Magento/ProductVariantDataExporter/Model/Query/ProductRelationsQuery.php
@@ -0,0 +1,55 @@
+resourceConnection = $resourceConnection;
+ }
+
+ /**
+ * Return the parent ids of product relations
+ *
+ * @param int[] $ids
+ * @return array
+ */
+ public function getRelationsParentIds(array $ids): array
+ {
+ $connection = $this->resourceConnection->getConnection();
+ $select = $connection->select()->from(
+ ['cpr' => $this->resourceConnection->getTableName('catalog_product_relation')],
+ []
+ )->join(
+ ['cpe' => $catalogProductTable = $this->resourceConnection->getTableName('catalog_product_entity')],
+ \sprintf('cpe.%1$s = cpr.parent_id', $connection->getAutoIncrementField($catalogProductTable)),
+ ['entity_id']
+ )->where(
+ sprintf(
+ 'cpe.entity_id IN ("%1$s") OR cpr.child_id IN ("%1$s")',
+ \implode(",", $ids)
+ )
+ );
+ return array_filter($connection->fetchCol($select));
+ }
+}
diff --git a/app/code/Magento/ProductVariantDataExporter/Plugin/ReindexVariantsOnDelete.php b/app/code/Magento/ProductVariantDataExporter/Plugin/ReindexVariantsOnDelete.php
new file mode 100644
index 000000000..95789efad
--- /dev/null
+++ b/app/code/Magento/ProductVariantDataExporter/Plugin/ReindexVariantsOnDelete.php
@@ -0,0 +1,89 @@
+indexerRegistry = $indexerRegistry;
+ $this->updateChangeLog = $updateChangeLog;
+ $this->productRelationsQuery = $productRelationsQuery;
+ }
+
+ /**
+ * Reindex product variants on product deletion
+ *
+ * @param ResourceProduct $subject
+ * @param \Closure $proceed
+ * @param AbstractModel $product
+ * @return ResourceProduct
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function aroundDelete(
+ ResourceProduct $subject,
+ \Closure $proceed,
+ AbstractModel $product
+ ): ResourceProduct {
+ $ids = $this->productRelationsQuery->getRelationsParentIds([$product->getId()]);
+ $result = $proceed($product);
+ if (!empty($ids)) {
+ $this->reindexVariants($ids);
+ }
+ return $result;
+ }
+
+ /**
+ * Reindex product variants
+ *
+ * @param int[] $ids
+ * @return void
+ */
+ private function reindexVariants(array $ids): void
+ {
+ $indexer = $this->indexerRegistry->get(ProductVariantFeedIndexer::INDEXER_ID);
+ if ($indexer->isScheduled()) {
+ $this->updateChangeLog->execute($indexer->getViewId(), $ids);
+ } else {
+ $indexer->reindexList($ids);
+ }
+ }
+}
diff --git a/app/code/Magento/ProductVariantDataExporter/Plugin/ReindexVariantsOnRelationsChange.php b/app/code/Magento/ProductVariantDataExporter/Plugin/ReindexVariantsOnRelationsChange.php
new file mode 100644
index 000000000..e8cdc8e81
--- /dev/null
+++ b/app/code/Magento/ProductVariantDataExporter/Plugin/ReindexVariantsOnRelationsChange.php
@@ -0,0 +1,186 @@
+indexerRegistry = $indexerRegistry;
+ $this->updateChangeLog = $updateChangeLog;
+ $this->metadataPool = $metadataPool;
+ $this->resourceConnection = $resourceConnection;
+ $this->logger = $logger;
+ }
+
+ /**
+ * Reindex variants after addition of new relations
+ *
+ * @param Relation $subject
+ * @param Relation $result
+ * @param int $parentLinkId
+ * @param int[] $childIds
+ * @return Relation
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterAddRelations(
+ Relation $subject,
+ Relation $result,
+ int $parentLinkId,
+ array $childIds
+ ): Relation {
+ if (!empty($childIds)) {
+ try {
+ $parentId = $this->getProductEntityId($parentLinkId);
+ $this->addCommitCallback($subject, (int)$parentId);
+ } catch (\Exception $e) {
+ $this->logger->error(sprintf(
+ 'Failed to reindex product variants after product relation addition: "%s"',
+ $e->getMessage()
+ ));
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Reindex variants after removal of relations
+ *
+ * @param Relation $subject
+ * @param Relation $result
+ * @param int $parentLinkId
+ * @param int[] $childIds
+ * @return Relation
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterRemoveRelations(
+ Relation $subject,
+ Relation $result,
+ int $parentLinkId,
+ array $childIds
+ ): Relation {
+ if (!empty($childIds)) {
+ try {
+ $parentId = $this->getProductEntityId($parentLinkId);
+ $this->addCommitCallback($subject, (int)$parentId);
+ } catch (\Exception $e) {
+ $this->logger->error(sprintf(
+ 'Failed to reindex product variants after product relation removal: "%s"',
+ $e->getMessage()
+ ));
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Reindex product variants after commit
+ *
+ * @param Relation $subject
+ * @param int $id
+ * @return void
+ */
+ private function addCommitCallback(Relation $subject, int $id): void
+ {
+ $indexer = $this->indexerRegistry->get(ProductVariantFeedIndexer::INDEXER_ID);
+ $viewId = $indexer->getViewId();
+
+ if ($indexer->isScheduled()) {
+ $subject->addCommitCallback(function () use ($viewId, $id) {
+ $this->updateChangeLog->execute($viewId, [$id]);
+ });
+ } else {
+ $subject->addCommitCallback(function () use ($indexer, $id) {
+ $indexer->reindexRow($id);
+ });
+ }
+ }
+
+ /**
+ * Get product entity id from product link id
+ *
+ * @param int $linkId
+ * @return int
+ * @throws \Exception
+ */
+ private function getProductEntityId(int $linkId): int
+ {
+ if (($linkField = $this->getProductEntityLinkField()) !== 'entity_id') {
+ $connection = $this->resourceConnection->getConnection();
+ $select = $connection->select()->from(
+ ['cpe' => $this->resourceConnection->getTableName('catalog_product_entity')],
+ ['entity_id']
+ )->where(
+ sprintf('%1$s = ?', $linkField),
+ $linkId
+ );
+ return (int)$connection->fetchOne($select);
+ }
+ return $linkId;
+ }
+
+ /**
+ * Get product entity link field
+ *
+ * @return string
+ * @throws \Exception
+ */
+ private function getProductEntityLinkField(): string
+ {
+ return $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
+ }
+}
diff --git a/app/code/Magento/ProductVariantDataExporter/composer.json b/app/code/Magento/ProductVariantDataExporter/composer.json
index db5517b00..ac698cb3b 100644
--- a/app/code/Magento/ProductVariantDataExporter/composer.json
+++ b/app/code/Magento/ProductVariantDataExporter/composer.json
@@ -22,6 +22,7 @@
"guzzlehttp/guzzle": "*",
"guzzlehttp/psr7": "~1.0",
"magento/framework": "*",
- "magento/module-data-exporter": "*"
+ "magento/module-data-exporter": "*",
+ "magento/module-catalog": "*"
}
}
diff --git a/app/code/Magento/ProductVariantDataExporter/etc/di.xml b/app/code/Magento/ProductVariantDataExporter/etc/di.xml
index 2371528b9..15c659688 100644
--- a/app/code/Magento/ProductVariantDataExporter/etc/di.xml
+++ b/app/code/Magento/ProductVariantDataExporter/etc/di.xml
@@ -31,17 +31,21 @@
-
-
-
+
+
+ Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantFeedIndexMetadata
+ catalog.export.product.variants.data
+ product_variants_updated
+ product_variants_deleted
+
+
Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantFeedIndexMetadata
Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantDataSerializer
- Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantIndexerCallbackInterface
+ Magento\CatalogExport\Model\Indexer\ProductVariantIndexerCallback
@@ -58,4 +62,12 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/ProductVariantDataExporter/etc/indexer.xml b/app/code/Magento/ProductVariantDataExporter/etc/indexer.xml
index 774175ede..c8d22dd88 100644
--- a/app/code/Magento/ProductVariantDataExporter/etc/indexer.xml
+++ b/app/code/Magento/ProductVariantDataExporter/etc/indexer.xml
@@ -13,8 +13,5 @@
>
Product Variant Feed
Collects data for a Product Variants Feed
-
-
-
diff --git a/app/code/Magento/ProductVariantDataExporter/etc/mview.xml b/app/code/Magento/ProductVariantDataExporter/etc/mview.xml
index 83ad31221..9c3f4acf3 100644
--- a/app/code/Magento/ProductVariantDataExporter/etc/mview.xml
+++ b/app/code/Magento/ProductVariantDataExporter/etc/mview.xml
@@ -6,9 +6,5 @@
*/
-->
-
-
-
-
-
+