Know More About Your Customers - Adding Custom Signup Attributes
15 Jun 2009, by Denis Margetic
65 Comments · Posted in Magento

    Magento provides a simple user account signup page. However, some online stores might want to collect relevant customer information for more targeted and personal interactions with their customers. Some examples of details that could be collected include shoe size, clothing size or favourite colour.

    Adding your custom fields on the signup form is not difficult, but it is not trivial either, since one cannot use the Magento backend for the task. As an example of how it can be done, I will demonstrate the addition of a new custom field to the signup form asking new users to enter their favourite ice cream flavour.

    1. We need to make a module to extend the functionality of the customer model. Start by adding the module xml file to the app/etc/modules/ directory. You need to decide on a module name. In this example we will use the Fontis scope, and call the module 'Customer'. Therefore we need to create a file named Fontis_Customer.xml and add the following content:

      <config>
      	<modules>
      		<Fontis_Customer>
      			<active>true</active>
      			<codePool>local</codePool>
      		</Fontis_Customer>
      	</modules>
      </config>
      
    2. Adding the above file means that Magento is now aware of a new custom module. Now, we need to create the module itself, which must be located in the app/code/local/Fontis/Customer directory. Inside this directory, create an etc directory and copying the following file inside:

      app/code/core/Mage/Customer/etc/config.xml

      Edit the file and change :

      <modules>
              <Mage_Customer>
                  <version>x.x.x</version>
              </Mage_Customer>
      </modules>

      to:

      <modules>
              <Fontis_Customer>
                  <version>1.0.0</version>
              </Fontis_Customer>
      </modules>
    3. This file contains two different <fieldsets> - one in <config><admin> and one in <config><global>. At the end of the second one, in the <config><global><fieldsets><customer_account> scope, add:

      <flavour>
              <create>1</create>
              <update>1</update>
      </flavour>
      

      In this example flavour is the chosen attribute code. The attribute code that you choose here will be important in all the following steps.

    4. Now we need to add the attribute to the Customer Entity Setup Model. To do this, copy the getDefaultEntities method from app/code/core/Mage/Customer/Model/Entity/Setup.php file to a new file, Model/Entity/Setup.php in our module. Put the method inside the following class:

      class Fontis_Customer_Model_Entity_Setup extends Mage_Customer_Model_Entity_Setup
      

      Then add the following code at the end of the attributes array inside the customer arrray:

      'flavour' => array(
      	'label'		=> 'Ice Cream Flavour',
      	'visible'	=> true,
      	'required'	=> true,
      ),

      In this case the new attribute is set as compulsory by adding

      'required' => true,
      to the end of that array. If you want the attribute to be optional, remove the required lines.

    5. The new attribute needs to be added to the Magento database. The best way to do this is to tell Magento to insert it for you. You can either create your own script that uses the Magento code or you can just drop the following code into one of your template files:

      $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
      $setup->addAttribute('customer', 'flavour', array(
      	'label'		=> 'Ice Cream Flavour',
      	'type'		=> 'varchar',
      	'input'		=> 'text',
      	'visible'	=> true,
      	'required'	=> true,
      	'position'	=> 1,
      	));

      A handy place to add the above code is the /template/customer/form/register.phtml file since it needs to be edited to add a custom field for the new attribute. Make sure the above code is enclosed with

      
      

      To add the attribute (ie. run this code) view the register new customer page. Once you have viewed the page this code can be removed.

      In this example the attribute type is set to varchar and the input is set to text. This needs to be modified to match the requirements of each specific attribute.

    6. At this point, the attribute is installed and it will show up in the backend. We need to modify the frontend, so that the customers can enter values for the custom attribute. There are two fairly similar phtml files:

      /template/customer/form/register.phtml /template/customer/form/edit.phtml

      As a minimum, you need to add a new text box in the register.phtml file, since that is what customers see on the register page. You can add the same text box in the edit.phtml file so that customers can make changes to the original entry that they have made on sign-up. Make sure that the ID and name of the new input text box match the attribute code chosen in step 3. In this case it is 'flavour'. The following shows the sample code that adds a new text box with a label:



    Address details


    If you only want to add fields for address details you are in luck. Those fields are already setup in the template/customer/form/register.phtml file, but they are disabled by an inactive if statement that so far has not actually been linked to anything else in Magento. Therefore to enable the address related fields you simply need to comment out or delete the following statements:

    getShowAddressFields()): ?>

    and

    
    
    

    Note that there are two occurrences of this if statement. One is around the area where the customer actually inputs their data and the other is at the bottom of the file. The first statement shows all the areas for the customer to enter their data and the second statement is around some JavaScript code that sets up the State/Province select.


    Removing phone number field


    One final issue relates to the telephone number field. By default it is considered a required field and that is hard-coded in the input validation function. If you do not want the telephone field to be mandatory (or any other field for that matter), you need to remove the relevant statement from:

    magento/app/code/core/Mage/Customer/Model/Address/Abstract.php

    This is the code that needs to be removed from public function validate():

    
    if (!Zend_Validate::is($this->getTelephone(), 'NotEmpty')) {
        $errors[] = $helper->__('Please enter telephone.');
    }
    

    In order to make sure that your Magento installation still works properly after you do an upgrade, rather than changing the core file, the safest option is to copy the above file into the following file structure:

    magento/app/code/local/Mage/Customer/Model/Address/Abstract.php

    Since files in /local don't get affected when you run upgrades, it means your signup form will work as expected after an upgrade.


    Magento Compatibility

    Post originally written for Magento version: 1.3.2.4
    Tested with Magento version(s): 1.3.2.4

    Update: Due to a change in core Magento files the technique for adding custom customer attributes had to be modified. This blog post has been updated accordingly, and current instructions have been tested with Magento 1.3.2.4 -- 16/10/2009