Skip to content

Commit

Permalink
Merge branch '27_product-variants' into 437_reindex_variants_by_child_id
Browse files Browse the repository at this point in the history
  • Loading branch information
jekabs committed Nov 30, 2020
2 parents 70bac0b + 2997c98 commit 2d9d3fe
Show file tree
Hide file tree
Showing 13 changed files with 460 additions and 42 deletions.
11 changes: 0 additions & 11 deletions app/code/Magento/CatalogExport/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<preference for="Magento\CatalogExportApi\Api\ProductVariantRepositoryInterface" type="Magento\CatalogExport\Model\ProductVariantRepository"/>
<preference for="Magento\CatalogDataExporter\Model\Indexer\ProductIndexerCallbackInterface" type="Magento\CatalogExport\Model\Indexer\ProductIndexerCallback" />
<preference for="Magento\CatalogDataExporter\Model\Indexer\CategoryIndexerCallbackInterface" type="Magento\CatalogExport\Model\Indexer\CategoryIndexerCallback" />
<preference for="Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantIndexerCallbackInterface" type="Magento\CatalogExport\Model\Indexer\ProductVariantIndexerCallback"/>

<virtualType name="Magento\CatalogExport\Model\Indexer\CategoryIndexerCallback"
type="Magento\CatalogExport\Model\Indexer\EntityIndexerCallback">
Expand All @@ -33,16 +32,6 @@
</arguments>
</virtualType>

<virtualType name="Magento\CatalogExport\Model\Indexer\ProductVariantIndexerCallback"
type="Magento\CatalogExport\Model\Indexer\EntityIndexerCallback">
<arguments>
<argument name="feedIndexMetadata" xsi:type="object">Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantFeedIndexMetadata</argument>
<argument name="topicName" xsi:type="string">catalog.export.product.variants.data</argument>
<argument name="updatedEventType" xsi:type="string">product_variants_updated</argument>
<argument name="deletedEventType" xsi:type="string">product_variants_deleted</argument>
</arguments>
</virtualType>

<type name="Magento\Framework\Console\CommandListInterface">
<arguments>
<argument name="commands" xsi:type="array">
Expand Down
7 changes: 1 addition & 6 deletions app/code/Magento/CatalogExport/etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,5 @@
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magento_CatalogExport">
<sequence>
<module name="Magento_CatalogDataExporter"/>
<module name="Magento_ProductVariantDataExporter"/>
</sequence>
</module>
<module name="Magento_CatalogExport"/>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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);
}
}
}
4 changes: 2 additions & 2 deletions app/code/Magento/ConfigurableProductDataExporter/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
</arguments>
</type>
<type name="Magento\Catalog\Model\ResourceModel\Product">
<plugin name="trigger_reindex_on_configurable_parent_product_variants"
type="Magento\ConfigurableProductDataExporter\Plugin\ReindexVariants"/>
<plugin name="reindex_configurable_variants_after_save"
type="Magento\ConfigurableProductDataExporter\Plugin\ReindexVariantsAfterSave"/>
</type>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
*/
class ProductVariantFeedIndexer extends FeedIndexer
{
/**
* Product variant feed indexer id
*/
public const INDEXER_ID = 'catalog_data_exporter_product_variants';

/**
* Get Ids select
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ProductVariantDataExporter\Model\Indexer;

use Magento\Framework\App\ResourceConnection;
use Psr\Log\LoggerInterface;

/**
* Update indexer changelog
*/
class UpdateChangeLog
{
/**
* @var ResourceConnection
*/
private $resourceConnection;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param ResourceConnection $resourceConnection
* @param LoggerInterface $logger
*/
public function __construct(
ResourceConnection $resourceConnection,
LoggerInterface $logger
) {
$this->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()
)
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ProductVariantDataExporter\Model\Query;

use Magento\Framework\App\ResourceConnection;

/**
* Retrieve product relations
*/
class ProductRelationsQuery
{
/**
* @var ResourceConnection
*/
private $resourceConnection;

/**
* @param ResourceConnection $resourceConnection
*/
public function __construct(
ResourceConnection $resourceConnection
) {
$this->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));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ProductVariantDataExporter\Plugin;

use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\Framework\Model\AbstractModel;
use Magento\ProductVariantDataExporter\Model\Indexer\ProductVariantFeedIndexer;
use Magento\ProductVariantDataExporter\Model\Indexer\UpdateChangeLog;
use Magento\ProductVariantDataExporter\Model\Query\ProductRelationsQuery;

/**
* Plugin to trigger reindex on product variants upon product deletion
*/
class ReindexVariantsOnDelete
{
/**
* @var IndexerRegistry
*/
private $indexerRegistry;

/**
* @var UpdateChangeLog
*/
private $updateChangeLog;

/**
* @var ProductRelationsQuery
*/
private $productRelationsQuery;

/**
* @param IndexerRegistry $indexerRegistry
* @param UpdateChangeLog $updateChangeLog
* @param ProductRelationsQuery $productRelationsQuery
*/
public function __construct(
IndexerRegistry $indexerRegistry,
UpdateChangeLog $updateChangeLog,
ProductRelationsQuery $productRelationsQuery
) {
$this->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);
}
}
}
Loading

0 comments on commit 2d9d3fe

Please sign in to comment.