1

自过去 4 天以来一直被这个问题困扰并到处检查,但我找不到解决方案。

在 Prestashop 中,我需要为客户(对于 b2b 网站)提供每个订单历史记录的 csv 下载。这就是我所做的:

1-覆盖OrderDetailController.php并在initContent()下编写以下代码:

if ( !array_key_exists('csv_download', $_GET) ) {
    parent::initContent();
} else if ( array_key_exists('csv_download', $_GET) ) {
    header('Content-type: text/csv');
    header('Content-Type: application/force-download; charset=UTF-8');
    header('Cache-Control: no-store, no-cache');
    header('Content-disposition: attachment; filename="'.'abc'.'_'.date('Y-m-d_His').'.csv"');
    $this->context->smarty->display(_PS_THEME_DIR_.'order-detail-csv.tpl');
}

order-detail-csv.tpl 是:

col1, col2, col3, col4
1,2,3,4
5,6,7,8

(我在模板中有硬编码值用于测试目的)

问题是,当单击链接访问此链接时,CSV 底部会附加以下内容:

col1, col2, col3, col4
1,2,3,4
5,6,7,8
<!-- MODULE Block footer -->
<div class="block_various_links" id="block_various_links_footer">
<p class="title_block">Information</p>
<ul>
<br />
<b>Notice</b>: Undefined index: PS_CATALOG_MODE in <b>D:\Program_Files\xampp\htdocs  \prestashop\cache\smarty\compile\66\40\fc\6640fcf250c9a844925d45d85c39618c4233b46e.file.blockcms.tpl.php</b> on line <b>93</b><br />
<br />
<b>Notice</b>: Trying to get property of non-object in <b>D:\Program_Files\xampp\htdocs\prestashop\cache\smarty\compile\66\40\fc\6640fcf250c9a844925d45d85c39618c4233b46e.file.blockcms.tpl.php</b> on line <b>93</b><br />
<li class="first_item"><a href="<br />
<b>Notice</b>: Undefined index: link in <b>D:\Program_Files\xampp\htdocs\prestashop\cache\smarty\compile\66\40\fc\6640fcf250c9a844925d45d85c39618c4233b46e.file.blockcms.tpl.php</b> on line <b>93</b><br />
<br />
<b>Notice</b>: Trying to get property of non-object in <b>D:\Program_Files\xampp\htdocs\prestashop\cache\smarty\compile\66\40\fc\6640fcf250c9a844925d45d85c39618c4233b46e.file.blockcms.tpl.php</b> on line <b>93</b><br />
<br />
<b>Fatal error</b>: Call to a member function getPageLink() on a non-object in <b>D:\Program_Files\xampp\htdocs\prestashop\cache\smarty\compile\66\40\fc\6640fcf250c9a844925d45d85c39618c4233b46e.file.blockcms.tpl.php</b> on line <b>93</b><br />

进一步检查,问题在于 CSV 底部的消息打印来自名为“CMS 块”的模块挂钩。如果我进入 admin-> modules->positions-> select CMS block,我可以通过在异常字段中输入“orderdetail”来从页脚区域删除这个钩子。

但是随后错误消息被另一个钩子的另一个错误消息替换,如果我也删除它,它会继续下去。编辑每个模块位置并添加 orderdetail 作为例外是不切实际的。

必须有适当的方法来做到这一点,以便 prestashop 可以忽略 smarty 布局和所有位置模块挂钩并发送纯 csv(由上面的order-detail-csv.tpl表示)。

4

1 回答 1

1

好的,找到了解决方案。不是理想情况下的 prestashop 方式,但可以完成工作。

我没有使用 prestashop MVC 向客户提供 CSV 订单历史记录(简直是一场噩梦!),而是创建了一个独立的 php 脚本并将其放在 prestashop 根目录下,并使用所需的 GET 参数直接访问它:

(我仍在使用 Prestashop 配置连接到 db 并使用上下文类来访问用户的 cookie 数据)

<?php
 require(dirname(__FILE__).'/config/config.inc.php');

$context = Context::getContext();

header('Content-type: text/csv');
header('Content-Type: application/force-download; charset=UTF-8');
header('Cache-Control: no-store, no-cache');
header('Content-disposition: attachment; filename="'.'abc'.'_'.date('Y-m-d_His').'.csv"');

try {
    $csv_string="";

    $conn = new PDO('mysql:host='._DB_SERVER_.';dbname='._DB_NAME_, _DB_USER_, _DB_PASSWD_);

    $query = " SELECT
            o.*,
            od.*
        FROM
            orders o
        INNER JOIN
            order_detail od ON od.id_order = o.id_order
        WHERE
            o.id_customer = ".$context->customer->id;

    if(isset($_GET['id_order']) && !empty($_GET['id_order'])) {
        $query = $query." AND o.id_order = ".$_GET['id_order'];
    } else if(isset($_GET['from']) && !empty($_GET['from'])) {
        $query = $query." AND o.date_add > '".$_GET['from']."' AND o.date_add < '".$_GET['to']."'";
    }

    //Get column names
    $fetch_type = PDO::FETCH_ASSOC;
    $result = $conn->query($query);
    $col_row = $result->fetchAll($fetch_type);
    $columns = empty($col_row) ? array() : array_keys((array)$col_row[0]);
    //assemble csv
    foreach($columns as $col) {
        $csv_string = $csv_string.$col.', ';
    }

    //get values
    $result = $conn->query($query);
    //assemble csv
    foreach($result as $row) {
         $csv_string = $csv_string."\n";
         foreach($columns as $col) {
             $csv_string = $csv_string . $row[$col].', ';
         }
    }

    echo($csv_string);

    $conn = null;

} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}
?>

显然,上面的脚本需要条件检查来阻止它在被未登录的人访问或使用错误的 GET 参数访问时停止(我稍后会这样做。超出本主题)。

它至少完成了我需要它完成的任务。

于 2013-08-07T12:20:38.773 回答