27

I would like to create a new product attribute with some predefined options using an upgrade script.

I have an upgrade script working, so the only thing i dont know how to do is to add the drop down options along with the attribute.

I am adding my attribute inside my modules upgrade script using the following:

$installer->addAttribute('catalog_product', "shirt_size", array(
 'type' => 'int',
 'input' => 'select',
 'label' => 'Shirt Size',
 'sort_order' => 1000,
 'required' => false,
 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
));

How can I add 3 options along with it: small, medium and large?

I do not want to use a custom source model. I want normal options

Siarhey Uchukhlebau
16.2k11 gold badges57 silver badges89 bronze badges
asked Jun 26, 2013 at 18:14

4 Answers 4

30

This is a classic case where code-generation is your friend. Stop creating these by hand, and try using the following free and open source script, (which has also been incorporated into the n98-magerun tool)

For example, the following will duplicate the sample data's color attribute

$ magento-create-setup.php color
//WARNING, non false value detected in is_used_for_price_rules. The setup resource migration scripts may not support this (per 1.7.0.1)
<?php
if(! ($this instanceof Mage_Catalog_Model_Resource_Setup) )
{
 throw new Exception("Resource Class needs to inherit from " .
 "Mage_Catalog_Model_Resource_Setup for this to work");
}
$attr = array (
 'attribute_model' => NULL,
 'backend' => '',
 'type' => 'int',
 'table' => '',
 'frontend' => '',
 'input' => 'select',
 'label' => 'Color',
 'frontend_class' => '',
 'source' => '',
 'required' => '0',
 'user_defined' => '1',
 'default' => '',
 'unique' => '0',
 'note' => '',
 'input_renderer' => NULL,
 'global' => '1',
 'visible' => '1',
 'searchable' => '1',
 'filterable' => '1',
 'comparable' => '1',
 'visible_on_front' => '0',
 'is_html_allowed_on_front' => '0',
 'is_used_for_price_rules' => '1',
 'filterable_in_search' => '1',
 'used_in_product_listing' => '0',
 'used_for_sort_by' => '0',
 'is_configurable' => '1',
 'apply_to' => 'simple',
 'visible_in_advanced_search' => '1',
 'position' => '1',
 'wysiwyg_enabled' => '0',
 'used_for_promo_rules' => '1',
 'option' => 
 array (
 'values' => 
 array (
 0 => 'Green',
 1 => 'Silver',
 2 => 'Black',
 3 => 'Blue',
 4 => 'Red',
 5 => 'Pink',
 6 => 'Magenta',
 7 => 'Brown',
 8 => 'White',
 9 => 'Gray',
 ),
 ),
);
$this->addAttribute(Mage_Catalog_Model_Product::ENTITY, 'color', $attr);

If you're using the n98-magerun version, that'd be

$ n98-magerun dev:setup:script:attribute catalog_product color

Using code generation will let you get your job done quicker, and as time goes on you'll start to learn the format.

Teja Bhagavan Kollepara
3,8275 gold badges33 silver badges69 bronze badges
answered Jun 26, 2013 at 19:04
1
  • 1
    can we add js event observer like onClick and onChange in options for attribute? Commented Dec 17, 2016 at 21:23
18
$installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, 'shirt_size', [
 'type' => 'int',
 'input' => 'select',
 'label' => 'Shirt Size',
 'sort_order' => 1000,
 'required' => false,
 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
 'backend' => 'eav/entity_attribute_backend_array',
 'option' => [
 'values' => [
 0 => 'Small',
 1 => 'Medium',
 2 => 'Large',
 ]
 ],
]);

Each element in the value array represents an option. You can add the labels for each store view if you have more like this:

[
 0=>'Small',
 1=>'Small',
 2=>'Petit'
]

Basically it's store_id=>'Label for store'

Tim Bezhashvyly
11.6k6 gold badges44 silver badges73 bronze badges
answered Jun 26, 2013 at 18:23
21
  • 6
    Marius, do you work for a living? :-) Commented Jun 26, 2013 at 18:38
  • 7
    @benmarks. I do work for a living and I really enjoy the work I'm doing. I just like from time to time to take 2 minute breaks to answer a question. Do you want me to stop answering? :) Commented Jun 26, 2013 at 18:55
  • 1
    @philwinkle. Yeah...4 hour week, but not every week. I don't want to get tired.:) Commented Jun 27, 2013 at 6:34
  • 1
    @Dexter add $installer = $this; as the first line in the installer script. Commented Sep 29, 2015 at 11:25
  • 1
    @mujas. backend is the equivalent of backend_model column in the eav_attribute table. An attribute can support frontend models (that are actually blocks used for rendering the attribute field in the backend), source models (for dropdown and multiselect attributes. this is the source of the options) and backend model. You can use the class you set a backend model to perform actions before the attribute value is saved or after it's loaded. You can use this to perform additional validations or to to alter the value. In this specific case, the array you send from the form is serialized. Commented Oct 14, 2015 at 12:13
3

Add source model whenever you create attribute type dropdown.

