Skip to content

Commit cd102ba

Browse files
committed
MAGETWO-54682: Fast load of product options
- MAGETWO-55756: Porting to 2.1
1 parent df20093 commit cd102ba

File tree

4 files changed

+47
-71
lines changed

4 files changed

+47
-71
lines changed

app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -575,46 +575,36 @@ public function getUsedProducts($product, $requiredAttributeIds = null)
575575
} else {
576576
$collection
577577
->setFlag('has_stock_status_filter', true)
578-
->addAttributeToSelect('name')
579-
->addAttributeToSelect('price')
580-
->addAttributeToSelect('weight')
581-
->addAttributeToSelect('image')
582-
->addAttributeToSelect('thumbnail')
583-
->addAttributeToSelect('status')
584-
->addAttributeToSelect('media_gallery')
585578
->addAttributeToSelect($this->getCatalogConfig()->getProductAttributes())
586579
->addFilterByRequiredOptions()
587580
->setStoreId($product->getStoreId());
581+
582+
$requiredAttributes = ['name', 'price', 'weight', 'image', 'thumbnail', 'status', 'media_gallery'];
583+
foreach ($requiredAttributes as $attributeCode) {
584+
$collection->addAttributeToSelect($attributeCode);
585+
}
588586
foreach ($this->getUsedProductAttributes($product) as $usedProductAttribute) {
589587
$collection->addAttributeToSelect($usedProductAttribute->getAttributeCode());
590588
}
591-
if (is_array($requiredAttributeIds)) {
592-
foreach ($requiredAttributeIds as $attributeId) {
593-
$attribute = $this->getAttributeById($attributeId, $product);
594-
if (!is_null($attribute)) {
595-
$collection->addAttributeToFilter($attribute->getAttributeCode(), ['notnull' => 1]);
596-
}
597-
}
598-
}
599-
$tags = ['price', self::TYPE_CODE . '_' . $productId];
600589
$collection->addMediaGalleryData();
601590
$collection->addTierPriceData();
602591
$usedProducts = $collection->getItems();
603-
$cache = array_map(
604-
function ($item) {
605-
return $item->getData();
606-
},
607-
$usedProducts
608-
);
592+
609593
$this->getCache()->save(
610-
serialize($cache),
594+
serialize(array_map(
595+
function ($item) {
596+
return $item->getData();
597+
},
598+
$usedProducts
599+
)),
611600
$key,
612601
array_merge(
613602
$product->getIdentities(),
614-
$tags,
615603
[
616604
\Magento\Catalog\Model\Category::CACHE_TAG,
617-
\Magento\Catalog\Model\Product::CACHE_TAG
605+
\Magento\Catalog\Model\Product::CACHE_TAG,
606+
'price',
607+
self::TYPE_CODE . '_' . $productId
618608
]
619609
)
620610
);

app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public function testSave()
227227
'getConfigurableProductLinks'
228228
])
229229
->getMockForAbstractClass();
230-
$this->entityMetadata->expects($this->exactly(2))
230+
$this->entityMetadata->expects($this->any())
231231
->method('getLinkField')
232232
->willReturn('link');
233233
$dataMap = [
@@ -338,18 +338,26 @@ public function testGetUsedProducts()
338338
$product->expects($this->any())->method('getId')->will($this->returnValue(1));
339339
$product->expects($this->any())->method('getIdentities')->willReturn(['123']);
340340
$product->expects($this->any())->method('getAssociatedProductIds')->will($this->returnValue([2]));
341+
341342
$product->expects($this->any())->method('hasData')
342343
->will(
343344
$this->returnValueMap(
344345
[
345346
['_cache_instance_used_product_attribute_ids', 1],
346347
['_cache_instance_products', 0],
347348
['_cache_instance_configurable_attributes', 1],
349+
['_cache_instance_used_product_attributes', 1],
348350
]
349351
)
350352
);
351353
$product->expects($this->any())->method('getData')
352-
->will($this->returnValue(1));
354+
->will($this->returnValueMap(
355+
[
356+
['_cache_instance_used_product_attributes', null, []],
357+
]
358+
));
359+
360+
353361
$productCollection = $this->getMockBuilder(
354362
'Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection'
355363
)->setMethods(

app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/ConfigurableTest.php

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ protected function setUp()
8080
[
8181
'resource' => $this->resource,
8282
'catalogProductRelation' => $this->relation,
83+
'scopeResolver' => $this->getMockForAbstractClass(\Magento\Framework\App\ScopeResolverInterface::class)
8384
]
8485
);
8586
$reflection = new \ReflectionClass(
@@ -89,6 +90,7 @@ protected function setUp()
8990
$reflectionProperty->setAccessible(true);
9091
$reflectionProperty->setValue($this->configurable, $this->metadataPoolMock);
9192
}
93+
9294
public function testSaveProducts()
9395
{
9496
/** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $mainProduct */
@@ -104,9 +106,6 @@ public function testSaveProducts()
104106
->method('getData')
105107
->with('link')
106108
->willReturn(3);
107-
108-
$mainProduct->expects($this->once())->method('getIsDuplicate')->will($this->returnValue(false));
109-
110109

111110
$select = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
112111

@@ -121,19 +120,6 @@ public function testSaveProducts()
121120
$this->configurable->saveProducts($mainProduct, [1, 2, 3]);
122121
}
123122

124-
public function testSaveProductsForDuplicate()
125-
{
126-
$mainProduct = $this->getMockBuilder('Magento\Catalog\Model\Product')
127-
->setMethods(['getIsDuplicate', '__sleep', '__wakeup', 'getTypeInstance', 'getConnection'])
128-
->disableOriginalConstructor()
129-
->getMock();
130-
131-
$mainProduct->expects($this->once())->method('getIsDuplicate')->will($this->returnValue(true));
132-
$mainProduct->expects($this->never())->method('getTypeInstance')->will($this->returnSelf());
133-
134-
$this->configurable->saveProducts($mainProduct, [1, 2, 3]);
135-
}
136-
137123
/**
138124
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
139125
*/
@@ -162,11 +148,7 @@ public function testGetConfigurableOptions()
162148
$context = $this->getMockBuilder(Context::class)
163149
->disableOriginalConstructor()
164150
->getMock();
165-
/** @var Configurable|\PHPUnit_Framework_MockObject_MockObject $configurable */
166-
$configurable = $this->getMockBuilder(Configurable::class)
167-
->setMethods(['getTable', 'getConnection'])
168-
->setConstructorArgs([$context, $this->relation])
169-
->getMock();
151+
170152
$reflection = new \ReflectionClass(Configurable::class);
171153
$reflectionProperty = $reflection->getProperty('metadataPool');
172154
$reflectionProperty->setAccessible(true);
@@ -328,8 +310,6 @@ public function testGetConfigurableOptions()
328310
'getAttributeId value'
329311
]
330312
);
331-
$readerAdapter = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
332-
333313

