Adding customer attributes and displaying them in the Magento admin

Share

No doubt, many a work hour has been dedicated to adding custom customer data to Magento Commerce. Magento is an extremely robust and flexible e-commerce engine, allowing you to customize products with an infinite number of attributes, but this level of customization has not been applied to configuration of customer data.

One of the most common customer attributes has to be an account number. This is especially common with wholesalers. In this post I’ll go over how I added an account number attribute to a Magento site I’m working on for my employer. The basic principles covered here should carry over to any basic customer data you want added to the Magento admin tool. I am assuming you are already familiar with building modules for Magento;

Getting Started

We have basically two objectives:

  1. Provide an input field in the Magento admin tool to add and store the account number
  2. Display the account number in the customer profile section of the admin tool

A possible third objective would be to display this data to the customer on the front end, but we’ll hold off on that part for another day.

Like any good Magento developer, we’ll build our own module. Our module namespace will be “Echotrue” and our module name will be “Customer.”

Building the Customer Module

Our module only handles the first objective listed above, which is to provide a means to input and update the customer account number through the admin tool.

Here is what our module directory structure looks like:

app
etc
local.xml
modules
Echotrue_Customer.xml
code
local
Echotrue
Customer
etc
config.xml
Model
Resource
Eav
Mysql4
Setup.php
sql
customer_setup
mysql4-install-0.1.0.php

Module Declaration

There is nothing special about our module declaration.

app/etc/modules/Echotrue_Customer.xml

<config>
<modules>
<Echotrue_Customer>
<active>true</active>
<codePool>local</codePool>
</Echotrue_Customer>
</modules>
</config>

Module Configuration

Our config.xml file is where we tell Magento what we’re doing in our module.

Echotrue/Customer/etc/config.xml

<config>
<modules>
<Echotrue_Customer>
<version>0.1.0</version>
</Echotrue_Customer>
</modules>
<global>
<fieldsets>
<customer_account>
<accountnumber><create>1</create><update>1</update></accountnumber>
</customer_account>
</fieldsets>
<models>
<customer>
<class>Echotrue_Customer_Model</class>
</customer>
</models>
<resources>
<customer_setup>
<setup>
<module>Echotrue_Customer</module>
<class>Echotrue_Customer_Model_Resource_Eav_Mysql4_Setup</class>
</setup>
<connection>
<use>core_setup</use>
</connection>
</customer_setup>
<customer_write>
<connection>
<use>core_write</use>
</connection>
</customer_write>
<customer_read>
<connection>
<use>core_read</use>
</connection>
</customer_read>
</resources>
</global>
</config>

The contents of the <fieldsets> node tells Magento that we want to add an attribute input called “accountnumber” to the customer/account form. The <create> and <update> nodes tell the system that this field should be able to create a new attribute value entry and also be able to update an existing entry. These database connections are handled using the “core_write” and “core_read” connection objects as defined using<customer_write> and <customer_read>.

The <customer_setup> node tells Magento that we have a setup resource. This setup resource is how we’ll add our custom attribute, and is necessary because we have no way using the admin tool to create a customer attribute. Anyway, it’s nice to have this done during the install of the module so things just work from the start with no setup.

Module Attribute Setup

Our setup class is an extension of Mage_Eav_Model_Entity_Setup and consists of a function called getDefaultEntitites(). This function returns an array that defines our attribute. You can install any kind of attribute in this manner and the best place to get more info on these attribute properties is, unfortunately, the Magento core. I’ll go over the properties I’ve used for the “accountnumber” attribute so you know what’s going on.

Echotrue/Customer/Model/Resource/Eav/Mysql4/Setup.php

class Echotrue_Customer_Model_Resource_Eav_Mysql4_Setup extends Mage_Eav_Model_Entity_Setup
{
public function getDefaultEntities()
{
return array(
'customer' => array(
'entity_model' =>'customer/customer',
'table' => 'customer/entity',
'increment_model' => 'eav/entity_increment_numeric',
'increment_per_store' => false,
'attributes' => array(
'accountnumber' => array(
'type' => 'varchar',
'input' => 'text',
'label' => 'Account Number',
'visible' => true,
'required' => false,
'position' => 69,
),
),
),
);
}
}

The root array consists of a single key called “customer,” which is the type of attribute we’re adding. If we were adding a product attribute, we’d use a key value of “catalog_product.” These names follow along with the Magento namespacing we see everywhere else in Magento.

The value of this single key is a nested array of properties. “Entity_model” tells the system with which model to associate our attribute. Ours is a customer attribute, so the system will use the customer model of the customer module. The “table” key/value pair defines the database table in which our attribute values will be stored. Just an FYI: If you look in the database you’ll be hard pressed to find a table called “customer/entity.” This value is found by the system the the customer module’s config.xml file.

I have to assume that the “increment_model” and “increment_per_store” properties deal with how Magento handles the primary keys of eav attributes in the database. The documentation on this stuff is non-existent.

Finally, we come to the “attributes” property. This property is yet another array. This is where we define any attributes we want our module to install, each as an array of key/value pairs. There are a ton of possible properties; I refer you, again, to the source code or the Magento community for more info here.

The properties for our attribute are pretty self explanatory save one, the “position” attribute. You’ll notice the value of “69.” No, I did not add this as a joke. It’s the position of our form input in relation to all of the other customer attribute input fields in the admin tool. I got this number by looking at Customer/Model/Entity/Setup.php.

Ok, that was a lot of info. I promise we’re almost done with our module.

Module Installation

The next bit is our installer. All this does is tell Magento to run the module installation script that will use the class we setup in the previous step.

Echotrue/Customer/sql/customer_setup.php

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

I just hit the high points on module creation and installation. There is a lot more to it I assure you, but this will get you going in the right direction. If all went well, you should have a new input labeled “Account Number” which will accept and store whatever you put into it.

Displaying our Attribute Value

The next step is to display this value on the initial customer information screen in the admin tool. If you wanted to skip this step you could, as the attribute value will be displayed in the account information screen inside our new input field. However, I wanted our customer service staff to see the account number on the first screen – one less click. This is vital information, after all.

Magento does not have a way to define an admin template like it does for websites/stores. We’ll have to tell Magento that we’re using a different admin theme. To do this, we need to edit the local.xml file by adding the following code.

app/code/etc/local.xml

<config>
...
<stores>
<admin>
<design>
<theme>
<default>echotrue</default>
</theme>
</design>
</admin>
</stores>
...
</config>

Now we’ll add our new admin theme just like we would for a website, except the template goes under the adminhtml directory instead of the frontend directory.

Our directory structure will look like this:

app
design
adminhtml
default
echotrue
template
customer
tab
view.phtml

For the view.phtml we can just copy the same file from the default template and make our changes. I wanted the account number to be at the top of the left column, so added the following table row to the table with the class name of “box-left”.

...
<tr>
<td><strong><?php echo $this->__('Account Number:') ?></strong></td>
<td>
<?php
if ($this->getCustomer()->getAccountnumber() )
{
echo $this->getCustomer()->getAccountnumber();
}else { echo "<strong class='error'>Not Set</strong>"; }
?>
</td>
</tr>
...

We’re essentially checking to see if a value exists for our attribute and echoing it. If no value exists, a notification is given to the user that the value has not yet been declared. Simple!

Leave a Reply

You must be logged in to post a comment.