修改Magento默认Export Customers功能

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这个文件名可以很快定位代码位置,主要的工作是在以下这两个代码片段中完成的:

    忽略上下不相关的代码:

 1 /**
 2      * Load data with filter applying and create file for download.
 3      *
 4      * @return Mage_ImportExport_Adminhtml_ExportController
 5      */
 6     public function exportAction()
 7     {
 8          ......
 9                 /** @var $model Mage_ImportExport_Model_Export */
10                 $model = Mage::getModel(‘importexport/export‘);
11                 $model->setData($this->getRequest()->getParams());
12
13                 return $this->_prepareDownloadResponse(
14                     $model->getFileName(),
15                     $model->export(),
16                     $model->getContentType()
17                 );
18          ......
19     }

    $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数据

1 $collection->getSelect()->joinLeft(
2     array(‘ns‘ => ‘newsletter_subscriber‘),
3     ‘ns.customer_id = e.entity_id‘,
4     ‘ns.subscriber_status‘
5 );

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

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

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

 1 protected function getSubscriberLabel($item)
 2 {
 3     $subscriberStatus = (int)$item->getSubscriberStatus();
 4     if(!empty($subscriberStatus)){
 5         switch($subscriberStatus){
 6             case 1: return ‘Subscribed‘;
 7             case 2: return ‘Not_Active‘;
 8             case 3: return ‘Unsubscribed‘;
 9             case 4: return ‘Unconfirmed‘;
10             default: return null;
11         }
12     }
13     return null;
14 }

    别忘记添加表头:

1 // create export file
2 $writer->setHeaderCols(array_merge(
3     array(‘subscribe_status‘),
4     $this->_permanentAttributes, $validAttrCodes,
5     array(‘password‘), $addrColNames,
6     array_keys($defaultAddrMap)
7 ));

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

  1 /**
  2  * Export process.
  3  *
  4  * @return string
  5  */
  6 public function export()
  7 {
  8     $collection     = $this->_prepareEntityCollection(Mage::getResourceModel(‘customer/customer_collection‘));
  9     $validAttrCodes = $this->_getExportAttrCodes();
 10     $writer         = $this->getWriter();
 11     $defaultAddrMap = Mage_ImportExport_Model_Import_Entity_Customer_Address::getDefaultAddressAttrMapping();
 12
 13     // prepare address data
 14     $addrAttributes = array();
 15     $addrColNames   = array();
 16     $customerAddrs  = array();
 17
 18     foreach (Mage::getResourceModel(‘customer/address_attribute_collection‘)
 19                  ->addSystemHiddenFilter()
 20                  ->addExcludeHiddenFrontendFilter() as $attribute) {
 21         $options  = array();
 22         $attrCode = $attribute->getAttributeCode();
 23
 24         if ($attribute->usesSource() && ‘country_id‘ != $attrCode) {
 25             foreach ($attribute->getSource()->getAllOptions(false) as $option) {
 26                 foreach (is_array($option[‘value‘]) ? $option[‘value‘] : array($option) as $innerOption) {
 27                     if (strlen($innerOption[‘value‘])) { // skip ‘ -- Please Select -- ‘ option
 28                         $options[$innerOption[‘value‘]] = $innerOption[‘label‘];
 29                     }
 30                 }
 31             }
 32         }
 33         $addrAttributes[$attrCode] = $options;
 34         $addrColNames[] = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
 35     }
 36     foreach (Mage::getResourceModel(‘customer/address_collection‘)->addAttributeToSelect(‘*‘) as $address) {
 37         $addrRow = array();
 38
 39         foreach ($addrAttributes as $attrCode => $attrValues) {
 40             if (null !== $address->getData($attrCode)) {
 41                 $value = $address->getData($attrCode);
 42
 43                 if ($attrValues) {
 44                     $value = $attrValues[$value];
 45                 }
 46                 $column = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
 47                 $addrRow[$column] = $value;
 48             }
 49         }
 50         $customerAddrs[$address[‘parent_id‘]][$address->getId()] = $addrRow;
 51     }
 52
 53     // create export file
 54     $writer->setHeaderCols(array_merge(
 55         array(‘subscribe_status‘),
 56         $this->_permanentAttributes, $validAttrCodes,
 57         array(‘password‘), $addrColNames,
 58         array_keys($defaultAddrMap)
 59     ));
 60
 61     $collection->getSelect()->joinLeft(
 62         array(‘ns‘ => ‘newsletter_subscriber‘),
 63         ‘ns.customer_id = e.entity_id‘,
 64         ‘ns.subscriber_status‘
 65     );
 66     foreach ($collection as $itemId => $item) { // go through all customers
 67         $row = array();
 68
 69         // go through all valid attribute codes
 70         foreach ($validAttrCodes as $attrCode) {
 71             $attrValue = $item->getData($attrCode);
 72
 73             if (isset($this->_attributeValues[$attrCode])
 74                 && isset($this->_attributeValues[$attrCode][$attrValue])
 75             ) {
 76                 $attrValue = $this->_attributeValues[$attrCode][$attrValue];
 77             }
 78             if (null !== $attrValue) {
 79                 $row[$attrCode] = $attrValue;
 80             }
 81         }
 82         $row[self::COL_WEBSITE] = $this->_websiteIdToCode[$item[‘website_id‘]];
 83         $row[self::COL_STORE]   = $this->_storeIdToCode[$item[‘store_id‘]];
 84         $row[‘subscribe_status‘] = $this->getSubscriberLabel($item); 86
 87         // addresses injection
 88         $defaultAddrs = array();
 89
 90         foreach ($defaultAddrMap as $colName => $addrAttrCode) {
 91             if (!empty($item[$addrAttrCode])) {
 92                 $defaultAddrs[$item[$addrAttrCode]][] = $colName;
 93             }
 94         }
 95         if (isset($customerAddrs[$itemId])) {
 96             while (($addrRow = each($customerAddrs[$itemId]))) {
 97                 if (isset($defaultAddrs[$addrRow[‘key‘]])) {
 98                     foreach ($defaultAddrs[$addrRow[‘key‘]] as $colName) {
 99                         $row[$colName] = 1;
100                     }
101                 }
102                 $writer->writeRow(array_merge($row, $addrRow[‘value‘]));
103
104                 $row = array();
105             }
106         } else {
107             $writer->writeRow($row);
108         }
109     }
110     return $writer->getContents();
111 }

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