'source' => 'eav/entity_attribute_source_table', 
Marius
199k55 gold badges431 silver badges837 bronze badges
answered Feb 18, 2014 at 14:01
0
$valStringArray = array("Nike","Addidas");
createAttribute("Brand","manufacturer",-1,-1,-1,$valStringArray);
//
// Create an attribute.
//
// For reference, see Mage_Adminhtml_Catalog_Product_AttributeController::saveAction().
//
// @return int|false
// 
function createAttribute($labelText, $attributeCode, $values = -1, $productTypes = -1, $setInfo = -1, $options = -1)
{
 $labelText = trim($labelText);
 $attributeCode = trim($attributeCode);
 if($labelText == '' || $attributeCode == '')
 {
 echo "Can't import the attribute with an empty label or code. LABEL= [$labelText] CODE= [$attributeCode]"."<br/>";
 return false;
 }
 if($values === -1)
 $values = array();
 if($productTypes === -1)
 $productTypes = array();
 if($setInfo !== -1 && (isset($setInfo['SetID']) == false || isset($setInfo['GroupID']) == false))
 {
 echo "Please provide both the set-ID and the group-ID of the attribute-set if you'd like to subscribe to one."."<br/>";
 return false;
 }
 echo "Creating attribute [$labelText] with code [$attributeCode]."."<br/>";
 //>>>> Build the data structure that will define the attribute. See
 // Mage_Adminhtml_Catalog_Product_AttributeController::saveAction().
 $data = array(
 'is_global' => '1',
 'frontend_input' => 'select',
 'default_value_text' => '',
 'default_value_yesno' => '0',
 'default_value_date' => '',
 'default_value_textarea' => '',
 'is_unique' => '0',
 'is_required' => '0',
 'frontend_class' => '',
 'is_searchable' => '1',
 'is_visible_in_advanced_search' => '1',
 'is_comparable' => '1',
 'is_used_for_promo_rules' => '0',
 'is_html_allowed_on_front' => '1',
 'is_visible_on_front' => '0',
 'used_in_product_listing' => '0',
 'used_for_sort_by' => '0',
 'is_configurable' => '0',
 'is_filterable' => '1',
 'is_filterable_in_search' => '1',
 'backend_type' => 'varchar',
 'default_value' => '',
 'is_user_defined' => '0',
 'is_visible' => '1',
 'is_used_for_price_rules' => '0',
 'position' => '0',
 'is_wysiwyg_enabled' => '0',
 'backend_model' => '',
 'attribute_model' => '',
 'backend_table' => '',
 'frontend_model' => '',
 'source_model' => '',
 'note' => '',
 'frontend_input_renderer' => '', 
 );
 // Now, overlay the incoming values on to the defaults.
 foreach($values as $key => $newValue)
 if(isset($data[$key]) == false)
 {
 echo "Attribute feature [$key] is not valid."."<br/>";
 return false;
 }
 else
 $data[$key] = $newValue;
 // Valid product types: simple, grouped, configurable, virtual, bundle, downloadable, giftcard
 $data['apply_to'] = $productTypes;
 $data['attribute_code'] = $attributeCode;
 $data['frontend_label'] = array(
 0 => $labelText,
 1 => '',
 3 => '',
 2 => '',
 4 => '',
 );
 //<<<<
 //>>>> Build the model.
 $model = Mage::getModel('catalog/resource_eav_attribute');
 $model->addData($data);
 if($setInfo !== -1)
 {
 $model->setAttributeSetId($setInfo['SetID']);
 $model->setAttributeGroupId($setInfo['GroupID']);
 }
 $entityTypeID = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
 $model->setEntityTypeId($entityTypeID);
 $model->setIsUserDefined(1);
 //<<<<
 // Save.
 try
 {
 $model->save();
 }
 catch(Exception $ex)
 {
 echo "Attribute [$labelText] could not be saved: " . $ex->getMessage()."<br/>";
 if($ex->getMessage() == "Attribute with the same code already exists."){
 if(is_array($options)){
 foreach($options as $_opt){
 addAttributeValue($attributeCode, $_opt);
 }
 }
 }
 return false;
 }
 if(is_array($options)){
 foreach($options as $_opt){
 addAttributeValue($attributeCode, $_opt);
 }
 }
 $id = $model->getId();
 echo "Attribute [$labelText] has been saved as ID ($id).<br/>";
 // Asssign to attribute set.
 $model1 = Mage::getModel('eav/entity_setup','core_setup');
 $model1->addAttributeToSet(
 'catalog_product', 'Default', 'General', $attributeCode
 ); //Default = attribute set, General = attribute group
 // return $id;
}
function addAttributeValue($arg_attribute, $arg_value)
{
 $attribute_model = Mage::getModel('eav/entity_attribute');
 $attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
 $attribute = $attribute_model->load($attribute_code);
 if(!attributeValueExists($arg_attribute, $arg_value))
 {
 $value['option'] = array($arg_value,$arg_value);
 $result = array('value' => $value);
 $attribute->setData('option',$result);
 $attribute->save();
 }
 $attribute_options_model= Mage::getModel('eav/entity_attribute_source_table') ;
 $attribute_table = $attribute_options_model->setAttribute($attribute);
 $options = $attribute_options_model->getAllOptions(false);
 foreach($options as $option)
 {
 if ($option['label'] == $arg_value)
 {
 return $option['value'];
 }
 }
 return false;
}
function attributeValueExists($arg_attribute, $arg_value)
{
 $attribute_model = Mage::getModel('eav/entity_attribute');
 $attribute_options_model= Mage::getModel('eav/entity_attribute_source_table') ;
 $attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
 $attribute = $attribute_model->load($attribute_code);
 $attribute_table = $attribute_options_model->setAttribute($attribute);
 $options = $attribute_options_model->getAllOptions(false);
 foreach($options as $option)
 {
 if ($option['label'] == $arg_value)
 {
 return $option['value'];
 }
 }
 return false;
}

try this. I have added so many attributes and attribute values through this code and you can assign the attribute to attribute set through this code.

answered Jun 2, 2016 at 5:33

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.