Skip to content

Commit e90f779

Browse files
authored
ENGCOM-3421: Magento 2.3 Fix Notice and Exception while adding image to product programmatically #18952
2 parents 34c7a5a + ab320ca commit e90f779

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
@@ -6,9 +6,10 @@
66

77
namespace Magento\Catalog\Model\Product\Gallery;
88

9+
use Magento\Framework\Api\Data\ImageContentInterface;
910
use Magento\Framework\App\Filesystem\DirectoryList;
1011
use Magento\Framework\Exception\LocalizedException;
11-
use Magento\Framework\Filesystem\DriverInterface;
12+
use Magento\Framework\App\ObjectManager;
1213

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

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

8090
/**
91+
* Return media_gallery attribute
92+
*
8193
* @return \Magento\Catalog\Api\Data\ProductAttributeInterface
8294
* @since 101.0.0
8395
*/
@@ -183,6 +195,13 @@ public function addImage(
183195
$attrCode = $this->getAttribute()->getAttributeCode();
184196
$mediaGalleryData = $product->getData($attrCode);
185197
$position = 0;
198+
199+
$absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file);
200+
$imageMimeType = $this->mime->getMimeType($absoluteFilePath);
201+
$imageContent = $this->mediaDirectory->readFile($absoluteFilePath);
202+
$imageBase64 = base64_encode($imageContent);
203+
$imageName = $pathinfo['filename'];
204+
186205
if (!is_array($mediaGalleryData)) {
187206
$mediaGalleryData = ['images' => []];
188207
}
@@ -197,9 +216,17 @@ public function addImage(
197216
$mediaGalleryData['images'][] = [
198217
'file' => $fileName,
199218
'position' => $position,
200-
'media_type' => 'image',
201219
'label' => '',
202220
'disabled' => (int)$exclude,
221+
'media_type' => 'image',
222+
'types' => $mediaAttribute,
223+
'content' => [
224+
'data' => [
225+
ImageContentInterface::NAME => $imageName,
226+
ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64,
227+
ImageContentInterface::TYPE => $imageMimeType,
228+
]
229+
]
203230
];
204231

205232
$product->setData($attrCode, $mediaGalleryData);
@@ -358,7 +385,8 @@ public function setMediaAttribute(\Magento\Catalog\Model\Product $product, $medi
358385
}
359386

360387
/**
361-
* get media attribute codes
388+
* Get media attribute codes
389+
*
362390
* @return array
363391
* @since 101.0.0
364392
*/
@@ -368,6 +396,8 @@ public function getMediaAttributeCodes()
368396
}
369397

370398
/**
399+
* Trim .tmp ending from filename
400+
*
371401
* @param string $file
372402
* @return string
373403
* @since 101.0.0
@@ -489,7 +519,6 @@ public function getAffectedFields($object)
489519
/**
490520
* Attribute value is not to be saved in a conventional way, separate table is used to store the complex value
491521
*
492-
* {@inheritdoc}
493522
* @since 101.0.0
494523
*/
495524
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
@@ -90,4 +90,52 @@ public function skuDataProvider(): array
9090
['sku' => 'simple '],
9191
];
9292
}
93+
94+
/**
95+
* Test save product with gallery image
96+
*
97+
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_image.php
98+
*
99+
* @throws \Magento\Framework\Exception\CouldNotSaveException
100+
* @throws \Magento\Framework\Exception\InputException
101+
* @throws \Magento\Framework\Exception\StateException
102+
*/
103+
public function testSaveProductWithGalleryImage(): void
104+
{
105+
/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */
106+
$mediaConfig = Bootstrap::getObjectManager()
107+
->get(\Magento\Catalog\Model\Product\Media\Config::class);
108+
109+
/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
110+
$mediaDirectory = Bootstrap::getObjectManager()
111+
->get(\Magento\Framework\Filesystem::class)
112+
->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
113+
114+
$product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
115+
$product->load(1);
116+
117+
$path = $mediaConfig->getBaseMediaPath() . '/magento_image.jpg';
118+
$absolutePath = $mediaDirectory->getAbsolutePath() . $path;
119+
$product->addImageToMediaGallery($absolutePath, [
120+
'image',
121+
'small_image',
122+
], false, false);
123+
124+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
125+
$productRepository = Bootstrap::getObjectManager()
126+
->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
127+
$productRepository->save($product);
128+
129+
$gallery = $product->getData('media_gallery');
130+
$this->assertArrayHasKey('images', $gallery);
131+
$images = array_values($gallery['images']);
132+
133+
$this->assertNotEmpty($gallery);
134+
$this->assertTrue(isset($images[0]['file']));
135+
$this->assertStringStartsWith('/m/a/magento_image', $images[0]['file']);
136+
$this->assertArrayHasKey('media_type', $images[0]);
137+
$this->assertEquals('image', $images[0]['media_type']);
138+
$this->assertStringStartsWith('/m/a/magento_image', $product->getData('image'));
139+
$this->assertStringStartsWith('/m/a/magento_image', $product->getData('small_image'));
140+
}
93141
}
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)