Magento2: Updating a product through the API removes its images

Created on 8 Aug 2017  路  23Comments  路  Source: magento/magento2


Preconditions


  1. Magento 2.1.2 or Magento 2.2.0-dev.
  2. Use the PHP api rather than the json one.

Steps to reproduce

  1. A product already exists in Magento, that has images (of any type) on it.
  2. Update the images on the product through the API and save it.

Expected result

  1. On updating a product through the php API, any existing images should remain on the product and new ones updated.

Actual result

  1. The images (whether new or existing) are removed from the product in the UI.


Note: On product update, the value of the store id on table 'catalog_product_entity_media_gallery_value' is set to 1 (when previously it was set to 0). I believe this prevents the update being done to the catalog_product_entity_varchar table for the asset.

I have got round this issue by inserting a row to the varchar table for each asset type after a product save. The assets still exist on the media gallery tables, but are removed from the product varchar table, which prevents them from being displayed in the UI.

Clear Description Format is valid needs update bug report

All 23 comments

What is the complete JSON string you are POSTing to the server?

The problem you describe will happen if you are sending an empty array assigned to "media_gallery_entries" in your request because you are overwriting it's current media gallery.

@jordanbrauer I'm not writing an empty value to the media gallery entries, I'm writing the same values as were on the product previously to the media gallery.
So there is an existing product that I've created through the API. The product is updated on a separate PIM system, a message is pushed through to the Magento API code I've written, for the whole product string, including the media gallery entry, but the images are removed from the Magento UI on product save. (the product varchar table).
I can send the same images for the product or new ones, and the issue is the same, they are not added to the varchar table, on product save, only to the media gallery tables, and this issue prevents the images from displaying in the Magento UI.
A create new product is fine, it is just updating the product that causes the issue. I am sure it's a bug, related to the store id issue, as the store id is set to 1 on one of the media gallery tables when updating and saving a product through the API.

I have a similar setup as you and I do not have this problem. 馃

I am curious though - why are you resending the same images if they already exist on the product? That could be a potential contributor to the reason this is happening.

The JSON object that you are POSTing to the API, what does it look like? For example, mine looks like this for our stock level & inventory status update script (ignore that it is PHP for now and pretend it was a JSON object),

          $json = [
            'product' => [
              'status' => $row->status,
              'sku' => $row->sku,
              'extension_attributes' => [
                'stock_item' => [
                  'qty' => $row->qty,
                  'is_in_stock' => is_in_stock($row->qty),
                ],
              ],
            ],
            'save_options' => true,
          ];

Notice that I am not including the "media_gallery_entries" key because the products don't need their images to be set by a script that is updating stock, pricing, cost, meta data, etc. The key take away here is that by only including the information _required_ to update the product, we minimize the chance of other data being mutated in the process.


If you believe it to be a store ID issue - I have a workaround for that that may or may not work for you.

What I do is simply dispatch the request/operation again on the same set of products, except with a different store_id in the API endpoint than has already been done.

_e.g.,_

Using the following as a template, /index.php/rest/{{ store_id }}/V1/products/{{ sku }}, we simply call our product updates on the endpoints, like so

Default Endpoint: /index.php/rest/all/V1/products/{{ sku }} (all or default works here. We find that all works best for us)

Specific Endpoint: /index.php/rest/en/V1/products/{{ sku }} (swap this one out with whatever store IDs you want to be updated)

I should have mentioned, that we are using the PHP api rather than the json one, as we have our own web service for dealing with importing data.
So I don't have a json string, just php. So I can't use your suggested workaround as I'm not using json and curl requests. I'll update the main issue to make this clear.

Anyway if I send a different set of images for a product update, the issue is the same.

Ah I understand. My bad!

As far as I know, you're still able to specify the store ID with the framework using,

$product->setStoreId($store_id);

So the workaround might work.

The images thing is quite strange for sure. Is there ant chance your shop is able to upgrade to 2.1.5 > ?

Well it's my bad really for not stating I was using the PHP api but thanks for spending the time to look into it. I could update to 2.1.5 but I have a linux VM version of Magento that is running version 2.2.0-dev and that has the same issue so I don't think it would make any difference.

Oh yes I tried that setting the store id on the product - but on product save it still creates the store id 1 version of the product (as described in issue #7877 ). The workaround for that is to save the attribute value with a store id of 0 - I could maybe try that for the image type values - I didn't try that approach.
Anyway I do have my own workaround for this issue which is to insert a row to the product varchar table for the missing values after a product save. Not great I know.

I just thought I would raise the issue for anyone else struggling with the php api.

Could this be investigated and raised as a bug if appropriate?
I do need a fix for the issue as the workaround I've got can't tell which cached image is of which type (thumbnail, main etc) and so I have lost that relationship.
I tried looking into updating the image type attribute with a store id of 0, but I can't use this as I don't know the new value of the cached image until after a product save by which time it's too late.

We just have to wait until a Magento CE team member sees this and deems it worthy of being added to their internal tickets.

Do you have any 3rd part extensions that alter products, images, and/or stores?

@kervin
Yes that sounds like the same issue.
It may be that once #7877 is fixed, that this will be fixed too, I am sure it is related to that issue.

I am sharing the workaround I have for this issue, for anyone who might find it helpful.
Insert the code after a product save (there is no need to do another subsequent product save after the workaround). Note that the workaround involves a direct table update, and that the relationship between the image type and the asset is lost (so you may find that a thumbnail image is now a main, etc). This is not an issue if all your images are the same on a product, or you may decide that any image is better than none.

productimage_workaround.txt

There is also this workaround, mentioned on #10687
If you are not changing images, unset media_gallery

$product->unsetData('media_gallery'); $this->productRepository->save($product);

@CatherineLearmonth, thank you for your report.
We've created internal ticket(s) MAGETWO-83133 to track progress on the issue.

@CatherineLearmonth Can you please specify where the mentioned fix needs to be added?

Saving the product is the thing that removes its images. If you're not changing the product image, use this fix:
$product->unsetData('media_gallery'); $this->productRepository->save($product);

If you are updating the images, try the other code (in the txt file) but add it after the product save.

@CatherineLearmonth Thanks for a quick response, but what we need is the specific location? Can you name a file or a class? something we could cling on....

I inserted the fix into a bespoke Magento module that I wrote that takes products from one system and writes them to Magento. I don't know where you would insert the code fix into the Magento code base itself if that is what you are looking for.
This issue has been recognised as a bug by Magento (MAGETWO-83133) so I guess you'll just have to check that ticket and wait until it is fixed.

You can look into

Magento\Catalog\Model\ProductRepository

DEBUG HER:
public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)

if media_gallery in empty then, unset($productDataArray['media_gallery']);

I had similar iussue. Solved it to set null value for json id property:
"media_gallery_entries": [
{
"id": null,
"mediaType": "image",
"label": "Immagine_0_003084.999-150",
"position": 1,
"disabled": false,
"types": [
"image",
"small_image",
"thumbnail"
],
"file": null,
"content": {
"Base64EncodedData": "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT

I think its issue on Magento 2.2.3 or below version
Open root/app/code/Magento/Catalog/Model/ProductRepository.php

protected function processMediaGallery(ProductInterface $product, $mediaGalleryEntries)
{
find : if (isset($entry['value_id']) // near line no : 499
TO
if (isset($entry['value_id']) && $entry['value_id'] != '') {
}

I have make this patched and its working for me.

I'm having this issue in 2.3.3 - what is the recommended fix?

Hi @engcom-Delta. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if you want to validate it one more time, please, go though the following instruction:

  • [ ] 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.
  • [ ] 2. Verify that the issue is reproducible on 2.4-develop branch

    Details- Add the comment @magento give me 2.4-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.4-develop branch, please, add the label Reproduced on 2.4.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!

  • [ ] 3. If the issue is not relevant or is not reproducible any more, feel free to close it.


Hi @merance2000 . Unfortunately, I cannot reproduce this issue on 2.4-develop.
Case1:
$product->setPrice($price); $this->productRepository->save($product);
Actual result:
:heavy_check_mark: Images are not removed from updated product

Case2:
Via Rest API:
Post : /rest/V1/products
Simple body for request:
{ "product": { "id": 1203, "sku": "simple1", "name": "Test", "price": 11, "status": 1, "visibility": 3, "weight": 1 } }
Actual result:
:heavy_check_mark: Images are not removed from updated product

Could you add detailed steps to reproduce this issue in your case?

@merance2000, we are closing this issue due to inactivity. If you'd like to update it, please reopen the issue.

Was this page helpful?
0 / 5 - 0 ratings