Skip to content

Commit 5218dd9

Browse files
author
Stanislav Idolov
authored
ENGCOM-3490: Magento 2.2 Fix Product::addImageToMediaGallery throws Exception #18951
2 parents 0bc3a68 + 651606e commit 5218dd9

File tree

3 files changed

+127
-5
lines changed

3 files changed

+127
-5
lines changed

app/code/Magento/Catalog/Model/Product/Gallery/Processor.php

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
*/
66
namespace Magento\Catalog\Model\Product\Gallery;
77

8+
use Magento\Framework\Api\Data\ImageContentInterface;
89
use Magento\Framework\App\Filesystem\DirectoryList;
910
use Magento\Framework\Exception\LocalizedException;
10-
use Magento\Framework\Filesystem\DriverInterface;
11+
use Magento\Framework\App\ObjectManager;
1112

1213
/**
1314
* Catalog product Media Gallery attribute processor.
@@ -55,28 +56,39 @@ class Processor
5556
*/
5657
protected $resourceModel;
5758

59+
/**
60+
* @var \Magento\Framework\File\Mime
61+
*/
62+
private $mime;
63+
5864
/**
5965
* @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
6066
* @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb
6167
* @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig
6268
* @param \Magento\Framework\Filesystem $filesystem
6369
* @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel
70+
* @param \Magento\Framework\File\Mime|null $mime
71+
* @throws \Magento\Framework\Exception\FileSystemException
6472
*/
6573
public function __construct(
6674
\Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
6775
\Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb,
6876
\Magento\Catalog\Model\Product\Media\Config $mediaConfig,
6977
\Magento\Framework\Filesystem $filesystem,
70-
\Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel
78+
\Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel,
79+
\Magento\Framework\File\Mime $mime = null
7180
) {
7281
$this->attributeRepository = $attributeRepository;
7382
$this->fileStorageDb = $fileStorageDb;
7483
$this->mediaConfig = $mediaConfig;
7584
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
7685
$this->resourceModel = $resourceModel;
86+
$this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class);
7787
}
7888

7989
/**
90+
* Return media_gallery attribute
91+
*
8092
* @return \Magento\Catalog\Api\Data\ProductAttributeInterface
8193
* @since 101.0.0
8294
*/
@@ -178,6 +190,13 @@ public function addImage(
178190
$attrCode = $this->getAttribute()->getAttributeCode();
179191
$mediaGalleryData = $product->getData($attrCode);
180192
$position = 0;
193+
194+
$absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file);
195+
$imageMimeType = $this->mime->getMimeType($absoluteFilePath);
196+
$imageContent = $this->mediaDirectory->readFile($absoluteFilePath);
197+
$imageBase64 = base64_encode($imageContent);
198+
$imageName = $pathinfo['filename'];
199+
181200
if (!is_array($mediaGalleryData)) {
182201
$mediaGalleryData = ['images' => []];
183202
}
@@ -192,9 +211,17 @@ public function addImage(
192211
$mediaGalleryData['images'][] = [
193212
'file' => $fileName,
194213
'position' => $position,
195-
'media_type' => 'image',
196214
'label' => '',
197215
'disabled' => (int)$exclude,
216+
'media_type' => 'image',
217+
'types' => $mediaAttribute,
218+
'content' => [
219+
'data' => [
220+
ImageContentInterface::NAME => $imageName,
221+
ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64,
222+
ImageContentInterface::TYPE => $imageMimeType,
223+
]
224+
]
198225
];
199226

200227
$product->setData($attrCode, $mediaGalleryData);
@@ -353,7 +380,8 @@ public function setMediaAttribute(\Magento\Catalog\Model\Product $product, $medi
353380
}
354381

355382
/**
356-
* get media attribute codes
383+
* Get media attribute codes
384+
*
357385
* @return array
358386
* @since 101.0.0
359387
*/
@@ -363,6 +391,8 @@ public function getMediaAttributeCodes()
363391
}
364392

