Skip to content

Commit ebcf4b2

Browse files
authored
Merge pull request #200 from magento-performance/perf-configurable
[Performance] MAGETWO-54682: [Customer] Fast load of product options
2 parents 7426d3d + 6a0c73b commit ebcf4b2

File tree

81 files changed

+2541
-414
lines changed

Some content is hidden

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

81 files changed

+2541
-414
lines changed

app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,58 @@ class Media extends Product\Attribute\Backend\AbstractMedia
2222
*/
2323
public function afterLoad($object)
2424
{
25-
$attribute = $this->getAttribute();
26-
$attrCode = $attribute->getAttributeCode();
25+
$mediaEntries = $this->getResource()->loadProductGalleryByAttributeId(
26+
$object,
27+
$this->getAttribute()->getId()
28+
);
29+
$this->addMediaDataToProduct(
30+
$object,
31+
$mediaEntries
32+
);
33+
34+
return $object;
35+
}
36+
37+
/**
38+
* @param Product $product
39+
* @param array $mediaEntries
40+
* @return $this
41+
*/
42+
public function addMediaDataToProduct(Product $product, array $mediaEntries)
43+
{
44+
$attrCode = $this->getAttribute()->getAttributeCode();
2745
$value = [];
2846
$value['images'] = [];
2947
$value['values'] = [];
30-
$localAttributes = ['label', 'position', 'disabled'];
3148

32-
$mediaEntries = $this->getResource()->loadProductGalleryByAttributeId($object, $attribute->getId());
3349
foreach ($mediaEntries as $mediaEntry) {
34-
foreach ($localAttributes as $localAttribute) {
35-
if ($mediaEntry[$localAttribute] === null) {
36-
$mediaEntry[$localAttribute] = $this->findDefaultValue($localAttribute, $mediaEntry);
37-
}
38-
}
50+
$mediaEntry = $this->substituteNullsWithDefaultValues($mediaEntry);
3951
$value['images'][] = $mediaEntry;
4052
}
41-
$object->setData($attrCode, $value);
53+
$product->setData($attrCode, $value);
4254

43-
return $object;
55+
return $this;
56+
}
57+
58+
/**
59+
* @param array $rawData
60+
* @return array
61+
*/
62+
private function substituteNullsWithDefaultValues(array $rawData)
63+
{
64+
$processedData = [];
65+
foreach ($rawData as $key => $rawValue) {
66+
if (null !== $rawValue) {
67+
$processedValue = $rawValue;
68+
} elseif (isset($rawData[$key . '_default'])) {
69+
$processedValue = $rawData[$key . '_default'];
70+
} else {
71+
$processedValue = null;
72+
}
73+
$processedData[$key] = $processedValue;
74+
}
75+
76+
return $processedData;
4477
}
4578

4679
/**
@@ -341,6 +374,7 @@ protected function copyImage($file)
341374
}
342375

343376
/**
377+
* @deprecated
344378
* @param string $key
345379
* @param string[] &$image
346380
* @return string

app/code/Magento/Catalog/Model/Product/Link.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public function getAttributeTypeTable($type)
136136
public function getProductCollection()
137137
{
138138
$collection = $this->_productCollectionFactory->create()->setLinkModel($this);
139-
$this->stockHelper->addInStockFilterToCollection($collection);
139+
$this->stockHelper->addIsInStockFilterToCollection($collection);
140140
return $collection;
141141
}
142142

app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,4 +818,30 @@ public function afterDelete()
818818
$this->_eavConfig->clear();
819819
return parent::afterDelete();
820820
}
821+
822+
/**
823+
* @inheritdoc
824+
*/
825+
public function __sleep()
826+
{
827+
return array_diff(
828+
parent::__sleep(),
829+
['_indexerEavProcessor', '_productFlatIndexerProcessor', '_productFlatIndexerHelper', 'attrLockValidator']
830+
);
831+
}
832+
833+
/**
834+
* @inheritdoc
835+
*/
836+
public function __wakeup()
837+
{
838+
parent::__wakeup();
839+
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
840+
$this->_indexerEavProcessor = $objectManager->get(\Magento\Catalog\Model\Indexer\Product\Flat\Processor::class);
841+
$this->_productFlatIndexerProcessor = $objectManager->get(
842+
\Magento\Catalog\Model\Indexer\Product\Eav\Processor::class
843+
);
844+
$this->_productFlatIndexerHelper = $objectManager->get(\Magento\Catalog\Helper\Product\Flat\Indexer::class);
845+
$this->attrLockValidator = $objectManager->get(LockValidatorInterface::class);
846+
}
821847
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Media.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend;
1010

