Magento Hacks – Saving Attribute Option Values to a Product

by on August 27, 2013

You may have tried this before:

But you noticed that when you look in the Manage Products admin section, you see this: (Where’s the value I just set?)

manufacturer-empty

And if you check the Manage Attributes admin section, you see this: (Where’s my option?)

manufacturer-empty2

But if you directly call $product->getManufacturer() you will get “AMCE”. The problem is just a simple misunderstanding of how attribute option values are created and assigned to products. To understand how attribute options work, take a look at the database tables eav_attribute_option and eav_attribute_option_value. Let’s focus on “Manufacturer”, in this case is attribute_id 81. I manually assigned 4 options to this attribute under the “Manage Labels/Options” tab. Here’s what that looks like in the eav_attribute_option table:

eav_attribute_option

As you can see, for attribute_id = 81 we have option_id 3, 4, 5, and 6. If you were to set your product to one of your new “labels” it’s value when called directly is the option_id you see here. The values are in a different table. Look in the eav_attribute_option_value table:

eav_attribute_option_value

Here you can see our values for option_id 3, 4, 5, and 6. Now that you see how the option / value eav tables work, let’s hack magento to accept $product->setManufacturer(“ACME”); or $product->setManufacturer(“New Option”);

First, you need to find “manufacturer” in the eav_attribute table:

eav_attribute

I highlighted backend_model to show that there is currently none set. Part of a backend model’s role in Magento is to call beforeSave() and afterSave() methods when a product (or another entity which contains eav attributes) is saved. Each attribute associated with a product entity can have its own custom backend model. This gives us a way to validate data before being saved. This is exactly what we want to do. In order to add or check for existing attribute options before saving, we set our model here. For this example, my backend_model class is Ip_Global_Model_Backend_Newoption, so I’ll set the backend_model for the manufacturer attribute as “global/backend_newoption”.

eav_attribute-2

Now let’s take a look at our beforeSave() method to see what happens when we call $product->setManufacturer(“New Option”);

First, we get the $code which in this example will return “manufacturer”. After a quick check to make sure the value supplied is not empty, we get right to business adding the attribute value if it does not exist by calling $this->addAttributeValue(“manufacturer”, “New Option”);

The Mage_Eav_Model_Entity_Attribute model is called so we can get the attribute_id from it’s code, then load the $attribute object. We pass this $attribute object and the string $value to a method getOptionId() which simply checks if the option_id already exists. If it doesn’t, we must create it using the Mage_Eav_Model_Entity_Setup model.

Here you can see we create an $option array and assign “attribute_id” and “value”. The structure of this array is important and perhaps made sense to someone at some point many years ago. But you don’t have to worry about that, because the hard work is now done. Once more we call getOptionId() to grab the newly created option_id and we return it to the beforeSave() method where we started!

So now, we have $option_id with the correct id, whether it was just created or already existed. We now use setData() to assign it to our $product and we are done!

manufacturer-added

As you can see, the product is now assigned “New Option”, and it can also be found in the Manage Labels/Options section when modifying the attribute:

manufacturer-added-2

See the full code on gist.github.com!

If you’re looking for Magento Services, give us a call!

Share This Post