Skip to content

Commit 70207f4

Browse files
authored
Merge pull request #4792 from magento-tsg-csl3/MC-19539
[TSG-CSL3] For 2.2 (MC-19539)
2 parents 41c0af2 + e94ea09 commit 70207f4

File tree

5 files changed

+494
-4
lines changed

5 files changed

+494
-4
lines changed

app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,6 @@ public function duplicateImagesForVariations($productsData)
233233

234234
foreach ($simpleProductData['media_gallery']['images'] as $imageId => $image) {
235235
$image['variation_id'] = $variationId;
236-
if (isset($imagesForCopy[$imageId][0])) {
237-
// skip duplicate image for first product
238-
unset($imagesForCopy[$imageId][0]);
239-
}
240236
$imagesForCopy[$imageId][] = $image;
241237
}
242238
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
/**
3+
* Product initialization helper
4+
*
5+
* Copyright © Magento, Inc. All rights reserved.
6+
* See COPYING.txt for license details.
7+
*/
8+
declare(strict_types=1);
9+
10+
namespace Magento\ConfigurableProduct\Plugin\Controller\Adminhtml\Product\Initialization\Helper;
11+
12+
use Magento\Framework\App\Filesystem\DirectoryList;
13+
use Magento\Catalog\Model\Product;
14+
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper;
15+
use Magento\Framework\Filesystem;
16+
use Magento\Catalog\Model\Product\Media\Config as MediaConfig;
17+
use Magento\MediaStorage\Helper\File\Storage\Database;
18+
use Magento\Framework\Filesystem\Directory\WriteInterface;
19+
use Magento\Framework\App\RequestInterface;
20+
21+
/**
22+
* Class cleaning configuration tmp images
23+
*/
24+
class CleanConfigurationTmpImages
25+
{
26+
/**
27+
* @var Database
28+
*/
29+
private $fileStorageDb;
30+
31+
/**
32+
* @var MediaConfig
33+
*/
34+
private $mediaConfig;
35+
36+
/**
37+
* @var WriteInterface
38+
*/
39+
private $mediaDirectory;
40+
41+
/**
42+
* @var RequestInterface
43+
*/
44+
private $request;
45+
46+
/**
47+
* @param RequestInterface $request
48+
* @param Database $fileStorageDb
49+
* @param MediaConfig $mediaConfig
50+
* @param Filesystem $filesystem
51+
*/
52+
public function __construct(
53+
RequestInterface $request,
54+
Database $fileStorageDb,
55+
MediaConfig $mediaConfig,
56+
Filesystem $filesystem
57+
) {
58+
$this->request = $request;
59+
$this->fileStorageDb = $fileStorageDb;
60+
$this->mediaConfig = $mediaConfig;
61+
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
62+
}
63+
64+
/**
65+
* Clean Tmp configurable images
66+
*
67+
* @param Helper $subject
68+
* @param Product $configurableProduct
69+
*
70+
* @return Product
71+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
72+
*/
73+
public function afterInitialize(Helper $subject, Product $configurableProduct): Product
74+
{
75+
// Clean tmp
76+
$configurations = $this->getConfigurations();
77+
foreach ($configurations as $simpleProductData) {
78+
if (!isset($simpleProductData['media_gallery']['images'])) {
79+
continue;
80+
}
81+
foreach ($simpleProductData['media_gallery']['images'] as $image) {
82+
$file = $this->getFilenameFromTmp($image['file']);
83+
if ($this->fileStorageDb->checkDbUsage()) {
84+
$filename = $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getTmpMediaShortUrl($file));
85+
$this->fileStorageDb->deleteFile($filename);
86+
} else {
87+
$filename = $this->mediaConfig->getTmpMediaPath($file);
88+
$this->mediaDirectory->delete($filename);
89+
}
90+
}
91+
}
92+
93+
return $configurableProduct;
94+
}
95+
96+
/**
97+
* Trim .tmp ending from filename
98+
*
99+
* @param string $file
100+
*
101+
* @return string
102+
*/
103+
private function getFilenameFromTmp(string $file): string
104+
{
105+
return strrpos($file, '.tmp') == strlen($file) - 4 ? substr($file, 0, strlen($file) - 4) : $file;
106+
}
107+
108+
/**
109+
* Get configurations from request
110+
*
111+
* @return array
112+
*/
113+
private function getConfigurations(): array
114+
{
115+
$result = [];
116+
$configurableMatrix = $this->request->getParam('configurable-matrix-serialized', "[]");
117+
if (!empty($configurableMatrix)) {
118+
$configurableMatrix = json_decode($configurableMatrix, true);
119+
foreach ($configurableMatrix as $item) {
120+
if (empty($item['was_changed']) && empty($item['newProduct'])) {
121+
continue;
122+
}
123+
$result[] = $item;
124+
}
125+
}
126+
127+
return $result;
128+
}
129+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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\ConfigurableProduct\Test\Unit\Plugin\Controller\Adminhtml\Product\Initialization\Helper;
9+
10+
use Magento\ConfigurableProduct\Plugin\Controller\Adminhtml\Product\Initialization\Helper\CleanConfigurationTmpImages;
11+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
12+
use Magento\Framework\App\RequestInterface;
13+
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper as ProductInitializationHelper;
14+
use Magento\Catalog\Model\Product;
15+
use Magento\Framework\Filesystem\Directory\Write;
16+
use Magento\Catalog\Model\Product\Media\Config;
17+
use Magento\MediaStorage\Helper\File\Storage\Database;
18+
use PHPUnit\Framework\MockObject\MockObject;
19+
use PHPUnit\Framework\TestCase;
20+
21+
/**
22+
* Class for testing cleaning configuration tmp images
23+
*
24+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
25+
*/
26+
class CleanConfigurationTmpImagesTest extends TestCase
27+
{
28+
/**
29+
* @var CleanConfigurationTmpImages
30+
*/
31+
private $cleanConfigurationTmpImages;
32+
33+
/**
34+
* @var ObjectManagerHelper
35+
*/
36+
private $objectManagerHelper;
37+
38+
/**
39+
* @var RequestInterface|MockObject
40+
*/
41+
private $requestMock;
42+
43+
/**
44+
* @var Config|MockObject
45+
*/
46+
protected $mediaConfig;
47+
48+
/**
49+
* @var Write|MockObject
50+
*/
51+
private $mediaDirectory;
52+
53+
/**
54+
* @var ProductInitializationHelper|MockObject
55+
*/
56+
private $subjectMock;
57+
58+
/**
59+
* @inheritdoc
60+
*/
61+
protected function setUp()
62+
{
63+
$fileStorageDb = $this->createMock(Database::class);
64+
$this->mediaConfig = $this->createMock(Config::class);
65+
$this->mediaDirectory = $this->createMock(Write::class);
66+
$this->requestMock = $this->getMockBuilder(RequestInterface::class)
67+
->getMockForAbstractClass();
68+
$this->subjectMock = $this->getMockBuilder(ProductInitializationHelper::class)
69+
->disableOriginalConstructor()
70+
->getMock();
71+
72+
$this->objectManagerHelper = new ObjectManagerHelper($this);
73+
$this->cleanConfigurationTmpImages = $this->objectManagerHelper->getObject(
74+
CleanConfigurationTmpImages::class,
75+
[
76+
'request' => $this->requestMock,
77+
'fileStorageDb' => $fileStorageDb,
78+
'mediaConfig' => $this->mediaConfig,
79+
'mediaDirectory' => $this->mediaDirectory
80+
]
81+
);
82+
}
83+
84+
/**
85+
* Prepare configurable matrix
86+
*
87+
* @return array
88+
*/
89+
private function getConfigurableMatrix()
90+
{
91+
return [
92+
[
93+
'newProduct' => false,
94+
'id' => 'product2',
95+
'sku' => 'simple2_sku',
96+
'name' => 'simple2_name',
97+
'price' => '3.33',
98+
'configurable_attribute' => 'simple2_configurable_attribute',
99+
'was_changed' => true,
100+
'media_gallery' => [
101+
'images' => [
102+
[
103+
'file' => 'a/b/test_image.png.tmp',
104+
],
105+
],
106+
],
107+
],
108+
];
109+
}
110+
111+
/**
112+
* Test after initialize
113+
*
114+
* @return void
115+
*/
116+
public function testAfterInitialize()
117+
{
118+
$configurableMatrix = $this->getConfigurableMatrix();
119+
$this->requestMock->method('getParam')
120+
->willReturnMap(
121+
[
122+
['store', 0, 0],
123+
['configurable-matrix-serialized', "[]", json_encode($configurableMatrix)]
124+
]
125+
);
126+
127+
/** @var Product|\PHPUnit_Framework_MockObject_MockObject $productMock */
128+
$productMock = $this->getMockBuilder(Product::class)
129+
->disableOriginalConstructor()
130+
->getMock();
131+
132+
$this->mediaConfig->expects($this->once())->method('getTmpMediaPath');
133+
$this->mediaDirectory->expects($this->once())->method('delete');
134+
135+
$this->assertSame(
136+
$productMock,
137+
$this->cleanConfigurationTmpImages->afterInitialize($this->subjectMock, $productMock)
138+
);
139+
}
140+
}

app/code/Magento/ConfigurableProduct/etc/adminhtml/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<type name="Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper">
1010
<plugin name="configurable" type="Magento\ConfigurableProduct\Controller\Adminhtml\Product\Initialization\Helper\Plugin\Configurable" sortOrder="50" />
1111
<plugin name="updateConfigurations" type="Magento\ConfigurableProduct\Controller\Adminhtml\Product\Initialization\Helper\Plugin\UpdateConfigurations" sortOrder="60" />
12+
<plugin name="cleanConfigurationTmpImages" type="Magento\ConfigurableProduct\Plugin\Controller\Adminhtml\Product\Initialization\Helper\CleanConfigurationTmpImages" sortOrder="999" />
1213
</type>
1314
<type name="Magento\Catalog\Controller\Adminhtml\Product\Builder">
1415
<plugin name="configurable" type="Magento\ConfigurableProduct\Controller\Adminhtml\Product\Builder\Plugin" sortOrder="50" />

0 commit comments

Comments
 (0)