1111
use Magento\Catalog\Model\Product;
12+
use Magento\Store\Model\Store;
1213

1314
/**
1415
* Catalog product media gallery attribute backend resource
@@ -133,6 +134,23 @@ public function getMainTableAlias()
133134
* @throws \Magento\Framework\Exception\LocalizedException
134135
*/
135136
protected function createBaseLoadSelect($entityId, $storeId, $attributeId)
137+
{
138+
$select = $this->createBatchBaseSelect($storeId, $attributeId);
139+
140+
$select = $select->where(
141+
'entity.entity_id = ?',
142+
$entityId
143+
);
144+
return $select;
145+
}
146+
147+
/**
148+
* @param int $storeId
149+
* @param int $attributeId
150+
* @return \Magento\Framework\DB\Select
151+
* @throws \Magento\Framework\Exception\LocalizedException
152+
*/
153+
public function createBatchBaseSelect($storeId, $attributeId)
136154
{
137155
$connection = $this->getConnection();
138156

@@ -161,7 +179,6 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId)
161179
[
162180
$mainTableAlias . '.value_id = value.value_id',
163181
$connection->quoteInto('value.store_id = ?', (int)$storeId),
164-
$connection->quoteInto('value.entity_id = ?', (int)$entityId)
165182
]
166183
),
167184
['label', 'position', 'disabled']
@@ -171,8 +188,7 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId)
171188
' AND ',
172189
[
173190
$mainTableAlias . '.value_id = default_value.value_id',
174-
'default_value.store_id = 0',
175-
$connection->quoteInto('default_value.entity_id = ?', (int)$entityId)
191+
$connection->quoteInto('default_value.store_id = ?', Store::DEFAULT_STORE_ID),
176192
]
177193
),
178194
['label_default' => 'label', 'position_default' => 'position', 'disabled_default' => 'disabled']
@@ -181,11 +197,9 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId)
181197
$attributeId
182198
)->where(
183199
$mainTableAlias . '.disabled = 0'
184-
)->where(
185-
'entity.entity_id = ?',
186-
$entityId
187-
)
188-
->order($positionCheckSql . ' ' . \Magento\Framework\DB\Select::SQL_ASC);
200+
)->order(
201+
$positionCheckSql . ' ' . \Magento\Framework\DB\Select::SQL_ASC
202+
);
189203

190204
return $select;
191205
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
1313
use Magento\Customer\Api\GroupManagementInterface;
1414
use Magento\Framework\DB\Select;
15+
use Magento\Framework\App\ObjectManager;
1516
use Magento\Store\Model\Store;
17+
use Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Media;
1618

1719
/**
1820
* Product collection
@@ -242,7 +244,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
242244
protected $dateTime;
243245

244246
/**
245-
* @var GroupManagementInterface
247+
* @var \Magento\Customer\Api\GroupManagementInterface
246248
*/
247249
protected $_groupManagement;
248250

@@ -253,6 +255,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
253255
*/
254256
protected $needToAddWebsiteNamesToResult;
255257

