Skip to content

Commit 66fbb33

Browse files
committed
Merge remote-tracking branch 'magento-l3/ACP2E-1524' into FEB132023_PR_arul
2 parents eefe2ef + 222e5de commit 66fbb33

File tree

2 files changed

+124
-18
lines changed

2 files changed

+124
-18
lines changed

app/code/Magento/ConfigurableProduct/Plugin/Model/ResourceModel/Product.php

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,29 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
78

89
namespace Magento\ConfigurableProduct\Plugin\Model\ResourceModel;
910

1011
use Magento\Catalog\Api\Data\ProductAttributeInterface;
1112
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
13+
use Magento\Catalog\Model\Product as ProductModel;
14+
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
1215
use Magento\ConfigurableProduct\Api\Data\OptionInterface;
1316
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
1417
use Magento\Framework\Api\FilterBuilder;
1518
use Magento\Framework\Api\SearchCriteriaBuilder;
19+
use Magento\Framework\App\CacheInterface;
1620
use Magento\Framework\App\ObjectManager;
21+
use Magento\Framework\DataObject;
22+
use Magento\Framework\Event\Manager as EventManager;
1723
use Magento\Framework\Indexer\ActionInterface;
24+
use Magento\Framework\Indexer\CacheContext;
1825

1926
/**
2027
* Plugin product resource model
28+
*
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2130
*/
2231
class Product
2332
{
@@ -46,21 +55,42 @@ class Product
4655
*/
4756
private $filterBuilder;
4857

58+
/**
59+
* @var CacheContext
60+
*/
61+
private $cacheContext;
62+
63+
/**
64+
* @var EventManager
65+
*/
66+
private $eventManager;
67+
68+
/**
69+
* @var CacheInterface
70+
*/
71+
private $appCache;
72+
4973
/**
5074
* Initialize Product dependencies.
5175
*
5276
* @param Configurable $configurable
5377
* @param ActionInterface $productIndexer
54-
* @param ProductAttributeRepositoryInterface $productAttributeRepository
55-
* @param SearchCriteriaBuilder $searchCriteriaBuilder
56-
* @param FilterBuilder $filterBuilder
78+
* @param ProductAttributeRepositoryInterface|null $productAttributeRepository
79+
* @param SearchCriteriaBuilder|null $searchCriteriaBuilder
80+
* @param FilterBuilder|null $filterBuilder
81+
* @param CacheContext|null $cacheContext
82+
* @param EventManager|null $eventManager
83+
* @param CacheInterface|null $appCache
5784
*/
5885
public function __construct(
5986
Configurable $configurable,
6087
ActionInterface $productIndexer,
6188
ProductAttributeRepositoryInterface $productAttributeRepository = null,
62-
SearchCriteriaBuilder $searchCriteriaBuilder = null,
63-
FilterBuilder $filterBuilder = null
89+
?SearchCriteriaBuilder $searchCriteriaBuilder = null,
90+
?FilterBuilder $filterBuilder = null,
91+
?CacheContext $cacheContext = null,
92+
?EventManager $eventManager = null,
93+
?CacheInterface $appCache = null
6494
) {
6595
$this->configurable = $configurable;
6696
$this->productIndexer = $productIndexer;
@@ -70,35 +100,65 @@ public function __construct(
70100
->get(SearchCriteriaBuilder::class);
71101
$this->filterBuilder = $filterBuilder ?: ObjectManager::getInstance()
72102
->get(FilterBuilder::class);
103+
$this->cacheContext = $cacheContext ?? ObjectManager::getInstance()->get(CacheContext::class);
104+
$this->eventManager = $eventManager ?? ObjectManager::getInstance()->get(EventManager::class);
105+
$this->appCache = $appCache ?? ObjectManager::getInstance()->get(CacheInterface::class);
73106
}
74107

75108
/**
76109
* We need reset attribute set id to attribute after related simple product was saved
77110
*
78-
* @param \Magento\Catalog\Model\ResourceModel\Product $subject
79-
* @param \Magento\Framework\DataObject $object
111+
* @param ProductResource $subject
112+
* @param DataObject $object
80113
* @return void
81-
* @throws \Magento\Framework\Exception\NoSuchEntityException
82114
*
83115
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
84116
*/
85117
public function beforeSave(
86-
\Magento\Catalog\Model\ResourceModel\Product $subject,
87-
\Magento\Framework\DataObject $object
118+
ProductResource $subject,
119+
DataObject $object
88120
) {
89-
/** @var \Magento\Catalog\Model\Product $object */
121+
/** @var ProductModel $object */
90122
if ($object->getTypeId() == Configurable::TYPE_CODE) {
91123
$object->getTypeInstance()->getSetAttributes($object);
92124
$this->resetConfigurableOptionsData($object);
93125
}
94126
}
95127

128+
/**
129+
* Invalidate cache and perform reindexing for configurable associated product
130+
*
131+
* @param ProductResource $subject
132+
* @param ProductResource $result
133+
* @param DataObject $object
134+
* @return ProductResource
135+
*
136+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
137+
*/
138+
public function afterSave(
139+
ProductResource $subject,
140+
ProductResource $result,
141+
DataObject $object
142+
): ProductResource {
143+
$configurableProductIds = $this->configurable->getParentIdsByChild($object->getId());
144+
if (count($configurableProductIds) > 0) {
145+
$this->cacheContext->registerEntities(ProductModel::CACHE_TAG, $configurableProductIds);
146+
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
147+
$identities = $this->cacheContext->getIdentities();
148+
if (!empty($identities)) {
149+
$this->appCache->clean($identities);
150+
$this->cacheContext->flush();
151+
}
152+
}
153+
154+
return $result;
155+
}
156+
96157
/**
97158
* Set null for configurable options attribute of configurable product
98159
*
99-
* @param \Magento\Catalog\Model\Product $object
160+
* @param ProductModel $object
100161
* @return void
101-
* @throws \Magento\Framework\Exception\NoSuchEntityException
102162
*/
103163
private function resetConfigurableOptionsData($object)
104164
{
@@ -128,16 +188,16 @@ private function resetConfigurableOptionsData($object)
128188
/**
129189
* Gather configurable parent ids of product being deleted and reindex after delete is complete.
130190
*
131-
* @param \Magento\Catalog\Model\ResourceModel\Product $subject
191+
* @param ProductResource $subject
132192
* @param \Closure $proceed
133-
* @param \Magento\Catalog\Model\Product $product
134-
* @return \Magento\Catalog\Model\ResourceModel\Product
193+
* @param ProductModel $product
194+
* @return ProductResource
135195
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
136196
*/
137197
public function aroundDelete(
138-
\Magento\Catalog\Model\ResourceModel\Product $subject,
198+
ProductResource $subject,
139199
\Closure $proceed,
140-
\Magento\Catalog\Model\Product $product
200+
ProductModel $product
141201
) {
142202
$configurableProductIds = $this->configurable->getParentIdsByChild($product->getId());
143203
$result = $proceed($product);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="StorefrontCheckConfigurableProductPriceWhenChildProductPriceUpdatedTest" extends="AdminCheckConfigurableProductPriceWhenChildProductPriceUpdatedTest">
11+
<annotations>
12+
<stories value="Configurable Product"/>
13+
<title value="Page Cache is not cleared for the parent product on the child product save"/>
14+
<description value="Verify the updated price of a configurable child product on the storefront when the indexer mode is set to `Update by Schedule` and the price of the child product is updated by admin."/>
15+
<severity value="AVERAGE"/>
16+
<testCaseId value="AC-7815"/>
17+
<useCaseId value="ACP2E-1524"/>
18+
<group value="product"/>
19+
</annotations>
20+
21+
<remove keyForRemoval="updateSimpleProductOne"/>
22+
<actionGroup ref="AdminFillProductPriceFieldAndPressEnterOnProductEditPageActionGroup" stepKey="fillProductPrice" after="waitForProductPageToLoad">
23+
<argument name="price" value="{{SimpleProductUpdatePrice90.price}}"/>
24+
</actionGroup>
25+
<actionGroup ref="AdminProductFormSaveButtonClickActionGroup" stepKey="clickSaveButton" after="fillProductPrice"/>
26+
27+
<remove keyForRemoval="index"/>
28+
<remove keyForRemoval="flushCache"/>
29+
<remove keyForRemoval="waitForUpdateStarts"/>
30+
31+
<!--Select product Attribute option1 and verify changes in the price -->
32+
<remove keyForRemoval="seeChildProduct1PriceInStoreFrontAfterUpdate"/>
33+
<actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeChildProduct1PriceInStoreFrontAfterUpdate" after="selectOption1AfterUpdate">
34+
<argument name="productPrice" value="{{SimpleProductUpdatePrice90.price}}"/>
35+
</actionGroup>
36+
37+
<!--Select product Attribute option2 and verify no changes in the price -->
38+
<actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectOption2AfterUpdate" after="seeChildProduct1PriceInStoreFrontAfterUpdate">
39+
<argument name="attributeLabel" value="$$createConfigProductAttribute.default_value$$"/>
40+
<argument name="optionLabel" value="$$getConfigAttributeOption2.label$$"/>
41+
</actionGroup>
42+
<actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeChildProduct2PriceInStoreFrontAfterUpdate" after="selectOption2AfterUpdate">
43+
<argument name="productPrice" value="$$createConfigChildProduct2.price$$"/>
44+
</actionGroup>
45+
</test>
46+
</tests>

0 commit comments

Comments
 (0)