Skip to content

Commit eec0348

Browse files
authored
Merge pull request #241 from magento-l3/PR_20_JUN_2022_odubovyk
L3 Bugfix Delivery
2 parents 4c666e4 + 55a68e4 commit eec0348

File tree

6 files changed

+416
-63
lines changed

6 files changed

+416
-63
lines changed

InventoryCache/Plugin/InventoryIndexer/Indexer/SourceItem/Strategy/Sync/CacheFlush.php

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77

88
namespace Magento\InventoryCache\Plugin\InventoryIndexer\Indexer\SourceItem\Strategy\Sync;
99

10+
use Magento\Framework\Indexer\IndexerRegistry;
1011
use Magento\InventoryCache\Model\FlushCacheByCategoryIds;
1112
use Magento\InventoryCache\Model\FlushCacheByProductIds;
13+
use Magento\InventoryIndexer\Model\GetProductsIdsToProcess;
1214
use Magento\InventoryIndexer\Indexer\SourceItem\Strategy\Sync;
15+
use Magento\InventoryIndexer\Indexer\SourceItem\GetSalableStatuses;
1316
use Magento\InventoryIndexer\Model\ResourceModel\GetCategoryIdsByProductIds;
14-
use Magento\InventoryIndexer\Model\ResourceModel\GetProductIdsBySourceItemIds;
17+
use Magento\InventoryIndexer\Indexer\InventoryIndexer;
1518

1619
/**
1720
* Clean cache for corresponding products after source item reindex.
@@ -24,52 +27,79 @@ class CacheFlush
2427
private $flushCacheByIds;
2528

2629
/**
27-
* @var GetProductIdsBySourceItemIds
30+
* @var GetCategoryIdsByProductIds
2831
*/
29-
private $getProductIdsBySourceItemIds;
32+
private $getCategoryIdsByProductIds;
3033

3134
/**
32-
* @var GetCategoryIdsByProductIds
35+
* @var GetSalableStatuses
3336
*/
34-
private $getCategoryIdsByProductIds;
37+
private $getSalableStatuses;
3538

3639
/**
3740
* @var FlushCacheByCategoryIds
3841
*/
3942
private $flushCategoryByCategoryIds;
4043

44+
/**
45+
* @var GetProductsIdsToProcess
46+
*/
47+
private $getProductsIdsToProcess;
48+
49+
/**
50+
* @var IndexerRegistry
51+
*/
52+
private $indexerRegistry;
53+
4154
/**
4255
* @param FlushCacheByProductIds $flushCacheByIds
43-
* @param GetProductIdsBySourceItemIds $getProductIdsBySourceItemIds
4456
* @param GetCategoryIdsByProductIds $getCategoryIdsByProductIds
4557
* @param FlushCacheByCategoryIds $flushCategoryByCategoryIds
58+
* @param GetSalableStatuses $getSalableStatuses
59+
* @param GetProductsIdsToProcess $getProductsIdsToProcess
60+
* @param IndexerRegistry $indexerRegistry
4661
*/
4762
public function __construct(
4863
FlushCacheByProductIds $flushCacheByIds,
49-
GetProductIdsBySourceItemIds $getProductIdsBySourceItemIds,
5064
GetCategoryIdsByProductIds $getCategoryIdsByProductIds,
51-
FlushCacheByCategoryIds $flushCategoryByCategoryIds
65+
FlushCacheByCategoryIds $flushCategoryByCategoryIds,
66+
GetSalableStatuses $getSalableStatuses,
67+
GetProductsIdsToProcess $getProductsIdsToProcess,
68+
IndexerRegistry $indexerRegistry
5269
) {
5370
$this->flushCacheByIds = $flushCacheByIds;
54-
$this->getProductIdsBySourceItemIds = $getProductIdsBySourceItemIds;
5571
$this->getCategoryIdsByProductIds = $getCategoryIdsByProductIds;
5672
$this->flushCategoryByCategoryIds = $flushCategoryByCategoryIds;
73+
$this->getSalableStatuses = $getSalableStatuses;
74+
$this->getProductsIdsToProcess = $getProductsIdsToProcess;
75+
$this->indexerRegistry = $indexerRegistry;
5776
}
5877

