1

Magento Update Multiselect Attribute: add 1 option (dont overwrite curent0) via script or massupdate or extension

Situation Product with multiselect attribute for color

 - COLOR       [Green]   [Yellow]    [Blue]    [Red]        
 - Product1       x         x          x         
 - Product2                            x          
 - Product3                 x           

We now want to update all 3 products in 1 go to be like this

 - COLOR       [Green]   [Yellow]    [Blue]    [Red]        
 - Product1       x         x          x         x
 - Product2                            x         x
 - Product3                 x                    x

In this case we ADD the option RED to all 3 (and dont remove any data)

Questions: Can this be done via a massupdate in backend? (I think it overwrites all and leaves ONLY red selected); or maybe via a script or other method?

I appreciate your help

  • Would this be for Magento 1 or 2? – Niels Mar 19 '18 at 12:22
  • 1
    1. But maybe als 2 for others. We use m1 – snh_nl Mar 19 '18 at 12:23
  • Can you please give soe feedback if it works for you? – sv3n Apr 25 '18 at 10:17
1

I think mass action will overwrite current values.

To update a multiselect attribute you have to save the options IDs as comma seperated string ...

For multiple products this should work:

$attributeCode = 'multiselect_attribute';
$attributeValue = 'Red';
$attribute = Mage::getModel('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attributeCode);
$optionId = $attribute->getSource()->getOptionId($attributeValue);

$productIds = array(1, 2);
$products = Mage::getResourceModel('catalog/product_collection')
    ->addIdFilter($productIds)
    ->addAttributeToSelect($attributeCode);

$storeId = 0;
$action = Mage::getResourceSingleton('catalog/product_action');
foreach ($products as $product) {
    $options = array_filter(explode(',', $product->getData($attributeCode)));
    $options[] = $optionId;
    $options = array_unique($options);
    $action->updateAttributes(
        array($product->getId()),
        array($attributeCode => implode(',', $options)),
        $storeId
    );
}

Note: after that you have to reindex your attributes manually

  • 1
    Perhaps you should add a call to array_unique just to prevent dups? – Lee Saferite Mar 22 '18 at 12:25
  • 1
    Also be aware, this snippet does not add an indexer event like the normal mass action code does. – Lee Saferite Mar 22 '18 at 12:47
  • @LeeSaferite it works without array_unique, but its definitly cleaner. Also added array_filter to prevent empty array value (explode(',', null)). Thanks for mention indexer ... i'll add some code later :) – sv3n Mar 22 '18 at 13:01
  • thanks see my answer below. We use rawdata() .... but this code looks like it does exactly what it needs to do. THANKS! – snh_nl Apr 25 '18 at 10:24
0

This is the solution we are using now, where data is offered using a product id and a column header. Of the header code is multiselect then it executes the code utilizing - and + to add or remove data from the multiselect.

```

                $attribute = Mage::getSingleton('catalog/product')->getResource()->getAttribute($_key);
                if (
                    $attribute->getFrontendInput() === 'multiselect'
                    && $attribute->getBackend() instanceof Mage_Eav_Model_Entity_Attribute_Backend_Array
                ) {
                    /**
                     * Handles multiselect attribute
                     */
                    $toAdd = array();
                    $toSubstract = array();

                    foreach (explode('|', $_keyval) as $singleKeyValue) {
                        // Parse & check operator
                        $operator = substr($singleKeyValue, 0, 1);
                        if (!in_array($operator, array("-","+"))) {
                            Mage::throwException('Unallowable operator: '.$operator);
                        }

                        // get option value id
                        $optionValue = substr($singleKeyValue, 1);
                        $optionValueId = $attribute->getSource()->getOptionId($optionValue);

                        if (!$optionValueId) {
                            Mage::throwException('No such option');
                        }

                        if ($operator === "+") {
                            $toAdd[] = $optionValueId;
                        } else {
                            // is "-"
                            $toSubstract[] = $optionValueId;
                        }
                    }
                    // get current product value ids
                    $currentValue = Mage::getSingleton('catalog/product')->getResource()->getAttributeRawValue($_id, $_key, Mage::app()->getStore());
                    $currentOptionValues = explode(',', $currentValue);
                    sort($currentOptionValues);

                    $newOptionValues = array_diff($currentOptionValues, $toSubstract);
                    $newOptionValues = array_merge($newOptionValues, $toAdd);
                    $newOptionValues = array_unique($newOptionValues);
                    sort($newOptionValues);

                    if ($newOptionValues !== $currentOptionValues) {
                        $valuesToSave[$_key] = implode(',', $newOptionValues);
                    }
                }
                    /**
                     * Saving prepared values to the product
                     * in one transaction
                     */
                    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(array($id), $valuesToSave, 0);

```

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.