Magento 1.x的Export功能可以很方便地对Customers的数据进行导出,但是存在几个不足(或者说不方便)的地方:

  1. 默认导出的 .CSV文件是以UTF-8格式编码的,而MS Excle是无法识别UTF-8编码的,所以导出的 .CSV文件直接在Excle中打开时中文会乱码,乱码不仅会导致中文单元格无法阅读, 而且会影响其它单元格,会使其它单元格错位

  2. 缺少subscriber_status的信息。subscriber_status是用来标识一个Customer是否愿意接收订阅消息(Newsletter),这个信息经常会用到,但很可惜原生Magento Export无法导出subscriber_status信息,因为subscriber_status信息仅仅是Newsletter表的一个Field,不是Customer的attribute。

上面列出的2个不足:

  其中第1条是可以通过文件转码的方式解决的,不需要修改程序,而且修改程序会比较复杂。具体做法是用txt打开下载好的.CVS文件,然后选择“另存为”,在“另存为”对话框的下方,会有选择编码格式的下拉菜单,将编码格式从UTF-8改为ANSI,然后保存即可解决乱码问题。

  第2条是需要修改程序才能解决的。首先来看一下Magento的Default Export是如何实现的:

    在后台的Export页面,通过Form的action(index.php/admin/export/export/key/......./)可以知道,Export请求是在一个名叫Export的Controller中的exportAction中完成的。

    通过在IDE中搜索ExportController.php这个文件名可以很快定位代码位置,主要的工作是在以下这两个代码片段中完成的:

    忽略上下不相关的代码:

 /**
* Load data with filter applying and create file for download.
*
* @return Mage_ImportExport_Adminhtml_ExportController
*/
public function exportAction()
{
......
/** @var $model Mage_ImportExport_Model_Export */
$model = Mage::getModel('importexport/export');
$model->setData($this->getRequest()->getParams()); return $this->_prepareDownloadResponse(
$model->getFileName(),
$model->export(),
$model->getContentType()
);
......
}

    $this->_prepareDownloadResponse($fileName, $content, $contentType = 'application/octet-stream', $contentLength = null)方法是Mage_Core_Controller_Varien_Action 类提供的封装好的方法,它根据参数中提供的文件名、文件内容、文件类型生成一个文件并发送到浏览器,这是一个公用的方法,我们只需要修改传给它的参数就可以修改Magento导出用户(Export customers)功能。

    我现在要给导出的.CSV文件添加subscriber_status项,也就是修改传给_prepareDownloadResponse()方法的第2个参数$model->export():

    具体思路:首先修改$collection,让$collection包含customers的subscriber_status数据

 $collection->getSelect()->joinLeft(
array('ns' => 'newsletter_subscriber'),
'ns.customer_id = e.entity_id',
'ns.subscriber_status'
);

    然后在$row数组中添加subscriber_status数据:

 $row['subscribe_status'] = $this->getSubscriberLabel($item);

    其中, $this->getSubscriberLabel($item) 是新增的用来将subscriber_status转为容易阅读的label的方法:

 protected function getSubscriberLabel($item)
{
$subscriberStatus = (int)$item->getSubscriberStatus();
if(!empty($subscriberStatus)){
switch($subscriberStatus){
case 1: return 'Subscribed';
case 2: return 'Not_Active';
case 3: return 'Unsubscribed';
case 4: return 'Unconfirmed';
default: return null;
}
}
return null;
}

    别忘记添加表头:

 // create export file
