-
Notifications
You must be signed in to change notification settings - Fork 154
Small image URL added to the product data #132
Conversation
@@ -259,6 +259,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ | |||
meta_description: String @doc(description: "A brief overview of the product for search results listings, maximum 255 characters") | |||
image: String @doc(description: "The relative path to the main image on the product page") | |||
small_image: String @doc(description: "The relative path to the small image, which is used on catalog pages") | |||
small_image_url: String @doc(description: "The small image URL, which is used on catalog pages") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\SmallImageUrl") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presence of both small_image
and small_image_url
may confuse developer. We should find another names or provide more details in the description. Also seems like similar pairs should be added for image
and thumbnail
. As an alternative solution, a path to media files may be part of a config type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rogyar how about having the following structure
small_image: ProductImage
type ProductImage
{
url: String
path: String
}
and then re-use it for other image types?
@misha-kotov please provide a reference to the related tickets for other image types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ticket for other image types #174
$product = $value['model']; | ||
|
||
/* If small_image is not loaded for product, need to load it separately */ | ||
if (!$product->getSmallImage()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the use case for it to be not loaded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's loaded when we specify both small_image
and small_image_url
in the GraphQl request. If we specify only small_image_url
we don't have any information about the small image and cannot use catalogImageHelper
for the image URL generation.
$area->load(Area::PART_DESIGN); | ||
|
||
$smallImageURL = $this->catalogImageHelper->init($product, 'product_small_image')->getUrl(); | ||
$product->getMediaAttributes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need this part to generate a correct URL to the image. The product media gallery does not contain any information about the product image URL (only relative path). Upon a product image URL generation, the system takes into account some factors (like static content signing). The loaded area is also taken into account (in the core image retrieving flow). That's why we need to use these operations.
By removing the area loading, for example, we will always have a path (incorrect) to the placeholder instead of image URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we need $product->getMediaAttributes()
call specifically? It looks like temporal coupling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right. It was an initial solution and I tried to reuse as much Magento core approaches as possible. Unfortunately, we have the temporal coupling here there in the core. I'm going to dig deeper and find more clear way for that. But, probably, we will need to introduce some new logic within a scope of this task for images URL generation that is different that we have in the code to avoid temporal coupling and other issues (especially performance issues).
/** | ||
* Retrieves small image from the product gallery image | ||
* | ||
* @param $productImages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please specify argument type.
$response = $this->graphQlQuery($query); | ||
|
||
self::assertArrayHasKey('small_image_url', $response['products']['items'][0]); | ||
self::assertContains('placeholder/small_image.jpg', $response['products']['items'][0]['small_image_url']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we should verify that the image can be loaded using returned URL. Can be done just with curl request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address several comments above
} | ||
|
||
/* Design area is necessary to return the correct storefront image URL (or a placeholder) */ | ||
$area = $this->areaList->getArea(Area::AREA_FRONTEND); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to avoid area emulation. Instead we can copy configuration from storefront di.xml
to graphql di.xml
. @rogyar could you please check how much configuration need to be copied to make it work without area emulation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I will try to figure it out
@@ -43,7 +44,7 @@ public function resolve( | |||
array $args = null | |||
): array { | |||
if (!isset($value['model'])) { | |||
throw new \LogicException(__("Cannot resolve entity model")); | |||
throw new GraphQlInputException(__('"model" value should be specified')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? Client knows nothing about the model. It must be passed from the parent resolver. I think before the change we had correct exception, the only change I would made is remove translation:
throw new \LogicException("Cannot resolve entity model");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#189
Has been created
…info -- Update benchmarks scenarios according to updated GraphQL Schema
Description
This PR adds an extra field to the
ProductInterface
with image URL. We already have thesmall_image
field with information about the image path. However, the image path information is not very useful for PWA applications that build a list of products and require rather URLs than some data that needs to be parsed.Fixed Issues (if relevant)
Manual testing scenarios