Skip to content

Commit 23f7456

Browse files
author
Alexander Akimov
authored
Merge pull request #1009 from magento-folks/stock_indexer_batching
[Folks] Update catalog_inventory stock indexer
2 parents 8b656e2 + 8a306f1 commit 23f7456

File tree

50 files changed

+1392
-60
lines changed

Some content is hidden

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

50 files changed

+1392
-60
lines changed

app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Bundle\Model\ResourceModel\Indexer;
77

88
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\CatalogInventory\Model\Indexer\Stock\Action\Full;
910

1011
/**
1112
* Bundle Stock Status Indexer Resource Model
@@ -15,16 +16,33 @@
1516
class Stock extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\DefaultStock
1617
{
1718
/**
18-
* Reindex temporary (price result data) for defined product(s)
19-
*
20-
* @param int|array $entityIds
21-
* @return $this
19+
* @var \Magento\Indexer\Model\ResourceModel\FrontendResource
2220
*/
23-
public function reindexEntity($entityIds)
24-
{
25-
$this->_updateIndex($entityIds);
21+
private $indexerStockFrontendResource;
2622

27-
return $this;
23+
/**
24+
* Class constructor
25+
*
26+
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
27+
* @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy
28+
* @param \Magento\Eav\Model\Config $eavConfig
29+
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
30+
* @param string $connectionName
31+
* @param null|\Magento\Indexer\Model\Indexer\StateFactory $stateFactory
32+
* @param null|\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerStockFrontendResource
33+
*/
34+
public function __construct(
35+
\Magento\Framework\Model\ResourceModel\Db\Context $context,
36+
\Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
37+
\Magento\Eav\Model\Config $eavConfig,
38+
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
39+
$connectionName = null,
40+
\Magento\Indexer\Model\Indexer\StateFactory $stateFactory = null,
41+
\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerStockFrontendResource = null
42+
) {
43+
parent::__construct($context, $tableStrategy, $eavConfig, $scopeConfig, $connectionName, $stateFactory);
44+
$this->indexerStockFrontendResource = $indexerStockFrontendResource ?: ObjectManager::getInstance()
45+
->get(\Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\FrontendResource::class);
2846
}
2947

3048
/**
@@ -48,7 +66,10 @@ protected function _prepareBundleOptionStockData($entityIds = null, $usePrimaryT
4866
{
4967
$this->_cleanBundleOptionStockData();
5068
$linkField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField();
51-
$idxTable = $usePrimaryTable ? $this->getMainTable() : $this->getIdxTable();
69+
$table = $this->getActionType() === Full::ACTION_TYPE
70+
? $this->getMainTable()
71+
: $this->indexerStockFrontendResource->getMainTable();
72+
$idxTable = $usePrimaryTable ? $table : $this->getIdxTable();
5273
$connection = $this->getConnection();
5374
$select = $connection->select()->from(
5475
['product' => $this->getTable('catalog_product_entity')],

app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@
88
use Magento\Customer\Api\GroupManagementInterface;
99
use Magento\Framework\DataObject;
1010
use Magento\Framework\DB\Select;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;
13+
use Magento\Framework\App\ObjectManager;
1114

1215
/**
1316
* Bundle Selections Resource Collection
17+
*
18+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1419
*/
1520
class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
1621
{
@@ -38,6 +43,99 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
3843
*/
3944
private $websiteScopePriceJoined = false;
4045

46+
/**
47+
* @var \Magento\Indexer\Model\ResourceModel\FrontendResource
48+
*/
49+
private $indexerStockFrontendResource;
50+
51+
/**
52+
* Collection constructor.
53+
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
54+
* @param \Psr\Log\LoggerInterface $logger
55+
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
56+
* @param \Magento\Framework\Event\ManagerInterface $eventManager
57+
* @param \Magento\Eav\Model\Config $eavConfig
58+
* @param \Magento\Framework\App\ResourceConnection $resource
59+
* @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
60+
* @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper
61+
* @param \Magento\Framework\Validator\UniversalFactory $universalFactory
62+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
63+
* @param \Magento\Framework\Module\Manager $moduleManager
64+
* @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState
65+
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
66+
* @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory
67+
* @param \Magento\Catalog\Model\ResourceModel\Url $catalogUrl
68+
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
69+
* @param \Magento\Customer\Model\Session $customerSession
70+
* @param \Magento\Framework\Stdlib\DateTime $dateTime
71+
* @param GroupManagementInterface $groupManagement
72+
* @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
73+
* @param ProductLimitationFactory|null $productLimitationFactory
74+
* @param MetadataPool|null $metadataPool
75+
* @param \Magento\Indexer\Model\ResourceModel\FrontendResource|null $indexerFrontendResource
76+
* @param \Magento\Indexer\Model\ResourceModel\FrontendResource|null $categoryProductIndexerFrontend
77+
* @param \Magento\Indexer\Model\ResourceModel\FrontendResource|null $indexerStockFrontendResource
78+
*
79+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
80+
* @SuppressWarnings(Magento.TypeDuplication)
81+
*/
82+
public function __construct(
83+
\Magento\Framework\Data\Collection\EntityFactory $entityFactory,
84+
\Psr\Log\LoggerInterface $logger,
85+
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
86+
\Magento\Framework\Event\ManagerInterface $eventManager,
87+
\Magento\Eav\Model\Config $eavConfig,
88+
\Magento\Framework\App\ResourceConnection $resource,
89+
\Magento\Eav\Model\EntityFactory $eavEntityFactory,
90+
\Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
91+
\Magento\Framework\Validator\UniversalFactory $universalFactory,
92+
\Magento\Store\Model\StoreManagerInterface $storeManager,
93+
\Magento\Framework\Module\Manager $moduleManager,
94+
\Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState,
95+
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
96+
\Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
97+
\Magento\Catalog\Model\ResourceModel\Url $catalogUrl,
98+
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
99+
\Magento\Customer\Model\Session $customerSession,
100+
\Magento\Framework\Stdlib\DateTime $dateTime,
101+
GroupManagementInterface $groupManagement,
102+
\Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
103+
ProductLimitationFactory $productLimitationFactory = null,
104+
MetadataPool $metadataPool = null,
105+
\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerFrontendResource = null,
106+
\Magento\Indexer\Model\ResourceModel\FrontendResource $categoryProductIndexerFrontend = null,
107+
\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerStockFrontendResource = null
108+
) {
109+
parent::__construct(
110+
$entityFactory,
111+
$logger,
112+
$fetchStrategy,
113+
$eventManager,
114+
$eavConfig,
115+
$resource,
116+
$eavEntityFactory,
117+
$resourceHelper,
118+
$universalFactory,
119+
$storeManager,
120+
$moduleManager,
121+
$catalogProductFlatState,
122+
$scopeConfig,
123+
$productOptionFactory,
124+
$catalogUrl,
125+
$localeDate,
126+
$customerSession,
127+
$dateTime,
128+
$groupManagement,
129+
$connection,
130+
$productLimitationFactory,
131+
$metadataPool,
132+
$indexerFrontendResource,
133+
$categoryProductIndexerFrontend
134+
);
135+
$this->indexerStockFrontendResource = $indexerStockFrontendResource ?: ObjectManager::getInstance()
136+
->get(\Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\FrontendResource::class);
137+
}
138+
41139
/**
42140
* Initialize collection
43141
*
@@ -162,7 +260,7 @@ public function addQuantityFilter()
162260
{
163261
$this->getSelect()
164262
->joinInner(
165-
['stock' => $this->getTable('cataloginventory_stock_status')],
263+
['stock' => $this->indexerStockFrontendResource->getMainTable()],
166264
'selection.product_id = stock.product_id',
167265
[]
168266
)
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Bundle\Test\Unit\Model\ResourceModel\Selection;
7+
8+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
9+
use Magento\Indexer\Model\ResourceModel\FrontendResource;
10+
use Magento\Store\Model\StoreManagerInterface;
11+
use Magento\Store\Api\Data\StoreInterface;
12+
use Magento\Framework\Validator\UniversalFactory;
13+
use Magento\Eav\Model\Entity\AbstractEntity;
14+
use Magento\Framework\DB\Adapter\AdapterInterface;
15+
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;
16+
use Magento\Framework\DB\Select;
17+
18+
/**
19+
* Class CollectionTest.
20+
* Unit test for \Magento\Indexer\Model\ResourceModel\FrontendResource.
21+
*/
22+
class CollectionTest extends \PHPUnit_Framework_TestCase
23+
{
24+
/**
25+
* @var \PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
private $frontendResource;
28+
29+
/**
30+
* @var \PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
private $storeManager;
33+
34+
/**
35+
* @var \PHPUnit_Framework_MockObject_MockObject
36+
*/
37+
private $store;
38+
39+
/**
40+
* @var \PHPUnit_Framework_MockObject_MockObject
41+
*/
42+
private $universalFactory;
43+
44+
/**
45+
* @var \PHPUnit_Framework_MockObject_MockObject
46+
*/
47+
private $entity;
48+
49+
/**
50+
* @var \PHPUnit_Framework_MockObject_MockObject
51+
*/
52+
private $adapter;
53+
54+
/**
55+
* @var \PHPUnit_Framework_MockObject_MockObject
56+
*/
57+
private $select;
58+
59+
/**
60+
* @var \Magento\Bundle\Model\ResourceModel\Selection\Collection
61+
*/
62+
private $model;
63+
64+
protected function setUp()
65+
{
66+
$objectManager = new ObjectManager($this);
67+
$this->frontendResource = $this->getMockBuilder(FrontendResource::class)
68+
->disableOriginalConstructor()
69+
->getMock();
70+
$this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
71+
->disableOriginalConstructor()
72+
->getMock();
73+
$this->store = $this->getMockBuilder(StoreInterface::class)
74+
->disableOriginalConstructor()
75+
->getMock();
76+
$this->universalFactory = $this->getMockBuilder(UniversalFactory::class)
77+
->disableOriginalConstructor()
78+
->getMock();
79+
$this->entity = $this->getMockBuilder(AbstractEntity::class)
80+
->disableOriginalConstructor()
81+
->getMock();
82+
$this->adapter = $this->getMockBuilder(AdapterInterface::class)
83+
->disableOriginalConstructor()
84+
->getMock();
85+
$this->select = $this->getMockBuilder(Select::class)
86+
->disableOriginalConstructor()
87+
->getMock();
88+
$factory = $this->getMockBuilder(ProductLimitationFactory::class)
89+
->disableOriginalConstructor()
90+
->setMethods(['create'])
91+
->getMock();
92+
93+
$this->storeManager->expects($this->any())
94+
->method('getStore')
95+
->willReturn($this->store);
96+
$this->store->expects($this->any())
97+
->method('getId')
98+
->willReturn(1);
99+
$this->universalFactory->expects($this->any())
100+
->method('create')
101+
->willReturn($this->entity);
102+
$this->entity->expects($this->any())
103+
->method('getConnection')
104+
->willReturn($this->adapter);
105+
$this->entity->expects($this->any())
106+
->method('getDefaultAttributes')
107+
->willReturn([]);
108+
$this->adapter->expects($this->any())
109+
->method('select')
110+
->willReturn($this->select);
111+
112+
$this->model = $objectManager->getObject(
113+
\Magento\Bundle\Model\ResourceModel\Selection\Collection::class,
114+
[
115+
'storeManager' => $this->storeManager,
116+
'universalFactory' => $this->universalFactory,
117+
'productLimitationFactory' => $factory,
118+
'indexerStockFrontendResource' => $this->frontendResource
119+
]
120+
);
121+
}
122+
123+
public function testAddQuantityFilter()
124+
{
125+
$tableName = 'cataloginventory_stock_status';
126+
$this->frontendResource->expects($this->once())
127+
->method('getMainTable')
128+
->willReturn($tableName);
129+
$this->select->expects($this->once())
130+
->method('joinInner')
131+
->with(
132+
['stock' => $tableName],
133+
'selection.product_id = stock.product_id',
134+
[]
135+
)->willReturnSelf();
136+
$this->assertEquals($this->model, $this->model->addQuantityFilter());
137+
}
138+
}

app/code/Magento/Bundle/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"magento/framework": "100.2.*",
1919
"magento/module-quote": "100.2.*",
2020
"magento/module-media-storage": "100.2.*",
21-
"magento/module-ui": "100.2.*"
21+
"magento/module-ui": "100.2.*",
22+
"magento/module-indexer": "100.2.*"
2223
},
2324
"suggest": {
2425
"magento/module-webapi": "100.2.*",

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,21 @@
150150
<argument name="connectionName" xsi:type="string">indexer</argument>
151151
</arguments>
152152
</type>
153+
<type name="Magento\CatalogInventory\Model\Indexer\Stock\Action\Full">
154+
<arguments>
155+
<argument name="memoryTablesMinRows" xsi:type="array">
156+
<item name="bundle" xsi:type="number">136</item>
157+
</argument>
158+
</arguments>
159+
</type>
160+
<type name="Magento\Bundle\Model\ResourceModel\Selection\Collection">
161+
<arguments>
162+
<argument name="indexerStockFrontendResource" xsi:type="object">Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\FrontendResource</argument>
163+
</arguments>
164+
</type>
165+
<type name="Magento\Bundle\Model\ResourceModel\Indexer\Stock">
166+
<arguments>
167+
<argument name="indexerStockFrontendResource" xsi:type="object">Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\FrontendResource</argument>
168+
</arguments>
169+
</type>
153170
</config>

0 commit comments

Comments
 (0)