Skip to content

Commit 3aa119f

Browse files
author
Valeriy Nayda
committed
MAGETWO-65095: [Performance] Redundant objects created for configurable product
1 parent 412777e commit 3aa119f

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Catalog\Api\Data\ProductAttributeInterface;
99
use Magento\Catalog\Api\Data\ProductInterface;
10+
use Magento\Catalog\Api\Data\ProductInterfaceFactory;
1011
use Magento\Catalog\Api\ProductRepositoryInterface;
1112
use Magento\Catalog\Model\Config;
1213
use Magento\Framework\App\ObjectManager;
@@ -163,6 +164,11 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
163164
*/
164165
private $customerSession;
165166

167+
/**
168+
* @var ProductInterfaceFactory
169+
*/
170+
private $productFactory;
171+
166172
/**
167173
* @codingStandardsIgnoreStart/End
168174
*
@@ -184,6 +190,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
184190
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
185191
* @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
186192
* @param \Magento\Framework\Serialize\Serializer\Json $serializer
193+
* @param ProductInterfaceFactory $productFactory
187194
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
188195
*/
189196
public function __construct(
@@ -206,7 +213,8 @@ public function __construct(
206213
\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor,
207214
\Magento\Framework\Cache\FrontendInterface $cache = null,
208215
\Magento\Customer\Model\Session $customerSession = null,
209-
\Magento\Framework\Serialize\Serializer\Json $serializer = null
216+
\Magento\Framework\Serialize\Serializer\Json $serializer = null,
217+
ProductInterfaceFactory $productFactory = null
210218
) {
211219
$this->typeConfigurableFactory = $typeConfigurableFactory;
212220
$this->_eavAttributeFactory = $eavAttributeFactory;
@@ -218,6 +226,8 @@ public function __construct(
218226
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
219227
$this->cache = $cache;
220228
$this->customerSession = $customerSession;
229+
$this->productFactory = $productFactory ?: ObjectManager::getInstance()
230+
->get(ProductInterfaceFactory::class);
221231
parent::__construct(
222232
$catalogProductOption,
223233
$eavConfig,
@@ -529,15 +539,16 @@ public function getUsedProducts($product, $requiredAttributeIds = null)
529539
]
530540
)
531541
);
532-
$collection = $this->getUsedProductCollection($product);
533542
$data = $this->serializer->unserialize($this->getCache()->load($key));
534543
if (!empty($data)) {
535544
$usedProducts = [];
536545
foreach ($data as $item) {
537-
$productItem = $collection->getNewEmptyItem()->setData($item);
546+
$productItem = $this->productFactory->create();
547+
$productItem->setData($item);
538548
$usedProducts[] = $productItem;
539549
}
540550
} else {
551+
$collection = $this->getUsedProductCollection($product);
541552
$collection
542553
->setFlag('has_stock_status_filter', true)
543554
->addAttributeToSelect($this->getCatalogConfig()->getProductAttributes())

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
110110
*/
111111
protected $catalogConfig;
112112

113+
/**
114+
* @var \Magento\Catalog\Api\Data\ProductInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
115+
*/
116+
private $productFactory;
117+
113118
/**
114119
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
115120
*/
@@ -177,6 +182,10 @@ protected function setUp()
177182
->method('getMetadata')
178183
->with(ProductInterface::class)
179184
->willReturn($this->entityMetadata);
185+
$this->productFactory = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterfaceFactory::class)
186+
->setMethods(['create'])
187+
->disableOriginalConstructor()
188+
->getMock();
180189

181190
$this->_model = $this->_objectHelper->getObject(
182191
Configurable::class,
@@ -197,6 +206,7 @@ protected function setUp()
197206
'cache' => $this->cache,
198207
'catalogConfig' => $this->catalogConfig,
199208
'serializer' => $this->serializer,
209+
'productFactory' => $this->productFactory,
200210
]
201211
);
202212
$refClass = new \ReflectionClass(Configurable::class);
@@ -374,6 +384,50 @@ public function testGetUsedProducts()
374384
$this->_model->getUsedProducts($product);
375385
}
376386

387+
public function testGetUsedProductsWithDataInCache()
388+
{
389+
$product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
390+
->disableOriginalConstructor()
391+
->getMock();
392+
$childProduct = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
393+
->disableOriginalConstructor()
394+
->getMock();
395+
396+
$dataKey = '_cache_instance_products';
397+
$usedProductsData = [['first']];
398+
$usedProducts = [$childProduct];
399+
400+
$product->expects($this->once())
401+
->method('hasData')
402+
->with($dataKey)
403+
->willReturn(false);
404+
$product->expects($this->once())
405+
->method('setData')
406+
->with($dataKey, $usedProducts);
407+
$product->expects($this->any())
408+
->method('getData')
409+
->willReturnOnConsecutiveCalls(1, $usedProducts);
410+
411+
$childProduct->expects($this->once())
412+
->method('setData')
413+
->with($usedProductsData[0]);
414+
415+
$this->productFactory->expects($this->once())
416+
->method('create')
417+
->willReturn($childProduct);
418+
419+
$this->cache->expects($this->once())
420+
->method('load')
421+
->willReturn($usedProductsData);
422+
423+
$this->serializer->expects($this->once())
424+
->method('unserialize')
425+
->with($usedProductsData)
426+
->willReturn($usedProductsData);
427+
428+
self::assertEquals($usedProducts, $this->_model->getUsedProducts($product));
429+
}
430+
377431
/**
378432
* @param int $productStore
379433
*

0 commit comments

Comments
 (0)