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?

2
  • Let me know if it's working for you. Oct 2 '20 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.. Mar 3 at 19:01
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);
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?
    – Lez
    Oct 2 '20 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. Oct 2 '20 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.
    – Lez
    Oct 2 '20 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.

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.