Skip to content

Commit a083717

Browse files
Merge pull request #2091 from magento-trigger/MAGETWO-86533-MediaGalleryImage-Inside-Form
Magetwo 86533 media gallery image inside form
2 parents c166940 + f26b717 commit a083717

File tree

69 files changed

+1979
-291
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1979
-291
lines changed

app/code/Magento/Catalog/Model/Category.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,22 @@ public function getImageUrl($attributeCode = 'image')
650650
$image = $this->getData($attributeCode);
651651
if ($image) {
652652
if (is_string($image)) {
653-
$url = $this->_storeManager->getStore()->getBaseUrl(
653+
$store = $this->_storeManager->getStore();
654+
655+
$isRelativeUrl = substr($image, 0, 1) === '/';
656+
657+
$mediaBaseUrl = $store->getBaseUrl(
654658
\Magento\Framework\UrlInterface::URL_TYPE_MEDIA
655-
) . 'catalog/category/' . $image;
659+
);
660+
661+
if ($isRelativeUrl) {
662+
$url = $image;
663+
} else {
664+
$url = $mediaBaseUrl
665+
. ltrim(\Magento\Catalog\Model\Category\FileInfo::ENTITY_MEDIA_PATH, '/')
666+
. '/'
667+
. $image;
668+
}
656669
} else {
657670
throw new \Magento\Framework\Exception\LocalizedException(
658671
__('Something went wrong while getting the image url.')

app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Model\Category\Attribute\Backend;
77

8+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
810
/**
911
* Catalog category image attribute backend model
1012
*
@@ -95,6 +97,11 @@ public function beforeSave($object)
9597
$attributeName = $this->getAttribute()->getName();
9698
$value = $object->getData($attributeName);
9799

100+
if ($this->fileResidesOutsideCategoryDir($value)) {
101+
// use relative path for image attribute so we know it's outside of category dir when we fetch it
102+
$value[0]['name'] = $value[0]['url'];
103+
}
104+
98105
if ($imageName = $this->getUploadedImageName($value)) {
99106
$object->setData($this->additionalData . $attributeName, $value);
100107
$object->setData($attributeName, $imageName);
@@ -131,6 +138,26 @@ private function isTmpFileAvailable($value)
131138
return is_array($value) && isset($value[0]['tmp_name']);
132139
}
133140

141+
/**
142+
* Check for file path resides outside of category media dir. The URL will be a path including pub/media if true
143+
*
144+
* @param array|null $value
145+
* @return bool
146+
*/
147+
private function fileResidesOutsideCategoryDir($value)
148+
{
149+
if (!is_array($value) || !isset($value[0]['url'])) {
150+
return false;
151+
}
152+
153+
$fileUrl = ltrim($value[0]['url'], '/');
154+
$baseMediaDir = $this->_filesystem->getUri(DirectoryList::MEDIA);
155+
156+
$usingPathRelativeToBase = strpos($fileUrl, $baseMediaDir) === 0;
157+
158+
return $usingPathRelativeToBase;
159+
}
160+
134161
/**
135162
* Save uploaded file and set its name to category
136163
*
@@ -148,6 +175,7 @@ public function afterSave($object)
148175
$this->_logger->critical($e);
149176
}
150177
}
178+
151179
return $this;
152180
}
153181
}

app/code/Magento/Catalog/Model/Category/DataProvider.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,12 +492,20 @@ private function convertValues($category, $categoryData)
492492
unset($categoryData[$attributeCode]);
493493

494494
$fileName = $category->getData($attributeCode);
495-
if ($this->getFileInfo()->isExist($fileName)) {
496-
$stat = $this->getFileInfo()->getStat($fileName);
497-
$mime = $this->getFileInfo()->getMimeType($fileName);
495+
$fileInfo = $this->getFileInfo();
496+
497+
if ($fileInfo->isExist($fileName)) {
498+
$stat = $fileInfo->getStat($fileName);
499+
$mime = $fileInfo->getMimeType($fileName);
500+
501+
$categoryData[$attributeCode][0]['name'] = basename($fileName);
502+
503+
if ($fileInfo->isBeginsWithMediaDirectoryPath($fileName)) {
504+
$categoryData[$attributeCode][0]['url'] = $fileName;
505+
} else {
506+
$categoryData[$attributeCode][0]['url'] = $category->getImageUrl($attributeCode);
507+
}
498508

499-
$categoryData[$attributeCode][0]['name'] = $fileName;
500-
$categoryData[$attributeCode][0]['url'] = $category->getImageUrl($attributeCode);
501509
$categoryData[$attributeCode][0]['size'] = isset($stat) ? $stat['size'] : 0;
502510
$categoryData[$attributeCode][0]['type'] = $mime;
503511
}

app/code/Magento/Catalog/Model/Category/FileInfo.php

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\Framework\File\Mime;
1010
use Magento\Framework\Filesystem;
1111
use Magento\Framework\Filesystem\Directory\WriteInterface;
12+
use Magento\Framework\Filesystem\Directory\ReadInterface;
1213

1314
/**
1415
* Class FileInfo
@@ -37,6 +38,11 @@ class FileInfo
3738
*/
3839
private $mediaDirectory;
3940

41+
/**
42+
* @var ReadInterface
43+
*/
44+
private $baseDirectory;
45+
4046
/**
4147
* @param Filesystem $filesystem
4248
* @param Mime $mime
@@ -62,6 +68,20 @@ private function getMediaDirectory()
6268
return $this->mediaDirectory;
6369
}
6470

71+
/**
72+
* Get Base Directory read instance
73+
*
74+
* @return ReadInterface
75+
*/
76+
private function getBaseDirectory()
77+
{
78+
if (!isset($this->baseDirectory)) {
79+
$this->baseDirectory = $this->filesystem->getDirectoryRead(DirectoryList::ROOT);
80+
}
81+
82+
return $this->baseDirectory;
83+
}
84+
6585
/**
6686
* Retrieve MIME type of requested file
6787
*
@@ -70,7 +90,7 @@ private function getMediaDirectory()
7090
*/
7191
public function getMimeType($fileName)
7292
{
73-
$filePath = self::ENTITY_MEDIA_PATH . '/' . ltrim($fileName, '/');
93+
$filePath = $this->getFilePath($fileName);
7494
$absoluteFilePath = $this->getMediaDirectory()->getAbsolutePath($filePath);
7595

7696
$result = $this->mime->getMimeType($absoluteFilePath);
@@ -85,7 +105,7 @@ public function getMimeType($fileName)
85105
*/
86106
public function getStat($fileName)
87107
{
88-
$filePath = self::ENTITY_MEDIA_PATH . '/' . ltrim($fileName, '/');
108+
$filePath = $this->getFilePath($fileName);
89109

90110
$result = $this->getMediaDirectory()->stat($filePath);
91111
return $result;
@@ -99,9 +119,65 @@ public function getStat($fileName)
99119
*/
100120
public function isExist($fileName)
101121
{
102-
$filePath = self::ENTITY_MEDIA_PATH . '/' . ltrim($fileName, '/');
122+
$filePath = $this->getFilePath($fileName);
103123

104124
$result = $this->getMediaDirectory()->isExist($filePath);
105125
return $result;
106126
}
127+
128+
/**
129+
* Construct and return file subpath based on filename relative to media directory
130+
*
131+
* @param string $fileName
132+
* @return string
133+
*/
134+
private function getFilePath($fileName)
135+
{
136+
$filePath = ltrim($fileName, '/');
137+
138+
$mediaDirectoryRelativeSubpath = $this->getMediaDirectoryPathRelativeToBaseDirectoryPath();
139+
$isFileNameBeginsWithMediaDirectoryPath = $this->isBeginsWithMediaDirectoryPath($fileName);
140+
141+
// if the file is not using a relative path, it resides in the catalog/category media directory
142+
$fileIsInCategoryMediaDir = !$isFileNameBeginsWithMediaDirectoryPath;
143+
144+
if ($fileIsInCategoryMediaDir) {
145+
$filePath = self::ENTITY_MEDIA_PATH . '/' . $filePath;
146+
} else {
147+
$filePath = substr($filePath, strlen($mediaDirectoryRelativeSubpath));
148+
}
149+
150+
return $filePath;
151+
}
152+
153+
/**
154+
* Checks for whether $fileName string begins with media directory path
155+
*
156+
* @param string $fileName
157+
* @return bool
158+
*/
159+
public function isBeginsWithMediaDirectoryPath($fileName)
160+
{
161+
$filePath = ltrim($fileName, '/');
162+
163+
$mediaDirectoryRelativeSubpath = $this->getMediaDirectoryPathRelativeToBaseDirectoryPath();
164+
$isFileNameBeginsWithMediaDirectoryPath = strpos($filePath, $mediaDirectoryRelativeSubpath) === 0;
165+
166+
return $isFileNameBeginsWithMediaDirectoryPath;
167+
}
168+
169+
/**
170+
* Get media directory subpath relative to base directory path
171+
*
172+
* @return string
173+
*/
174+
private function getMediaDirectoryPathRelativeToBaseDirectoryPath()
175+
{
176+
$baseDirectoryPath = $this->getBaseDirectory()->getAbsolutePath();
177+
$mediaDirectoryPath = $this->getMediaDirectory()->getAbsolutePath();
178+
179+
$mediaDirectoryRelativeSubpath = substr($mediaDirectoryPath, strlen($baseDirectoryPath));
180+
181+
return $mediaDirectoryRelativeSubpath;
182+
}
107183
}

app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Test\Unit\Model\Category\Attribute\Backend;
77

8+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
810
class ImageTest extends \PHPUnit\Framework\TestCase
911
{
1012
/**
@@ -27,6 +29,11 @@ class ImageTest extends \PHPUnit\Framework\TestCase
2729
*/
2830
private $logger;
2931

32+
/**
33+
* @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject
34+
*/
35+
private $filesystem;
36+
3037
protected function setUp()
3138
{
3239
$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -59,6 +66,9 @@ protected function setUp()
5966
\Magento\Catalog\Model\ImageUploader::class,
6067
['moveFileFromTmp']
6168
);
69+
70+
$this->filesystem = $this->getMockBuilder(\Magento\Framework\Filesystem::class)->disableOriginalConstructor()
71+
->getMock();
6272
}
6373

6474
/**
@@ -144,6 +154,38 @@ public function testBeforeSaveAttributeFileName()
144154
$this->assertEquals('test123.jpg', $object->getTestAttribute());
145155
}
146156

157+
public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir()
158+
{
159+
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class, [
160+
'filesystem' => $this->filesystem
161+
]);
162+
163+
$model->setAttribute($this->attribute);
164+
165+
$this->filesystem
166+
->expects($this->once())
167+
->method('getUri')
168+
->with(DirectoryList::MEDIA)
169+
->willReturn('pub/media');
170+
171+
$object = new \Magento\Framework\DataObject([
172+
'test_attribute' => [
173+
[
174+
'name' => '/test123.jpg',
175+
'url' => '/pub/media/wysiwyg/test123.jpg',
176+
]
177+
]
178+
]);
179+
180+
$model->beforeSave($object);
181+
182+
$this->assertEquals('/pub/media/wysiwyg/test123.jpg', $object->getTestAttribute());
183+
$this->assertEquals(
184+
[['name' => '/pub/media/wysiwyg/test123.jpg', 'url' => '/pub/media/wysiwyg/test123.jpg']],
185+
$object->getData('_additional_data_test_attribute')
186+
);
187+
}
188+
147189
public function testBeforeSaveTemporaryAttribute()
148190
{
149191
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class);

0 commit comments

Comments
 (0)