本文版权属作者所有,转载请注明出处: http://www.cnblogs.com/jpdoutop/p/Magento-Customers-Export.html

(完)

时间: 2024-09-28 14:12:33

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

修改Magento默认Export Customs功能

Magento 1.x的Export功能可以很方便地对Products和Customs的数据进行导出,但是存在几个不足(或者说不方便)的地方: 1. 默认导出的 .CSV文件是以UTF-8格式编码的,而MS Excle的默认编码格式是Unicode,所以导出的 .CSV文件直接在Excle中打开时中文会乱码,乱码不仅会导致中文单元格无法阅读,别且会影响其它单元格,会使其它单元格错位 2. 缺少is_subscribed的信息.is_subscribed是用来标识一个Custom是否愿意接收订阅消

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

magento默认模板里面的产品信息页面的布局是以两栏带右侧栏显示的,那么如何修改为两栏带左侧栏或者三栏.一栏的方式显示呢?下面教大家一种很简单的方法就可以实现.下面是默认的布局预览:修改成两栏带左侧栏后的效果:修改成三栏后的效果:修改成一栏效果: 这样的效果很容易实现的,首先你需打开catalog.xml文件1.3版本app > design > frontend > default > deault > layout > catalog.xml1.4版本app &g

修改eclipse的自动完成功能

修改eclipse的自动完成功能   周银辉 用eclipse时还是比较习惯Visual Studio那样的敲一个字母就弹出自动完成框,而不是总要等到敲.号,其实可以设置的: 在preferences -> Java -> Editor -> Content assist -> Auto Activation 下 默认的"auto activation triggers for java" 只有一个小数点 把它改成abcdefghijklmnopqrstuvwx

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

在创建FTP服务器之有先命令: ps -ef |grep vsftpd 查一下系统有没有安装vsftpd这个服务器,如果出现如下图所示的界面说明没有安装.   然后再执行:yum install vsftpd -y 进行在线安装vsftpd这个服务.   安装成功以后需要把匿名登陆的这个功能关闭了. 使用命令: vim /etc/vsftpd/vsftpd.conf 然后在里成找到:? anonymous_enable=NO   然后再查看一下vsftpd这个服务有没有启动. 使用命令: chk

question --> maven assembly plugin 修改文件默认权限

使用maven assembly plugin插件添加执行脚本时,发现默认权限为644,还需要手动添加执行权限.这很麻烦,于是查看文档 官方文档 http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_fileSet fileMode String Similar to a UNIX permission, sets the file mode of the files included. THIS IS

Linux下使用MySQL——忘记root密码及修改MySQL默认编码

概述: 本博客不再对MySQL的语法进行讲解和说明,想了解或熟悉的朋友请自行百度或Google学习.本博客主要是针对MySQL除语法之外的总结,希望能够也能帮助到你. 1.CentOS6.x下MySQL忘记root密码解决方法 Ⅰ. 修改MySQL的登录设置 # vim /etc/my.cnf 在[mysqld]段中加上一句:skip-grant-tables Ⅱ. 重启服务 # service mysqld restart Ⅲ. 登录Mysql,修改密码信息 # mysql mysql> US

修改mysql默认字符集

(1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值,ubuntu下mysql的配置文件是在 /etc/mysql/my.cnf下, 我是将这个文件复制到我的 /home/username文件夹下,重命名为 .my.cnf,这样即使配置出错,也不会影响数据库的正常运行 如: [client] default-character-set = utf8 [mysqld] character_set_server = utf8 修改完后,重启mysql的服务, sudo res

RHEL7.0修改SSH默认端口及SELinux运行状态修改

Linux系统安装好后,默认会开启SSH服务以便远程配置.但使用默认端口22不安全,一般不建议使用默认端口,那就需要修改SSH默认端口.在RHEL7.0上修改和7.0以下类似,但要注意SELinux的修改. SSH 为 Secure Shell,由IETF的网络工作小组(Network Working Group)所制定:SSH 是建立在应用层和传输层基础上的一种安全协议.SSH传输数据是加密的,可以有效防止传输过程被截取数据保障安全.SSH的数据是经过压缩的,所以可以加快传输的速度. 修改步骤

iOS7 修改导航系统默认返回按钮文字及颜色

//iOS7 修改系统默认返回按钮文字及颜色 UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"返" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = item; [[UINavigationBar appearance] setTintColor:[UIColor