Skip to content

Commit

Permalink
ENGCOM-3490: Magento 2.2 Fix Product::addImageToMediaGallery throws E…
Browse files Browse the repository at this point in the history
…xception #18951
  • Loading branch information
Stanislav Idolov authored Nov 22, 2018
2 parents 0bc3a68 + 651606e commit 5218dd9
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 5 deletions.
39 changes: 34 additions & 5 deletions app/code/Magento/Catalog/Model/Product/Gallery/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
*/
namespace Magento\Catalog\Model\Product\Gallery;

use Magento\Framework\Api\Data\ImageContentInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem\DriverInterface;
use Magento\Framework\App\ObjectManager;

/**
* Catalog product Media Gallery attribute processor.
Expand Down Expand Up @@ -55,28 +56,39 @@ class Processor
*/
protected $resourceModel;

/**
* @var \Magento\Framework\File\Mime
*/
private $mime;

/**
* @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
* @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb
* @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig
* @param \Magento\Framework\Filesystem $filesystem
* @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel
* @param \Magento\Framework\File\Mime|null $mime
* @throws \Magento\Framework\Exception\FileSystemException
*/
public function __construct(
\Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
\Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb,
\Magento\Catalog\Model\Product\Media\Config $mediaConfig,
\Magento\Framework\Filesystem $filesystem,
\Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel
\Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel,
\Magento\Framework\File\Mime $mime = null
) {
$this->attributeRepository = $attributeRepository;
$this->fileStorageDb = $fileStorageDb;
$this->mediaConfig = $mediaConfig;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->resourceModel = $resourceModel;
$this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class);
}

/**
* Return media_gallery attribute
*
* @return \Magento\Catalog\Api\Data\ProductAttributeInterface
* @since 101.0.0
*/
Expand Down Expand Up @@ -178,6 +190,13 @@ public function addImage(
$attrCode = $this->getAttribute()->getAttributeCode();
$mediaGalleryData = $product->getData($attrCode);
$position = 0;

$absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file);
$imageMimeType = $this->mime->getMimeType($absoluteFilePath);
$imageContent = $this->mediaDirectory->readFile($absoluteFilePath);
$imageBase64 = base64_encode($imageContent);
$imageName = $pathinfo['filename'];

if (!is_array($mediaGalleryData)) {
$mediaGalleryData = ['images' => []];
}
Expand All @@ -192,9 +211,17 @@ public function addImage(
$mediaGalleryData['images'][] = [
'file' => $fileName,
'position' => $position,
'media_type' => 'image',
'label' => '',
'disabled' => (int)$exclude,
'media_type' => 'image',
'types' => $mediaAttribute,
'content' => [
'data' => [
ImageContentInterface::NAME => $imageName,
ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64,
ImageContentInterface::TYPE => $imageMimeType,
]
]
];

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

/**
* get media attribute codes
* Get media attribute codes
*
* @return array
* @since 101.0.0
*/
Expand All @@ -363,6 +391,8 @@ public function getMediaAttributeCodes()
}

/**
* Trim .tmp ending from filename
*
* @param string $file
* @return string
* @since 101.0.0
Expand Down Expand Up @@ -484,7 +514,6 @@ public function getAffectedFields($object)
/**
* Attribute value is not to be saved in a conventional way, separate table is used to store the complex value
*
* {@inheritdoc}
* @since 101.0.0
*/
public function isScalar()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,52 @@ public function testFilterByStoreId()

$this->assertGreaterThanOrEqual(1, $count);
}

/**
* Test save product with gallery image
*
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_image.php
*
* @throws \Magento\Framework\Exception\CouldNotSaveException
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\StateException
*/
public function testSaveProductWithGalleryImage()
{
/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */
$mediaConfig = Bootstrap::getObjectManager()
->get(\Magento\Catalog\Model\Product\Media\Config::class);

/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
$mediaDirectory = Bootstrap::getObjectManager()
->get(\Magento\Framework\Filesystem::class)
->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);

$product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
$product->load(1);

$path = $mediaConfig->getBaseMediaPath() . '/magento_image.jpg';
$absolutePath = $mediaDirectory->getAbsolutePath() . $path;
$product->addImageToMediaGallery($absolutePath, [
'image',
'small_image',
], false, false);

/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
$productRepository = Bootstrap::getObjectManager()
->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
$productRepository->save($product);

$gallery = $product->getData('media_gallery');
$this->assertArrayHasKey('images', $gallery);
$images = array_values($gallery['images']);

$this->assertNotEmpty($gallery);
$this->assertTrue(isset($images[0]['file']));
$this->assertStringStartsWith('/m/a/magento_image', $images[0]['file']);
$this->assertArrayHasKey('media_type', $images[0]);
$this->assertEquals('image', $images[0]['media_type']);
$this->assertStringStartsWith('/m/a/magento_image', $product->getData('image'));
$this->assertStringStartsWith('/m/a/magento_image', $product->getData('small_image'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory;
use Magento\Framework\App\Filesystem\DirectoryList;

\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();

/** @var \Magento\TestFramework\ObjectManager $objectManager */
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();

/** @var $product \Magento\Catalog\Model\Product */
$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
$product->isObjectNew(true);
$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
->setId(1)
->setAttributeSetId(4)
->setWebsiteIds([1])
->setName('Simple Product')
->setSku('simple')
->setPrice(10)
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);

/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */
$mediaConfig = $objectManager->get(\Magento\Catalog\Model\Product\Media\Config::class);

/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */
$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class)
->getDirectoryWrite(DirectoryList::MEDIA);

$targetDirPath = $mediaConfig->getBaseMediaPath();
$targetTmpDirPath = $mediaConfig->getBaseTmpMediaPath();

$mediaDirectory->create($targetDirPath);
$mediaDirectory->create($targetTmpDirPath);

$dist = $mediaDirectory->getAbsolutePath($mediaConfig->getBaseMediaPath() . DIRECTORY_SEPARATOR . 'magento_image.jpg');
copy(__DIR__ . '/magento_image.jpg', $dist);

/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
$productRepository->save($product);

0 comments on commit 5218dd9

Please sign in to comment.