258+
/**
259+
* @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Media
260+
*/
261+
private $mediaGalleryResource;
262+
256263
/**
257264
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
258265
* @param \Psr\Log\LoggerInterface $logger
@@ -2155,6 +2162,59 @@ public function addPriceDataFieldFilter($comparisonFormat, $fields)
21552162
return $this;
21562163
}
21572164

2165+
/**
2166+
* Add media gallery data to loaded items
2167+
*
2168+
* @return $this
2169+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
2170+
* @SuppressWarnings(PHPMD.NPathComplexity)
2171+
*/
2172+
public function addMediaGalleryData()
2173+
{
2174+
if ($this->getFlag('media_gallery_added')) {
2175+
return $this;
2176+
}
2177+
2178+
$mediaGalleries = [];
2179+
if (!$this->count()) {
2180+
return $this;
2181+
}
2182+
2183+
/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
2184+
$attribute = $this->getAttribute('media_gallery');
2185+
$select = $this->getMediaGalleryResource()->createBatchBaseSelect(
2186+
$this->getStoreId(),
2187+
$attribute->getAttributeId()
2188+
);
2189+
2190+
foreach ($this->getConnection()->fetchAll($select) as $row) {
2191+
$mediaGalleries[$row['entity_id']][] = $row;
2192+
}
2193+
2194+
/* @var $backend \Magento\Catalog\Model\Product\Attribute\Backend\Media */
2195+
$backend = $attribute->getBackend();
2196+
2197+
foreach ($this->getItems() as $item) {
2198+
$mediaEntries = isset($mediaGalleries[$item->getId()]) ? $mediaGalleries[$item->getId()] : [];
2199+
$backend->addMediaDataToProduct($item, $mediaEntries);
2200+
}
2201+
2202+
$this->setFlag('media_gallery_added', true);
2203+
return $this;
2204+
}
2205+
2206+
/**
2207+
* @deprecated
2208+
* @return \Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Media
2209+
*/
2210+
private function getMediaGalleryResource()
2211+
{
2212+
if (null === $this->mediaGalleryResource) {
2213+
$this->mediaGalleryResource = ObjectManager::getInstance()->get(Media::class);
2214+
}
2215+
return $this->mediaGalleryResource;
2216+
}
2217+
21582218
/**
21592219
* Clear collection
21602220
*
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\ResourceModel\Product\Indexer;
7+
8+
use Magento\Catalog\Model\Product;
9+
use Magento\Framework\DB\Select;
10+
use Magento\Store\Model\Store;
11+
use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface;
12+
13+
class LinkedProductSelectBuilderByIndexPrice implements LinkedProductSelectBuilderInterface
14+
{
15+
/**
16+
* @var \Magento\Store\Model\StoreManagerInterface
17+
*/
18+
private $storeManager;
19+
20+
/**
21+
* @var \Magento\Framework\App\ResourceConnection
22+
*/
23+
private $resource;
24+
25+
/**
26+
* @var \Magento\Customer\Model\Session
27+
*/
28+
private $customerSession;
29+
30+
/**
31+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
32+
* @param \Magento\Framework\App\ResourceConnection $resourceConnection
33+
* @param \Magento\Customer\Model\Session $customerSession
34+
*/
35+
public function __construct(
36+
\Magento\Store\Model\StoreManagerInterface $storeManager,
37+
\Magento\Framework\App\ResourceConnection $resourceConnection,
38+
\Magento\Customer\Model\Session $customerSession
39+
) {
40+
$this->storeManager = $storeManager;
41+
$this->resource = $resourceConnection;
42+
$this->customerSession = $customerSession;
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function build($productId)
49+
{
50+
return [$this->resource->getConnection()->select()
51+
->from(['t' => $this->resource->getTableName('catalog_product_index_price')], 'entity_id')
52+
->joinInner(
53+
['link' => $this->resource->getTableName('catalog_product_relation')],
54+
'link.child_id = t.entity_id',
55+
[]
56+
)->where('link.parent_id = ? ', $productId)
57+
->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId())
58+
->where('t.customer_group_id = ?', $this->customerSession->getCustomerGroupId())
59+
->order('t.min_price ' . Select::SQL_ASC)
60+
->limit(1)];
61+
}
62+
}

0 commit comments

Comments
 (0)