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
    Hi guys, see bug 6803 report on github as it pertains to this question. – quickshiftin Mar 25 '17 at 22:32
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

  • 3
    do you have any concret snippet adding image to product and not using addImageToMediaGallery() – Bartosz Kubicki Dec 30 '16 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 ? – Manthan Dave Sep 15 '17 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
  • 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 ? – Thomas Domingues Aug 31 '16 at 15:39
  • @ThomasDomingues I always save after – Raphael at Digital Pianism Aug 31 '16 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 ? – Thomas Domingues Aug 31 '16 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. – Raphael at Digital Pianism Aug 31 '16 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);
}
  • 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" – Manthan Dave Sep 15 '17 at 8:05
  • @ManthanDave In what case did you get this msg? I didn't experience any problems using this code. – spiil Sep 21 '17 at 10:17
  • When i save product with - \Magento\Catalog\Model\ResourceModel\Product $productResource - Product resource model i am getting this error – Manthan Dave Sep 21 '17 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 – CompactCode Sep 28 '17 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, privacy policy and cookie policy

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