Skip to content

Commit 241b77d

Browse files
committed
Merge remote-tracking branch 'origin/MC-17765' into 2.3-develop-pr59
2 parents dedea8c + ddaccac commit 241b77d

File tree

8 files changed

+211
-54
lines changed

8 files changed

+211
-54
lines changed

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

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Catalog\Model\Category\Attribute\Backend;
77

88
use Magento\Framework\App\Filesystem\DirectoryList;
9+
use Magento\Framework\File\Uploader;
910

1011
/**
1112
* Catalog category image attribute backend model
@@ -71,7 +72,7 @@ public function __construct(
7172
/**
7273
* Gets image name from $value array.
7374
*
74-
* Will return empty string in a case when $value is not an array
75+
* Will return empty string in a case when $value is not an array.
7576
*
7677
* @param array $value Attribute value
7778
* @return string
@@ -86,9 +87,28 @@ private function getUploadedImageName($value)
8687
}
8788

8889
/**
89-
* Avoiding saving potential upload data to DB
90+
* Check that image name exists in catalog/category directory and return new image name if it already exists.
9091
*
91-
* Will set empty image attribute value if image was not uploaded
92+
* @param string $imageName
93+
* @return string
94+
*/
95+
private function checkUniqueImageName(string $imageName): string
96+
{
97+
$imageUploader = $this->getImageUploader();
98+
$mediaDirectory = $this->_filesystem->getDirectoryWrite(DirectoryList::MEDIA);
99+
$imageAbsolutePath = $mediaDirectory->getAbsolutePath(
100+
$imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $imageName
101+
);
102+
103+
$imageName = Uploader::getNewFilename($imageAbsolutePath);
104+
105+
return $imageName;
106+
}
107+
108+
/**
109+
* Avoiding saving potential upload data to DB.
110+
*
111+
* Will set empty image attribute value if image was not uploaded.
92112
*
93113
* @param \Magento\Framework\DataObject $object
94114
* @return $this
@@ -105,6 +125,7 @@ public function beforeSave($object)
105125
}
106126

107127
if ($imageName = $this->getUploadedImageName($value)) {
128+
$imageName = $this->checkUniqueImageName($imageName);
108129
$object->setData($this->additionalData . $attributeName, $value);
109130
$object->setData($attributeName, $imageName);
110131
} elseif (!is_string($value)) {
@@ -160,6 +181,7 @@ private function fileResidesOutsideCategoryDir($value)
160181
if (!$baseMediaDir) {
161182
return false;
162183
}
184+
163185
return strpos($fileUrl, $baseMediaDir) === 0;
164186
}
165187

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Model;
77

8+
use Magento\Framework\File\Uploader;
9+
810
/**
911
* Catalog image uploader
1012
*/
@@ -199,7 +201,14 @@ public function moveFileFromTmp($imageName)
199201
$baseTmpPath = $this->getBaseTmpPath();
200202
$basePath = $this->getBasePath();
201203

202-
$baseImagePath = $this->getFilePath($basePath, $imageName);
204+
$baseImagePath = $this->getFilePath(
205+
$basePath,
206+
Uploader::getNewFileName(
207+
$this->mediaDirectory->getAbsolutePath(
208+
$this->getFilePath($basePath, $imageName)
209+
)
210+
)
211+
);
203212
$baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName);
204213

