37

my current goal is to add a new customer attribute (with int type) which should appear as select with predefined options (loaded from a model with entries editable in backend, which is done). I'm struggling with proper use of $installer->addAttribute() method, especially specifying correct source option. Other problem is the new attribute isn't saved to eav_entity_attribute table

I'm on Magento CE 1.5.1.0

Jonathan Day
  • 18,519
  • 10
  • 84
  • 137
Zifius
  • 1,650
  • 1
  • 16
  • 27

4 Answers4

70

This is the code for a basic int attribute with text renderer:

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

$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$setup->addAttribute('customer', 'your_attribute_code_here', array(
    'input'         => 'text',
    'type'          => 'int',
    'label'         => 'Some textual description',
    'visible'       => 1,
    'required'      => 0,
    'user_defined' => 1,
));

$entityTypeId     = $setup->getEntityTypeId('customer');
$attributeSetId   = $setup->getDefaultAttributeSetId($entityTypeId);
$attributeGroupId = $setup->getDefaultAttributeGroupId($entityTypeId, $attributeSetId);

$setup->addAttributeToGroup(
 $entityTypeId,
 $attributeSetId,
 $attributeGroupId,
 'your_attribute_code_here',
 '999'  //sort_order
);

$oAttribute = Mage::getSingleton('eav/config')->getAttribute('customer', 'your_attribute_code_here');
$oAttribute->setData('used_in_forms', array('adminhtml_customer'));
$oAttribute->save();

$setup->endSetup();

The unusual step for adding attributes is the setData('used_in_forms') this seems to be unique to customer attributes. Without it, the field won't get rendered, certainly not in the adminhtml anyway. You can see the valid options for this array in the customer_form_attribute database table.

In terms of using a select with predefined options, this is what you need:

$iAttributeId = $installer->getAttributeId($entityTypeId, 'your_attribute_code_here');
$aClasses = array('TV','DVD','Home Theatre','Air Conditioner','Stereo/Hifi','Game Console','Camcorder','VCR','Set Top Box','PVR');
$aOption = array();
$aOption['attribute_id'] = $iAttributeId;

for($iCount=0;$iCount<sizeof($aClasses);$iCount++){
    $aOption['value']['option'.$iCount][0] = $aClasses[$iCount];
}
$setup->addAttributeOption($aOption);

And here is a walk-through on using a custom source for your drop-down

Hope this helps,
JD

Black
  • 18,150
  • 39
  • 158
  • 271
Jonathan Day
  • 18,519
  • 10
  • 84
  • 137
  • Thanks for the reply, I will be giving this a try. As for predefined options they should not be static in my case but editable from admin interface, that's why I was trying to make use of `source` option – Zifius May 11 '11 at 10:37
  • Edited with link for dynamic options. My example of predefined options are editable in the admin if you are using a version of Magento that provides the Customer Attribute Manager, it's just a starting set. – Jonathan Day May 11 '11 at 13:18
  • Just tried your code and its worked like a charm, addAttributeToGroup call was really helpful. Also I set up the source option. – Zifius May 17 '11 at 09:48
  • But now I've got different problem - the attribute value is not saved from registration form to `customer_entity_int` table, although I have `` set up for `` for my attribute name. On the other side should the new attribute appear on the registration form or additional coding required? I use custom block injected using `getChildHtml` but this feels wrong. Hope this not out of scope for my initial question – Zifius May 17 '11 at 09:54
  • @zifius - it would be easier to answer if you ask a separate question. If you can see your attribute installed as you desire, mark this as accepted and we'll try to answer the next one. Cheers, JD – Jonathan Day May 17 '11 at 11:41
  • Ok, just did that, thanks again for clear answer. Best regards, Alex – Zifius May 17 '11 at 13:17
  • 7
    **Attention with sort_order:** With code like that I always got sort_order = 0 in the DB, it took me some hours of debugging to see why: addAttributeToGroup() works fine but $oAttribute->save() overwrites the sort_order again, actually it executed the following queries: `INSERT INTO customer_form_attribute (form_code,attribute_id) VALUES('adminhtml_customer',159); UPDATE eav_entity_attribute SET sort_order = 0 WHERE (attribute_id='159')` **Solution:** Set sort_order before saving the attribute instead: `$oAttribute->setData('sort_order', $sortOrder);` – Fabian Schmengler Aug 03 '11 at 21:32
  • Thanks @Fabian, I've noticed the sorting issue but didn't bother to check why it was happening as everything else worked – Zifius Aug 19 '11 at 08:18
  • 3
    If you need help knowing how to add this setup information to your install then I recommend using this post: http://alanstorm.com/magento_setup_resources – Chris Sep 19 '11 at 14:40
  • Mage::getSingleton('eav/config')->getAttribute('customer', 'your_attribute_code_here'); keeps returning a Mage_Eav_Model_Entity_Attribute vs a Mage_Customer_Model_Entity_Attribute object. it looks the same, just has a different attribute code. any ideas why this happens? – veilig Nov 10 '11 at 20:48
  • I was getting the following error on Magento Enterprise 1.12 on the server. It worked fine on localhost. Had become a nightmare. After I removed $setup = new Mage_Eav_Model_Entity_Setup('core_setup'); everything worked fine. I changed it to: $setup = $this; $setup->startSetup(); ------------------------------ Install Error: exception 'Exception' with message 'Notice: Trying to get property of non-object in /var/www/vhosts/mage/app/code/core/Mage/Core/Model/Resource/Setup.php on line 139' in /var/www/vhosts/mage/app/code/core/Mage/Core/functions.php:245 – Hashid Hameed Sep 19 '14 at 09:54
  • @JonathanDay you are executing `$installer->startSetup();` but then at the end `$setup->endSetup();` ??? – Black Sep 14 '18 at 15:44
