Skip to content

Commit c67893b

Browse files
author
Alexander Akimov
authored
Merge pull request #2696 from magento-tsg/2.3-develop-pr23
[TSG] Upporting for 2.3 (pr23) (2.3.0)
2 parents 285a39c + 012d0a3 commit c67893b

File tree

62 files changed

+1891
-371
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1891
-371
lines changed

app/code/Magento/Bundle/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
},
2626
"suggest": {
2727
"magento/module-webapi": "*",
28-
"magento/module-bundle-sample-data": "*"
28+
"magento/module-bundle-sample-data": "*",
29+
"magento/module-sales-rule": "*"
2930
},
3031
"type": "magento2-module",
3132
"license": [

app/code/Magento/Bundle/etc/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,11 @@
207207
</argument>
208208
</arguments>
209209
</type>
210+
<type name="Magento\SalesRule\Model\Quote\ChildrenValidationLocator">
211+
<arguments>
212+
<argument name="productTypeChildrenValidationMap" xsi:type="array">
213+
<item name="bundle" xsi:type="boolean">false</item>
214+
</argument>
215+
</arguments>
216+
</type>
210217
</config>

app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
*/
1515
interface StockStatusInterface extends ExtensibleDataInterface
1616
{
17+
/**#@+
18+
* Stock Status values.
19+
*/
20+
const STATUS_OUT_OF_STOCK = 0;
21+
22+
const STATUS_IN_STOCK = 1;
23+
/**#@-*/
24+
1725
/**#@+
1826
* Stock status object data keys
1927
*/

app/code/Magento/CatalogInventory/Model/Stock/Status.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,6 @@
1717
*/
1818
class Status extends AbstractExtensibleModel implements StockStatusInterface
1919
{
20-
/**#@+
21-
* Stock Status values
22-
*/
23-
const STATUS_OUT_OF_STOCK = 0;
24-
25-
const STATUS_IN_STOCK = 1;
26-
/**#@-*/
27-
2820
/**#@+
2921
* Field name
3022
*/

app/code/Magento/Elasticsearch/Model/Config.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
namespace Magento\Elasticsearch\Model;
77

88
use Magento\Framework\App\Config\ScopeConfigInterface;
9+
use Magento\Framework\Search\EngineResolverInterface;
10+
use Magento\Search\Model\EngineResolver;
911
use Magento\Store\Model\ScopeInterface;
1012
use Magento\AdvancedSearch\Model\Client\ClientOptionsInterface;
1113
use Magento\AdvancedSearch\Model\Client\ClientResolver;
@@ -54,21 +56,28 @@ class Config implements ClientOptionsInterface
5456
*/
5557
private $clientResolver;
5658

59+
/**
60+
* @var EngineResolverInterface
61+
*/
62+
private $engineResolver;
63+
5764
/**
5865
* Constructor
5966
*
6067
* @param ScopeConfigInterface $scopeConfig
61-
* @param ClientResolver $clientResolver
62-
* @param string $prefix
68+
* @param ClientResolver|null $clientResolver
69+
* @param EngineResolverInterface|null $engineResolver
70+
* @param string|null $prefix
6371
*/
6472
public function __construct(
6573
ScopeConfigInterface $scopeConfig,
6674
ClientResolver $clientResolver = null,
75+
EngineResolverInterface $engineResolver = null,
6776
$prefix = null
6877
) {
6978
$this->scopeConfig = $scopeConfig;
70-
$this->clientResolver = $clientResolver ?:
71-
ObjectManager::getInstance()->get(ClientResolver::class);
79+
$this->clientResolver = $clientResolver ?: ObjectManager::getInstance()->get(ClientResolver::class);
80+
$this->engineResolver = $engineResolver ?: ObjectManager::getInstance()->get(EngineResolverInterface::class);
7281
$this->prefix = $prefix ?: $this->clientResolver->getCurrentEngine();
7382
}
7483

@@ -126,7 +135,7 @@ public function getSearchConfigData($field, $storeId = null)
126135
*/
127136
public function isElasticsearchEnabled()
128137
{
129-
return $this->getSearchConfigData('engine') == self::ENGINE_NAME;
138+
return $this->engineResolver->getCurrentSearchEngine() === self::ENGINE_NAME;
130139
}
131140

132141
/**
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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\Elasticsearch\Model\Indexer\Plugin;
9+
10+
use Magento\Elasticsearch\Model\Config;
11+
use Magento\Framework\Indexer\Config\DependencyInfoProvider as Provider;
12+
use Magento\CatalogSearch\Model\Indexer\Fulltext as CatalogSearchFulltextIndexer;
13+
use Magento\CatalogInventory\Model\Indexer\Stock\Processor as CatalogInventoryStockIndexer;
14+
15+
/**
16+
* Plugin for maintenance catalog search index dependency on stock index.
17+
* If elasticsearch is used as search engine catalog search index becomes dependent on stock index. Elasticsearch
18+
* module declares this dependence. But in case when elasticsearch module is enabled and elasticsearch engine isn`t
19+
* used as search engine other search engines don`t need this dependency.
20+
* This plugin remove catalog search index dependency on stock index when elasticsearch isn`t used as search engine
21+
* except full reindexing. During full reindexing this dependency doesn`t make overhead.
22+
*/
23+
class DependencyUpdaterPlugin
24+
{
25+
/**
26+
* @var Config
27+
*/
28+
private $config;
29+
30+
/**
31+
* @param Config $config
32+
*/
33+
public function __construct(Config $config)
34+
{
35+
$this->config = $config;
36+
}
37+
38+
/**
39+
* Remove index dependency, if it needed, on run reindexing by specifics indexes.
40+
*
41+
* @param Provider $provider
42+
* @param array $dependencies
43+
* @param string $indexerId
44+
* @return array
45+
* @see \Magento\Indexer\Console\Command\IndexerReindexCommand::getIndexers()
46+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
47+
*/
48+
public function afterGetIndexerIdsToRunBefore(Provider $provider, array $dependencies, string $indexerId): array
49+
{
50+
if ($this->isFilteringNeeded($indexerId, CatalogSearchFulltextIndexer::INDEXER_ID)) {
51+
$dependencies = array_diff($dependencies, [CatalogInventoryStockIndexer::INDEXER_ID]);
52+
}
53+
54+
return $dependencies;
55+
}
56+
57+
/**
58+
* Remove index dependency, if it needed, on reindex triggers.
59+
*
60+
* @param Provider $provider
61+
* @param array $dependencies
62+
* @param string $indexerId
63+
* @return array
64+
* @see \Magento\Indexer\Model\Indexer\DependencyDecorator
65+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
66+
*/
67+
public function afterGetIndexerIdsToRunAfter(Provider $provider, array $dependencies, string $indexerId): array
68+
{
69+
if ($this->isFilteringNeeded($indexerId, CatalogInventoryStockIndexer::INDEXER_ID)) {
70+
$dependencies = array_diff($dependencies, [CatalogSearchFulltextIndexer::INDEXER_ID]);
71+
}
72+
73+
return $dependencies;
74+
}
75+
76+
/**
77+
* @param string $currentIndexerId
78+
* @param string $targetIndexerId
79+
* @return bool
80+
*/
81+
private function isFilteringNeeded(string $currentIndexerId, string $targetIndexerId): bool
82+
{
83+
return (!$this->config->isElasticsearchEnabled() && $targetIndexerId === $currentIndexerId);
84+
}
85+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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\Elasticsearch\Model\Indexer\Plugin;
9+
10+
use Magento\Elasticsearch\Model\Config;
11+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
12+
use Magento\CatalogInventory\Api\StockStatusRepositoryInterface;
13+
use Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory;
14+
use Magento\CatalogInventory\Api\Data\StockStatusInterface;
15+
use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider;
16+
17+
/**
18+
* Plugin for filtering child products that are out of stock for preventing their saving to catalog search index.
19+
*/
20+
class StockedProductsFilterPlugin
21+
{
22+
/**
23+
* @var Config
24+
*/
25+
private $config;
26+
27+
/**
28+
* @var StockConfigurationInterface
29+
*/
30+
private $stockConfiguration;
31+
32+
/**
33+
* @var StockStatusRepositoryInterface
34+
*/
35+
private $stockStatusRepository;
36+
37+
/**
38+
* @var StockStatusCriteriaInterfaceFactory
39+
*/
40+
private $stockStatusCriteriaFactory;
41+
42+
/**
43+
* @param Config $config
44+
* @param StockConfigurationInterface $stockConfiguration
45+
* @param StockStatusRepositoryInterface $stockStatusRepository
46+
* @param StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory
47+
*/
48+
public function __construct(
49+
Config $config,
50+
StockConfigurationInterface $stockConfiguration,
51+
StockStatusRepositoryInterface $stockStatusRepository,
52+
StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory
53+
) {
54+
$this->config = $config;
55+
$this->stockConfiguration = $stockConfiguration;
56+
$this->stockStatusRepository = $stockStatusRepository;
57+
$this->stockStatusCriteriaFactory = $stockStatusCriteriaFactory;
58+
}
59+
60+
/**
61+
* Filter out of stock options for configurable product.
62+
*
63+
* @param DataProvider $dataProvider
64+
* @param array $indexData
65+
* @param array $productData
66+
* @param int $storeId
67+
* @return array
68+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
69+
*/
70+
public function beforePrepareProductIndex(
71+
DataProvider $dataProvider,
72+
array $indexData,
73+
array $productData,
74+
int $storeId
75+
): array {
76+
if ($this->config->isElasticsearchEnabled() && !$this->stockConfiguration->isShowOutOfStock($storeId)) {
77+
$productIds = array_keys($indexData);
78+
$stockStatusCriteria = $this->stockStatusCriteriaFactory->create();
79+
$stockStatusCriteria->setProductsFilter($productIds);
80+
$stockStatusCollection = $this->stockStatusRepository->getList($stockStatusCriteria);
81+
$stockStatuses = $stockStatusCollection->getItems();
82+
$stockStatuses = array_filter($stockStatuses, function (StockStatusInterface $stockStatus) {
83+
return StockStatusInterface::STATUS_IN_STOCK == $stockStatus->getStockStatus();
84+
});
85+
$indexData = array_intersect_key($indexData, $stockStatuses);
86+
}
87+
88+
return [
89+
$indexData,
90+
$productData,
91+
$storeId,
92+
];
93+
}
94+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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\Elasticsearch\Test\Unit\Model\Indexer\Plugin;
9+
10+
use Magento\Elasticsearch\Model\Config;
11+
use Magento\Elasticsearch\Model\Indexer\Plugin\DependencyUpdaterPlugin;
12+
use Magento\Framework\Indexer\Config\DependencyInfoProvider;
13+
use Magento\CatalogSearch\Model\Indexer\Fulltext as CatalogSearchFulltextIndexer;
14+
use Magento\CatalogInventory\Model\Indexer\Stock\Processor as CatalogInventoryStockIndexer;
15+
16+
/**
17+
* Test for Magento\Elasticsearch\Model\Indexer\Plugin\DependencyUpdaterPlugin class.
18+
*/
19+
class DependencyUpdaterPluginTest extends \PHPUnit\Framework\TestCase
20+
{
21+
/**
22+
* @var Config|\PHPUnit_Framework_MockObject_MockObject
23+
*/
24+
private $configMock;
25+
26+
/**
27+
* @var DependencyUpdaterPlugin
28+
*/
29+
private $plugin;
30+
31+
/**
32+
* @var DependencyInfoProvider|\PHPUnit_Framework_MockObject_MockObject
33+
*/
34+
private $providerMock;
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
protected function setUp()
40+
{
41+
$this->configMock = $this->getMockBuilder(Config::class)
42+
->disableOriginalConstructor()
43+
->getMock();
44+
$this->configMock->expects($this->exactly(2))
45+
->method('isElasticsearchEnabled')
46+
->willReturnOnConsecutiveCalls(true, false);
47+
$this->providerMock = $this->getMockBuilder(DependencyInfoProvider::class)
48+
->disableOriginalConstructor()
49+
->getMock();
50+
51+
$this->plugin = new DependencyUpdaterPlugin($this->configMock);
52+
}
53+
54+
/**
55+
* @return void
56+
*/
57+
public function testAfterGetIndexerIdsToRunBefore(): void
58+
{
59+
$dependencies = [
60+
CatalogInventoryStockIndexer::INDEXER_ID,
61+
];
62+
$indexerId = CatalogSearchFulltextIndexer::INDEXER_ID;
63+
64+
$indexerIds = $this->plugin->afterGetIndexerIdsToRunBefore($this->providerMock, $dependencies, $indexerId);
65+
$this->assertContains(CatalogInventoryStockIndexer::INDEXER_ID, $indexerIds);
66+
67+
$indexerIds = $this->plugin->afterGetIndexerIdsToRunBefore($this->providerMock, $dependencies, $indexerId);
68+
$this->assertNotContains(CatalogInventoryStockIndexer::INDEXER_ID, $indexerIds);
69+
}
70+
71+
/**
72+
* @return void
73+
*/
74+
public function testAfterGetIndexerIdsToRunAfter(): void
75+
{
76+
$dependencies = [
77+
CatalogSearchFulltextIndexer::INDEXER_ID,
78+
];
79+
$indexerId = CatalogInventoryStockIndexer::INDEXER_ID;
80+
81+
$indexerIds = $this->plugin->afterGetIndexerIdsToRunAfter($this->providerMock, $dependencies, $indexerId);
82+
$this->assertContains(CatalogSearchFulltextIndexer::INDEXER_ID, $indexerIds);
83+
84+
$indexerIds = $this->plugin->afterGetIndexerIdsToRunAfter($this->providerMock, $dependencies, $indexerId);
85+
$this->assertNotContains(CatalogSearchFulltextIndexer::INDEXER_ID, $indexerIds);
86+
}
87+
}

0 commit comments

Comments
 (0)