365393
/**
394+
* Trim .tmp ending from filename
395+
*
366396
* @param string $file
367397
* @return string
368398
* @since 101.0.0
@@ -484,7 +514,6 @@ public function getAffectedFields($object)
484514
/**
485515
* Attribute value is not to be saved in a conventional way, separate table is used to store the complex value
486516
*
487-
* {@inheritdoc}
488517
* @since 101.0.0
489518
*/
490519
public function isScalar()

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,52 @@ public function testFilterByStoreId()
198198

199199
$this->assertGreaterThanOrEqual(1, $count);
200200
}
201+
202+
/**
203+
* Test save product with gallery image
204+
*
205+
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_image.php
206+
*
207+
* @throws \Magento\Framework\Exception\CouldNotSaveException
208+
* @throws \Magento\Framework\Exception\InputException
209+
* @throws \Magento\Framework\Exception\StateException
210+
*/
211+
public function testSaveProductWithGalleryImage()
212+
{
213+
/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */
214+
$mediaConfig = Bootstrap::getObjectManager()
215+
->get(\Magento\Catalog\Model\Product\Media\Config::class);
216+
217+
/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
218+
$mediaDirectory = Bootstrap::getObjectManager()
219+
->get(\Magento\Framework\Filesystem::class)
220+
->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
221+
222+
$product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
223+
$product->load(1);
224+
225+
$path = $mediaConfig->getBaseMediaPath() . '/magento_image.jpg';
226+
$absolutePath = $mediaDirectory->getAbsolutePath() . $path;
227+
$product->addImageToMediaGallery($absolutePath, [
228+
'image',
229+
'small_image',
230+
], false, false);
231+
232+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
233+
$productRepository = Bootstrap::getObjectManager()
234+
->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
235+
$productRepository->save($product);
236+
237+
$gallery = $product->getData('media_gallery');
238+
$this->assertArrayHasKey('images', $gallery);
239+
$images = array_values($gallery['images']);
240+
241+
$this->assertNotEmpty($gallery);
242+
$this->assertTrue(isset($images[0]['file']));
243+
$this->assertStringStartsWith('/m/a/magento_image', $images[0]['file']);
244+
$this->assertArrayHasKey('media_type', $images[0]);
245+
$this->assertEquals('image', $images[0]['media_type']);
246+
$this->assertStringStartsWith('/m/a/magento_image', $product->getData('image'));
247+
$this->assertStringStartsWith('/m/a/magento_image', $product->getData('small_image'));
248+
}
201249
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory;
8+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
10+
\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
11+
12+
/** @var \Magento\TestFramework\ObjectManager $objectManager */
13+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
14+
15+
/** @var $product \Magento\Catalog\Model\Product */
16+
$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
17+
$product->isObjectNew(true);
18+
$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
19+
->setId(1)
20+
->setAttributeSetId(4)
21+
->setWebsiteIds([1])
22+
->setName('Simple Product')
23+
->setSku('simple')
24+
->setPrice(10)
25+
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
26+
27+
/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */
28+
$mediaConfig = $objectManager->get(\Magento\Catalog\Model\Product\Media\Config::class);
29+
30+
/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
31+
$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class)
32+
->getDirectoryWrite(DirectoryList::MEDIA);
33+
34+
$targetDirPath = $mediaConfig->getBaseMediaPath();
35+
$targetTmpDirPath = $mediaConfig->getBaseTmpMediaPath();
36+
37+
$mediaDirectory->create($targetDirPath);
38+
$mediaDirectory->create($targetTmpDirPath);
39+
40+
$dist = $mediaDirectory->getAbsolutePath($mediaConfig->getBaseMediaPath() . DIRECTORY_SEPARATOR . 'magento_image.jpg');
41+
copy(__DIR__ . '/magento_image.jpg', $dist);
42+
43+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
44+
$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
45+
$productRepository->save($product);

0 commit comments

Comments
 (0)