Adding columns to customer grid using observer or overriding the customer grid
The Observers way:
Declare 2 observers in your config.xml file: one to add your column to the grid block and the other one to load data from the corresponding attribute:
<adminhtml>
<events>
<core_block_abstract_to_html_before>
<observers>
<{observer_name}>
<type>singleton</type>
<class>{namespace}_{module}/observer</class>
<method>beforeBlockToHtml</method>
</{observer_name}>
</observers>
</core_block_abstract_to_html_before>
<eav_collection_abstract_load_before>
<observers>
<{observer_name}>
<class>{namespace}_{module}/observer</class>
<method>beforeCollectionLoad</method>
</{observer_name}>
</observers>
</eav_collection_abstract_load_before>
</events>
</adminhtml>
Create an Observer class with appropriate methods:
class {Namespace}_{Module}_Model_Observer
{
public function beforeBlockToHtml(Varien_Event_Observer $observer)
{
$grid = $observer->getBlock();
/**
* Mage_Adminhtml_Block_Customer_Grid
*/
if ($grid instanceof Mage_Adminhtml_Block_Customer_Grid) {
$grid->addColumnAfter(
'{column_code}',
array(
'header' => Mage::helper('{Module}_customer')->__('{{column_name}}'),
'index' => '{column_code}'
),
'entity_id'
);
}
}
public function beforeCollectionLoad(Varien_Event_Observer $observer)
{
$collection = $observer->getCollection();
if (!isset($collection)) {
return;
}
/**
* Mage_Customer_Model_Resource_Customer_Collection
*/
if ($collection instanceof Mage_Customer_Model_Resource_Customer_Collection) {
/* @var $collection Mage_Customer_Model_Resource_Customer_Collection */
$collection->addAttributeToSelect('{attribute_code}');
}
}
}
To add a column to the customer grid, you need to override 2 things in the block Mage_Adminhtml_Block_Customer_Grid
.
_prepareCollection
- to add your attribute in the collection_prepareColumns
- to add the column in your grid.
For this you should create a new extension. Let's call it Easylife_Customer
. For this you will need the following files:
app/etc/module/Easylife_Customer.xml
- the declaration file
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Customer>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Customer /><!-- your module should depend on Mage_Customer -->
<Mage_Adminhtml /><!-- your module should depend on Mage_Adminhtml also -->
</depends>
</Easylife_Customer>
</modules>
</config>
app/code/local/Easylife/Customer/etc/config.xml
- the configuration file
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Customer>
<version>0.0.1</version>
</Easylife_Customer>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<customer_grid>Easylife_Customer_Block_Adminhtml_Customer_Grid</customer_grid><!-- rewrite the customer grid -->
</rewrite>
</adminhtml>
</blocks>
</global>
</config>
app/code/local/Easylife/Customer/Block/Adminhtml/Customer/Grid.php
- your own version of the customer grid. Read my comments in the code:
<?php
class Easylife_Customer_Block_Adminhtml_Customer_Grid extends Mage_Adminhtml_Block_Customer_Grid{
/**
* override the _prepareCollection to add an other attribute to the grid
* @return $this
*/
protected function _prepareCollection(){
$collection = Mage::getResourceModel('customer/customer_collection')
->addNameToSelect()
->addAttributeToSelect('email')
->addAttributeToSelect('created_at')
->addAttributeToSelect('group_id')
//if the attribute belongs to the customer, use the line below
->addAttributeToSelect('mobile')
//if the attribute belongs to the customer address, comment the line above and use the one below
//->joinAttribute('mobile', 'customer_address/mobile', 'default_billing', null, 'left')
->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left');
$this->setCollection($collection);
//code from Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
//since calling parent::_prepareCollection will render the code above useless
//and you cannot call in php parent::parent::_prepareCollection()
if ($this->getCollection()) {
$this->_preparePage();
$columnId = $this->getParam($this->getVarNameSort(), $this->_defaultSort);
$dir = $this->getParam($this->getVarNameDir(), $this->_defaultDir);
$filter = $this->getParam($this->getVarNameFilter(), null);
if (is_null($filter)) {
$filter = $this->_defaultFilter;
}
if (is_string($filter)) {
$data = $this->helper('adminhtml')->prepareFilterString($filter);
$this->_setFilterValues($data);
}
else if ($filter && is_array($filter)) {
$this->_setFilterValues($filter);
}
else if(0 !== sizeof($this->_defaultFilter)) {
$this->_setFilterValues($this->_defaultFilter);
}
if (isset($this->_columns[$columnId]) && $this->_columns[$columnId]->getIndex()) {
$dir = (strtolower($dir)=='desc') ? 'desc' : 'asc';
$this->_columns[$columnId]->setDir($dir);
$this->_setCollectionOrder($this->_columns[$columnId]);
}
if (!$this->_isExport) {
$this->getCollection()->load();
$this->_afterLoadCollection();
}
}
return $this;
}
/**
* override the _prepareColumns method to add a new column after the 'email' column
* if you want the new column on a different position just change the 3rd parameter
* of the addColumnAfter method to the id of your desired column
*/
protected function _prepareColumns(){
$this->addColumnAfter('mobile', array(
'header' => Mage::helper('customer')->__('Mobile'),
'index' => 'mobile'
),'email');
return parent::_prepareColumns();
}
}
Clear the cache and you should be ready.
I reply to Alex comment :
To export in CSV too use
core_block_abstract_prepare_layout_before
instead of
core_block_abstract_to_html_before