Agregar columnas a la cuadrícula del cliente usando observador o anular la cuadrícula del cliente
-
16-10-2019 - |
Pregunta
Me enfrento a un problema de agregar una columna en la red de clientes y mostrar valores en esa columna.
Aquí está el código del observador que he estado intentando mostrar la columna:-
if ($block->getType() == 'adminhtml/customer_grid') {
$customer = $observer->getCustomer();
$collection = Mage::getResourceModel('customer/customer_collection');
$block->addColumnAfter('mobile', array(
'header' => 'Mobile No.',
'type' => 'text',
'index' => 'mobile',
), 'email');
}
Esto agrega la columna pero no se muestran valores en eso.
Solución
Para agregar una columna a la cuadrícula del cliente, debe anular 2 cosas en el bloque Mage_Adminhtml_Block_Customer_Grid
.
_prepareCollection
- Para agregar su atributo en la colección_prepareColumns
- Para agregar la columna en su cuadrícula.
Para esto, debe crear una nueva extensión. Vamos a llamarlo Easylife_Customer
. Para esto necesitará los siguientes archivos:
app/etc/module/Easylife_Customer.xml
- el archivo de declaración
<?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
- El archivo de configuración
<?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
- Su propia versión de la cuadrícula del cliente. Lea mis comentarios en el código:
<?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();
}
}
Borre el caché y debería estar listo.
Otros consejos
La forma de los observadores:
Declare 2 observadores en su archivo config.xml: uno para agregar su columna al bloque de cuadrícula y el otro para cargar datos del atributo correspondiente:
<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>
Cree una clase de observador con los métodos apropiados:
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}');
}
}
}
Respondo al comentario de Alex:
Para exportar en CSV también usar
core_block_abstract_prepare_layout_before
en vez de
core_block_abstract_to_html_before
Asumiendo que $block
es una instancia de Mage_Adminhtml_Block_Customer_Grid
después
$block->getCollection()
debe devolver una colección de clientes utilizada en la cuadrícula, que es una instancia de Mage_Customer_Model_Resource_Customer_Collection
. Cuando miras el código en Mage_Adminhtml_Block_Customer_Grid::_prepareCollection()
Verá cómo puede agregar un atributo a esa colección.
Debería ser (aunque no probado)
Suponiendo que hay un móvil de atributo agregado a la entidad del cliente
$block->getCollection()
->addAttributeToSelect('mobile');
o si el móvil es y el atributo agregado a la entidad de la dirección de facturación
$block->getCollection()
->joinAttriubte('mobile','customer_address/mobile','defaul_billing',null,'left');
De otra manera:
Reescribir el bloque de cuadrícula de clientes con su módulo personalizado y usar setCollection()
Funcionar para obtener su atributo personalizado.
App/Code/[local o comunidad] /yourcompany/yourmodule/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<yourcompany_yourmodule>
<version>0.1.0</version>
</yourcompany_yourmodule>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<customer_grid>YourCompany_YourModule_Block_Customer_Grid</customer_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
</config>
App/Code/[local o comunidad] /yourcompany/yourmodule/block/customer/grid.php
<?php
class YourCompany_YourModule_Block_Customer_Grid extends Mage_Adminhtml_Block_Customer_Grid
{
public function setCollection($collection)
{
// your field/attribute to fetch, assuming it to be 'mobile'
$collection->addAttributeToSelect('mobile');
parent::setCollection($collection);
}
protected function _prepareColumns()
{
parent::_prepareColumns();
$this->addColumn('mobile', array(
'header'=> Mage::helper('customer')->__('Mobile'),
'index' => 'mobile',
'type' => 'text',
'width' => '100px',
));
// show your new column named 'mobile' after ZIP column
$this->addColumnsOrder('mobile', 'billing_postcode');
return parent::_prepareColumns();
}
}
Necesitaba eliminar algunas columnas predeterminadas y agregar columnas adicionales en la cuadrícula del cliente. Decidí hacer las columnas configurables. Primero agregué 2 cajas multiselectas en system.xml:
<config>
<sections>
<extendedcustomer translate="label" module="extendedcustomer">
<label>Extended Customer</label>
<tab>customer</tab>
<sort_order>100</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<manage_grid translate="label">
<label>Manage Customer Grid in Backend</label>
<frontend_type>text</frontend_type>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<remove translate="label">
<label>Remove Columns</label>
<frontend_type>multiselect</frontend_type>
<source_model>extendedcustomer/source_gridColumn</source_model>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</remove>
<add translate="label">
<label>Add Columns</label>
<frontend_type>multiselect</frontend_type>
<source_model>extendedcustomer/source_attributeCode</source_model>
<sort_order>20</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</add>
</fields>
</manage_grid>
</groups>
</extendedcustomer>
</sections>
</config>
Los modelos de origen son sencillos:
class SomeCo_ExtendedCustomer_Model_Source_GridColumn
{
public function toOptionArray()
{
return [
['value' => 'name', 'label' => 'Name'],
['value' => 'email', 'label' => 'Email'],
['value' => 'group', 'label' => 'Group'],
['value' => 'billing_telephone', 'label' => 'Telephone'],
['value' => 'billing_postcode', 'label' => 'ZIP'],
['value' => 'billing_country_id', 'label' => 'Country'],
['value' => 'billing_region', 'label' => 'State/Province'],
['value' => 'customer_since', 'label' => 'Customer Since'],
['value' => 'website_id', 'label' => 'Website'],
['value' => 'action', 'label' => 'Action']
];
}
}
El segundo modelo fuente
class SomeCo_ExtendedCustomer_Model_Source_AttributeCode
{
public function toOptionArray()
{
$collection = Mage::getResourceModel('customer/attribute_collection')
->addFieldToSelect(['attribute_code', 'frontend_label'])
->addFieldToFilter('frontend_label', ['notnull'=>'notnull'])
->addFieldToFilter('is_user_defined', 1);
$options = [];
foreach ($collection as $item) {
$options[] = [
'value' => $item->getData('attribute_code'),
'label' => $item->getData('frontend_label')
];
}
return $options;
}
}
Luego anule la clase de la cuadrícula:
class SomeCo_ExtendedCustomer_Block_Adminhtml_Customer_Grid extends Mage_Adminhtml_Block_Customer_Grid
{
public function __construct()
{
parent::__construct();
if ($remove = Mage::getStoreConfig('extendedcustomer/manage_grid/remove')) {
$remove = explode(',', $remove);
} else {
$remove = false;
}
$this->setRemoveList($remove);
if ($add = Mage::getStoreConfig('extendedcustomer/manage_grid/add')) {
$add = explode(',', $add);
} else {
$add = false;
}
$this->setAddList($add);
}
protected function _prepareCollection()
{
if ($remove = $this->getRemoveList()) {
$collection = Mage::getResourceModel('customer/customer_collection');
if (!in_array('name', $remove)) {
$collection->addNameToSelect();
}
foreach (['postcode', 'city', 'telephone', 'region', 'country_id'] as $suffix) {
if (!in_array('billing_'.$suffix, $remove)) {
$collection->joinAttribute('billing_'.$suffix, 'customer_address/'.$suffix, 'default_billing', null, 'left');
}
}
} else {
$collection = Mage::getResourceModel('customer/customer_collection')
->addNameToSelect()
//->addAttributeToSelect('email') // static attributes are added by default
//->addAttributeToSelect('created_at')
//->addAttributeToSelect('group_id')
->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');
}
if ($add = $this->getAddList()) {
$collection->addAttributeToSelect($add);
}
$this->setCollection($collection);
return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection(); // call grandParent
}
protected function _prepareColumns()
{
$this->addColumn('entity_id', array(
'header' => Mage::helper('customer')->__('ID'),
'width' => '50px',
'index' => 'entity_id',
'type' => 'number',
));
$remove = $this->getRemoveList();
if (!$remove || !in_array('name', $remove)) {
$this->addColumn('name', array(
'header' => Mage::helper('customer')->__('Name'),
'index' => 'name'
));
}
if ($add = $this->getAddList()) {
$collection = Mage::getResourceModel('customer/attribute_collection')
->addFieldToSelect(['attribute_code', 'frontend_label', 'source_model'])
->addFieldToFilter('attribute_code', ['in' => $add]);
foreach ($collection as $item) {
if ($source = $item->getSourceModel()) {
$this->addColumn($item->getAttributeCode(), array(
'header' => $item->getFrontendLabel(),
'width' => '100',
'index' => $item->getAttributeCode(),
'type' => 'options',
'options' => Mage::getSingleton($source)->toOptionHash(false)
));
} else {
$this->addColumn($item->getAttributeCode(), array(
'header' => $item->getFrontendLabel(),
'width' => '150',
'index' => $item->getAttributeCode()
));
}
}
}
if (!$remove || !in_array('email', $remove)) {
$this->addColumn('email', array(
'header' => Mage::helper('customer')->__('Email'),
'width' => '150',
'index' => 'email'
));
}
if (!$remove || !in_array('group', $remove)) {
$groups = Mage::getResourceModel('customer/group_collection')
->addFieldToFilter('customer_group_id', array('gt'=> 0))
->load()
->toOptionHash();
$this->addColumn('group', array(
'header' => Mage::helper('customer')->__('Group'),
'width' => '100',
'index' => 'group_id',
'type' => 'options',
'options' => $groups,
));
}
if (!$remove || !in_array('billing_telephone', $remove)) {
$this->addColumn('Telephone', array(
'header' => Mage::helper('customer')->__('Telephone'),
'width' => '100',
'index' => 'billing_telephone'
));
}
if (!$remove || !in_array('billing_postcode', $remove)) {
$this->addColumn('billing_postcode', array(
'header' => Mage::helper('customer')->__('ZIP'),
'width' => '90',
'index' => 'billing_postcode',
));
}
if (!$remove || !in_array('billing_country_id', $remove)) {
$this->addColumn('billing_country_id', array(
'header' => Mage::helper('customer')->__('Country'),
'width' => '100',
'type' => 'country',
'index' => 'billing_country_id',
));
}
if (!$remove || !in_array('billing_region', $remove)) {
$this->addColumn('billing_region', array(
'header' => Mage::helper('customer')->__('State/Province'),
'width' => '100',
'index' => 'billing_region',
));
}
if (!$remove || !in_array('customer_since', $remove)) {
$this->addColumn('customer_since', array(
'header' => Mage::helper('customer')->__('Customer Since'),
'type' => 'datetime',
'align' => 'center',
'index' => 'created_at',
'gmtoffset' => true
));
}
if (!$remove || !in_array('website_id', $remove)) {
if (!Mage::app()->isSingleStoreMode()) {
$this->addColumn('website_id', array(
'header' => Mage::helper('customer')->__('Website'),
'align' => 'center',
'width' => '80px',
'type' => 'options',
'options' => Mage::getSingleton('adminhtml/system_store')->getWebsiteOptionHash(true),
'index' => 'website_id',
));
}
}
if (!$remove || !in_array('action', $remove)) {
$this->addColumn('action',
array(
'header' => Mage::helper('customer')->__('Action'),
'width' => '100',
'type' => 'action',
'getter' => 'getId',
'actions' => array(
array(
'caption' => Mage::helper('customer')->__('Edit'),
'url' => array('base'=> '*/*/edit'),
'field' => 'id'
)
),
'filter' => false,
'sortable' => false,
'index' => 'stores',
'is_system' => true,
));
}
$this->addExportType('*/*/exportCsv', Mage::helper('customer')->__('CSV'));
$this->addExportType('*/*/exportXml', Mage::helper('customer')->__('Excel XML'));
return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
}
}