We changed price, color on some product, but sometimes it's not updated on the front end, after we cleared cache, it's updated.
The issue is on Magento 2.4.4-p1
SOLUTION:
Please check the below patch to fix
diff --git a/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php b/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php
index 2f333e7ca6f6..9c226641b6e3 100644
--- a/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php
+++ b/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php
@@ -4,20 +4,29 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\ConfigurableProduct\Plugin\Model\ResourceModel;
use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
+use Magento\Catalog\Model\Indexer\Product\Category\Action\Rows;
+use Magento\Catalog\Model\Indexer\Product\Price\Processor;
+use Magento\Catalog\Model\Product as ProductModel;
+use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
use Magento\ConfigurableProduct\Api\Data\OptionInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\DataObject;
use Magento\Framework\Indexer\ActionInterface;
+use Magento\Framework\Indexer\IndexerRegistry;
/**
* Plugin product resource model
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Product
{
@@ -46,21 +55,35 @@ class Product
*/
private $filterBuilder;
+ /**
+ * @var IndexerRegistry
+ */
+ private $indexerRegistry;
+
+ /**
+ * @var Rows
+ */
+ private $rowsAction;
+
/**
* Initialize Product dependencies.
*
* @param Configurable $configurable
* @param ActionInterface $productIndexer
- * @param ProductAttributeRepositoryInterface $productAttributeRepository
- * @param SearchCriteriaBuilder $searchCriteriaBuilder
- * @param FilterBuilder $filterBuilder
+ * @param ProductAttributeRepositoryInterface|null $productAttributeRepository
+ * @param SearchCriteriaBuilder|null $searchCriteriaBuilder
+ * @param FilterBuilder|null $filterBuilder
+ * @param IndexerRegistry|null $indexerRegistry
+ * @param Rows|null $rowsAction
*/
public function __construct(
Configurable $configurable,
ActionInterface $productIndexer,
ProductAttributeRepositoryInterface $productAttributeRepository = null,
- SearchCriteriaBuilder $searchCriteriaBuilder = null,
- FilterBuilder $filterBuilder = null
+ ?SearchCriteriaBuilder $searchCriteriaBuilder = null,
+ ?FilterBuilder $filterBuilder = null,
+ ?IndexerRegistry $indexerRegistry = null,
+ ?Rows $rowsAction = null
) {
$this->configurable = $configurable;
$this->productIndexer = $productIndexer;
@@ -70,35 +93,62 @@ public function __construct(
->get(SearchCriteriaBuilder::class);
$this->filterBuilder = $filterBuilder ?: ObjectManager::getInstance()
->get(FilterBuilder::class);
+ $this->indexerRegistry = $indexerRegistry ?: ObjectManager::getInstance()
+ ->get(IndexerRegistry::class);
+ $this->rowsAction = $rowsAction ?: ObjectManager::getInstance()
+ ->get(Rows::class);
}
/**
* We need reset attribute set id to attribute after related simple product was saved
*
- * @param \Magento\Catalog\Model\ResourceModel\Product $subject
- * @param \Magento\Framework\DataObject $object
+ * @param ProductResource $subject
+ * @param DataObject $object
* @return void
- * @throws \Magento\Framework\Exception\NoSuchEntityException
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function beforeSave(
- \Magento\Catalog\Model\ResourceModel\Product $subject,
- \Magento\Framework\DataObject $object
+ ProductResource $subject,
+ DataObject $object
) {
- /** @var \Magento\Catalog\Model\Product $object */
+ /** @var ProductModel $object */
if ($object->getTypeId() == Configurable::TYPE_CODE) {
$object->getTypeInstance()->getSetAttributes($object);
$this->resetConfigurableOptionsData($object);
}
}
+ /**
+ * Invalidate cache and per<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">diff --git a/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php b/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php
index 2f333e7ca6f6..9c226641b6e3 100644
--- a/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php
+++ b/vendor/magento/module-configurable-product/Plugin/Model/ResourceModel/Product.php
@@ -4,20 +4,29 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\ConfigurableProduct\Plugin\Model\ResourceModel;
use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
+use Magento\Catalog\Model\Indexer\Product\Category\Action\Rows;
+use Magento\Catalog\Model\Indexer\Product\Price\Processor;
+use Magento\Catalog\Model\Product as ProductModel;
+use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
use Magento\ConfigurableProduct\Api\Data\OptionInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\DataObject;
use Magento\Framework\Indexer\ActionInterface;
+use Magento\Framework\Indexer\IndexerRegistry;
/**
* Plugin product resource model
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Product
{
@@ -46,21 +55,35 @@ class Product
*/
private $filterBuilder;
+ /**
+ * @var IndexerRegistry
+ */
+ private $indexerRegistry;
+
+ /**
+ * @var Rows
+ */
+ private $rowsAction;
+
/**
* Initialize Product dependencies.
*
* @param Configurable $configurable
* @param ActionInterface $productIndexer
- * @param ProductAttributeRepositoryInterface $productAttributeRepository
- * @param SearchCriteriaBuilder $searchCriteriaBuilder
- * @param FilterBuilder $filterBuilder
+ * @param ProductAttributeRepositoryInterface|null $productAttributeRepository
+ * @param SearchCriteriaBuilder|null $searchCriteriaBuilder
+ * @param FilterBuilder|null $filterBuilder
+ * @param IndexerRegistry|null $indexerRegistry
+ * @param Rows|null $rowsAction
*/
public function __construct(
Configurable $configurable,
ActionInterface $productIndexer,
ProductAttributeRepositoryInterface $productAttributeRepository = null,
- SearchCriteriaBuilder $searchCriteriaBuilder = null,
- FilterBuilder $filterBuilder = null
+ ?SearchCriteriaBuilder $searchCriteriaBuilder = null,
+ ?FilterBuilder $filterBuilder = null,
+ ?IndexerRegistry $indexerRegistry = null,
+ ?Rows $rowsAction = null
) {
$this->configurable = $configurable;
$this->productIndexer = $productIndexer;
@@ -70,35 +93,62 @@ public function __construct(
->get(SearchCriteriaBuilder::class);
$this->filterBuilder = $filterBuilder ?: ObjectManager::getInstance()
->get(FilterBuilder::class);
+ $this->indexerRegistry = $indexerRegistry ?: ObjectManager::getInstance()
+ ->get(IndexerRegistry::class);
+ $this->rowsAction = $rowsAction ?: ObjectManager::getInstance()
+ ->get(Rows::class);
}
/**
* We need reset attribute set id to attribute after related simple product was saved
*
- * @param \Magento\Catalog\Model\ResourceModel\Product $subject
- * @param \Magento\Framework\DataObject $object
+ * @param ProductResource $subject
+ * @param DataObject $object
* @return void
- * @throws \Magento\Framework\Exception\NoSuchEntityException
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function beforeSave(
- \Magento\Catalog\Model\ResourceModel\Product $subject,
- \Magento\Framework\DataObject $object
+ ProductResource $subject,
+ DataObject $object
) {
- /** @var \Magento\Catalog\Model\Product $object */
+ /** @var ProductModel $object */
if ($object->getTypeId() == Configurable::TYPE_CODE) {
$object->getTypeInstance()->getSetAttributes($object);
$this->resetConfigurableOptionsData($object);
}
}
+ /**
+ * Invalidate cache and perform reindexing for configurable associated product
+ *
+ * @param ProductResource $subject
+ * @param ProductResource $result
+ * @param DataObject $object
+ * @return ProductResource
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterSave(
+ ProductResource $subject,
+ ProductResource $result,
+ DataObject $object
+ ): ProductResource {
+ $productId = $object->getId();
+ $priceIndexer = $this->indexerRegistry->get(Processor::INDEXER_ID);
+ if ($priceIndexer->isScheduled()
+ && count($this->configurable->getParentIdsByChild($productId)) > 0) {
+ $this->rowsAction->execute([$productId]);
+ }
+
+ return $result;
+ }
+
/**
* Set null for configurable options attribute of configurable product
*
- * @param \Magento\Catalog\Model\Product $object
+ * @param ProductModel $object
* @return void
- * @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function resetConfigurableOptionsData($object)
{
@@ -128,16 +178,16 @@ private function resetConfigurableOptionsData($object)
/**
* Gather configurable parent ids of product being deleted and reindex after delete is complete.
*
- * @param \Magento\Catalog\Model\ResourceModel\Product $subject
+ * @param ProductResource $subject
* @param \Closure $proceed
- * @param \Magento\Catalog\Model\Product $product
- * @return \Magento\Catalog\Model\ResourceModel\Product
+ * @param ProductModel $product
+ * @return ProductResource
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function aroundDelete(
- \Magento\Catalog\Model\ResourceModel\Product $subject,
+ ProductResource $subject,
\Closure $proceed,
- \Magento\Catalog\Model\Product $product
+ ProductModel $product
) {
$configurableProductIds = $this->configurable->getParentIdsByChild($product->getId());
$result = $proceed($product);
</pre></div>
form reindexing for configurable associated product
+ *
+ * @param ProductResource $subject
+ * @param ProductResource $result
+ * @param DataObject $object
+ * @return ProductResource
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterSave(
+ ProductResource $subject,
+ ProductResource $result,
+ DataObject $object
+ ): ProductResource {
+ $productId = $object->getId();
+ $priceIndexer = $this->indexerRegistry->get(Processor::INDEXER_ID);
+ if ($priceIndexer->isScheduled()
+ && count($this->configurable->getParentIdsByChild($productId)) > 0) {
+ $this->rowsAction->execute([$productId]);
+ }
+
+ return $result;
+ }
+
/**
* Set null for configurable options attribute of configurable product
*
- * @param \Magento\Catalog\Model\Product $object
+ * @param ProductModel $object
* @return void
- * @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function resetConfigurableOptionsData($object)
{
@@ -128,16 +178,16 @@ private function resetConfigurableOptionsData($object)
/**
* Gather configurable parent ids of product being deleted and reindex after delete is complete.
*
- * @param \Magento\Catalog\Model\ResourceModel\Product $subject
+ * @param ProductResource $subject
* @param \Closure $proceed
- * @param \Magento\Catalog\Model\Product $product
- * @return \Magento\Catalog\Model\ResourceModel\Product
+ * @param ProductModel $product
+ * @return ProductResource
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function aroundDelete(
- \Magento\Catalog\Model\ResourceModel\Product $subject,
+ ProductResource $subject,
\Closure $proceed,
- \Magento\Catalog\Model\Product $product
+ ProductModel $product
) {
$configurableProductIds = $this->configurable->getParentIdsByChild($product->getId());
$result = $proceed($product);