5978
/**
6079
* Clean cache for specific products after source items reindex.
6180
*
6281
* @param Sync $subject
63-
* @param void $result
82+
* @param callable $proceed
6483
* @param array $sourceItemIds
65-
* @throws \Exception in case catalog product entity type hasn't been initialize.
84+
* @return void
85+
* @throws \Exception in case catalog product entity type hasn't been initialized.
6686
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
6787
*/
68-
public function afterExecuteList(Sync $subject, $result, array $sourceItemIds)
88+
public function aroundExecuteList(Sync $subject, callable $proceed, array $sourceItemIds) : void
6989
{
70-
$productIds = $this->getProductIdsBySourceItemIds->execute($sourceItemIds);
71-
$categoryIds = $this->getCategoryIdsByProductIds->execute($productIds);
72-
$this->flushCategoryByCategoryIds->execute($categoryIds);
73-
$this->flushCacheByIds->execute($productIds);
90+
$beforeSalableList = $this->getSalableStatuses->execute($sourceItemIds);
91+
$proceed($sourceItemIds);
92+
$afterSalableList = $this->getSalableStatuses->execute($sourceItemIds);
93+
$forceDefaultProcessing = !$this->indexerRegistry->get(InventoryIndexer::INDEXER_ID)->isScheduled();
94+
$productsIdsToFlush = $this->getProductsIdsToProcess->execute(
95+
$beforeSalableList,
96+
$afterSalableList,
97+
$forceDefaultProcessing
98+
);
99+
if (!empty($productsIdsToFlush)) {
100+
$categoryIds = $this->getCategoryIdsByProductIds->execute($productsIdsToFlush);
101+
$this->flushCacheByIds->execute($productsIdsToFlush);
102+
$this->flushCategoryByCategoryIds->execute($categoryIds);
103+
}
74104
}
75105
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventoryCache\Test\Unit\Plugin\InventoryIndexer\Indexer\SourceItem\Strategy\Sync;
9+
10+
use Magento\Framework\Indexer\IndexerRegistry;
11+
use Magento\Framework\Indexer\IndexerInterface;
12+
use Magento\InventoryCache\Plugin\InventoryIndexer\Indexer\SourceItem\Strategy\Sync\CacheFlush;
13+
use Magento\InventoryCache\Model\FlushCacheByCategoryIds;
14+
use Magento\InventoryCache\Model\FlushCacheByProductIds;
15+
use Magento\InventoryIndexer\Model\ResourceModel\GetCategoryIdsByProductIds;
16+
use Magento\InventoryIndexer\Model\GetProductsIdsToProcess;
17+
use Magento\InventoryIndexer\Indexer\SourceItem\GetSalableStatuses;
18+
use Magento\InventoryIndexer\Indexer\SourceItem\Strategy\Sync;
19+
use PHPUnit\Framework\TestCase;
20+
use PHPUnit\Framework\MockObject\MockObject;
21+
22+
class CacheFlushTest extends TestCase
23+
{
24+
/**
25+
* @var CacheFlush
26+
*/
27+
private $cacheFlush;
28+
29+
/**
30+
* @var FlushCacheByProductIds|MockObject
31+
*/
32+
private $flushCacheByIds;
33+
34+
/**
35+
* @var GetCategoryIdsByProductIds|MockObject
36+
*/
37+
private $getCategoryIdsByProductIds;
38+
39+
/**
40+
* @var FlushCacheByCategoryIds|MockObject
41+
*/
42+
private $flushCategoryByCategoryIds;
43+
44+
/**
45+
* @var GetSalableStatuses|MockObject
46+
*/
47+
private $getSalableStatuses;
48+
49+
/**
50+
* @var GetProductsIdsToProcess|MockObject
51+
*/
52+
private $getProductsIdsToProcess;
53+
54+
/**
55+
* @var Sync|MockObject
56+
*/
57+
private $sync;
58+
59+
/**
60+
* @var \Callable|MockObject
61+
*/
62+
private $proceedMock;
63+
64+
/**
65+
* @var IndexerRegistry|MockObject
66+
*/
67+
private $indexerRegistry;
68+
69+
/**
70+
* @var IndexerInterface|MockObject
71+
*/
72+
private $indexer;
73+
74+
/**
75+
* @var bool
76+
*/
77+
private $isProceedMockCalled = false;
78+
79+
protected function setUp(): void
80+
{
81+
$this->proceedMock = function () {
82+
$this->isProceedMockCalled = true;
83+
};
84+
$this->flushCacheByIds = $this->getMockBuilder(FlushCacheByProductIds::class)
85+
->disableOriginalConstructor()
86+
->getMock();
87+
$this->getCategoryIdsByProductIds = $this->getMockBuilder(GetCategoryIdsByProductIds::class)
88+
->disableOriginalConstructor()
89+
->getMock();
90+
$this->flushCategoryByCategoryIds = $this->getMockBuilder(FlushCacheByCategoryIds::class)
91+
->disableOriginalConstructor()
92+
->getMock();
93+
$this->getSalableStatuses = $this->getMockBuilder(GetSalableStatuses::class)
94+
->disableOriginalConstructor()
95+
->getMock();
96+
$this->getProductsIdsToProcess = $this->getMockBuilder(GetProductsIdsToProcess::class)
97+
->disableOriginalConstructor()
98+
->getMock();
99+
$this->sync = $this->getMockBuilder(Sync::class)
100+
->disableOriginalConstructor()
101+
->getMock();
102+
$this->indexer = $this->getMockBuilder(IndexerInterface::class)
103+
->getMockForAbstractClass();
104+
$this->indexerRegistry = $this->getMockBuilder(IndexerRegistry::class)
105+
->disableOriginalConstructor()
106+
->getMock();
107+
$this->cacheFlush = new CacheFlush(
108+
$this->flushCacheByIds,
109+
$this->getCategoryIdsByProductIds,
110+
$this->flushCategoryByCategoryIds,
111+
$this->getSalableStatuses,
112+
$this->getProductsIdsToProcess,
113+
$this->indexerRegistry
114+
);
115+
}
116+
117+
/**
118+
* @dataProvider executeListDataProvider
119+
* @param array $sourceItemIds
120+
* @param array $beforeSalableList
121+
* @param array $afterSalableList
122+
* @param array $changedProductIds,
123+
* @param int $numberOfCacheCleans,
124+
* @return void
125+
*/
126+
public function testAroundExecuteList(
127+
array $sourceItemIds,
128+
array $beforeSalableList,
129+
array $afterSalableList,
130+
array $changedProductIds,
131+
int $numberOfCacheCleans
132+
): void {
133+
$this->indexerRegistry->expects($this->once())
134+
->method('get')
135+
->willReturn($this->indexer);
136+
$this->indexer->expects($this->any())
137+
->method('isScheduled')
138+
->willReturn(true);
139+
$this->getSalableStatuses->expects($this->exactly(2))
140+
->method('execute')
141+
->with($sourceItemIds)
142+
->willReturnOnConsecutiveCalls(
143+
$beforeSalableList,
144+
$afterSalableList
145+
);
146+
$this->getProductsIdsToProcess->expects($this->once())
147+
->method('execute')
148+
->with($beforeSalableList, $afterSalableList)
149+
->willReturn($changedProductIds);
150+
151+
$this->getCategoryIdsByProductIds->expects($this->exactly($numberOfCacheCleans))
152+
->method('execute')
153+
->with($changedProductIds)
154+
->willReturn([]);
155+
$this->flushCacheByIds->expects($this->exactly($numberOfCacheCleans))
156+
->method('execute')
157+
->with($changedProductIds);
158+
$this->flushCategoryByCategoryIds->expects($this->exactly($numberOfCacheCleans))
159+
->method('execute');
160+
161+
$this->cacheFlush->aroundExecuteList($this->sync, $this->proceedMock, $sourceItemIds);
162+
$this->assertTrue($this->isProceedMockCalled);
163+
}
164+
165+
/**
166+
* Data provider for testAroundExecuteList
167+
* @return array
168+
*/
169+
public function executeListDataProvider(): array
170+
{
171+
return [
172+
[[1], ['sku1' => [1 => true]], ['sku1' => [1 => true]], [], 0],
173+
[[1], ['sku1' => [1 => true]], ['sku1' => [1 => false]], [1], 1]
174+
];
175+
}
176+
}

