magento2: Custom attributes do not work as intended

See below example

$product = $this->productRepository->get('test-sku');
// $product->getCustomAttribute('custom_attr_code')->getValue() == 0
$product->setCustomAttribute('custom_attr_code', 1); // changing value from 0 to 1
$this->productRepository->save($product);
// $product->get('custom_attr_code') == 0
// and $product->getCustomAttribute('custom_attr_code')->getValue() == 0

ANY values in $_data[self::CUSTOM_ATTRIBUTES] is lost, and not saved properly.

This is because the product repository issues a product model load which loads all attributes, custom or not, into the _data array. Anytime the app calls ProductInterface::getCustomAttributes (which it does try to do when saving, to grab any values there) any custom attribute ‘key’ in $_data['custom_attributes']['key'] is overwritten because that key exists in $_data['key']. This overwriting happens here.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 9
  • Comments: 16 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Step 1.

Clone Magento2 from any version since general availability.

Step 2.

Set up access to product repository API such as through test framework/module

Step 3.

[Insert original issue comment]

The only way to have these work as intended is to use a builder such as \Magento\Catalog\Api\Data\ProductInterfaceFactory and set sku along with any data changes. While that might seem like an easy work around, the product repository is central to the app and it seems like a bad idea to leave this fragility in place.

Recap

Any time a product model load is issued (such as during ProductRepository::get), all of the custom attributes are loaded directly into the _data array. Thus any further usage of custom attributes interface methods are useless because once a custom attributes key exists in the _data property, it will always be preferred over the _data['custom_attributes'] array.

I’m not sure if is the same error, but looks like a lot to me. When I update a custom attribute of a product in multi stores, the thumbnail of this product is unset. I don’t lose the image, just the set up thumbnail.

Loading a product by Magento\Catalog\Model\ProductRepository. I update same custom attribute and then save this using ProductRepository.

$product->setData('material', implode(',', $material));
$this->_productRepository->save($product);

To fix it, I use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory to save.