Skip to content

Commit f6405d5

Browse files
authored
Merge pull request #5066 from magento-honey-badgers/MC-23091-2.3.5
[honey] MC-23091: Optimize product queries to obtain better wall time
2 parents 54bd0d8 + 59a60e5 commit f6405d5

File tree

13 files changed

+212
-146
lines changed

13 files changed

+212
-146
lines changed

app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
1515
use Magento\Framework\GraphQl\Query\ResolverInterface;
1616
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
17+
use Magento\Framework\Exception\LocalizedException;
1718

1819
/**
1920
* @inheritdoc
@@ -63,10 +64,13 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
6364
$this->productDataProvider->addEavAttributes($fields);
6465

6566
$result = function () use ($value) {
66-
$data = $this->productDataProvider->getProductBySku($value['sku']);
67+
$data = $value['product'] ?? $this->productDataProvider->getProductBySku($value['sku']);
6768
if (empty($data)) {
6869
return null;
6970
}
71+
if (!isset($data['model'])) {
72+
throw new LocalizedException(__('"model" value should be specified'));
73+
}
7074
$productModel = $data['model'];
7175
/** @var \Magento\Catalog\Model\Product $productModel */
7276
$data = $productModel->getData();
@@ -79,10 +83,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
7983
}
8084
}
8185
}
82-
8386
return array_replace($value, $data);
8487
};
85-
8688
return $this->valueFactory->create($result);
8789
}
8890
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGallery/Label.php

Lines changed: 0 additions & 87 deletions
This file was deleted.

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGallery/Url.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,17 @@ class Url implements ResolverInterface
2424
* @var ImageFactory
2525
*/
2626
private $productImageFactory;
27+
2728
/**
2829
* @var PlaceholderProvider
2930
*/
3031
private $placeholderProvider;
3132

