phpmagentoproductentity-attribute-value

Magento add new select value/option to products with upgrade script


I want to make a new select attribute option visible in all products.

I have products that each use a select box attribute called "bracket_size". That attribute has three options:

bracket size options

(/admin/catalog_product_attribute/edit/)

Most of the products only have two of these options selected:

product attribute config

(/admin/catalog_product/edit/)

If I select "18mm" in that screen then it shows on the frontend.

I want to create an upgrade script that will set all products to show the "18mm" option.

I had been doing it by selecting all products, fetching them and updating their attribute value:

$options = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'bracket_size')->getSource()->getAllOptions(false);
$option18mmId = $options[0]['value'];

foreach (Mage::getModel('catalog/product')->getCollection() as $product) {
    // Get a writable product
    $product = Mage::getModel('catalog/product')->load($product->getId());

    // All products in these attribute sets should have bracket sizes
    $bracketSizeValue = $product->getBracketSize(); // string containing option IDs - something like '645,345'

    if (isset($bracketSizeValue)) {
        // Get options currently selected for this product
        $optionIds = explode(',', $bracketSizeValue);

        // Check if the option is already included in this product
        if (!in_array($option18mmId, $optionIds)) {
            // If not, rebuild the attribute value to add it
            array_unshift($optionIds, $option18mmId);

            // Add it back to the product
            $product->setData('bracket_size', implode(',', $optionIds));
            $product->save();
        }
    }
}

But this doesn't work. It throws an error:

Warning: Invalid argument supplied for foreach()  in /.../public/app/code/core/Mage/Eav/Model/Entity/Abstract.php on line 1068

at the $product->save() line.

How can I do this?


Solution

  • If you trying to save products in setup/update script then you need to disable update mode and set current store id first:

    $app = Mage::app();
    $app->setUpdateMode(false);
    $app->setCurrentStore($app::ADMIN_STORE_ID);
    

    Ideally it would be done exactly before saving and then reverted back after saving:

    $app->setCurrentStore(null);
    $app->setUpdateMode(true);
    

    Then you could also optimise your code my removing loading and saving of each product and doing it on collection items instead.

    Loading of collection with desired attribute:

    $collection = Mage::getModel('catalog/product')->getCollection();
    $collection->addAttributeToSelect('bracket_code');
    

    Saving of changes on collection items:

    $collection->save();