Magento 2 – Add Company Column to Customers Admin Grid with Observer

adminhtmlcustomer-grid

I want to add the "Company" column from the customer's Address attributes.

Is there any way to populate this column through an observer or do I need to extend the prepareCollection or preparePage functions?


Working Code:

Observer is set up on event core_block_abstract_prepare_layout_before


XML

/app/code/local/Mbs/Changegrid/etc/config.xml
<?xml version="1.0"?>
<config>
    <modules>
        <Mbs_Changegrid>
            <version>0.4.0</version>
        </Mbs_Changegrid>
    </modules>
    <global>
        <models>
            <mbs_changegrid>
                <class>Mbs_Changegrid_Model</class>
            </mbs_changegrid>
        </models>
    </global>
    <adminhtml>
        <events>
            <core_block_abstract_to_html_before>
                <observers>
                    <changegrid_before_block>
                        <class>Mbs_Changegrid_Model_Observer</class>
                        <method>beforeBlockToHtml</method>
                    </changegrid_before_block>
                </observers>
            </core_block_abstract_to_html_before>
            <eav_collection_abstract_load_before>
                <observers>
                    <changegrid_collection_load>
                        <class>Mbs_Changegrid_Model_Observer</class>
                        <method>beforeCollectionLoad</method>
                    </changegrid_collection_load>
                </observers>
            </eav_collection_abstract_load_before>
        </events>
    </adminhtml>
</config>

PHP

/app/code/local/Mbs/Changegrid/Model/Observer.php
class Mbs_Changegrid_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(
                'company',
                array(
                    'header' => Mage::helper('customer')->__('Company'),
                    'index'  => 'company'
                ),
                'name'
            );
        }
    }

    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('company');
            $addressCollection = Mage::getModel('customer/address')->getCollection()->addAttributeToSelect('company');
            $addressCollection->getSelect()->limit(1);
            $address = $addressCollection->getFirstItem();
            foreach ($address->getAttributes() as $attribute) {
                if (is_null($attribute->getAttributeID()) || is_null($attribute->getFrontendLabel()) || ($attribute->getFrontendLabel() == '')) {
                    continue;
                }
                $collection->joinAttribute($attribute->getName(), 'customer_address/' . $attribute->getName(), 'default_billing', null, 'left');
            }
        }
    }
}

Best Answer

It is possible thru rewrite or observer: (observer is better to prevent rewrite conflicts)

Using Observer

Configure your 2 observers: loading the column to grid and loading of collection

<adminhtml>
    <events>
        <core_block_abstract_to_html_before>
            <observers>
                <{observer_name}>
                    <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>

Then create your observer class with the methods in the declaration

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}');
        }
    }
}

See this answer: https://magento.stackexchange.com/a/5986/21518

Using Rewrite

Rewrite the grid block's _prepareCollection method and add your column to the collection.

See this answer: https://magento.stackexchange.com/a/5975/21518

Related Topic