Skip to content

Commit 2891b2a

Browse files
committed
MC-31551: Category images are broken after migrating to 2.3.4
- refactor resolver
1 parent 9d66ee8 commit 2891b2a

File tree

3 files changed

+107
-14
lines changed

3 files changed

+107
-14
lines changed

app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Image.php

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use Magento\Framework\Exception\LocalizedException;
1414
use Magento\Store\Api\Data\StoreInterface;
1515
use Magento\Framework\Filesystem\DirectoryList;
16+
use Magento\Catalog\Model\Category\FileInfo;
17+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1618

1719
/**
1820
* Resolve category image to a fully qualified URL
@@ -22,12 +24,19 @@ class Image implements ResolverInterface
2224
/** @var DirectoryList */
2325
private $directoryList;
2426

27+
/** @var FileInfo */
28+
private $fileInfo;
29+
2530
/**
2631
* @param DirectoryList $directoryList
32+
* @param FileInfo $fileInfo
2733
*/
28-
public function __construct(DirectoryList $directoryList)
29-
{
34+
public function __construct(
35+
DirectoryList $directoryList,
36+
FileInfo $fileInfo
37+
) {
3038
$this->directoryList = $directoryList;
39+
$this->fileInfo = $fileInfo;
3140
}
3241

3342
/**
@@ -45,21 +54,38 @@ public function resolve(
4554
}
4655
/** @var \Magento\Catalog\Model\Category $category */
4756
$category = $value['model'];
48-
$imagePath = $category->getImage();
57+
$imagePath = $category->getData('image');
4958
if (empty($imagePath)) {
5059
return null;
5160
}
5261
/** @var StoreInterface $store */
5362
$store = $context->getExtensionAttributes()->getStore();
54-
$baseUrl = $store->getBaseUrl('media');
63+
$baseUrl = $store->getBaseUrl();
5564

56-
$mediaPath = $this->directoryList->getUrlPath('media');
57-
$pos = strpos($imagePath, $mediaPath);
58-
if ($pos !== false) {
59-
$imagePath = substr($imagePath, $pos + strlen($mediaPath));
65+
$filenameWithMedia = $this->fileInfo->isBeginsWithMediaDirectoryPath($imagePath)
66+
? $imagePath : $this->formatFileNameWithMediaCategoryFolder($imagePath);
67+
68+
if (!$this->fileInfo->isExist($filenameWithMedia)) {
69+
throw new GraphQlInputException(__('Category image not found.'));
6070
}
61-
$imageUrl = rtrim($baseUrl, '/') . '/' . ltrim($imagePath, '/');
6271

63-
return $imageUrl;
72+
// return full url
73+
return rtrim($baseUrl, '/') . $filenameWithMedia;
74+
}
75+
76+
/**
77+
* Format category media folder to filename
78+
*
79+
* @param string $fileName
80+
* @return string
81+
*/
82+
private function formatFileNameWithMediaCategoryFolder(string $fileName): string
83+
{
84+
return '/'
85+
. $this->directoryList->getUrlPath('media')
86+
. '/'
87+
. ltrim(FileInfo::ENTITY_MEDIA_PATH, '/')
88+
. '/'
89+
. basename($fileName);
6490
}
6591
}

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

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use Magento\Catalog\Model\CategoryRepository;
1414
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1515
use Magento\Framework\DataObject;
16+
use Magento\Framework\EntityManager\MetadataPool;
17+
use Magento\Store\Model\Store;
1618
use Magento\Store\Model\StoreManagerInterface;
1719
use Magento\TestFramework\ObjectManager;
1820
use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException;
@@ -33,10 +35,22 @@ class CategoryTest extends GraphQlAbstract
3335
*/
3436
private $categoryRepository;
3537

38+
/**
39+
* @var Store
40+
*/
41+
private $store;
42+
43+
/**
44+
* @var MetadataPool
45+
*/
46+
private $metadataPool;
47+
3648
protected function setUp()
3749
{
3850
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
3951
$this->categoryRepository = $this->objectManager->get(CategoryRepository::class);
52+
$this->store = $this->objectManager->get(Store::class);
53+
$this->metadataPool = $this->objectManager->get(MetadataPool::class);
4054
}
4155

