Skip to content

Commit c8cbacc

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.3-develop expedited
Accepted Community Pull Requests: - #23598: [2.3] magento catalog:images:resize now Database Media Storage mode aware (by @gwharton) - #23358: #23345: Creditmemo getOrder() method loads order incorrectly. (by @p-bystritsky) - #23459: #22814: Product stock alert - unsubscribe not working (by @yuriichayka) Fixed GitHub Issues: - #23594: Database Media Storage : php bin/magento catalog:images:resize fails when image does not exist locally (reported by @gwharton) has been fixed in #23598 by @gwharton in 2.3-develop branch Related commits: 1. 2f62382 - #23595: Database Media Storage : php bin/magento catalog:images:resize fails to generate cached images in database (reported by @gwharton) has been fixed in #23598 by @gwharton in 2.3-develop branch Related commits: 1. 2f62382 - #23596: Database Media Storage : Add new product image, cached images not generated (reported by @gwharton) has been fixed in #23598 by @gwharton in 2.3-develop branch Related commits: 1. 2f62382 - #23345: Creditmemo getOrder() method loads order incorrectly (reported by @pavdan) has been fixed in #23358 by @p-bystritsky in 2.3-develop branch Related commits: 1. 14212b1 - #22814: Product stock alert - unsubscribe not working (reported by @davidpixie) has been fixed in #23459 by @yuriichayka in 2.3-develop branch Related commits: 1. 259534d 2. e2b58cd
2 parents c63b388 + e03bd31 commit c8cbacc

File tree

5 files changed

+424
-42
lines changed

5 files changed

+424
-42
lines changed

app/code/Magento/MediaStorage/Service/ImageResize.php

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Magento\Theme\Model\Config\Customization as ThemeCustomizationConfig;
2323
use Magento\Theme\Model\ResourceModel\Theme\Collection;
2424
use Magento\Framework\App\Filesystem\DirectoryList;
25+
use Magento\MediaStorage\Helper\File\Storage\Database;
2526

2627
/**
2728
* Image resize service.
@@ -85,6 +86,11 @@ class ImageResize
8586
*/
8687
private $filesystem;
8788

