Skip to content

Commit da2b7e2

Browse files
committed
Merge remote-tracking branch 'magento-l3/ACP2E-165' into L3_PR_21-12-10
2 parents 1b2617c + b4eeb82 commit da2b7e2

File tree

7 files changed

+227
-63
lines changed

7 files changed

+227
-63
lines changed

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/BaseStockStatusSelectProcessor.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ public function process(Select $select)
4949
{
5050
// Does not make sense to extend query if out of stock products won't appear in tables for indexing
5151
if ($this->stockConfig->isShowOutOfStock()) {
52-
$select->join(
53-
['si' => $this->resource->getTableName('cataloginventory_stock_item')],
54-
'si.product_id = l.product_id',
52+
$stockIndexTableName = $this->resource->getTableName('cataloginventory_stock_status');
53+
$select->joinInner(
54+
['child_stock_default' => $stockIndexTableName],
55+
'child_stock_default.product_id = l.product_id',
5556
[]
56-
);
57-
$select->join(
58-
['si_parent' => $this->resource->getTableName('cataloginventory_stock_item')],
59-
'si_parent.product_id = l.parent_id',
57+
)->joinInner(
58+
['parent_stock_default' => $stockIndexTableName],
59+
'parent_stock_default.product_id = le.entity_id',
6060
[]
61+
)->where(
62+
'child_stock_default.stock_status = 1 OR parent_stock_default.stock_status = 0'
6163
);
62-
$select->where('si.is_in_stock = ?', Stock::STOCK_IN_STOCK);
63-
$select->orWhere('si_parent.is_in_stock = ?', Stock::STOCK_OUT_OF_STOCK);
6464
}
6565

6666
return $select;

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
1111
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BasePriceModifier;
12-
use Magento\Framework\DB\Select;
1312
use Magento\Framework\Indexer\DimensionalIndexerInterface;
1413
use Magento\Framework\EntityManager\MetadataPool;
1514
use Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer;
@@ -18,7 +17,6 @@
1817
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
1918
use Magento\Framework\App\Config\ScopeConfigInterface;
2019
use Magento\Framework\App\ObjectManager;
21-
use Magento\CatalogInventory\Model\Stock;
2220

2321
/**
2422
* Configurable Products Price Indexer Resource model
@@ -82,6 +80,11 @@ class Configurable implements DimensionalIndexerInterface
8280
*/
8381
private $baseSelectProcessor;
8482

83+
/**
84+
* @var OptionsIndexerInterface
85+
*/
86+
private $optionsIndexer;
87+
8588
/**
8689
* @param BaseFinalPrice $baseFinalPrice
8790
* @param IndexTableStructureFactory $indexTableStructureFactory
@@ -91,9 +94,9 @@ class Configurable implements DimensionalIndexerInterface
9194
* @param BasePriceModifier $basePriceModifier
9295
* @param bool $fullReindexAction
9396
* @param string $connectionName
94-
* @param ScopeConfigInterface $scopeConfig
97+
* @param ScopeConfigInterface|null $scopeConfig
9598
* @param BaseSelectProcessorInterface|null $baseSelectProcessor
96-
*
99+
* @param OptionsIndexerInterface|null $optionsIndexer
97100
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
98101
*/
99102
public function __construct(
@@ -106,7 +109,8 @@ public function __construct(
106109
$fullReindexAction = false,
107110
$connectionName = 'indexer',
108111
ScopeConfigInterface $scopeConfig = null,
109-
?BaseSelectProcessorInterface $baseSelectProcessor = null
112+
?BaseSelectProcessorInterface $baseSelectProcessor = null,
113+
?OptionsIndexerInterface $optionsIndexer = null
110114
) {
111115
$this->baseFinalPrice = $baseFinalPrice;
112116
$this->indexTableStructureFactory = $indexTableStructureFactory;
@@ -119,6 +123,8 @@ public function __construct(
119123
$this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
120124
$this->baseSelectProcessor = $baseSelectProcessor ?:
121125
ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
126+
$this->optionsIndexer = $optionsIndexer
127+
?: ObjectManager::getInstance()->get(OptionsIndexerInterface::class);
122128
}
123129

124130
/**
@@ -175,62 +181,15 @@ private function applyConfigurableOption(
175181
true
176182
);
177183

178-
$this->fillTemporaryOptionsTable($temporaryOptionsTableName, $dimensions, $entityIds);
184+
$indexTableName = $this->getMainTable($dimensions);
185+
$this->optionsIndexer->execute($indexTableName, $temporaryOptionsTableName, $entityIds);
179186
$this->updateTemporaryTable($temporaryPriceTable->getTableName(), $temporaryOptionsTableName);
180187

181188
$this->getConnection()->delete($temporaryOptionsTableName);
182189

183190
return $this;
184191
}
185192

186-
/**
187-
* Put data into catalog product price indexer config option temp table
188-
*
189-
* @param string $temporaryOptionsTableName
190-
* @param array $dimensions
191-
* @param array $entityIds
192-
*
193-
* @return void
194-
* @throws \Exception
195-
*/
196-
private function fillTemporaryOptionsTable(string $temporaryOptionsTableName, array $dimensions, array $entityIds)
197-
{
198-
$metadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
199-
$linkField = $metadata->getLinkField();
200-
201-
$select = $this->getConnection()->select()->from(
202-
['i' => $this->getMainTable($dimensions)],
203-
[]
204-
)->join(
205-
['l' => $this->getTable('catalog_product_super_link')],
206-
'l.product_id = i.entity_id',
207-
[]
208-
)->join(
209-
['le' => $this->getTable('catalog_product_entity')],
210-
'le.' . $linkField . ' = l.parent_id',
211-
[]
212-
);
213-
214-
$this->baseSelectProcessor->process($select);
215-
216-
$select->columns(
217-
[
218-
'le.entity_id',
219-
'customer_group_id',
220-
'website_id',
221-
'MIN(final_price)',
222-
'MAX(final_price)',
223-
'MIN(tier_price)',
224-
]
225-
)->group(
226-
['le.entity_id', 'customer_group_id', 'website_id']
227-
);
228-
if ($entityIds !== null) {
229-
$select->where('le.entity_id IN (?)', $entityIds, \Zend_Db::INT_TYPE);
230-
}
231-
$this->tableMaintainer->insertFromSelect($select, $temporaryOptionsTableName, []);
232-
}
233-
234193
/**
235194
* Update data in the catalog product price indexer temp table
236195
*
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
9+
10+
use Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer;
11+
12+
/**
13+
* Configurable product options prices aggregator
14+
*/
15+
class OptionsIndexer implements OptionsIndexerInterface
16+
{
17+
/**
18+
* @var OptionsSelectBuilderInterface
19+
*/
20+
private $selectBuilder;
21+
22+
/**
23+
* @var TableMaintainer
24+
*/
25+
private $tableMaintainer;
26+
27+
/**
28+
* @param OptionsSelectBuilderInterface $selectBuilder
29+
* @param TableMaintainer $tableMaintainer
30+
*/
31+
public function __construct(
32+
OptionsSelectBuilderInterface $selectBuilder,
33+
TableMaintainer $tableMaintainer
34+
) {
35+
$this->selectBuilder = $selectBuilder;
36+
$this->tableMaintainer = $tableMaintainer;
37+
}
38+
39+
/**
40+
* @inheritdoc
41+
*/
42+
public function execute(string $indexTable, string $tempIndexTable, ?array $entityIds = null): void
43+
{
44+
$select = $this->selectBuilder->execute($indexTable, $entityIds);
45+
$this->tableMaintainer->insertFromSelect($select, $tempIndexTable, []);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
9+
10+
use Magento\Framework\DB\Select;
11+
12+
/**
13+
* Configurable product options prices aggregator
14+
*/
15+
interface OptionsIndexerInterface
16+
{
17+
/**
18+
* Aggregate configurable product options prices and save it in a temporary index table
19+
*
20+
* @param string $indexTable
21+
* @param string $tempIndexTable
22+
* @param array|null $entityIds
23+
*/
24+
public function execute(string $indexTable, string $tempIndexTable, ?array $entityIds = null): void;
25+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
11+
use Magento\Framework\App\ResourceConnection;
12+
use Magento\Framework\DB\Select;
13+
use Magento\Framework\EntityManager\MetadataPool;
14+
15+
/**
16+
* Build select for aggregating configurable product options prices
17+
*/
18+
class OptionsSelectBuilder implements OptionsSelectBuilderInterface
19+
{
20+
/**
21+
* @var MetadataPool
22+
*/
23+
private $metadataPool;
24+
25+
/**
26+
* @var ResourceConnection
27+
*/
28+
private $resourceConnection;
29+
30+
/**
31+
* @var string
32+
*/
33+
private $connectionName;
34+
35+
/**
36+
* @var BaseSelectProcessorInterface
37+
*/
38+
private $selectProcessor;
39+
40+
/**
41+
* @param BaseSelectProcessorInterface $selectProcessor
42+
* @param MetadataPool $metadataPool
43+
* @param ResourceConnection $resourceConnection
44+
* @param string $connectionName
45+
*/
46+
public function __construct(
47+
BaseSelectProcessorInterface $selectProcessor,
48+
MetadataPool $metadataPool,
49+
ResourceConnection $resourceConnection,
50+
string $connectionName = 'indexer'
51+
) {
52+
$this->selectProcessor = $selectProcessor;
53+
$this->metadataPool = $metadataPool;
54+
$this->resourceConnection = $resourceConnection;
55+
$this->connectionName = $connectionName;
56+
}
57+
58+
/**
59+
* @inheritdoc
60+
*/
61+
public function execute(string $indexTable, ?array $entityIds = null): Select
62+
{
63+
$connection = $this->resourceConnection->getConnection($this->connectionName);
64+
$metadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
65+
$linkField = $metadata->getLinkField();
66+
67+
$select = $connection->select()
68+
->from(
69+
['i' => $indexTable],
70+
[]
71+
)
72+
->join(
73+
['l' => $this->resourceConnection->getTableName('catalog_product_super_link', $this->connectionName)],
74+
'l.product_id = i.entity_id',
75+
[]
76+
)
77+
->join(
78+
['le' => $this->resourceConnection->getTableName('catalog_product_entity', $this->connectionName)],
79+
'le.' . $linkField . ' = l.parent_id',
80+
[]
81+
);
82+
83+
$select->columns(
84+
[
85+
'le.entity_id',
86+
'customer_group_id',
87+
'website_id',
88+
'MIN(final_price)',
89+
'MAX(final_price)',
90+
'MIN(tier_price)',
91+
]
92+
)->group(
93+
['le.entity_id', 'customer_group_id', 'website_id']
94+
);
95+
if ($entityIds !== null) {
96+
$select->where('le.entity_id IN (?)', $entityIds, \Zend_Db::INT_TYPE);
97+
}
98+
return $this->selectProcessor->process($select);
99+
}
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
9+
10+
use Magento\Framework\DB\Select;
11+
12+
/**
13+
* Aggregate configurable product options prices and save it in a temporary index table
14+
*/
15+
interface OptionsSelectBuilderInterface
16+
{
17+
/**
18+
* Return select with aggregated configurable product options prices
19+
*
20+
* @param string $indexTable
21+
* @param array|null $entityIds
22+
* @return Select
23+
*/
24+
public function execute(string $indexTable, ?array $entityIds = null): Select;
25+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
<preference for="Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface" type="Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProvider" />
1818
<preference for="Magento\ConfigurableProduct\Model\AttributeOptionProviderInterface" type="Magento\ConfigurableProduct\Model\AttributeOptionProvider" />
1919
<preference for="Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface" type="Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilder" />
20+
<preference for="Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\OptionsIndexerInterface" type="\Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\OptionsIndexer" />
21+
<preference for="Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\OptionsSelectBuilderInterface" type="\Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\OptionsSelectBuilder" />
2022

2123
<type name="Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option">
2224
<plugin name="configurable_product" type="Magento\ConfigurableProduct\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin\ConfigurableProduct" sortOrder="50" />
@@ -208,6 +210,12 @@
208210
<argument name="baseSelectProcessor" xsi:type="object">Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\BaseStockStatusSelectProcessor</argument>
209211
</arguments>
210212
</type>
213+
<type name="Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\OptionsSelectBuilder">
214+
<arguments>
215+
<argument name="selectProcessor" xsi:type="object">Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\BaseStockStatusSelectProcessor</argument>
216+
<argument name="connectionName" xsi:type="string">indexer</argument>
217+
</arguments>
218+
</type>
211219
<type name="Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Product">
212220
<arguments>
213221
<argument name="productIndexer" xsi:type="object">Magento\Catalog\Model\Indexer\Product\Full</argument>

0 commit comments

Comments
 (0)