33+
/**
34+
* @var string[]
35+
*/
36+
private $placeholderCache = [];
37+
3238
/**
3339
* @param ImageFactory $productImageFactory
3440
* @param PlaceholderProvider $placeholderProvider
@@ -64,12 +70,8 @@ public function resolve(
6470
if (isset($value['image_type'])) {
6571
$imagePath = $product->getData($value['image_type']);
6672
return $this->getImageUrl($value['image_type'], $imagePath);
67-
}
68-
if (isset($value['file'])) {
69-
$image = $this->productImageFactory->create();
70-
$image->setDestinationSubdir('image')->setBaseFile($value['file']);
71-
$imageUrl = $image->getUrl();
72-
return $imageUrl;
73+
} elseif (isset($value['file'])) {
74+
return $this->getImageUrl('image', $value['file']);
7375
}
7476
return [];
7577
}
@@ -84,12 +86,16 @@ public function resolve(
8486
*/
8587
private function getImageUrl(string $imageType, ?string $imagePath): string
8688
{
89+
if (empty($imagePath) && !empty($this->placeholderCache[$imageType])) {
90+
return $this->placeholderCache[$imageType];
91+
}
8792
$image = $this->productImageFactory->create();
8893
$image->setDestinationSubdir($imageType)
8994
->setBaseFile($imagePath);
9095

9196
if ($image->isBaseFilePlaceholder()) {
92-
return $this->placeholderProvider->getPlaceholder($imageType);
97+
$this->placeholderCache[$imageType] = $this->placeholderProvider->getPlaceholder($imageType);
98+
return $this->placeholderCache[$imageType];
9399
}
94100

95101
return $image->getUrl();

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@
1818
*/
1919
class ProductImage implements ResolverInterface
2020
{
21+
/** @var array */
22+
private static $catalogImageLabelTypes = [
23+
'image' => 'image_label',
24+
'small_image' => 'small_image_label',
25+
'thumbnail' => 'thumbnail_label'
26+
];
27+
28+
/** @var array */
29+
private $imageTypeLabels;
30+
31+
/**
32+
* @param array $imageTypeLabels
33+
*/
34+
public function __construct(
35+
array $imageTypeLabels = []
36+
) {
37+
$this->imageTypeLabels = array_replace(self::$catalogImageLabelTypes, $imageTypeLabels);
38+
}
39+
2140
/**
2241
* @inheritdoc
2342
*/
@@ -34,11 +53,16 @@ public function resolve(
3453

3554
/** @var Product $product */
3655
$product = $value['model'];
37-
$imageType = $field->getName();
56+
$label = $value['name'] ?? null;
57+
if (isset($this->imageTypeLabels[$info->fieldName])
58+
&& !empty($value[$this->imageTypeLabels[$info->fieldName]])) {
59+
$label = $value[$this->imageTypeLabels[$info->fieldName]];
60+
}
3861

3962
return [
4063
'model' => $product,
41-
'image_type' => $imageType,
64+
'image_type' => $field->getName(),
65+
'label' => $label
4266
];
4367
}
4468
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,27 @@ public function process(
5151
/**
5252
* Add attribute to collection select
5353
*
54+
* Add attributes to the collection where graphql fields names don't match attributes names, or if attributes exist
55+
* on a nested level and they need to be loaded.
56+
*
57+
* Format of the attribute can be string or array while array can have different formats.
58+
* Example: [
59+
* 'price_range' =>
60+
* [
61+
* 'price' => 'price',
62+
* 'price_type' => 'price_type',
63+
* ],
64+
* 'thumbnail' => //complex array where more than one attribute is needed to compute a value
65+
* [
66+
* 'label' =>
67+
* [
68+
* 'attribute' => 'thumbnail_label', // the actual attribute
69+
* 'fallback_attribute' => 'name', //used as default value in case attribute value is null
70+
* ],
71+
* 'url' => 'thumbnail',
72+
* ]
73+
* ]
74+
*
5475
* @param Collection $collection
5576
* @param string $attribute
5677
*/
@@ -59,9 +80,7 @@ private function addAttribute(Collection $collection, string $attribute): void
5980
if (isset($this->fieldToAttributeMap[$attribute])) {
6081
$attributeMap = $this->fieldToAttributeMap[$attribute];
6182
if (is_array($attributeMap)) {
62-
foreach ($attributeMap as $attributeName) {
63-
$collection->addAttributeToSelect($attributeName);
64-
}
83+
$this->addAttributeAsArray($collection, $attributeMap);
6584
} else {
6685
$collection->addAttributeToSelect($attributeMap);
6786
}
@@ -70,4 +89,39 @@ private function addAttribute(Collection $collection, string $attribute): void
7089
$collection->addAttributeToSelect($attribute);
7190
}
7291
}
92+
93+
/**
94+
* Add an array defined attribute to the collection
95+
*
96+
* @param Collection $collection
97+
* @param array $attributeMap
98+
* @return void
99+
*/
100+
private function addAttributeAsArray(Collection $collection, array $attributeMap): void
101+
{
102+
foreach ($attributeMap as $attribute) {
103+
if (is_array($attribute)) {
104+
$this->addAttributeComplexArrayToCollection($collection, $attribute);
105+
} else {
106+
$collection->addAttributeToSelect($attribute);
107+
}
108+
}
109+
}
110+
111+
/**
112+
* Add a complex array defined attribute to the collection
113+
*
114+
* @param Collection $collection
115+
* @param array $attribute
116+
* @return void
117+
*/
118+
private function addAttributeComplexArrayToCollection(Collection $collection, array $attribute): void
119+
{
120+
if (isset($attribute['attribute'])) {
121+
$collection->addAttributeToSelect($attribute['attribute']);
122+
}
123+
if (isset($attribute['fallback_attribute'])) {
124+
$collection->addAttributeToSelect($attribute['fallback_attribute']);
125+
}
126+
}
73127
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/FieldSelection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ private function getProductFields(ResolveInfo $info): array
5050
{
5151
$fieldNames = [];
5252
foreach ($info->fieldNodes as $node) {
53-
if ($node->name->value !== 'products') {
53+
if ($node->name->value !== 'products' && $node->name->value !== 'variants') {
5454
continue;
5555
}
5656
foreach ($node->selectionSet->selections as $selection) {
57-
if ($selection->name->value !== 'items') {
57+
if ($selection->name->value !== 'items' && $selection->name->value !== 'product') {
5858
continue;
5959
}
6060
$fieldNames[] = $this->collectProductFieldNames($selection, $fieldNames);

app/code/Magento/CatalogGraphQl/etc/graphql/di.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,33 @@
134134
<item name="price_range" xsi:type="array">
135135
<item name="price" xsi:type="string">price</item>
136136
</item>
137+
<item name="thumbnail" xsi:type="array">
138+
<item name="label" xsi:type="array">
139+
<item name="attribute" xsi:type="string">thumbnail_label</item>
140+
<item name="fallback_attribute" xsi:type="string">name</item>
141+
</item>
142+
<item name="url" xsi:type="string">thumbnail</item>
143+
</item>
144+
<item name="small_image" xsi:type="array">
145+
<item name="label" xsi:type="array">
146+
<item name="attribute" xsi:type="string">small_image_label</item>
147+
<item name="fallback_attribute" xsi:type="string">name</item>
148+
</item>
149+
<item name="url" xsi:type="string">small_image</item>
150+
</item>
151+
<item name="image" xsi:type="array">
152+
<item name="label" xsi:type="array">
153+
<item name="attribute" xsi:type="string">image_label</item>
154+
<item name="fallback_attribute" xsi:type="string">name</item>
155+
</item>
156+
<item name="url" xsi:type="string">image</item>
157+
</item>
158+
<item name="media_gallery" xsi:type="array">
159+
<item name="label" xsi:type="array">
160+
<item name="attribute" xsi:type="string">image_label</item>
161+
<item name="fallback_attribute" xsi:type="string">name</item>
162+
</item>
163+
</item>
137164
</argument>
138165
</arguments>
139166
</type>

app/code/Magento/CatalogGraphQl/etc/schema.graphqls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the
198198

199199
interface MediaGalleryInterface @doc(description: "Contains basic information about a product image or video.") @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\MediaGalleryTypeResolver") {
200200
url: String @doc(description: "The URL of the product image or video.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGallery\\Url")
201-
label: String @doc(description: "The label of the product image or video.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGallery\\Label")
201+
label: String @doc(description: "The label of the product image or video.")
202202
}
203203

204204
type ProductImage implements MediaGalleryInterface @doc(description: "Product image information. Contains the image URL and label.") {

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ protected function loadOptions()
331331
'use_default_value' => true
332332
];
333333
}
334+
$item->setOptionsMap($values);
334335
$values = array_values($values);
335336
$item->setOptions($values);
336337
}

0 commit comments

Comments
 (0)