6

Here is the code snippet I use to add an image in a product's media gallery :

$sku = 'product-example-sku';
$image_url = 'http://example.com/image.jpg';
$image_ext = pathinfo($image_url, PATHINFO_EXTENSION);
$image_path = '/import/' . $sku . '.' . $image_ext;
file_put_contents('pub/media' . $image_path, file_get_contents($image_url));
if (file_exists('pub/media' . $image_path))
{
    try
    {
        $product->addImageToMediaGallery($image_path, array('image'), true, false);
    }
    catch (\Exception $e)
    {
        echo '[ERROR] Image import failed for product "' . $sku . '": ' . $e->getMessage();
    }
}

$this->_productRepository->save($product);

I am sure that the image is actually downloaded and moved successfully. But when I try to save the product after adding the image, this exception is thrown by Magento:

Exception #0 (Exception): Notice: Undefined index: media_type in /var/www/<website>/vendor/magento/module-catalog/Model/Product.php on line 2527

I can't find in the Magento core's code how to solve my problem.

Any help would be appreciated.

1
  • 1
    Hi guys, see bug 6803 report on github as it pertains to this question. Commented Mar 25, 2017 at 22:32

4 Answers 4

7

Since addImageToMediaGallery is not added to interface \Magento\Catalog\Api\Data\ProductInterface, I'd not recommend to use addImageToMediaGallery with ProductRepository.

For better practice you can try to use Magento2 Service Layer. You can save a new image using \Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface::create

If you will go deep to the code, under the hood of the method the attribute "media_gallery" will be set and then \Magento\Catalog\Api\ProductRepositoryInterface::save will be invoked. And inside of this method the method \Magento\Catalog\Model\Product\Gallery\Processor::addImage will be invoked, which basically invoked, when you run addImageToMediaGallery

2
  • 3
    do you have any concret snippet adding image to product and not using addImageToMediaGallery() Commented Dec 30, 2016 at 19:28
  • Do you have code snippet for this ? or how i can store using the given answer ? i have read your same answer on lot of blogs but unable to solve the issue ? Commented Sep 15, 2017 at 10:26
2

Pretty sure you have to initialize the media gallery first. I've done that several times and the code I used was always like this:

->setMediaGallery(
    [
        'images'=>  [],
        'values'=>  []
    ]
) // Media gallery initialization
->addImageToMediaGallery(
    $image,
    [
        'image',
        'thumbnail',
        'small_image'
    ],
    false,
    false) // Assigning image, thumb and small image to media gallery
4
  • Thanks for your answer, but the exception is still thrown. Do you save the product before setting the media gallery for the first time, or maybe you can do it after ? Commented Aug 31, 2016 at 15:39
  • @ThomasDomingues I always save after Commented Aug 31, 2016 at 15:41
  • 1
    Thanks. I investigated a little: your solution works when I save the product directly by the product's instance (using $product->save();), but when I save it by the products' repository (using $this->_productRepository->save($product);), the exception is still thrown. Is it a better practice to save with the repository instead of saving directly the product instance ? If so, how to solve the issue ? Commented Aug 31, 2016 at 15:59
  • @ThomasDomingues you're right it's definitely better practice to use the product repository. I'm not too sure how to fix the issue though. Commented Aug 31, 2016 at 16:06
1

I found a temporary solution for this bug

You can use product resource model instead of ProductRepository and it works like a charm. Some code sample here:

public function __construct(
    \Magento\Catalog\Model\ProductRepository $productRepository,
    \Magento\Catalog\Model\ResourceModel\Product $productResource
)
{
    $this->productRepository = $productRepository;
    $this->productResource = $productResource;
}
public function addImage() {
    $sku = "product-example-sku";
    $image_path = '/import/' . $sku . '.png';
    $product = $this->productRepository->get($sku);
    $product->addImageToMediaGallery($image_path, array('image'), true, false);
    $this->productResource->save($product);
}
4
  • Your solution is worked , using resource model, but what if i need to update product ? it shows "URL key for specified store is already exists" Commented Sep 15, 2017 at 8:05
  • @ManthanDave In what case did you get this msg? I didn't experience any problems using this code.
    – spiilmusic
    Commented Sep 21, 2017 at 10:17
  • When i save product with - \Magento\Catalog\Model\ResourceModel\Product $productResource - Product resource model i am getting this error Commented Sep 21, 2017 at 11:11
  • 1
    The use of Product Resource Model gives a bunch of different errors , i do not reccomend this as a solution but it does provide intresting information Commented Sep 28, 2017 at 14:23
0

here is the solution to resolve the issue.

vendor\magento\module-catalog\Model\Product\Gallery\Processor.php

Please override the file in your theme.

Please search for

$mediaGalleryData['images'][] = [
            'file' => $fileName,
            'position' => $position,
            'label' => '',
            'disabled' => (int)$exclude,
               ];

and replace with

$mediaGalleryData['images'][] = [
            'file' => $fileName,
            'position' => $position,
            'label' => '',
            'disabled' => (int)$exclude,
            'media_type' => 'image',
            'types'      => $mediaAttribute
        ];

I have just added media_type and types fields here.

I have tested and it's working fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.