205214
try {

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

Lines changed: 84 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
namespace Magento\Catalog\Test\Unit\Model\Category\Attribute\Backend;
77

88
use Magento\Framework\App\Filesystem\DirectoryList;
9+
use Magento\Framework\Filesystem\Directory\WriteInterface;
910

11+
/**
12+
* Test for Magento\Catalog\Model\Category\Attribute\Backend\Image class.
13+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
14+
*/
1015
class ImageTest extends \PHPUnit\Framework\TestCase
1116
{
1217
/**
@@ -67,7 +72,7 @@ protected function setUp()
6772

6873
$this->imageUploader = $this->createPartialMock(
6974
\Magento\Catalog\Model\ImageUploader::class,
70-
['moveFileFromTmp']
75+
['moveFileFromTmp', 'getBasePath']
7176
);
7277

7378
$this->filesystem = $this->getMockBuilder(\Magento\Framework\Filesystem::class)->disableOriginalConstructor()
@@ -95,9 +100,7 @@ public function testBeforeSaveValueDeletion($value)
95100
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class);
96101
$model->setAttribute($this->attribute);
97102

98-
$object = new \Magento\Framework\DataObject([
99-
'test_attribute' => $value
100-
]);
103+
$object = new \Magento\Framework\DataObject(['test_attribute' => $value]);
101104

102105
$model->beforeSave($object);
103106

@@ -132,9 +135,7 @@ public function testBeforeSaveValueInvalid($value)
132135
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class);
133136
$model->setAttribute($this->attribute);
134137

135-
$object = new \Magento\Framework\DataObject([
136-
'test_attribute' => $value
137-
]);
138+
$object = new \Magento\Framework\DataObject(['test_attribute' => $value]);
138139

139140
$model->beforeSave($object);
140141

@@ -146,14 +147,25 @@ public function testBeforeSaveValueInvalid($value)
146147
*/
147148
public function testBeforeSaveAttributeFileName()
148149
{
149-
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class);
150-
$model->setAttribute($this->attribute);
150+
$model = $this->setUpModelForAfterSave();
151+
$mediaDirectoryMock = $this->createMock(WriteInterface::class);
152+
$this->filesystem->expects($this->once())
153+
->method('getDirectoryWrite')
154+
->with(DirectoryList::MEDIA)
155+
->willReturn($mediaDirectoryMock);
156+
$this->imageUploader->expects($this->once())->method('getBasePath')->willReturn('base/path');
157+
$mediaDirectoryMock->expects($this->once())
158+
->method('getAbsolutePath')
159+
->with('base/path/test123.jpg')
160+
->willReturn('absolute/path/base/path/test123.jpg');
151161

152-
$object = new \Magento\Framework\DataObject([
153-
'test_attribute' => [
154-
['name' => 'test123.jpg']
162+
$object = new \Magento\Framework\DataObject(
163+
[
164+
'test_attribute' => [
165+
['name' => 'test123.jpg'],
166+
],
155167
]
156-
]);
168+
);
157169

158170
$model->beforeSave($object);
159171

@@ -165,30 +177,37 @@ public function testBeforeSaveAttributeFileName()
165177
*/
166178
public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir()
167179
{
168-
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class, [
169-
'filesystem' => $this->filesystem
170-
]);
171-
180+
$model = $this->setUpModelForAfterSave();
172181
$model->setAttribute($this->attribute);
173182

183+
$mediaDirectoryMock = $this->createMock(WriteInterface::class);
184+
$this->filesystem->expects($this->once())
185+
->method('getDirectoryWrite')
186+
->with(DirectoryList::MEDIA)
187+
->willReturn($mediaDirectoryMock);
174188
$this->filesystem
175189
->expects($this->once())
176190
->method('getUri')
177191
->with(DirectoryList::MEDIA)
178192
->willReturn('pub/media');
193+
$mediaDirectoryMock->expects($this->once())
194+
->method('getAbsolutePath')
195+
->willReturn('/pub/media/wysiwyg/test123.jpg');
179196

180-
$object = new \Magento\Framework\DataObject([
181-
'test_attribute' => [
182-
[
183-
'name' => '/test123.jpg',
184-
'url' => '/pub/media/wysiwyg/test123.jpg',
185-
]
197+
$object = new \Magento\Framework\DataObject(
198+
[
199+
'test_attribute' => [
200+
[
201+
'name' => 'test123.jpg',
202+
'url' => '/pub/media/wysiwyg/test123.jpg',
203+
],
204+
],
186205
]
187-
]);
206+
);
188207

189208
$model->beforeSave($object);
190209

191-
$this->assertEquals('/pub/media/wysiwyg/test123.jpg', $object->getTestAttribute());
210+
$this->assertEquals('test123.jpg', $object->getTestAttribute());
192211
$this->assertEquals(
193212
[['name' => '/pub/media/wysiwyg/test123.jpg', 'url' => '/pub/media/wysiwyg/test123.jpg']],
194213
$object->getData('_additional_data_test_attribute')
@@ -200,20 +219,31 @@ public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir()
200219
*/
201220
public function testBeforeSaveTemporaryAttribute()
202221
{
203-
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class);
222+
$model = $this->setUpModelForAfterSave();
204223
$model->setAttribute($this->attribute);
205224

206-
$object = new \Magento\Framework\DataObject([
207-
'test_attribute' => [
208-
['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg']
225+
$mediaDirectoryMock = $this->createMock(WriteInterface::class);
226+
$this->filesystem->expects($this->once())
227+
->method('getDirectoryWrite')
228+
->with(DirectoryList::MEDIA)
229+
->willReturn($mediaDirectoryMock);
230+
231+
$object = new \Magento\Framework\DataObject(
232+
[
233+
'test_attribute' => [
234+
['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'],
235+
],
209236
]
210-
]);
237+
);
211238

212239
$model->beforeSave($object);
213240

214-
$this->assertEquals([
215-
['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg']
216-
], $object->getData('_additional_data_test_attribute'));
241+
$this->assertEquals(
242+
[
243+
['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'],
244+
],
245+
$object->getData('_additional_data_test_attribute')
246+
);
217247
}
218248

219249
/**
@@ -224,9 +254,7 @@ public function testBeforeSaveAttributeStringValue()
224254
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class);
225255
$model->setAttribute($this->attribute);
226256

227-
$object = new \Magento\Framework\DataObject([
228-
'test_attribute' => 'test123.jpg'
229-
]);
257+
$object = new \Magento\Framework\DataObject(['test_attribute' => 'test123.jpg']);
230258

231259
$model->beforeSave($object);
232260

@@ -245,18 +273,26 @@ private function setUpModelForAfterSave()
245273

246274
$objectManagerMock->expects($this->any())
247275
->method('get')
248-
->will($this->returnCallback(function ($class, $params = []) use ($imageUploaderMock) {
249-
if ($class == \Magento\Catalog\CategoryImageUpload::class) {
250-
return $imageUploaderMock;
251-
}
252-
253-
return $this->objectManager->get($class, $params);
254-
}));
255-
256-
$model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class, [
257-
'objectManager' => $objectManagerMock,
258-
'logger' => $this->logger
259-
]);
276+
->will(
277+
$this->returnCallback(
278+
function ($class, $params = []) use ($imageUploaderMock) {
279+
if ($class == \Magento\Catalog\CategoryImageUpload::class) {
280+
return $imageUploaderMock;
281+
}
282+
283+
return $this->objectManager->get($class, $params);
284+
}
285+
)
286+
);
287+
288+
$model = $this->objectManager->getObject(
289+
\Magento\Catalog\Model\Category\Attribute\Backend\Image::class,
290+
[
291+
'objectManager' => $objectManagerMock,
292+
'logger' => $this->logger,
293+
'filesystem' => $this->filesystem,
294+
]
295+
);
260296
$this->objectManager->setBackwardCompatibleProperty($model, 'imageUploader', $this->imageUploader);
261297

262298
return $model->setAttribute($this->attribute);

dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ protected function setUp()
4747
$this->imageUploader = $this->objectManager->create(
4848
\Magento\Catalog\Model\ImageUploader::class,
4949
[
50-
'baseTmpPath' => $this->mediaDirectory->getRelativePath('tmp'),
51-
'basePath' => __DIR__,
50+
'baseTmpPath' => 'catalog/tmp/category',
51+
'basePath' => 'catalog/category',
5252
'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'],
5353
'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png']
5454
]
@@ -79,6 +79,24 @@ public function testSaveFileToTmpDir(): void
7979
$this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($filePath)));
8080
}
8181

82+
/**
83+
* Test that method rename files when move it with the same name into base directory.
84+
*
85+
* @return void
86+
* @magentoDataFixture Magento/Catalog/_files/catalog_category_image.php
87+
* @magentoDataFixture Magento/Catalog/_files/catalog_tmp_category_image.php
88+
*/
89+
public function testMoveFileFromTmp(): void
90+
{
91+
$expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . 'magento_small_image_1.jpg';
92+
93+
$this->assertFileNotExists($this->mediaDirectory->getAbsolutePath($expectedFilePath));
94+
95+
$this->imageUploader->moveFileFromTmp('magento_small_image.jpg');
96+
97+
$this->assertFileExists($this->mediaDirectory->getAbsolutePath($expectedFilePath));
98+
}
99+
82100
/**
83101
* @expectedException \Magento\Framework\Exception\LocalizedException
84102
* @expectedExceptionMessage File validation failed.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
10+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
11+
12+
/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
13+
$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class)
14+
->getDirectoryWrite(DirectoryList::MEDIA);
15+
$fileName = 'magento_small_image.jpg';
16+
$filePath = 'catalog/category/' . $fileName;
17+
$mediaDirectory->create('catalog/category');
18+
19+
copy(__DIR__ . DIRECTORY_SEPARATOR . $fileName, $mediaDirectory->getAbsolutePath($filePath));
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
10+
/** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */
11+
$mediaDirectory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
12+
\Magento\Framework\Filesystem::class
13+
)->getDirectoryWrite(
14+
DirectoryList::MEDIA
15+
);
16+
17+
$mediaDirectory->delete('catalog/category');
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
10+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
11+
12+
/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
13+
$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class)
14+
->getDirectoryWrite(DirectoryList::MEDIA);
15+
$fileName = 'magento_small_image.jpg';
16+
$tmpFilePath = 'catalog/tmp/category/' . $fileName;
17+
$mediaDirectory->create('catalog/tmp/category');
18+
19+
copy(__DIR__ . DIRECTORY_SEPARATOR . $fileName, $mediaDirectory->getAbsolutePath($tmpFilePath));

0 commit comments

Comments
 (0)