4256
/**
@@ -211,7 +225,7 @@ public function testCategoriesTreeWithDisabledCategory()
211225
productImagePreview: products(pageSize: 1) {
212226
items {
213227
id
214-
}
228+
}
215229
}
216230
}
217231
}
@@ -557,17 +571,49 @@ public function testBreadCrumbs()
557571
/**
558572
* Test category image is returned as full url (not relative path)
559573
*
574+
* @param string $imagePrefix
560575
* @magentoApiDataFixture Magento/Catalog/_files/catalog_category_with_image.php
576+
* @dataProvider categoryImageDataProvider
561577
*/
562-
public function testCategoryImage()
578+
public function testCategoryImage(?string $imagePrefix)
563579
{
580+
/** @var CategoryCollection $categoryCollection */
564581
$categoryCollection = $this->objectManager->get(CategoryCollection::class);
565582
$categoryModel = $categoryCollection
566583
->addAttributeToSelect('image')
567584
->addAttributeToFilter('name', ['eq' => 'Parent Image Category'])
568585
->getFirstItem();
569586
$categoryId = $categoryModel->getId();
570587

588+
if ($imagePrefix !== null) {
589+
// update image to account for different stored image formats
590+
$connection = $categoryCollection->getConnection();
591+
$productLinkField = $this->metadataPool
592+
->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
593+
->getLinkField();
594+
595+
$defaultStoreId = $this->store->getId();
596+
597+
$imageAttributeValue = $imagePrefix . basename($categoryModel->getImage());
598+
599+
if (!empty($imageAttributeValue)) {
600+
$query = sprintf(
601+
'UPDATE %s SET `value` = "%s" ' .
602+
'WHERE `%s` = %d ' .
603+
'AND `store_id`= %d ' .
604+
'AND `attribute_id` = ' .
605+
'(SELECT `ea`.`attribute_id` FROM %s ea WHERE `ea`.`attribute_code` = "image" LIMIT 1)',
606+
$connection->getTableName('catalog_category_entity_varchar'),
607+
$imageAttributeValue,
608+
$productLinkField,
609+
$categoryModel->getData($productLinkField),
610+
$defaultStoreId,
611+
$connection->getTableName('eav_attribute')
612+
);
613+
$connection->query($query);
614+
}
615+
}
616+
571617
$query = <<<QUERY
572618
{
573619
categoryList(filters: {ids: {in: ["$categoryId"]}}) {
@@ -591,7 +637,7 @@ public function testCategoryImage()
591637
$this->assertNotEmpty($response['categoryList']);
592638
$categoryList = $response['categoryList'];
593639
$storeBaseUrl = $this->objectManager->get(StoreManagerInterface::class)->getStore()->getBaseUrl('media');
594-
$expectedImageUrl = rtrim($storeBaseUrl, '/'). '/' . ltrim($categoryModel->getImage(), '/');
640+
$expectedImageUrl = rtrim($storeBaseUrl, '/') . '/' . ltrim($categoryModel->getImage(), '/');
595641

596642
$this->assertEquals($categoryId, $categoryList[0]['id']);
597643
$this->assertEquals('Parent Image Category', $categoryList[0]['name']);
@@ -602,6 +648,27 @@ public function testCategoryImage()
602648
$this->assertEquals($expectedImageUrl, $childCategory['image']);
603649
}
604650

651+
/**
652+
* @return array
653+
*/
654+
public function categoryImageDataProvider(): array
655+
{
656+
return [
657+
'default_filename_strategy' => [
658+
'image_prefix' => null
659+
],
660+
'just_filename_strategy' => [
661+
'image_prefix' => ''
662+
],
663+
'with_pub_media_strategy' => [
664+
'image_prefix' => '/pub/media/catalog/category/'
665+
],
666+
'catalog_category_strategy' => [
667+
'image_prefix' => 'catalog/category/'
668+
],
669+
];
670+
}
671+
605672
/**
606673
* @param ProductInterface $product
607674
* @param array $actualResponse

dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_with_image.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* See COPYING.txt for license details.
55
*/
66

7-
require_once 'catalog_category_image.php';
7+
require 'catalog_category_image.php';
88

99
/** @var $category \Magento\Catalog\Model\Category */
1010
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();

0 commit comments

Comments
 (0)