23

@Jonathan Day's answer is great and helped me tremendously. However - as long as you've set your setup class to Mage_Customer_Model_Entity_Setup, then Magento can do all of that work for you:

<!-- config.xml Example -->
<?xml version="1.0"?>
<config>
    <global>
        <resources>
            <acme_module_setup>
                <setup>
                    <module>Acme_Module</module>
                    <class>Mage_Customer_Model_Entity_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </acme_module_setup>
        </resources>
    </global>
</config>

And here is the mysql4-install-X.X.X.php file:

<?php

$installer = $this;
/* @var $installer Mage_Customer_Model_Entity_Setup */

$installer->startSetup();

$installer->addAttribute(
    'customer',
    'acme_imported',
    array(
        'group'                => 'Default',
        'type'                 => 'int',
        'label'                => 'Imported into Acme',
        'input'                => 'select',
        'source'               => 'eav/entity_attribute_source_boolean',
        'global'               => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
        'required'             => 0,
        'default'              => 0,
        'visible_on_front'     => 1,
        'used_for_price_rules' => 0,
        'adminhtml_only'       => 1,
    )
);

$installer->endSetup();

The adminhtml_only above will handle all of the used_in_forms logic for you. Also, defining group will take care of assigning it to the attribute group.

Community
  • 1
  • 1
leek
  • 11,803
  • 8
  • 45
  • 61
  • 3
    Using 1.7.0.2 CE, the *adminhtml_only* trick didn't work for me. I still had to add: `Mage::getSingleton( 'eav/config' )->getAttribute( 'customer', $custom_attribute_id )->setData( 'used_in_forms', array( 'adminhtml_customer' ) )->save()` for the attribute to show up in the backend. – Louis B. Mar 30 '13 at 13:42
4

Just you have add your customer attribute under by your custom module mysql setup file through the following script.

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


$installer->addAttribute("customer", "yourattributename",  array(
    "type"     => "int",
    "backend"  => "",
    "label"    => "Bad Customer",
    "input"    => "select",
    "source"   => "eav/entity_attribute_source_boolean",
    "visible"  => true,
    "required" => false,
    "default" => "",
    "frontend" => "",
    "unique"     => false,
    "note"       => ""

    ));

        $attribute   = Mage::getSingleton("eav/config")->getAttribute("customer", "yourattributename");

The following script used for where want to use customer attribute

$used_in_forms=array();

$used_in_forms[]="adminhtml_customer";
        $attribute->setData("used_in_forms", $used_in_forms)
        ->setData("is_used_for_customer_segment", true)
        ->setData("is_system", 0)
        ->setData("is_user_defined", 1)
        ->setData("is_visible", 0)
        ->setData("sort_order", 100)
        ;
        $attribute->save();

$installer->endSetup();
Alexandar
  • 81
  • 2
0

The solution provide by alex and leek both worked for me. Only I have to add the setter function in our AccountController.php

$customer->setProfession($this->getRequest()->getPost('profession')) 
                        ->save(); // Added for updating Profession

Where "profession" was my custom attribute.

Suman-PHP4U
  • 1,185
  • 11
  • 13