InventoryCatalog/Plugin/InventoryIndexer/Indexer/SourceItem/Strategy/Sync/PriceIndexUpdater.php

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99

1010
use Magento\Catalog\Model\Indexer\Product\Price\Processor;
1111
use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface;
12+
use Magento\InventoryIndexer\Model\GetProductsIdsToProcess;
1213
use Magento\InventoryIndexer\Indexer\SourceItem\Strategy\Sync;
13-
use Magento\InventoryIndexer\Model\ResourceModel\GetProductIdsBySourceItemIds;
14+
use Magento\InventoryIndexer\Indexer\SourceItem\GetSalableStatuses;
1415
use Magento\InventoryIndexer\Model\ResourceModel\GetSourceCodesBySourceItemIds;
1516

1617
/**
@@ -23,11 +24,6 @@ class PriceIndexUpdater
2324
*/
2425
private $priceIndexProcessor;
2526

26-
/**
27-
* @var GetProductIdsBySourceItemIds
28-
*/
29-
private $productIdsBySourceItemIds;
30-
3127
/**
3228
* @var GetSourceCodesBySourceItemIds
3329
*/
@@ -38,51 +34,62 @@ class PriceIndexUpdater
3834
*/
3935
private $defaultSourceProvider;
4036

37+
/**
38+
* @var GetSalableStatuses
39+
*/
40+
private $getSalableStatuses;
41+
42+
/**
43+
* @var GetProductsIdsToProcess
44+
*/
45+
private $getProductsIdsToProcess;
46+
4147
/**
4248
* @param Processor $priceIndexProcessor
43-
* @param GetProductIdsBySourceItemIds $productIdsBySourceItemIds
4449
* @param GetSourceCodesBySourceItemIds $getSourceCodesBySourceItemIds
4550
* @param DefaultSourceProviderInterface $defaultSourceProvider
51+
* @param GetSalableStatuses $getSalableStatuses
52+
* @param GetProductsIdsToProcess $getProductsIdsToProcess
4653
*/
4754
public function __construct(
4855
Processor $priceIndexProcessor,
49-
GetProductIdsBySourceItemIds $productIdsBySourceItemIds,
5056
GetSourceCodesBySourceItemIds $getSourceCodesBySourceItemIds,
51-
DefaultSourceProviderInterface $defaultSourceProvider
57+
DefaultSourceProviderInterface $defaultSourceProvider,
58+
GetSalableStatuses $getSalableStatuses,
59+
GetProductsIdsToProcess $getProductsIdsToProcess
5260
) {
5361
$this->priceIndexProcessor = $priceIndexProcessor;
54-
$this->productIdsBySourceItemIds = $productIdsBySourceItemIds;
5562
$this->getSourceCodesBySourceItemIds = $getSourceCodesBySourceItemIds;
5663
$this->defaultSourceProvider = $defaultSourceProvider;
64+
$this->getSalableStatuses = $getSalableStatuses;
65+
$this->getProductsIdsToProcess = $getProductsIdsToProcess;
5766
}
5867