89+
/**
90+
* @var Database
91+
*/
92+
private $fileStorageDatabase;
93+
8894
/**
8995
* @param State $appState
9096
* @param MediaConfig $imageConfig
@@ -96,6 +102,7 @@ class ImageResize
96102
* @param ThemeCustomizationConfig $themeCustomizationConfig
97103
* @param Collection $themeCollection
98104
* @param Filesystem $filesystem
105+
* @param Database $fileStorageDatabase
99106
* @internal param ProductImage $gallery
100107
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
101108
*/
@@ -109,7 +116,8 @@ public function __construct(
109116
AssertImageFactory $assertImageFactory,
110117
ThemeCustomizationConfig $themeCustomizationConfig,
111118
Collection $themeCollection,
112-
Filesystem $filesystem
119+
Filesystem $filesystem,
120+
Database $fileStorageDatabase = null
113121
) {
114122
$this->appState = $appState;
115123
$this->imageConfig = $imageConfig;
@@ -122,6 +130,8 @@ public function __construct(
122130
$this->themeCollection = $themeCollection;
123131
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
124132
$this->filesystem = $filesystem;
133+
$this->fileStorageDatabase = $fileStorageDatabase ?:
134+
\Magento\Framework\App\ObjectManager::getInstance()->get(Database::class);
125135
}
126136

127137
/**
@@ -132,9 +142,15 @@ public function __construct(
132142
*/
133143
public function resizeFromImageName(string $originalImageName)
134144
{
135-
$originalImagePath = $this->mediaDirectory->getAbsolutePath(
136-
$this->imageConfig->getMediaPath($originalImageName)
137-
);
145+
$mediastoragefilename = $this->imageConfig->getMediaPath($originalImageName);
146+
$originalImagePath = $this->mediaDirectory->getAbsolutePath($mediastoragefilename);
147+
148+
if ($this->fileStorageDatabase->checkDbUsage() &&
149+
!$this->mediaDirectory->isFile($mediastoragefilename)
150+
) {
151+
$this->fileStorageDatabase->saveFileToFilesystem($mediastoragefilename);
152+
}
153+
138154
if (!$this->mediaDirectory->isFile($originalImagePath)) {
139155
throw new NotFoundException(__('Cannot resize image "%1" - original image not found', $originalImagePath));
140156
}
@@ -162,10 +178,15 @@ public function resizeFromThemes(array $themes = null): \Generator
162178

163179
foreach ($productImages as $image) {
164180
$originalImageName = $image['filepath'];
165-
$originalImagePath = $this->mediaDirectory->getAbsolutePath(
166-
$this->imageConfig->getMediaPath($originalImageName)
167-
);
181+
$mediastoragefilename = $this->imageConfig->getMediaPath($originalImageName);
182+
$originalImagePath = $this->mediaDirectory->getAbsolutePath($mediastoragefilename);
183+
168184
foreach ($viewImages as $viewImage) {
185+
if ($this->fileStorageDatabase->checkDbUsage() &&
186+
!$this->mediaDirectory->isFile($mediastoragefilename)
187+
) {
188+
$this->fileStorageDatabase->saveFileToFilesystem($mediastoragefilename);
189+
}
169190
$this->resize($viewImage, $originalImagePath, $originalImageName);
170191
}
171192
yield $originalImageName => $count;
@@ -293,6 +314,11 @@ private function resize(array $viewImage, string $originalImagePath, string $ori
293314
$image->resize($imageParams['image_width'], $imageParams['image_height']);
294315
}
295316
$image->save($imageAsset->getPath());
317+
318+
if ($this->fileStorageDatabase->checkDbUsage()) {
319+
$mediastoragefilename = $this->mediaDirectory->getRelativePath($imageAsset->getPath());
320+
$this->fileStorageDatabase->saveFile($mediastoragefilename);
321+
}
296322
}
297323

298324
/**
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\MediaStorage\Test\Unit\Service;
7+
8+
use Magento\Catalog\Model\Product\Image\ParamsBuilder;
9+
use Magento\Catalog\Model\View\Asset\ImageFactory as AssetImageFactory;
10+
use Magento\Catalog\Model\View\Asset\Image as AssetImage;
11+
use Magento\Framework\DataObject;
12+
use Magento\Framework\Filesystem;
13+
use Magento\Framework\Image\Factory as ImageFactory;
14+
use Magento\Framework\Image;
15+
use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig;
16+
use Magento\Framework\App\State;
17+
use Magento\Framework\View\ConfigInterface as ViewConfig;
18+
use Magento\Framework\Config\View;
19+
use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;
20+
use Magento\Theme\Model\Config\Customization as ThemeCustomizationConfig;
21+
use Magento\Theme\Model\ResourceModel\Theme\Collection;
22+
use Magento\MediaStorage\Helper\File\Storage\Database;
23+
use Magento\Framework\App\Filesystem\DirectoryList;
24+
25+
/**
26+
* Class ImageResizeTest
27+
*
28+
* @SuppressWarnings(PHPMD.TooManyFields)
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class ImageResizeTest extends \PHPUnit\Framework\TestCase
32+
{
33+
/**
34+
* @var \Magento\MediaStorage\Service\ImageResize
35+
*/
36+
protected $service;
37+
38+
/**
39+
* @var State|\PHPUnit_Framework_MockObject_MockObject
40+
*/
41+
protected $appStateMock;
42+
43+
/**
44+
* @var MediaConfig|\PHPUnit_Framework_MockObject_MockObject
45+
*/
46+
protected $imageConfigMock;
47+
48+
/**
49+
* @var ProductImage|\PHPUnit_Framework_MockObject_MockObject
50+
*/
51+
protected $productImageMock;
52+
53+
/**
54+
* @var ImageFactory|\PHPUnit_Framework_MockObject_MockObject
55+
*/
56+
protected $imageFactoryMock;
57+
58+
/**
59+
* @var Image|\PHPUnit_Framework_MockObject_MockObject
60+
*/
61+
protected $imageMock;
62+
63+
/**
64+
* @var ParamsBuilder|\PHPUnit_Framework_MockObject_MockObject
65+
*/
66+
protected $paramsBuilderMock;
67+
68+
/**
69+
* @var ViewConfig|\PHPUnit_Framework_MockObject_MockObject
70+
*/
71+
protected $viewConfigMock;
72+
73+
/**
74+
* @var View|\PHPUnit_Framework_MockObject_MockObject
75+
*/
76+
protected $viewMock;
77+
78+
/**
79+
* @var AssetImage|\PHPUnit_Framework_MockObject_MockObject
80+
*/
81+
protected $assetImageMock;
82+
83+
/**
84+
* @var AssetImageFactory|\PHPUnit_Framework_MockObject_MockObject
85+
*/
86+
protected $assetImageFactoryMock;
87+
88+
/**
89+
* @var ThemeCustomizationConfig|\PHPUnit_Framework_MockObject_MockObject
90+
*/
91+
protected $themeCustomizationConfigMock;
92+
93+
/**
94+
* @var Collection|\PHPUnit_Framework_MockObject_MockObject
95+
*/
96+
protected $themeCollectionMock;
97+
98+
/**
99+
* @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
100+
*/
101+
protected $filesystemMock;
102+
103+
/**
104+
* @var Database|\PHPUnit_Framework_MockObject_MockObject
105+
*/
106+
protected $databaseMock;
107+
108+
/**
109+
* @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
110+
*/
111+
private $mediaDirectoryMock;
112+
113+
/**
114+
* @var string
115+
*/
116+
private $testfilename;
117+
118+
/**
119+
* @var string
120+
*/
121+
private $testfilepath;
122+
123+
protected function setUp()
124+
{
125+
$this->testfilename = "image.jpg";
126+
$this->testfilepath = "/image.jpg";
127+
128+
$this->appStateMock = $this->createMock(State::class);
129+
$this->imageConfigMock = $this->createMock(MediaConfig::class);
130+
$this->productImageMock = $this->createMock(ProductImage::class);
131+
$this->imageMock = $this->createMock(Image::class);
132+
$this->imageFactoryMock = $this->createMock(ImageFactory::class);
133+
$this->paramsBuilderMock = $this->createMock(ParamsBuilder::class);
134+
$this->viewMock = $this->createMock(View::class);
135+
$this->viewConfigMock = $this->createMock(ViewConfig::class);
136+
$this->assetImageMock = $this->createMock(AssetImage::class);
137+
$this->assetImageFactoryMock = $this->createMock(AssetImageFactory::class);
138+
$this->themeCustomizationConfigMock = $this->createMock(ThemeCustomizationConfig::class);
139+
$this->themeCollectionMock = $this->createMock(Collection::class);
140+
$this->filesystemMock = $this->createMock(Filesystem::class);
141+
$this->databaseMock = $this->createMock(Database::class);
142+
143+
$this->mediaDirectoryMock = $this->getMockBuilder(Filesystem::class)
144+
->disableOriginalConstructor()
145+
->setMethods(['getAbsolutePath','isFile','getRelativePath'])
146+
->getMock();
147+
148+
$this->filesystemMock->expects($this->any())
149+
->method('getDirectoryWrite')
150+
->with(DirectoryList::MEDIA)
151+
->willReturn($this->mediaDirectoryMock);
152+
153+
$this->imageFactoryMock->expects($this->any())
154+
->method('create')
155+
->willReturn($this->imageMock);
156+
$this->assetImageMock->expects($this->any())
157+
->method('getPath')
158+
->will($this->returnValue($this->testfilepath));
159+
$this->assetImageFactoryMock->expects($this->any())
160+
->method('create')
161+
->willReturn($this->assetImageMock);
162+
163+
$this->paramsBuilderMock->expects($this->any())
164+
->method('build')
165+
->willReturn(
166+
[
167+
'keep_aspect_ratio' => null,
168+
'keep_frame' => null,
169+
'keep_transparency' => null,
170+
'constrain_only' => null,
171+
'background' => null,
172+
'quality' => null,
173+
'image_width' => null,
174+
'image_height' => null
175+
]
176+
);
177+
178+
$this->imageConfigMock->expects($this->any())
179+
->method('getMediaPath')
180+
->with($this->testfilename)
181+
->willReturn($this->testfilepath);
182+
$this->mediaDirectoryMock->expects($this->any())
183+
->method('getAbsolutePath')
184+
->with($this->testfilepath)
185+
->willReturn($this->testfilepath);
186+
$this->mediaDirectoryMock->expects($this->any())
187+
->method('getRelativePath')
188+
->with($this->testfilepath)
189+
->willReturn($this->testfilepath);
190+
191+
$this->viewMock->expects($this->any())
192+
->method('getMediaEntities')
193+
->willReturn(
194+
['product_small_image' =>
195+
[
196+
'type' => 'small_image',
197+
'width' => 75,
198+
'height' => 75
199+
]
200+
]
201+
);
202+
$this->viewConfigMock->expects($this->any())
203+
->method('getViewConfig')
204+
->willReturn($this->viewMock);
205+
206+
$this->service = new \Magento\MediaStorage\Service\ImageResize(
207+
$this->appStateMock,
208+
$this->imageConfigMock,
209+
$this->productImageMock,
210+
$this->imageFactoryMock,
211+
$this->paramsBuilderMock,
212+
$this->viewConfigMock,
213+
$this->assetImageFactoryMock,
214+
$this->themeCustomizationConfigMock,
215+
$this->themeCollectionMock,
216+
$this->filesystemMock,
217+
$this->databaseMock
218+
);
219+
}
220+
221+
protected function tearDown()
222+
{
223+
unset($this->service);
224+
}
225+
226+
public function testResizeFromThemesMediaStorageDatabase()
227+
{
228+
$this->databaseMock->expects($this->any())
229+
->method('checkDbUsage')
230+
->will($this->returnValue(true));
231+
232+
$this->productImageMock->expects($this->any())
233+
->method('getCountUsedProductImages')
234+
->willReturn(1);
235+
$this->productImageMock->expects($this->any())
236+
->method('getUsedProductImages')
237+
->will(
238+
$this->returnCallback(
239+
function () {
240+
$data = [[ 'filepath' => $this->testfilename ]];
241+
foreach ($data as $e) {
242+
yield $e;
243+
}
244+
}
245+
)
246+
);
247+
248+
$this->mediaDirectoryMock->expects($this->any())
249+
->method('isFile')
250+
->with($this->testfilepath)
251+
->will($this->returnValue(false));
252+
253+
$this->databaseMock->expects($this->once())
254+
->method('saveFileToFilesystem')
255+
->with($this->testfilepath);
256+
$this->databaseMock->expects($this->once())
257+
->method('saveFile')
258+
->with($this->testfilepath);
259+
260+
$generator = $this->service->resizeFromThemes(['test-theme']);
261+
while ($generator->valid()) {
262+
$generator->next();
263+
}
264+
}
265+
266+
public function testResizeFromImageNameMediaStorageDatabase()
267+
{
268+
$this->databaseMock->expects($this->any())
269+
->method('checkDbUsage')
270+
->will($this->returnValue(true));
271+
272+
$this->mediaDirectoryMock->expects($this->any())
273+
->method('isFile')
274+
->with($this->testfilepath)
275+
->willReturnOnConsecutiveCalls(
276+
$this->returnValue(false),
277+
$this->returnValue(true)
278+
);
279+
280+
$this->themeCollectionMock->expects($this->any())
281+
->method('loadRegisteredThemes')
282+
->willReturn(
283+
[ new DataObject(['id' => '0']) ]
284+
);
285+
$this->themeCustomizationConfigMock->expects($this->any())
286+
->method('getStoresByThemes')
287+
->willReturn(
288+
['0' => []]
289+
);
290+
291+
$this->databaseMock->expects($this->once())
292+
->method('saveFileToFilesystem')
293+
->with($this->testfilepath);
294+
$this->databaseMock->expects($this->once())
295+
->method('saveFile')
296+
->with($this->testfilepath);
297+
298+
$this->service->resizeFromImageName($this->testfilename);
299+
}
300+
}

0 commit comments

Comments
 (0)