Imagine, that you have created new select type attribute and you add some manufacturers to it.
Now you may have a script that imports products and you have absolutely no idea which manufacturers do exist in that product feed
It seems obvious that every time there is a new manufacturer in the product import feed, then it needs to be added as new attribute option value.
Unfortunately Magento uses numeric ID-s to store such data, so we need a method which would return the attribute option ID and if needed, then the same method would automatically add the new attribute option value to the database and return newly created attribute option value id.
This code snippet takes attribute code and new value as parameters, then returns the corresponding attribute option value id.
public static function getAttributeOptionId(
$attributeCode,
$newValue
) {
//load the attribute by attribute code
$entityTypeID = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
$attribute = Mage::getResourceModel('eav/entity_attribute_collection')
->setCodeFilter($attributeCode)
->setEntityTypeFilter($entityTypeID)
->getFirstItem();
//if no attribute found, then return null
//if it is so, then there is something wrong with the code
//exception should be thrown here.
if ($attribute == null || $attribute->getId() <= 0) return null;
//get the attribute id
$attribute_id = $attribute->getId();
//if newvalue is empty, then try to set the default value
//or return null, if no default value set
if ($newValue == '') {
if ($attribute->getDefaultValue() != '') {
return $attribute->getDefaultValue();
} else {
//no default value, leave empty
return null;
}
}
//get all the possible attribute values and put them into array
$mageAttrOptions = $attribute->getSource()->getAllOptions(false);
$attrOptions = array();
foreach ($mageAttrOptions as $option) {
$attrOptions[$option['label']] = $option['value'];
}
//if we do not have the attribute value set, then we need to add
//the new value to the attribute and return the id of the newly created
//attribute value
if (!isset($attrOptions[$newValue])) {
//create that option and retrieve the id
$_optionArr = array('value'=>array(), 'order'=>array(), 'delete'=>array());
foreach ($attrOptions as $label => $value) {
//iterate thru old ones
$_optionArr['value'][$value] = array($label);
}
//add the new one
$_optionArr['value']['option_1'] = array($newValue);
//set them to the attribute
$attribute->setOption($_optionArr);
//save the attribute
$attribute->save();
//get the new id for the value
$entityType = Mage::getModel('catalog/product')->getResource()->getEntityType();
$attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', $attribute_id);
$mageAttrOptions = $attribute->getSource()->getAllOptions(false);
$attrOptions = array();
foreach ($mageAttrOptions as $option) {
$attrOptions[$option['label']] = $option['value'];
}
//we have the new attribute value added, new ID fetched, now we need to return it
return $attrOptions[$newValue];
}
//if the attribute value already exists, then just return the id.
return $attrOptions[$newValue];
}
If this method has been implemented, then it can be used like this:
$product = Mage::getModel('catalog/product')->load($product_id);
$product->setData('manufacturer', self::getAttributeOptionId('manufacturer', 'Sanyo'));
If manufacturer Sanyo does not exist as attribute option value, then it will be automatically added to the Manufacturers list and it's ID will be returned.
This code can be easily used inside custom module, advanced users can build some sort of caching mechanism on top of that