334314
$readerAdapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
335315
->setMethods([
@@ -345,7 +325,6 @@ public function testGetConfigurableOptions()
345325
->method('fetchAll')
346326
->with($select)
347327
->willReturn('fetchAll value');
348-
$configurable->expects($this->exactly(2))
349328

350329
$configurable->expects($this->any())
351330
->method('getConnection')

app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
*/
66
namespace Magento\ConfigurableProduct\Test\Unit\Pricing\Price;
77

8+
use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
89
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
910

1011
class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
1112
{
13+
/** @var ConfigurableOptionsProviderInterface */
14+
private $cofigurableOptionProvider;
15+
1216
/**
1317
* @var \Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver
1418
*/
@@ -32,12 +36,17 @@ protected function setUp()
3236
$className = 'Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface';
3337
$this->priceResolver = $this->getMockForAbstractClass($className, [], '', false, true, true, ['resolvePrice']);
3438

39+
$this->cofigurableOptionProvider = $this->getMockBuilder(ConfigurableOptionsProviderInterface::class)
40+
->disableOriginalConstructor()->getMock();
41+
42+
3543
$objectManager = new ObjectManager($this);
3644
$this->resolver = $objectManager->getObject(
3745
'Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver',
3846
[
3947
'priceResolver' => $this->priceResolver,
4048
'configurable' => $this->configurable,
49+
'configurableOptionsProvider' => $this->cofigurableOptionProvider,
4150
]
4251
);
4352
}
@@ -49,18 +58,13 @@ protected function setUp()
4958
*/
5059
public function testResolvePriceWithNoPrices()
5160
{
52-
$product = $this->getMockForAbstractClass(
53-
'Magento\Framework\Pricing\SaleableInterface',
54-
[],
55-
'',
56-
false,
57-
true,
58-
true,
59-
['getSku']
60-
);
61+
$product = $this->getMockBuilder(
62+
\Magento\Catalog\Model\Product::class
63+
)->disableOriginalConstructor()->getMock();
64+
6165
$product->expects($this->once())->method('getSku')->willReturn('Kiwi');
6266

63-
$this->configurable->expects($this->once())->method('getUsedProducts')->willReturn([]);
67+
$this->cofigurableOptionProvider->expects($this->once())->method('getProducts')->willReturn([]);
6468

6569
$this->resolver->resolvePrice($product);
6670
}
@@ -74,18 +78,13 @@ public function testResolvePrice($expectedValue)
7478
{
7579
$price = $expectedValue;
7680

77-
$product = $this->getMockForAbstractClass(
78-
'Magento\Framework\Pricing\SaleableInterface',
79-
[],
80-
'',
81-
false,
82-
true,
83-
true,
84-
['getSku']
85-
);
81+
$product = $this->getMockBuilder(
82+
\Magento\Catalog\Model\Product::class
83+
)->disableOriginalConstructor()->getMock();
84+
8685
$product->expects($this->never())->method('getSku');
8786

88-
$this->configurable->expects($this->once())->method('getUsedProducts')->willReturn([$product]);
87+
$this->cofigurableOptionProvider->expects($this->once())->method('getProducts')->willReturn([$product]);
8988
$this->priceResolver->expects($this->atLeastOnce())->method('resolvePrice')->willReturn($price);
9089

9190
$this->assertEquals($expectedValue, $this->resolver->resolvePrice($product));

0 commit comments

Comments
 (0)