Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/MC-32273' into 2.4-develop-pr17
Browse files Browse the repository at this point in the history
  • Loading branch information
serhii-balko committed Mar 17, 2020
2 parents cb4969c + 8302a56 commit a544049
Show file tree
Hide file tree
Showing 9 changed files with 357 additions and 13 deletions.
16 changes: 10 additions & 6 deletions app/code/Magento/Catalog/Model/Category/DataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* @api
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.TooManyFields)
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @since 101.0.0
*/
class DataProvider extends ModifierPoolDataProvider
Expand Down Expand Up @@ -176,6 +177,10 @@ class DataProvider extends ModifierPoolDataProvider
* @var AuthorizationInterface
*/
private $auth;
/**
* @var Image
*/
private $categoryImage;

/**
* @param string $name
Expand All @@ -196,6 +201,7 @@ class DataProvider extends ModifierPoolDataProvider
* @param ScopeOverriddenValue|null $scopeOverriddenValue
* @param ArrayManager|null $arrayManager
* @param FileInfo|null $fileInfo
* @param Image|null $categoryImage
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Expand All @@ -216,7 +222,8 @@ public function __construct(
?ArrayUtils $arrayUtils = null,
ScopeOverriddenValue $scopeOverriddenValue = null,
ArrayManager $arrayManager = null,
FileInfo $fileInfo = null
FileInfo $fileInfo = null,
?Image $categoryImage = null
) {
$this->eavValidationRules = $eavValidationRules;
$this->collection = $categoryCollectionFactory->create();
Expand All @@ -232,6 +239,7 @@ public function __construct(
ObjectManager::getInstance()->get(ScopeOverriddenValue::class);
$this->arrayManager = $arrayManager ?: ObjectManager::getInstance()->get(ArrayManager::class);
$this->fileInfo = $fileInfo ?: ObjectManager::getInstance()->get(FileInfo::class);
$this->categoryImage = $categoryImage ?? ObjectManager::getInstance()->get(Image::class);

parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool);
}
Expand Down Expand Up @@ -601,11 +609,7 @@ private function convertValues($category, $categoryData): array
// phpcs:ignore Magento2.Functions.DiscouragedFunction
$categoryData[$attributeCode][0]['name'] = basename($fileName);

if ($this->fileInfo->isBeginsWithMediaDirectoryPath($fileName)) {
$categoryData[$attributeCode][0]['url'] = $fileName;
} else {
$categoryData[$attributeCode][0]['url'] = $category->getImageUrl($attributeCode);
}
$categoryData[$attributeCode][0]['url'] = $this->categoryImage->getUrl($category, $attributeCode);

$categoryData[$attributeCode][0]['size'] = isset($stat) ? $stat['size'] : 0;
$categoryData[$attributeCode][0]['type'] = $mime;
Expand Down
11 changes: 11 additions & 0 deletions app/code/Magento/Catalog/Model/Category/FileInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,15 @@ private function getMediaDirectoryPathRelativeToBaseDirectoryPath(string $filePa

return $mediaDirectoryRelativeSubpath;
}

/**
* Get file relative path to media directory
*
* @param string $filename
* @return string
*/
public function getRelativePathToMediaDirectory(string $filename): string
{
return $this->getFilePath($filename);
}
}
75 changes: 75 additions & 0 deletions app/code/Magento/Catalog/Model/Category/Image.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\Model\Category;

use Magento\Catalog\Model\Category;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\StoreManagerInterface;

/**
* Category Image Service
*/
class Image
{
private const ATTRIBUTE_NAME = 'image';
/**
* @var FileInfo
*/
private $fileInfo;
/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* Initialize dependencies.
*
* @param FileInfo $fileInfo
* @param StoreManagerInterface $storeManager
*/
public function __construct(
FileInfo $fileInfo,
StoreManagerInterface $storeManager
) {
$this->fileInfo = $fileInfo;
$this->storeManager = $storeManager;
}
/**
* Resolve category image URL
*
* @param Category $category
* @param string $attributeCode
* @return string
* @throws LocalizedException
*/
public function getUrl(Category $category, string $attributeCode = self::ATTRIBUTE_NAME): string
{
$url = '';
$image = $category->getData($attributeCode);
if ($image) {
if (is_string($image)) {
$store = $this->storeManager->getStore();
$mediaBaseUrl = $store->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);
if ($this->fileInfo->isBeginsWithMediaDirectoryPath($image)) {
$relativePath = $this->fileInfo->getRelativePathToMediaDirectory($image);
$url = rtrim($mediaBaseUrl, '/') . '/' . ltrim($relativePath, '/');
} elseif (substr($image, 0, 1) !== '/') {
$url = rtrim($mediaBaseUrl, '/') . '/' . ltrim(FileInfo::ENTITY_MEDIA_PATH, '/') . '/' . $image;
} else {
$url = $image;
}
} else {
throw new LocalizedException(
__('Something went wrong while getting the image url.')
);
}
}
return $url;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Magento\Catalog\Model\Category\Attribute\Backend\Image;
use Magento\Catalog\Model\Category\DataProvider;
use Magento\Catalog\Model\Category\FileInfo;
use Magento\Catalog\Model\Category\Image as CategoryImage;
use Magento\Catalog\Model\CategoryFactory;
use Magento\Catalog\Model\ResourceModel\Category\Collection;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
Expand Down Expand Up @@ -98,6 +99,11 @@ class DataProviderTest extends TestCase
*/
private $auth;

/**
* @var CategoryImage|MockObject
*/
private $categoryImage;

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -155,6 +161,11 @@ protected function setUp()
$this->arrayUtils = $this->getMockBuilder(ArrayUtils::class)
->setMethods(['flatten'])
->disableOriginalConstructor()->getMock();

$this->categoryImage = $this->createPartialMock(
CategoryImage::class,
['getUrl']
);
}

