Pages

Thursday, January 1, 2015

How to adding custom product attributes in Magento using setup script

Have you tried to add custom product attributes using the setup script and wondering why certain properties of the attribute are not set?
And in top of that, you're are running out time for this simple task, just because you don't find the right answer..
Here is an approach, how to solve this problem. Probably not the perfect solution, but it works ..!
To get started, you need to handle 3 parts in your module:

/yournamespace/modulename/sql/modulename_setup/install-0.1.0.php
/yournamespace/modulename/Resource/Eav/Mysql4/setup.php
/yournamespace/modulename/etc/config.xml

So let's start with the 1st part:
(Hint: if you update your module, name the script 'update-x.x.x.php')


<?php
/**
 * Add my_attribute values 
 * example by http://magento4newbies.blogspot.com.
 *
 */

$installer = $this;
$installer->startSetup();

$installer->addAttribute('catalog_product', 'my_attribute_date', array(
    'group'             => 'My Attribute Set',
    'label'             => 'My Attribute Date',
    'type'              => 'datetime',
    'input'             => 'date',
    'backend'           => 'eav/entity_attribute_backend_datetime',
    'frontend'          => '',
    'visible'           => true,
    'required'          => false,
    'user_defined'      => true,
    'searchable'        => false,
    'filterable'        => false,
    'comparable'        => false,
    'visible_on_front'  => true,
    'visible_in_advanced_search' => false,
    'unique'            => false,
    'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
));


$installer->endSetup();

You can modify 'input' and 'type' according to your needs:

//For textfield
'input' => 'text',
'type' => 'text',

//For textarea
'input' => 'textarea',
'type' => 'text',

//For date field
'input' => 'date',
'type' => 'datetime',

//For select list 
'input' => 'select',
'type' => 'text',

//For yes/no
'input' => 'boolean',
'type' => 'int',

2nd part is to define your resource class, so that your attribute's properties are written as expected:

<?php
/**
 * Yournamespace_Modulename_Model_Resource_Eav_Mysql4_Setup
 * example by http://magento4newbies.blogspot.com.
 *
 */

class Yournamespace_Modulename_Model_Resource_Eav_Mysql4_Setup extends Mage_Eav_Model_Entity_Setup
{
 
     /**
     * Prepare catalog attribute values to save
     * From: Mage_Catalog_Model_Resource_Setup
     *
     * @param array $attr
     * @return array
     */
    protected function _prepareValues($attr)
    {
        $data = parent::_prepareValues($attr);
        $data = array_merge($data, array(

            'apply_to'                      => $this->_getValue($attr, 'apply_to'),
            'frontend_input_renderer'       => $this->_getValue($attr, 'input_renderer'),
            'is_comparable'                 => $this->_getValue($attr, 'comparable', 0),
            'is_configurable'               => $this->_getValue($attr, 'is_configurable', 1),
            'is_filterable'                 => $this->_getValue($attr, 'filterable', 0),
            'is_filterable_in_search'       => $this->_getValue($attr, 'filterable_in_search', 0),
            'is_global'                     => $this->_getValue(
                $attr,
                'global',
                Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE
            ),
            'is_html_allowed_on_front'      => $this->_getValue($attr, 'is_html_allowed_on_front', 0),
            'is_searchable'                 => $this->_getValue($attr, 'searchable', 0),
            'is_used_for_promo_rules'       => $this->_getValue($attr, 'used_for_promo_rules', 0)
            'is_visible'                    => $this->_getValue($attr, 'visible', 1),
            'is_visible_on_front'           => $this->_getValue($attr, 'visible_on_front', 1),
            'is_wysiwyg_enabled'            => $this->_getValue($attr, 'wysiwyg_enabled', 0),
            'is_visible_in_advanced_search' => $this->_getValue($attr, 'visible_in_advanced_search', 0),
            'position'                      => $this->_getValue($attr, 'position', 0),
            'used_for_sort_by'              => $this->_getValue($attr, 'used_for_sort_by', 0),
            'used_in_product_listing'       => $this->_getValue($attr, 'used_in_product_listing', 0),
        ));
        return $data;
    }
}

And for the last part, you need to set the resource class and the right version number in config.xml.
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <yournamespace_modulename>
            <version>x.x.x</version> 
        </yournamespace_modulename>
    </modules>
    <global>
        <resources>
            <yournamespace_modulename_setup>
                <setup>
                    <module>Yournamespace_Modulename</module>
                    <class>Yournamespace_Modulename_Model_Resource_Eav_Mysql4_Setup</class>
                </setup>
            </yournamespace_modulename_setup>
        </resources>
    </global>
</config>

Now when you check your attributes within the Magento Admin GUI (Catalog->Attributes->Manage Attributes), you see is_filterable, is_visible, is_visible_on_front, is_html_allowed_on_front and the other parameters set to the same value as in the setup script.