Skip to content

Commit

Permalink
Merge pull request #5066 from magento-honey-badgers/MC-23091-2.3.5
Browse files Browse the repository at this point in the history
[honey] MC-23091: Optimize product queries to obtain better wall time
  • Loading branch information
cpartica authored Dec 2, 2019
2 parents 54bd0d8 + 59a60e5 commit f6405d5
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 146 deletions.
8 changes: 5 additions & 3 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Exception\LocalizedException;

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

$result = function () use ($value) {
$data = $this->productDataProvider->getProductBySku($value['sku']);
$data = $value['product'] ?? $this->productDataProvider->getProductBySku($value['sku']);
if (empty($data)) {
return null;
}
if (!isset($data['model'])) {
throw new LocalizedException(__('"model" value should be specified'));
}
$productModel = $data['model'];
/** @var \Magento\Catalog\Model\Product $productModel */
$data = $productModel->getData();
Expand All @@ -79,10 +83,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
}
}
}

return array_replace($value, $data);
};

return $this->valueFactory->create($result);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ class Url implements ResolverInterface
* @var ImageFactory
*/
private $productImageFactory;

/**
* @var PlaceholderProvider
*/
private $placeholderProvider;

/**
* @var string[]
*/
private $placeholderCache = [];

/**
* @param ImageFactory $productImageFactory
* @param PlaceholderProvider $placeholderProvider
Expand Down Expand Up @@ -64,12 +70,8 @@ public function resolve(
if (isset($value['image_type'])) {
$imagePath = $product->getData($value['image_type']);
return $this->getImageUrl($value['image_type'], $imagePath);
}
if (isset($value['file'])) {
$image = $this->productImageFactory->create();
$image->setDestinationSubdir('image')->setBaseFile($value['file']);
$imageUrl = $image->getUrl();
return $imageUrl;
} elseif (isset($value['file'])) {
return $this->getImageUrl('image', $value['file']);
}
return [];
}
Expand All @@ -84,12 +86,16 @@ public function resolve(
*/
private function getImageUrl(string $imageType, ?string $imagePath): string
{
if (empty($imagePath) && !empty($this->placeholderCache[$imageType])) {
return $this->placeholderCache[$imageType];
}
$image = $this->productImageFactory->create();
$image->setDestinationSubdir($imageType)
->setBaseFile($imagePath);

if ($image->isBaseFilePlaceholder()) {
return $this->placeholderProvider->getPlaceholder($imageType);
$this->placeholderCache[$imageType] = $this->placeholderProvider->getPlaceholder($imageType);
return $this->placeholderCache[$imageType];
}

return $image->getUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@
*/
class ProductImage implements ResolverInterface
{
/** @var array */
private static $catalogImageLabelTypes = [
'image' => 'image_label',
'small_image' => 'small_image_label',
'thumbnail' => 'thumbnail_label'
];

/** @var array */
private $imageTypeLabels;

/**
* @param array $imageTypeLabels
*/
public function __construct(
array $imageTypeLabels = []
) {
$this->imageTypeLabels = array_replace(self::$catalogImageLabelTypes, $imageTypeLabels);
}

/**
* @inheritdoc
*/
Expand All @@ -34,11 +53,16 @@ public function resolve(

/** @var Product $product */
$product = $value['model'];
$imageType = $field->getName();
$label = $value['name'] ?? null;
if (isset($this->imageTypeLabels[$info->fieldName])
&& !empty($value[$this->imageTypeLabels[$info->fieldName]])) {
$label = $value[$this->imageTypeLabels[$info->fieldName]];
}

return [
'model' => $product,
'image_type' => $imageType,
'image_type' => $field->getName(),
'label' => $label
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ public function process(
/**
* Add attribute to collection select
*
* Add attributes to the collection where graphql fields names don't match attributes names, or if attributes exist
* on a nested level and they need to be loaded.
*
* Format of the attribute can be string or array while array can have different formats.
* Example: [
* 'price_range' =>
* [
* 'price' => 'price',
* 'price_type' => 'price_type',
* ],
* 'thumbnail' => //complex array where more than one attribute is needed to compute a value
* [
* 'label' =>
* [
* 'attribute' => 'thumbnail_label', // the actual attribute
* 'fallback_attribute' => 'name', //used as default value in case attribute value is null
* ],
* 'url' => 'thumbnail',
* ]
* ]
*
* @param Collection $collection
* @param string $attribute
*/
Expand All @@ -59,9 +80,7 @@ private function addAttribute(Collection $collection, string $attribute): void
if (isset($this->fieldToAttributeMap[$attribute])) {
$attributeMap = $this->fieldToAttributeMap[$attribute];
if (is_array($attributeMap)) {
foreach ($attributeMap as $attributeName) {
$collection->addAttributeToSelect($attributeName);
}
$this->addAttributeAsArray($collection, $attributeMap);
} else {
$collection->addAttributeToSelect($attributeMap);
}
Expand All @@ -70,4 +89,39 @@ private function addAttribute(Collection $collection, string $attribute): void
$collection->addAttributeToSelect($attribute);
}
}

/**
* Add an array defined attribute to the collection
*
* @param Collection $collection
* @param array $attributeMap
* @return void
*/
private function addAttributeAsArray(Collection $collection, array $attributeMap): void
{
foreach ($attributeMap as $attribute) {
if (is_array($attribute)) {
$this->addAttributeComplexArrayToCollection($collection, $attribute);
} else {
$collection->addAttributeToSelect($attribute);
}
}
}

/**
* Add a complex array defined attribute to the collection
*
* @param Collection $collection
* @param array $attribute
* @return void
*/
private function addAttributeComplexArrayToCollection(Collection $collection, array $attribute): void
{
if (isset($attribute['attribute'])) {
$collection->addAttributeToSelect($attribute['attribute']);
}
if (isset($attribute['fallback_attribute'])) {
$collection->addAttributeToSelect($attribute['fallback_attribute']);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ private function getProductFields(ResolveInfo $info): array
{
$fieldNames = [];
foreach ($info->fieldNodes as $node) {
if ($node->name->value !== 'products') {
if ($node->name->value !== 'products' && $node->name->value !== 'variants') {
continue;
}
foreach ($node->selectionSet->selections as $selection) {
if ($selection->name->value !== 'items') {
if ($selection->name->value !== 'items' && $selection->name->value !== 'product') {
continue;
}
$fieldNames[] = $this->collectProductFieldNames($selection, $fieldNames);
Expand Down
27 changes: 27 additions & 0 deletions app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,33 @@
<item name="price_range" xsi:type="array">
<item name="price" xsi:type="string">price</item>
</item>
<item name="thumbnail" xsi:type="array">
<item name="label" xsi:type="array">
<item name="attribute" xsi:type="string">thumbnail_label</item>
<item name="fallback_attribute" xsi:type="string">name</item>
</item>
<item name="url" xsi:type="string">thumbnail</item>
</item>
<item name="small_image" xsi:type="array">
<item name="label" xsi:type="array">
<item name="attribute" xsi:type="string">small_image_label</item>
<item name="fallback_attribute" xsi:type="string">name</item>
</item>
<item name="url" xsi:type="string">small_image</item>
</item>
<item name="image" xsi:type="array">
<item name="label" xsi:type="array">
<item name="attribute" xsi:type="string">image_label</item>
<item name="fallback_attribute" xsi:type="string">name</item>
</item>
<item name="url" xsi:type="string">image</item>
</item>
<item name="media_gallery" xsi:type="array">
<item name="label" xsi:type="array">
<item name="attribute" xsi:type="string">image_label</item>
<item name="fallback_attribute" xsi:type="string">name</item>
</item>
</item>
</argument>
</arguments>
</type>
Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the

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

type ProductImage implements MediaGalleryInterface @doc(description: "Product image information. Contains the image URL and label.") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ protected function loadOptions()
'use_default_value' => true
];
}
$item->setOptionsMap($values);
$values = array_values($values);
$item->setOptions($values);
}
Expand Down
Loading

0 comments on commit f6405d5

Please sign in to comment.