1

I'm having trouble setting values to a multiselect type attribute for a product programatically.

Example attribute: material

Example values: cotton & polyester

Please note that both attribute and option values are created from the backend.

This is what I have tried so far:

$product = $objectManager->create('Magento\Catalog\Model\Product');
$sku = '1234';
$product_id = $product->getIdBySku($sku);
if ($product_id) {
 $product->load($product_id);
 $attribute_values = array('cotton','polyester');
 $product_resource = $product->getResource();
 $attribute_code = 'material';
 $attribute = $product_resource->getAttribute($attribute_code);
 if ($attribute->usesSource()) {
 foreach ($attribute_values as $attribute_value) {
 $attribute_option_ids[] = $attribute->getSource()->getOptionId($attribute_value);
 }
 $product->setData($attribute_code, $attribute_option_ids); // attempt 1
 //$product->setData($attribute_code, array($attribute_option_ids)); // attempt 2
 //$product->getResource()->saveAttribute($product, $attribute_code); // attempt 3 with combining attempt 1
 }
 $product->save();
}

The end result is that no values are set for the material attribute for product 1234.

Any ideas what I'm doing wrong?

asked Oct 2, 2020 at 7:06
2
  • Let me know if it's working for you. Commented Oct 2, 2020 at 7:47
  • Your question helped me, I was using setCustomAttribute instead of setData and for some reason sometimes it was working while other times not.. Commented Mar 3, 2021 at 19:01

2 Answers 2

1

Just to it like below code :

Inject this below class in your construct:

protected $productRepository;
public function __construct(
 \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
 $this->productRepository = $productRepository;
}

And use this below code :

$product = $this->productRepository->getById('product-id');
$product->setData('attribute-code', 'attribute-value');
$this->productRepository->save($product);

Object Manager :

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 
$product = $objectManager->get('\Magento\Catalog\Model\ProductRepository')->getById('product-id');
$product->setData('attribute-code', 'attribute-value');
$this->productRepository->save($product);
answered Oct 2, 2020 at 7:47
3
  • Thank you for the answer. It seems like a good way to set product data, but I figured out what the issue was by myself. BTW, do you have any idea if using the product repository is possibly faster/better at updating attributes than going through the product model? Commented Oct 2, 2020 at 8:52
  • Product repository used for rest API functionality also. So, it would be good if you use product repository. If it's useful you can accept answer :) Thanks. Commented Oct 2, 2020 at 8:53
  • I would, but I haven't tested and verified that it works with your method so I can't accept it. Since I solved the issue on my own, I won't be testing this, but if someone verifies that this works for multiselect attributes, I will gladly accept it. Commented Oct 2, 2020 at 10:23
0

It seems that my original code is working, but the problem was that I had 2 store views.

When setting attributes like this, it required an additional line of code:

$product->setStoreId(0); // store_id = 0 is the default store

Before saving the product.

The attributes were actually being saved for the main store view (my store has multiple store views), but the "default product data" (default view) remained unchanged.

The "attempt 1" from the code in my question was the correct way of setting this data.

answered Oct 2, 2020 at 8:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.