$writer->setHeaderCols(array_merge(
array('subscribe_status'),
$this->_permanentAttributes, $validAttrCodes,
array('password'), $addrColNames,
array_keys($defaultAddrMap)
));

    最终修改后的export()方法(修改过或者新增的代码用红色标出):

 /**
* Export process.
*
* @return string
*/
public function export()
{
$collection = $this->_prepareEntityCollection(Mage::getResourceModel('customer/customer_collection'));
$validAttrCodes = $this->_getExportAttrCodes();
$writer = $this->getWriter();
$defaultAddrMap = Mage_ImportExport_Model_Import_Entity_Customer_Address::getDefaultAddressAttrMapping(); // prepare address data
$addrAttributes = array();
$addrColNames = array();
$customerAddrs = array(); foreach (Mage::getResourceModel('customer/address_attribute_collection')
->addSystemHiddenFilter()
->addExcludeHiddenFrontendFilter() as $attribute) {
$options = array();
$attrCode = $attribute->getAttributeCode(); if ($attribute->usesSource() && 'country_id' != $attrCode) {
foreach ($attribute->getSource()->getAllOptions(false) as $option) {
foreach (is_array($option['value']) ? $option['value'] : array($option) as $innerOption) {
if (strlen($innerOption['value'])) { // skip ' -- Please Select -- ' option
$options[$innerOption['value']] = $innerOption['label'];
}
}
}
}
$addrAttributes[$attrCode] = $options;
$addrColNames[] = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
}
foreach (Mage::getResourceModel('customer/address_collection')->addAttributeToSelect('*') as $address) {
$addrRow = array(); foreach ($addrAttributes as $attrCode => $attrValues) {
if (null !== $address->getData($attrCode)) {
$value = $address->getData($attrCode); if ($attrValues) {
$value = $attrValues[$value];
}
$column = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
$addrRow[$column] = $value;
}
}
$customerAddrs[$address['parent_id']][$address->getId()] = $addrRow;
} // create export file
$writer->setHeaderCols(array_merge(
array('subscribe_status'),
$this->_permanentAttributes, $validAttrCodes,
array('password'), $addrColNames,
array_keys($defaultAddrMap)
)); $collection->getSelect()->joinLeft(
array('ns' => 'newsletter_subscriber'),
'ns.customer_id = e.entity_id',
'ns.subscriber_status'
);
foreach ($collection as $itemId => $item) { // go through all customers
$row = array(); // go through all valid attribute codes
foreach ($validAttrCodes as $attrCode) {
$attrValue = $item->getData($attrCode); if (isset($this->_attributeValues[$attrCode])
&& isset($this->_attributeValues[$attrCode][$attrValue])
) {
$attrValue = $this->_attributeValues[$attrCode][$attrValue];
}
if (null !== $attrValue) {
$row[$attrCode] = $attrValue;
}
}
$row[self::COL_WEBSITE] = $this->_websiteIdToCode[$item['website_id']];
$row[self::COL_STORE] = $this->_storeIdToCode[$item['store_id']];
$row['subscribe_status'] = $this->getSubscriberLabel($item);
// addresses injection
$defaultAddrs = array(); foreach ($defaultAddrMap as $colName => $addrAttrCode) {
if (!empty($item[$addrAttrCode])) {
$defaultAddrs[$item[$addrAttrCode]][] = $colName;
}
}
if (isset($customerAddrs[$itemId])) {
while (($addrRow = each($customerAddrs[$itemId]))) {
if (isset($defaultAddrs[$addrRow['key']])) {
foreach ($defaultAddrs[$addrRow['key']] as $colName) {
$row[$colName] = 1;
}
}
$writer->writeRow(array_merge($row, $addrRow['value'])); $row = array();
}
} else {
$writer->writeRow($row);
}
}
return $writer->getContents();
}

    建议不要直接修改Magento Default的代码,例如上面所做的修改,可以通过重写Magento Model的方法来实现。

如果您觉得阅读本文对您有帮助,欢迎转载本文,但是转载文章之后必须在文章页面明显位置保留此段声明,否则保留追究法律责任的权利。

作  者:blog.jpdou.top

原文链接:http://blog.jpdou.top/modify-magento-default-export-customers/

最新文章

  1. Azkaban源码学习笔记
  2. AngularJS 包含
  3. BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流
  4. ORACLE回收站机制介绍
  5. css3 文字过长用...代替
  6. Jmeter使用入门
  7. Python开发【第七篇】:面向对象
  8. likwid工具尝鲜
  9. Android Studio 中关于NDK编译及jni header生成的问题
  10. C# ObjectCache、OutputCache缓存
  11. 禁止 IOS 系统 数字 变超链 (自动识别为电话号码)
  12. jquery 按回城 等于提交按钮
  13. cf B. Inna and Nine
  14. python高级编程之选择好名称:完
  15. win 下python2.7 pymssql连接ms sqlserver 2000
  16. 动态接口服务 webservice
  17. c++ STL常用算法使用方法
  18. struts2对于处理JSON的配置
  19. CENTOS6.6下mysql5.7.11的percona-xtrabackup安装与备份
  20. Linux服务器安装Oracle服务端总结

热门文章

  1. Oracle数据常用操作
  2. 关于cuda 环境遇到的问题
  3. POJ2184(01背包变形)
  4. 安装和配置Rose HA
  5. HTML head元素
  6. js数组,在遍历中删除元素(用 for (var i in arr)是无效的 )
  7. set和multiset容器
  8. Lombok减少代码冗余量
  9. E20190215-mt
  10. 洛谷 - P1390 - 公约数的和 - 莫比乌斯反演 - 欧拉函数