/**
Expand Down Expand Up @@ -185,7 +196,8 @@ private function getModel()
'categoryFactory' => $this->categoryFactory,
'pool' => $this->modifierPool,
'auth' => $this->auth,
'arrayUtils' => $this->arrayUtils
'arrayUtils' => $this->arrayUtils,
'categoryImage' => $this->categoryImage,
]
);

Expand Down Expand Up @@ -324,8 +336,8 @@ public function testGetData()
$categoryMock->expects($this->once())
->method('getAttributes')
->willReturn(['image' => $attributeMock]);
$categoryMock->expects($this->once())
->method('getImageUrl')
$this->categoryImage->expects($this->once())
->method('getUrl')
->willReturn($categoryUrl);

$this->registry->expects($this->once())
Expand Down
146 changes: 146 additions & 0 deletions app/code/Magento/Catalog/Test/Unit/Model/Category/ImageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\Test\Unit\Model\Category;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Category\FileInfo;
use Magento\Catalog\Model\Category\Image;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManager;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* Test category image resolver
*/
class ImageTest extends TestCase
{
/**
* @var Store|MockObject
*/
private $store;
/**
* @var Category
*/
private $category;
/**
* @var Image
*/
private $model;

/**
* @inheritDoc
*/
protected function setUp()
{
$storeManager = $this->createPartialMock(StoreManager::class, ['getStore']);
$this->store = $this->createPartialMock(Store::class, ['getBaseUrl']);
$storeManager->method('getStore')->willReturn($this->store);
$objectManager = new ObjectManager($this);
$this->category = $objectManager->getObject(Category::class);
$this->model = $objectManager->getObject(
Image::class,
[
'storeManager' => $storeManager,
'fileInfo' => $this->getFileInfo()
]
);
}

/**
* Test that image URL resolver works correctly with different base URL format
*
* @param string $baseUrl
* @param string $imagePath
* @param string $url
* @dataProvider getUrlDataProvider
*/
public function testGetUrl(string $imagePath, string $baseUrl, string $url)
{
$this->store->method('getBaseUrl')
->with(UrlInterface::URL_TYPE_MEDIA)
->willReturn($baseUrl);
$this->category->setData('image_attr_code', $imagePath);
$this->assertEquals($url, $this->model->getUrl($this->category, 'image_attr_code'));
}

/**
* @return array
*/
public function getUrlDataProvider()
{
return [
[
'testimage',
'http://www.example.com/',
'http://www.example.com/catalog/category/testimage'
],
[
'testimage',
'http://www.example.com/pub/media/',
'http://www.example.com/pub/media/catalog/category/testimage'
],
[
'testimage',
'http://www.example.com/base/path/pub/media/',
'http://www.example.com/base/path/pub/media/catalog/category/testimage'
],
[
'/pub/media/catalog/category/testimage',
'http://www.example.com/pub/media/',
'http://www.example.com/pub/media/catalog/category/testimage'
],
[
'/pub/media/catalog/category/testimage',
'http://www.example.com/base/path/pub/media/',
'http://www.example.com/base/path/pub/media/catalog/category/testimage'
],
[
'/pub/media/posters/testimage',
'http://www.example.com/pub/media/',
'http://www.example.com/pub/media/posters/testimage'
],
[
'/pub/media/posters/testimage',
'http://www.example.com/base/path/pub/media/',
'http://www.example.com/base/path/pub/media/posters/testimage'
],
[
'',
'http://www.example.com/',
''
]
];
}

/**
* Get FileInfo mock
*
* @return MockObject
*/
private function getFileInfo(): MockObject
{
$mediaDir = 'pub/media';
$fileInfo = $this->createMock(FileInfo::class);
$fileInfo->method('isBeginsWithMediaDirectoryPath')
->willReturnCallback(
function ($path) use ($mediaDir) {
return strpos(ltrim($path, '/'), $mediaDir) === 0;
}
);
$fileInfo->method('getRelativePathToMediaDirectory')
->willReturnCallback(
function ($path) use ($mediaDir) {
return str_replace($mediaDir, '', $path);
}
);
return $fileInfo;
}
}
46 changes: 46 additions & 0 deletions app/code/Magento/Catalog/ViewModel/Category/Image.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\ViewModel\Category;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Category\Image as CategoryImage;
use Magento\Framework\View\Element\Block\ArgumentInterface;

/**
* Category image view model
*/
class Image implements ArgumentInterface
{
private const ATTRIBUTE_NAME = 'image';
/**
* @var CategoryImage
*/
private $image;

/**
* Initialize dependencies.
*
* @param CategoryImage $image
*/
public function __construct(CategoryImage $image)
{
$this->image = $image;
}

/**
* Resolve category image URL
*
* @param Category $category
* @param string $attributeCode
* @return string
*/
public function getUrl(Category $category, string $attributeCode = self::ATTRIBUTE_NAME): string
{
return $this->image->getUrl($category, $attributeCode);
}
}
Loading

0 comments on commit a544049

Please sign in to comment.