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/

修改Magento默认Export Customers功能的更多相关文章

  1. 修改eclipse的自动完成功能

    修改eclipse的自动完成功能   周银辉 用eclipse时还是比较习惯Visual Studio那样的敲一个字母就弹出自动完成框,而不是总要等到敲.号,其实可以设置的: 在preferences ...

  2. Linux怎样创建FTP服务器--修改用户默认目录

    在创建FTP服务器之有先命令: ps -ef |grep vsftpd 查一下系统有没有安装vsftpd这个服务器,如果出现如下图所示的界面说明没有安装.     然后再执行:yum install ...

  3. 如何修改magento产品详细页面的栏目

    magento默认模板里面的产品信息页面的布局是以两栏带右侧栏显示的,那么如何修改为两栏带左侧栏或者三栏.一栏的方式显示呢?下面教大家一种很简单的方法就可以实现.下面是默认的布局预览:

  4. Linux怎样创建FTP服务器--修改用户默认目录-完美解决 - 费元星

    在创建FTP服务器之有先命令: ps -ef |grep vsftpd 查一下系统有没有安装vsftpd这个服务器,如果出现如下图所示的界面说明没有安装.   然后再执行:yum install vs ...

  5. linux上修改系统默认语言设置

    locale命令设置语言环境(临时修改) [keysystem@localhost ~]$ date Fri Feb :: CST [keysystem@localhost ~]$ locale LA ...

  6. 修改MySQL默认字符集编码

    好记心不如烂笔头,很多东西当时没记下来,过了就忘了,下次用到时又得浪费好多时间才能解决.今天又遇到修改MySQL默认字符集编码的问题,折腾了半天解决了,赶快记录下来,以后就不用每次折腾了. 查看MyS ...

  7. Mysql 修改字段默认值

    环境:MySQL 5.7.13 问题描述:建表的时候,users_info表的role_id字段没有默认值,后期发现注册的时候,需要提供给用户一个默认角色,也就是给role_id字段一个默认值. 当前 ...

  8. SQL SERVER 2012 修改数据库默认位置不立即生效

    今天修改SQL SERVER 2012的数据库默认位置:即数据文件.日志文件默认位置时遇到一个问题,单击"服务器属性"(Server Properties)--> 数据库设置 ...

  9. xampp修改mysql默认密码详解

    在这里介绍xampp修改mysql默认密码的大概过程是先利用xampp的phpmyadmin进入修改mysql密码,修改之后我们再修改xampp中phpmyadmin的密码,这样就完整的修改mysql ...

随机推荐

  1. Django (2006, 'MySQL server has gone away') 本地重现与解决

    最近我们的Django项目供Java Sofa应用进行tr调用时, 经常会出现一个异常: django.db.utils.OperationalError: (2006, 'MySQL server ...

  2. SNE降维与可视化

    from sklearn import datasets digits = datasets.load_digits(n_class=5) X = digits.data y = digits.tar ...

  3. 洛谷 1082 同余方程——exgcd(水题)

    题目:https://www.luogu.org/problemnew/show/P1082 大水题. #include<iostream> #include<cstdio> ...

  4. su命令,sudo命令,visudo命令

    一.命令su 语法 : su [-] username后面可以跟 ‘-‘ 也可以不跟,普通用户su不加username时就是切换到root用户,当然root用户同样可以su到普通用户. ‘-‘ 这个字 ...

  5. bzoj2959

    lct+并查集 联赛之后忘了很多东西 复习一下 这并不是一棵树,所以我们不能直接上lct 但是把双联通分量缩了以后就是一棵树了 怎么缩呢 就是把splay拆了合并到一个点上 连通性和双联通分量拿两个并 ...

  6. JAVA实现DIJKSTRA算法

    import java.util.Queue; import java.util.LinkedList; public class dijkstra{ public static void main( ...

  7. 已有项目 iPhoneX 适配

    一.Assets 文件图片管理下的 LaunchImage 添加 iOS8.0 and latter 一项,并放一张 1125*2436 的LaunchPage 到对应的位置上. 二.有关 iPhon ...

  8. Perfect项目快速上手

    1.在您从Swift.org(英文版)完成Swift 4.0 toolchain工具集安装之后,请打开一个命令行终端并输入命令 swift --version Apple Swift version ...

  9. Unity3D研究院之游戏对象的访问绘制线与绘制面详解(十七)

    一眨眼学习Unity3D 也有一段时间了,基本已经拿下了这套游戏引擎,回过头来想想以前写的RPG 游戏引擎,越来越发现以前写的就是垃圾.人果然是要不断学习与不断进步,好好学习,天天向上.哇咔咔- 加油 ...

  10. jzoj5986. 【WC2019模拟2019.1.4】立体几何题 (权值线段树)

    传送门 题面 题解 不难看出每个点的大小为行列限制中较小的那一个(因为数据保证有解) 对于行的每个限制,能取到的个数是列里限制大于等于它的数的个数,同理,对于列是行里大于它的个数(这里没有等于,为了避 ...