5968
/**
6069
* Reindex product prices.
6170
*
6271
* @param Sync $subject
63-
* @param void $result
72+
* @param callable $proceed
6473
* @param array $sourceItemIds
74+
* @return void
6575
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
6676
*/
67-
public function afterExecuteList(
68-
Sync $subject,
69-
$result,
70-
array $sourceItemIds
71-
): void {
77+
public function aroundExecuteList(Sync $subject, callable $proceed, array $sourceItemIds) : void
78+
{
7279
$customSourceItemIds = [];
7380
$defaultSourceCode = $this->defaultSourceProvider->getCode();
7481
foreach ($this->getSourceCodesBySourceItemIds->execute($sourceItemIds) as $sourceItemId => $sourceCode) {
7582
if ($sourceCode !== $defaultSourceCode) {
7683
$customSourceItemIds[] = $sourceItemId;
7784
}
7885
}
79-
// In the case the source item is default source,
80-
// the price indexer will be executed according to indexer.xml configuration
81-
if ($customSourceItemIds) {
82-
$productIds = $this->productIdsBySourceItemIds->execute($customSourceItemIds);
83-
if (!empty($productIds)) {
84-
$this->priceIndexProcessor->reindexList($productIds, true);
85-
}
86+
$beforeSalableList = $this->getSalableStatuses->execute($customSourceItemIds);
87+
$proceed($sourceItemIds);
88+
$afterSalableList = $this->getSalableStatuses->execute($customSourceItemIds);
89+
90+
$productsIdsToReindex = $this->getProductsIdsToProcess->execute($beforeSalableList, $afterSalableList);
91+
if (!empty($productsIdsToReindex)) {
92+
$this->priceIndexProcessor->reindexList($productsIdsToReindex, true);
8693
}
8794
}
8895
}

0 commit comments

Comments
 (0)