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:
(/admin/catalog_product_attribute/edit/)
Most of the products only have two of these options selected:
(/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?
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();