• 修改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的方法来实现。

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

    作  者:blog.jpdou.top

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

  • 相关阅读:
    To do list
    Spring Boot学习总结(4)——使用Springloaded进行热部署
    App后台开发运维和架构实践学习总结(2)——RESTful API设计技巧
    程序员如何成为编程高手并以此创业
    小米宋强:生态化大数据平台的深度应用实践
    Tomcat学习总结(9)——Apache Tomcat 8新特性
    Mysql学习总结(41)——MySql数据库基本语句再体会
    Git学习总结(13)——使用git.oschina作为自己的源代码在线管理库
    将学习养成习惯
    Java基础学习总结(71)——深入理解Java虚拟机内存
  • 原文地址:https://www.cnblogs.com/jpdoutop/p/Magento-Customers-Export.html
Copyright © 2020-2023  润新知