Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.

Small image URL added to the product data #132

Merged
merged 19 commits into from
Sep 26, 2018

Conversation

rogyar
Copy link
Contributor

@rogyar rogyar commented Jul 26, 2018

Description

This PR adds an extra field to the ProductInterface with image URL. We already have the small_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)

  1. 'small_image' in 'ProductInterface' does not have enough info #88 : 'small_image' in 'ProductInterface' does not have enough info

Manual testing scenarios

  1. Create a new product with/without an image
  2. Make the following request:
{
  products (search: "withimages") {
    items {
      small_image_url
    }
  }
}
  1. You should see the small image URL in the response:
{
  "data": {
    "products": {
      "items": [
        {
          "small_image_url": "http://docker.graphql.loc:8087/media/catalog/product/cache/0c40cc075c35680261029fa6d255feee/1/6/16262-11.jpg"
        }
      ]
    }
  }
}
  1. If the requested product does not have an image, a placeholder URL should be returned

@@ -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")

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

Copy link
Contributor

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.

Copy link
Contributor

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()) {
Copy link
Contributor

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?

Copy link
Contributor Author

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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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']);
Copy link
Contributor

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.

Copy link
Contributor

@paliarush paliarush left a 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);
Copy link
Contributor

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?

Copy link
Contributor Author

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'));
Copy link
Contributor

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");

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#189
Has been created

Valeriy Nayda added 2 commits September 20, 2018 17:28
@magento-engcom-team magento-engcom-team modified the milestones: Release: 2.3.0, Release: 2.3.1 Sep 20, 2018
@magento-engcom-team magento-engcom-team merged commit dad6575 into 2.3-develop Sep 26, 2018
@naydav naydav removed this from the Release: 2.3.1 milestone Dec 7, 2018
@naydav naydav deleted the 88-small-image-url branch April 12, 2019 19:36
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants