Skip to content

Commit 9b84004

Browse files
committed
Merge remote-tracking branch 'origin/MC-15991-category-image' into MC-21691
2 parents 030c85f + baa0003 commit 9b84004

File tree

6 files changed

+190
-1
lines changed

6 files changed

+190
-1
lines changed

app/code/Magento/CatalogGraphQl/Model/Config/CategoryAttributeReader.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,24 @@ class CategoryAttributeReader implements ReaderInterface
5151
*/
5252
private $collectionFactory;
5353

54+
/**
55+
* @var array
56+
*/
57+
private $categoryAttributeResolvers;
58+
5459
/**
5560
* @param Type $typeLocator
5661
* @param CollectionFactory $collectionFactory
62+
* @param array $categoryAttributeResolvers
5763
*/
5864
public function __construct(
5965
Type $typeLocator,
60-
CollectionFactory $collectionFactory
66+
CollectionFactory $collectionFactory,
67+
array $categoryAttributeResolvers = []
6168
) {
6269
$this->typeLocator = $typeLocator;
6370
$this->collectionFactory = $collectionFactory;
71+
$this->categoryAttributeResolvers = $categoryAttributeResolvers;
6472
}
6573

6674
/**
@@ -93,6 +101,9 @@ public function read($scope = null) : array
93101
$data['fields'][$attributeCode]['name'] = $attributeCode;
94102
$data['fields'][$attributeCode]['type'] = $locatedType;
95103
$data['fields'][$attributeCode]['arguments'] = [];
104+
if (isset($this->categoryAttributeResolvers[$attributeCode])) {
105+
$data['fields'][$attributeCode]['resolver'] = $this->categoryAttributeResolvers[$attributeCode];
106+
}
96107
}
97108

98109
$config['CategoryInterface'] = $data;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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\Category;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Query\ResolverInterface;
12+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13+
use Magento\Framework\Exception\LocalizedException;
14+
use Magento\Store\Api\Data\StoreInterface;
15+
use Magento\Framework\Filesystem\DirectoryList;
16+
17+
/**
18+
* Resolve category image to a fully qualified URL
19+
*/
20+
class Image implements ResolverInterface
21+
{
22+
/** @var DirectoryList */
23+
private $directoryList;
24+
25+
/**
26+
* @param DirectoryList $directoryList
27+
*/
28+
public function __construct(DirectoryList $directoryList)
29+
{
30+
$this->directoryList = $directoryList;
31+
}
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
public function resolve(
37+
Field $field,
38+
$context,
39+
ResolveInfo $info,
40+
array $value = null,
41+
array $args = null
42+
) {
43+
if (!isset($value['model'])) {
44+
throw new LocalizedException(__('"model" value should be specified'));
45+
}
46+
/** @var \Magento\Catalog\Model\Category $category */
47+
$category = $value['model'];
48+
$imagePath = $category->getImage();
49+
if (empty($imagePath)) {
50+
return null;
51+
}
52+
/** @var StoreInterface $store */
53+
$store = $context->getExtensionAttributes()->getStore();
54+
$baseUrl = $store->getBaseUrl('media');
55+
56+
$mediaPath = $this->directoryList->getUrlPath('media');
57+
$pos = strpos($imagePath, $mediaPath);
58+
if ($pos !== false) {
59+
$imagePath = substr($imagePath, $pos + strlen($mediaPath), strlen($baseUrl));
60+
}
61+
$imageUrl = rtrim($baseUrl, '/') . '/' . ltrim($imagePath, '/');
62+
63+
return $imageUrl;
64+
}
65+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,12 @@
141141
<type name="Magento\Catalog\Block\Product\ImageFactory">
142142
<plugin name="designLoader" type="Magento\CatalogGraphQl\Plugin\DesignLoader" />
143143
</type>
144+
145+
<type name="Magento\CatalogGraphQl\Model\Config\CategoryAttributeReader">
146+
<arguments>
147+
<argument name="categoryAttributeResolvers" xsi:type="array">
148+
<item name="image" xsi:type="string">Magento\CatalogGraphQl\Model\Resolver\Category\Image</item>
149+
</argument>
150+
</arguments>
151+
</type>
144152
</config>

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Catalog\Model\CategoryRepository;
1414
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1515
use Magento\Framework\DataObject;
16+
use Magento\Store\Model\StoreManagerInterface;
1617
use Magento\TestFramework\ObjectManager;
1718
use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException;
1819
use Magento\TestFramework\TestCase\GraphQlAbstract;
@@ -553,6 +554,54 @@ public function testBreadCrumbs()
553554
$this->assertEquals($expectedResponse, $response);
554555
}
555556

557+
/**
558+
* Test category image is returned as full url (not relative path)
559+
*
560+
* @magentoApiDataFixture Magento/Catalog/_files/catalog_category_with_image.php
561+
*/
562+
public function testCategoryImage()
563+
{
564+
$categoryCollection = $this->objectManager->get(CategoryCollection::class);
565+
$categoryModel = $categoryCollection
566+
->addAttributeToSelect('image')
567+
->addAttributeToFilter('name', ['eq' => 'Parent Image Category'])
568+
->getFirstItem();
569+
$categoryId = $categoryModel->getId();
570+
571+
$query = <<<QUERY
572+
{
573+
categoryList(filters: {ids: {in: ["$categoryId"]}}) {
574+
id
575+
name
576+
url_key
577+
image
578+
children {
579+
id
580+
name
581+
url_key
582+
image
583+
}
584+
585+
}
586+
}
587+
QUERY;
588+
589+
$response = $this->graphQlQuery($query);
590+
$this->assertArrayNotHasKey('errors', $response);
591+
$this->assertNotEmpty($response['categoryList']);
592+
$categoryList = $response['categoryList'];
593+
$storeBaseUrl = $this->objectManager->get(StoreManagerInterface::class)->getStore()->getBaseUrl('media');
594+
$expectedImageUrl = rtrim($storeBaseUrl, '/'). '/' . ltrim($categoryModel->getImage(), '/');
595+
596+
$this->assertEquals($categoryId, $categoryList[0]['id']);
597+
$this->assertEquals('Parent Image Category', $categoryList[0]['name']);
598+
$this->assertEquals($expectedImageUrl, $categoryList[0]['image']);
599+
600+
$childCategory = $categoryList[0]['children'][0];
601+
$this->assertEquals('Child Image Category', $childCategory['name']);
602+
$this->assertEquals($expectedImageUrl, $childCategory['image']);
603+
}
604+
556605
/**
557606
* @param ProductInterface $product
558607
* @param array $actualResponse
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
require_once 'catalog_category_image.php';
8+
9+
/** @var $category \Magento\Catalog\Model\Category */
10+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
11+
12+
$categoryParent = $objectManager->create(\Magento\Catalog\Model\Category::class);
13+
$categoryParent->setName('Parent Image Category')
14+
->setPath('1/2')
15+
->setLevel(2)
16+
->setImage($filePath)
17+
->setAvailableSortBy('name')
18+
->setDefaultSortBy('name')
19+
->setIsActive(true)
20+
->setPosition(1)
21+
->save();
22+
23+
$categoryChild = $objectManager->create(\Magento\Catalog\Model\Category::class);
24+
$categoryChild->setName('Child Image Category')
25+
->setPath($categoryParent->getPath())
26+
->setLevel(3)
27+
->setImage($filePath)
28+
->setAvailableSortBy('name')
29+
->setDefaultSortBy('name')
30+
->setIsActive(true)
31+
->setPosition(2)
32+
->save();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
/** @var \Magento\Framework\ObjectManagerInterface $objectManager */
8+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
9+
10+
/** @var \Magento\Framework\Registry $registry */
11+
$registry = $objectManager->get(\Magento\Framework\Registry::class);
12+
13+
$registry->unregister('isSecureArea');
14+
$registry->register('isSecureArea', true);
15+
16+
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
17+
$collection = $objectManager->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class);
18+
$collection
19+
->addAttributeToFilter('name', ['in' => ['Parent Image Category', 'Child Image Category']])
20+
->load()
21+
->delete();
22+
23+
$registry->unregister('isSecureArea');
24+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)