Skip to content

Commit f584ae5

Browse files
ENGCOM-2993: Absolute image paths for the ProductInterface #183
- Merge Pull Request magento/graphql-ce#183 from magento/graphql-ce:174_absolute_image_paths_for_products - Merged commits: 1. 0400e32 2. 277c81f 3. 819b117 4. a636914 5. 0d191b7 6. 7867e91 7. bb4f601 8. 3d3b45f 9. c366d47 10. 0a9977f 11. b28d74a 12. 10fdcfc 13. 3196ebc 14. ddb64a5 15. 32baeb4
2 parents 53a8966 + 32baeb4 commit f584ae5

File tree

8 files changed

+328
-58
lines changed

8 files changed

+328
-58
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Product;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Query\ResolverInterface;
14+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
15+
16+
/**
17+
* Returns product's image data
18+
*/
19+
class ProductImage implements ResolverInterface
20+
{
21+
/**
22+
* @inheritdoc
23+
*/
24+
public function resolve(
25+
Field $field,
26+
$context,
27+
ResolveInfo $info,
28+
array $value = null,
29+
array $args = null
30+
): array {
31+
if (!isset($value['model'])) {
32+
throw new LocalizedException(__('"model" value should be specified'));
33+
}
34+
35+
/** @var Product $product */
36+
$product = $value['model'];
37+
$imageType = $field->getName();
38+
39+
return [
40+
'model' => $product,
41+
'image_type' => $imageType,
42+
];
43+
}
44+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
use Magento\Store\Model\StoreManagerInterface;
17+
18+
/**
19+
* Returns product's image label
20+
*/
21+
class Label implements ResolverInterface
22+
{
23+
/**
24+
* @var ProductResourceModel
25+
*/
26+
private $productResource;
27+
28+
/**
29+
* @var StoreManagerInterface
30+
*/
31+
private $storeManager;
32+
33+
/**
34+
* @param ProductResourceModel $productResource
35+
* @param StoreManagerInterface $storeManager
36+
*/
37+
public function __construct(
38+
ProductResourceModel $productResource,
39+
StoreManagerInterface $storeManager
40+
) {
41+
$this->productResource = $productResource;
42+
$this->storeManager = $storeManager;
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function resolve(
49+
Field $field,
50+
$context,
51+
ResolveInfo $info,
52+
array $value = null,
53+
array $args = null
54+
) {
55+
if (!isset($value['image_type'])) {
56+
throw new LocalizedException(__('"image_type" value should be specified'));
57+
}
58+
59+
if (!isset($value['model'])) {
60+
throw new LocalizedException(__('"model" value should be specified'));
61+
}
62+
63+
/** @var Product $product */
64+
$product = $value['model'];
65+
$imageType = $value['image_type'];
66+
$imagePath = $product->getData($imageType);
67+
$productId = (int)$product->getEntityId();
68+
69+
// null if image is not set
70+
if (null === $imagePath) {
71+
return $this->getAttributeValue($productId, 'name');
72+
}
73+
74+
$imageLabel = $this->getAttributeValue($productId, $imageType . '_label');
75+
if (null === $imageLabel) {
76+
$imageLabel = $this->getAttributeValue($productId, 'name');
77+
}
78+
79+
return $imageLabel;
80+
}
81+
82+
/**
83+
* Get attribute value
84+
*
85+
* @param int $productId
86+
* @param string $attributeCode
87+
* @return null|string Null if attribute value is not exists
88+
*/
89+
private function getAttributeValue(int $productId, string $attributeCode): ?string
90+
{
91+
$storeId = $this->storeManager->getStore()->getId();
92+
93+
$value = $this->productResource->getAttributeRawValue($productId, $attributeCode, $storeId);
94+
return is_array($value) && empty($value) ? null : $value;
95+
}
96+
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php renamed to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
declare(strict_types=1);
77

8-
namespace Magento\CatalogGraphQl\Model\Resolver\Product;
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage;
99

1010
use Magento\Catalog\Model\Product;
1111
use Magento\Catalog\Model\Product\ImageFactory;
@@ -15,13 +15,11 @@
1515
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1616

1717
/**
18-
* Returns product's image. If the image is not set, returns a placeholder
18+
* Returns product's image url
1919
*/
20-
class Image implements ResolverInterface
20+
class Url implements ResolverInterface
2121
{
2222
/**
23-
* Product image factory
24-
*
2523
* @var ImageFactory
2624
*/
2725
private $productImageFactory;
@@ -44,23 +42,36 @@ public function resolve(
4442
ResolveInfo $info,
4543
array $value = null,
4644
array $args = null
47-
): array {
45+
) {
46+
if (!isset($value['image_type'])) {
47+
throw new LocalizedException(__('"image_type" value should be specified'));
48+
}
49+
4850
if (!isset($value['model'])) {
4951
throw new LocalizedException(__('"model" value should be specified'));
5052
}
53+
5154
/** @var Product $product */
5255
$product = $value['model'];
53-
$imageType = $field->getName();
54-
$path = $product->getData($imageType);
56+
$imagePath = $product->getData($value['image_type']);
5557

58+
$imageUrl = $this->getImageUrl($value['image_type'], $imagePath);
59+
return $imageUrl;
60+
}
61+
62+
/**
63+
* Get image url
64+
*
65+
* @param string $imageType
66+
* @param string|null $imagePath Null if image is not set
67+
* @return string
68+
*/
69+
private function getImageUrl(string $imageType, ?string $imagePath): string
70+
{
5671
$image = $this->productImageFactory->create();
5772
$image->setDestinationSubdir($imageType)
58-
->setBaseFile($path);
73+
->setBaseFile($imagePath);
5974
$imageUrl = $image->getUrl();
60-
61-
return [
62-
'url' => $imageUrl,
63-
'path' => $path,
64-
];
75+
return $imageUrl;
6576
}
6677
}

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,13 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\
257257
meta_title: String @doc(description: "A string that is displayed in the title bar and tab of the browser and in search results lists")
258258
meta_keyword: String @doc(description: "A comma-separated list of keywords that are visible only to search engines")
259259
meta_description: String @doc(description: "A brief overview of the product for search results listings, maximum 255 characters")
260-
image: String @doc(description: "The relative path to the main image on the product page")
261-
small_image: ProductImage @doc(description: "The relative path to the small image, which is used on catalog pages") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Image")
262-
thumbnail: String @doc(description: "The relative path to the product's thumbnail image")
260+
image: ProductImage @doc(description: "The relative path to the main image on the product page") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage")
261+
small_image: ProductImage @doc(description: "The relative path to the small image, which is used on catalog pages") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage")
262+
thumbnail: ProductImage @doc(description: "The relative path to the product's thumbnail image") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage")
263263
new_from_date: String @doc(description: "The beginning date for new product listings, and determines if the product is featured as a new product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo")
264264
new_to_date: String @doc(description: "The end date for new product listings") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo")
265265
tier_price: Float @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached")
266266
options_container: String @doc(description: "If the product has multiple options, determines where they appear on the product page")
267-
image_label: String @doc(description: "The label assigned to a product image")
268-
small_image_label: String @doc(description: "The label assigned to a product's small image")
269-
thumbnail_label: String @doc(description: "The label assigned to a product's thumbnail image")
270267
created_at: String @doc(description: "Timestamp indicating when the product was created")
271268
updated_at: String @doc(description: "Timestamp indicating when the product was updated")
272269
country_of_manufacture: String @doc(description: "The product's country of origin")
@@ -352,9 +349,9 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the
352349
image_size_y: Int @doc(description: "The maximum height of an image")
353350
}
354351

355-
type ProductImage @doc(description: "Product image information. Contains image relative path and URL") {
356-
url: String
357-
path: String
352+
type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") {
353+
url: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Url")
354+
label: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Label")
358355
}
359356

360357
interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") {

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ public function testCategoryProducts()
141141
available_sort_by
142142
level
143143
}
144-
image
145-
image_label
144+
image { url, label }
146145
meta_description
147146
meta_keyword
148147
meta_title
@@ -225,16 +224,12 @@ public function testCategoryProducts()
225224
}
226225
short_description
227226
sku
228-
small_image {
229-
path
230-
}
231-
small_image_label
227+
small_image { url, label }
228+
thumbnail { url, label }
232229
special_from_date
233230
special_price
234231
special_to_date
235232
swatch_image
236-
thumbnail
237-
thumbnail_label
238233
tier_price
239234
tier_prices {
240235
customer_group_id

0 commit comments

Comments
 (0)