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. HDMI 8193 配置

    1, User space:ProjectConfig.mkMTK_HDMI_SUPPORT = yes MTK_MULTIBRIDGE_SUPPORT = yesMTK_INTERNAL_HDMI_ ...

  2. 896C

    ODT/珂朵莉树 原来这个东西很咸鱼,只能数据随机情况下nloglogn,不过作为卡常还是很好的 大概就是维护区间,值相同的并且连续当成一个区间存在set里,每次区间操作强行分裂就行了. 复杂度因为是 ...

  3. 用于生成交易统计时间戳(常配合echarts走势图使用)

    <?php //获取交易统计时间戳 时间段内每小时 public function getPayCountTimeHours($start_date,$end_date){ $data = ar ...

  4. html5 滚动小球

    <html> <head> <meta charset="utf-8"/> </head> <body onkeydown=& ...

  5. 页面跳转问题,多次 push 到新的页面的问题的解决方法

    今日在做一个扫一扫的功能,突然发现多次点击了扫一扫的图片后,造成多次触发轻拍手势,就多次push到新的页面,本想在轻拍手势内对push的进行拦截,但是又觉得如果有好多的地方都要实现对该问题的解决岂不是 ...

  6. 华为CodeCraft2018 周进展

    上周: python验证lstm,效果不好.很多拟合的是直线.C++抄了个lstm,输出也是直线,不知道是程序的问题,还是模型的问题. 尝试bp神经网络求解.代码是抄的.回看天数是写死的,隐层只有一层 ...

  7. conditon_variable(条件变量)用于线程间同步

    conditon_variable(条件变量)用于线程间同步 condition_variable有5个函数,函数名及对应的功能如下: wait阻塞自己,等待唤醒 wait_for阻塞自己,等待唤醒, ...

  8. error:: undefined reference to symbol '__glewBufferSubData' 未定义的引用 以及 error: main.o: undefined reference to symbol 'glTexImage2D'

    在把DSO移植到QT工程中,出现了 /usr/bin/ld: KeyFrameDisplay.o: undefined reference to symbol '__glewBufferSubData ...

  9. FZU 2150 Fire Game (高姿势bfs--两个起点)(路径不重叠:一个队列同时跑)

    Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows ...

  10. ZOJ3163【思维题】

    每天取最远的那面 int main() { init(); int n,x,y; while(~scanf("%d%d%d",&n,&x,&y)) prin ...