Skip to content

Commit 93f96f5

Browse files
author
Alexander Akimov
authored
Merge pull request #883 from magento-performance/MAGETWO-64669
[Performance] Performance degradation for bundle product if price view set as from..to
2 parents c993777 + ae4fe8f commit 93f96f5

File tree

5 files changed

+86
-73
lines changed

5 files changed

+86
-73
lines changed

app/code/Magento/Bundle/Model/Product/Type.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ public function isVirtual($product)
344344
}
345345
}
346346

347-
return $virtualCount == count($selections);
347+
return $virtualCount === count($selections);
348348
}
349349

350350
return false;
@@ -544,7 +544,7 @@ public function isSalable($product)
544544
}
545545

546546
$isSalable = false;
547-
foreach ($this->getOptionsCollection($product)->getItems() as $option) {
547+
foreach ($this->getOptionsCollection($product) as $option) {
548548
$hasSalable = false;
549549

550550
$selectionsCollection = $this->_bundleCollection->create();
@@ -972,7 +972,7 @@ public function hasOptions($product)
972972
->getAllIds();
973973
$collection = $this->getSelectionsCollection($optionIds, $product);
974974

975-
if (count($collection) > 0 || $product->getOptions()) {
975+
if ($collection->getSize() > 0 || $product->getOptions()) {
976976
return true;
977977
}
978978

app/code/Magento/Bundle/Pricing/Price/BundleOptionPrice.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,22 @@ public function getOptions()
109109
*/
110110
public function getOptionSelectionAmount($selection)
111111
{
112-
$selectionPrice = $this->selectionFactory
113-
->create($this->product, $selection, $selection->getSelectionQty());
114-
return $selectionPrice->getAmount();
112+
$cacheKey = implode(
113+
'_',
114+
[
115+
$this->product->getId(),
116+
$selection->getOptionId(),
117+
$selection->getSelectionId()
118+
]
119+
);
120+
121+
if (!isset($this->optionSelecionAmountCache[$cacheKey])) {
122+
$selectionPrice = $this->selectionFactory
123+
->create($this->product, $selection, $selection->getSelectionQty());
124+
$this->optionSelecionAmountCache[$cacheKey] = $selectionPrice->getAmount();
125+
}
126+
127+
return $this->optionSelecionAmountCache[$cacheKey];
115128
}
116129

117130
/**

app/code/Magento/Bundle/Pricing/Render/FinalPriceBox.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Magento\Bundle\Pricing\Render;
88

9-
use Magento\Bundle\Pricing\Price;
9+
use Magento\Bundle\Pricing\Price\FinalPrice;
1010
use Magento\Catalog\Pricing\Render as CatalogRender;
1111
use Magento\Catalog\Pricing\Price\CustomOptionPrice;
1212

@@ -22,10 +22,9 @@ class FinalPriceBox extends CatalogRender\FinalPriceBox
2222
*/
2323
public function showRangePrice()
2424
{
25-
//Check the bundle options
26-
/** @var Price\BundleOptionPrice $bundleOptionPrice */
27-
$bundleOptionPrice = $this->getPriceType(Price\BundleOptionPrice::PRICE_CODE);
28-
$showRange = $bundleOptionPrice->getValue() != $bundleOptionPrice->getMaxValue();
25+
/** @var FinalPrice $bundlePrice */
26+
$bundlePrice = $this->getPriceType(FinalPrice::PRICE_CODE);
27+
$showRange = $bundlePrice->getMinimalPrice() != $bundlePrice->getMaximalPrice();
2928

3029
if (!$showRange) {
3130
//Check the custom options, if any

app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ public function testPrepareForCartAdvancedWithShoppingCart()
315315
->getMock();
316316
/** @var \PHPUnit_Framework_MockObject_MockObject|SelectionCollection $selectionCollection */
317317
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
318-
->setMethods(['getItems'])
318+
->setMethods(['getItems', 'getSize'])
319319
->disableOriginalConstructor()
320320
->getMock();
321321
/** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject $buyRequest */
@@ -430,6 +430,9 @@ function ($key) use ($optionCollection, $selectionCollection) {
430430
$selectionCollection->expects($this->any())
431431
->method('getItems')
432432
->willReturn([$selection]);
433+
$selectionCollection->expects($this->any())
434+
->method('getSize')
435+
->willReturn(1);
433436
$selection->expects($this->once())
434437
->method('isSalable')
435438
->willReturn(false);
@@ -556,7 +559,7 @@ public function testPrepareForCartAdvancedEmptyShoppingCart()
556559
->getMock();
557560
/** @var \PHPUnit_Framework_MockObject_MockObject|SelectionCollection $selectionCollection */
558561
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
559-
->setMethods(['getItems'])
562+
->setMethods(['getItems', 'getSize'])
560563
->disableOriginalConstructor()
561564
->getMock();
562565
/** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject $buyRequest */
@@ -662,6 +665,9 @@ function ($key) use ($optionCollection, $selectionCollection) {
662665
$selectionCollection->expects($this->any())
663666
->method('getItems')
664667
->willReturn([$selection]);
668+
$selectionCollection->expects($this->any())
669+
->method('getSize')
670+
->willReturn(1);
665671
$selection->expects($this->once())
666672
->method('isSalable')
667673
->willReturn(false);
@@ -776,7 +782,7 @@ public function testPrepareForCartAdvancedStringInResult()
776782
->getMock();
777783
/** @var \PHPUnit_Framework_MockObject_MockObject|SelectionCollection $selectionCollection */
778784
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
779-
->setMethods(['getItems'])
785+
->setMethods(['getItems', 'getSize'])
780786
->disableOriginalConstructor()
781787
->getMock();
782788
/** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject $buyRequest */
@@ -882,6 +888,9 @@ function ($key) use ($optionCollection, $selectionCollection) {
882888
$selectionCollection->expects($this->any())
883889
->method('getItems')
884890
->willReturn([$selection]);
891+
$selectionCollection->expects($this->any())
892+
->method('getSize')
893+
->willReturn(1);
885894
$selection->expects($this->once())
886895
->method('isSalable')
887896
->willReturn(false);
@@ -1078,7 +1087,7 @@ public function testPrepareForCartAdvancedSelectionsSelectionIdsExists()
10781087
->getMock();
10791088
/** @var \PHPUnit_Framework_MockObject_MockObject|SelectionCollection $selectionCollection */
10801089
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
1081-
->setMethods(['getItems'])
1090+
->setMethods(['getItems', 'getSize'])
10821091
->disableOriginalConstructor()
10831092
->getMock();
10841093
/** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject $buyRequest */
@@ -1157,9 +1166,15 @@ function ($key) use ($optionCollection, $selectionCollection) {
11571166
$selectionCollection->expects($this->at(0))
11581167
->method('getItems')
11591168
->willReturn([$selection]);
1169+
$selectionCollection->expects($this->at(0))
1170+
->method('getSize')
1171+
->willReturn(1);
11601172
$selectionCollection->expects($this->at(1))
11611173
->method('getItems')
11621174
->willReturn([]);
1175+
$selectionCollection->expects($this->at(1))
1176+
->method('getSize')
1177+
->willReturn(0);
11631178
$option->expects($this->any())
11641179
->method('getId')
11651180
->willReturn(3);
@@ -1195,7 +1210,7 @@ public function testPrepareForCartAdvancedSelectRequiredOptions()
11951210
->getMock();
11961211
/** @var \PHPUnit_Framework_MockObject_MockObject|SelectionCollection $selectionCollection */
11971212
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
1198-
->setMethods(['getItems'])
1213+
->setMethods(['getItems', 'getSize'])
11991214
->disableOriginalConstructor()
12001215
->getMock();
12011216
/** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject $buyRequest */
@@ -1275,6 +1290,9 @@ function ($key) use ($optionCollection, $selectionCollection) {
12751290
$selectionCollection->expects($this->any())
12761291
->method('getItems')
12771292
->willReturn([$selection]);
1293+
$selectionCollection->expects($this->any())
1294+
->method('getSize')
1295+
->willReturn(1);
12781296
$selection->expects($this->once())
12791297
->method('isSalable')
12801298
->willReturn(false);
@@ -2198,38 +2216,39 @@ public function testIsSalableWithEmptySelectionsCollection()
21982216
/**
21992217
* @return void
22002218
*/
2201-
public function nottestIsSalableWithRequiredOptionsOutOfStock()
2219+
public function testIsSalableWithNonSalableRequiredOptions()
22022220
{
22032221
$option1 = $this->getRequiredOptionMock(10, 10);
2204-
$option1
2205-
->expects($this->atLeastOnce())
2206-
->method('getSelectionCanChangeQty')
2207-
->willReturn(false);
2208-
22092222
$option2 = $this->getRequiredOptionMock(20, 10);
2210-
$option2
2211-
->expects($this->atLeastOnce())
2212-
->method('getSelectionCanChangeQty')
2223+
$optionCollectionMock = $this->getOptionCollectionMock([$option1, $option2]);
2224+
2225+
$selection1 = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
2226+
->setMethods(['isSalable'])
2227+
->disableOriginalConstructor()
2228+
->getMock();
2229+
2230+
$selection1->expects($this->once())
2231+
->method('isSalable')
2232+
->willReturn(true);
2233+
2234+
$selection2 = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
2235+
->setMethods(['isSalable'])
2236+
->disableOriginalConstructor()
2237+
->getMock();
2238+
2239+
$selection2->expects($this->once())
2240+
->method('isSalable')
22132241
->willReturn(false);
22142242

2215-
$this->stockRegistry->method('getStockItem')
2216-
->willReturn($this->getStockItem(true));
2217-
$this->stockState
2218-
->method('getStockQty')
2219-
->will(
2220-
$this->returnValueMap(
2221-
[
2222-
[10, 10],
2223-
[20, 5]
2224-
]
2225-
)
2226-
);
2243+
$selectionCollectionMock1 = $this->getSelectionCollectionMock([$selection1]);
2244+
$selectionCollectionMock2 = $this->getSelectionCollectionMock([$selection2]);
22272245

2228-
$optionCollectionMock = $this->getOptionCollectionMock([$option1, $option2]);
2229-
$selectionCollectionMock = $this->getSelectionCollectionMock([$option1, $option2]);
2230-
$this->bundleCollection->expects($this->once())
2246+
$this->bundleCollection->expects($this->exactly(2))
22312247
->method('create')
2232-
->will($this->returnValue($selectionCollectionMock));
2248+
->will($this->onConsecutiveCalls(
2249+
$selectionCollectionMock1,
2250+
$selectionCollectionMock2
2251+
));
22332252

22342253
$product = new \Magento\Framework\DataObject(
22352254
[
@@ -2289,14 +2308,8 @@ private function getSelectionCollectionMock(array $selectedOptions)
22892308
{
22902309
$selectionCollectionMock = $this->getMockBuilder(
22912310
\Magento\Bundle\Model\ResourceModel\Selection\Collection::class
2292-
)
2293-
->disableOriginalConstructor()
2294-
->getMock();
2295-
2296-
$selectionCollectionMock
2297-
->expects($this->any())
2298-
->method('getItems')
2299-
->willReturn($selectedOptions);
2311+
)->disableOriginalConstructor()
2312+
->getMock();
23002313

23012314
$selectionCollectionMock
23022315
->expects($this->any())
@@ -2312,25 +2325,14 @@ private function getSelectionCollectionMock(array $selectedOptions)
23122325
*/
23132326
private function getOptionCollectionMock(array $options)
23142327
{
2315-
$ids = [];
2316-
foreach ($options as $option) {
2317-
$ids[] = $option->getId();
2318-
}
2319-
23202328
$optionCollectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
2321-
->setMethods(['getItems', 'getAllIds'])
2329+
->setMethods(['getIterator'])
23222330
->disableOriginalConstructor()
23232331
->getMock();
23242332

2325-
$optionCollectionMock
2326-
->expects($this->any())
2327-
->method('getItems')
2328-
->willReturn($options);
2329-
2330-
$optionCollectionMock
2331-
->expects($this->any())
2332-
->method('getAllIds')
2333-
->willReturn($ids);
2333+
$optionCollectionMock->expects($this->any())
2334+
->method('getIterator')
2335+
->will($this->returnValue(new \ArrayIterator($options)));
23342336

23352337
return $optionCollectionMock;
23362338
}
@@ -2560,7 +2562,7 @@ public function testHasOptions()
25602562
$selectionCollection = $this->getSelectionCollection();
25612563
$selectionCollection
25622564
->expects($this->any())
2563-
->method('count')
2565+
->method('getSize')
25642566
->willReturn(1);
25652567
$this->bundleCollection->expects($this->once())->method('create')->willReturn($selectionCollection);
25662568

app/code/Magento/Bundle/Test/Unit/Pricing/Render/FinalPriceBoxTest.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
namespace Magento\Bundle\Test\Unit\Pricing\Render;
77

88
use Magento\Bundle\Pricing\Render\FinalPriceBox;
9-
use Magento\Bundle\Pricing\Price;
109
use Magento\Catalog\Pricing\Price\CustomOptionPrice;
1110

1211
class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
@@ -40,7 +39,7 @@ public function testShowRangePrice($optMinValue, $optMaxValue, $custMinValue, $c
4039
$enableCustomOptionMocks = ($optMinValue == $optMaxValue);
4140

4241
$priceInfo = $this->getMock(\Magento\Framework\Pricing\PriceInfo\Base::class, [], [], '', false);
43-
$bundleOptionPrice = $this->getMockBuilder(\Magento\Bundle\Pricing\Price\BundleOptionPrice::class)
42+
$bundlePrice = $this->getMockBuilder(\Magento\Bundle\Pricing\Price\FinalPrice::class)
4443
->disableOriginalConstructor()
4544
->getMock();
4645
$customOptionPrice = $this->getMockBuilder(\Magento\Catalog\Pricing\Price\CustomOptionPrice::class)
@@ -53,20 +52,20 @@ public function testShowRangePrice($optMinValue, $optMaxValue, $custMinValue, $c
5352

5453
$priceInfo->expects($this->at(0))
5554
->method('getPrice')
56-
->with(Price\BundleOptionPrice::PRICE_CODE)
57-
->will($this->returnValue($bundleOptionPrice));
55+
->with(\Magento\Bundle\Pricing\Price\FinalPrice::PRICE_CODE)
56+
->will($this->returnValue($bundlePrice));
5857
if ($enableCustomOptionMocks) {
5958
$priceInfo->expects($this->at(1))
6059
->method('getPrice')
6160
->with(CustomOptionPrice::PRICE_CODE)
6261
->will($this->returnValue($customOptionPrice));
6362
}
6463

65-
$bundleOptionPrice->expects($this->once())
66-
->method('getValue')
64+
$bundlePrice->expects($this->once())
65+
->method('getMinimalPrice')
6766
->will($this->returnValue($optMinValue));
68-
$bundleOptionPrice->expects($this->once())
69-
->method('getMaxValue')
67+
$bundlePrice->expects($this->once())
68+
->method('getMaximalPrice')
7069
->will($this->returnValue($optMaxValue));
7170

7271
if ($enableCustomOptionMocks) {

0 commit comments

Comments
 (0)