source: branches/version-2_5-dev/data/class/helper/SC_Helper_CSV.php @ 19742

Revision 19742, 16.7 KB checked in by AMUAMU, 13 years ago (diff)

#657 (CSVダウンロードの改善) のうち商品CSVダウンロードの修正。
#781 (規格のデータベースを木構造に) の影響により機能していなかった商品CSVダウンロード機能の修正。
#823 (商品種別によってカートを分ける) や #792 (ダウンロード販売機能) による影響部分も修正。

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2  /*
3   * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
4   *
5   * http://www.lockon.co.jp/
6   */
7
8  /**
9   * CSV 関連 のヘルパークラス.
10   *
11   * @package Page
12   * @author LOCKON CO.,LTD.
13   * @version $Id$
14   */
15class SC_Helper_CSV {
16
17    // {{{ properties
18
19    /** 項目英名 */
20    var $arrSubnavi;
21
22    /** 項目名 */
23    var $arrSubnaviName;
24
25    /** レビュー管理項目 */
26    var $arrREVIEW_CVSCOL;
27
28    /** レビュータイトル */
29    var $arrREVIEW_CVSTITLE;
30
31    /** トラックバック項目 */
32    var $arrTRACKBACK_CVSCOL;
33
34    /** トラックバックタイトル */
35    var $arrTRACKBACK_CVSTITLE;
36
37
38    // }}}
39    // {{{ constructor
40
41    /**
42     * デフォルトコンストラクタ.
43     */
44    function SC_Helper_CSV() {
45        $this->init();
46
47        $masterData = new SC_DB_MasterData_Ex();
48        $this->arrPref = $masterData->getMasterData("mtb_pref",
49                                  array("pref_id", "pref_name", "rank"));
50        $this->arrSex = $masterData->getMasterData("mtb_sex");
51        $this->arrDISP = $masterData->getMasterData("mtb_disp");
52        $this->arrRECOMMEND = $masterData->getMasterData("mtb_recommend");
53    }
54
55    // }}}
56    // {{{ functions
57
58    /**
59     * CSV 項目を出力する.
60     *
61     * @param integer $csv_id CSV ID
62     * @param string $where SQL の WHERE 句
63     * @param array $arrVal WHERE 句の要素
64     * @return array CSV 項目の配列
65     */
66    function sfgetCsvOutput($csv_id = "", $where = '0=0', $arrVal = array()){
67        $objQuery = new SC_Query();
68        $ret = array();
69
70        $sql = <<< __EOS__
71            SELECT
72                no,
73                csv_id,
74                col,
75                disp_name,
76                rank,
77                status,
78                create_date,
79                update_date,
80                mb_convert_kana_option
81            FROM
82                dtb_csv
83__EOS__;
84
85        if (strlen($csv_id) >= 1) {
86            $where = "($where) AND csv_id = ?";
87            $arrVal[] = $csv_id;
88        }
89
90        if (strlen($where) >= 1) {
91            $sql .= " WHERE $where";
92        }
93
94        $sql .= " ORDER BY ";
95        $sql .= "     rank , no";
96        $sql .= " ";
97
98        $ret = $objQuery->getAll($sql, $arrVal);
99
100        return $ret;
101    }
102
103    // CSVを送信する。(共通。現状は受注のみ利用。)
104    function sfDownloadCsv($csv_id, $where, $arrval, $order) {
105        switch ($csv_id) {
106            case 3: // 受注
107                $from = 'dtb_order';
108                break;
109        }
110
111        // CSV出力タイトル行の作成
112        $arrCsvOutput = SC_Utils_Ex::sfSwapArray($this->sfgetCsvOutput($csv_id, 'status = 1'));
113
114        if (count($arrCsvOutput) <= 0) break;
115
116        $arrCsvOutputCols = $arrCsvOutput['col'];
117        $arrCsvOutputConvs = $arrCsvOutput['conv'];
118        $arrCsvOutputTitle = $arrCsvOutput['disp_name'];
119        $head = SC_Utils_Ex::sfGetCSVList($arrCsvOutputTitle);
120        $data = $objCSV->lfGetCSV("dtb_order", $where, $option, $arrval, $arrCsvOutputCols, $arrCsvOutputConvs);
121    }
122   
123    //  CSV作成 コールバック関数
124    function cbOutputProductCSV($data) {
125        $line = $this->sfArrayToCSV($data);
126        $line = mb_convert_encoding($line, 'SJIS-Win');
127        $line .= "\r\n";
128        fwrite($this->fpOutput, $line);
129        return true;
130    }
131
132    // CSVを送信する。(商品)
133    function sfDownloadProductsCsv($where, $arrval, $order, $is_download = false) {
134
135        // CSV出力タイトル行の作成
136        $arrOutput = SC_Utils_Ex::sfSwapArray($this->sfgetCsvOutput(1, 'status = 1'));
137        if (count($arrOutput) <= 0) return false; // 失敗終了
138        $arrOutputCols = $arrOutput['col'];
139
140        $objQuery = new SC_Query();
141        $objQuery->setOrder($order);
142       
143        $objProduct = new SC_Product();
144        $cols = SC_Utils_Ex::sfGetCommaList($arrOutputCols, true);
145        $sql = $objQuery->getSql($cols, $objProduct->prdclsSQL(),$where);
146        $header = $this->sfArrayToCSV($arrOutput['disp_name']);
147        $header = mb_convert_encoding($header, 'SJIS-Win');
148        $header .= "\r\n";
149       
150        //テンポラリファイル作成
151        // TODO: パフォーマンス向上には、ストリームを使うようにすると良い
152        //  環境要件がバージョン5.1以上になったら使うように変えても良いかと
153        //  fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
154        $tmp_filename = tempnam(CSV_TEMP_DIR, 'product_csv');
155        $this->fpOutput = fopen($tmp_filename, "w+");
156
157        fwrite($this->fpOutput, $header);
158
159        $objQuery->doCallbackAll(array(&$this, 'cbOutputProductCSV'), $sql, $arrval);
160
161        fclose($this->fpOutput);
162
163        if($is_download) {
164            // CSVを送信する。
165            $this->lfDownloadCSVFile($tmp_filename,"product_");
166            $res = true;
167        }else{
168            $res = SC_Utils_Ex::sfReadFile($tmp_filename);
169        }
170       
171        //テンポラリファイル削除
172        unlink($tmp_filename);
173        return $res;
174    }
175
176    // CSV出力データを作成する。(レビュー)
177    function lfGetReviewCSV($where, $option, $arrval) {
178
179        $from = "dtb_review AS A INNER JOIN dtb_products AS B on A.product_id = B.product_id ";
180        $cols = SC_Utils_Ex::sfGetCommaList($this->arrREVIEW_CVSCOL);
181
182        $objQuery = new SC_Query();
183        $objQuery->setOption($option);
184
185        $list_data = $objQuery->select($cols, $from, $where, $arrval);
186
187        $max = count($list_data);
188        if (!isset($data)) $data = "";
189        for($i = 0; $i < $max; $i++) {
190            // 各項目をCSV出力用に変換する。
191            $data .= $this->lfMakeReviewCSV($list_data[$i]);
192        }
193        return $data;
194    }
195
196    // CSV出力データを作成する。(トラックバック)
197    function lfGetTrackbackCSV($where, $option, $arrval) {
198        $from = "dtb_trackback AS A INNER JOIN dtb_products AS B on A.product_id = B.product_id ";
199        $cols = SC_Utils_Ex::sfGetCommaList($this->arrTRACKBACK_CVSCOL);
200
201        $objQuery = new SC_Query();
202        $objQuery->setOption($option);
203
204        $list_data = $objQuery->select($cols, $from, $where, $arrval);
205
206        $max = count($list_data);
207        if (!isset($data)) $data = "";
208        for($i = 0; $i < $max; $i++) {
209            // 各項目をCSV出力用に変換する。
210            $data .= $this->lfMakeTrackbackCSV($list_data[$i]);
211        }
212        return $data;
213    }
214
215    // CSVを送信する。(カテゴリ)
216    function sfDownloadCategoryCsv() {
217
218        // CSV出力タイトル行の作成
219        $arrOutput = SC_Utils_Ex::sfSwapArray($this->sfgetCsvOutput(5, 'status = 1'));
220        if (count($arrOutput) <= 0) return false; // 失敗終了
221        $arrOutputCols = $arrOutput['col'];
222
223        $objQuery = new SC_Query();
224        $objQuery->setOrder('rank DESC');
225
226        $dataRows = $objQuery->select(
227             SC_Utils_Ex::sfGetCommaList($arrOutputCols)
228            ,'dtb_category'
229            ,'del_flg = 0'
230        );
231       
232        $outputArray = array();
233       
234        // ヘッダ行
235        $outputArray[] = $arrOutput['disp_name'];
236       
237        // データ行
238        foreach ($dataRows as $row) {
239            $outputArray[] = $row;
240        }
241       
242        // CSVを送信する。
243        $this->lfDownloadCsv($outputArray, 'category');
244       
245        // 成功終了
246        return true;
247    }
248
249    // CSV出力データを作成する。
250    function lfGetCSV($from, $where, $option, $arrval, $arrCsvOutputCols = "", $arrCsvOutputConverts = array()) {
251
252        $cols = SC_Utils_Ex::sfGetCommaList($arrCsvOutputCols);
253
254        $objQuery = new SC_Query();
255        $objQuery->setOption($option);
256
257        $list_data = $objQuery->select($cols, $from, $where, $arrval, MDB2_FETCHMODE_ORDERED);
258
259        $csv = '';
260        foreach ($list_data as $row) {
261            $row = SC_Utils_Ex::mbConvertKanaWithArray($row, $arrCsvOutputConverts);
262            // 各項目をCSV出力用に変換する。
263            $line = $this->sfArrayToCsv($row);
264            $csv .= "$line\r\n";
265        }
266        return $csv;
267    }
268
269    // 各項目をCSV出力用に変換する。
270    function lfMakeCSV($list) {
271        $line = "";
272       
273        foreach($list as $key => $val) {
274            $tmp = "";
275            switch($key) {
276                case 'order_pref':
277                case 'deliv_pref':
278                    $tmp = $this->arrPref[$val];
279                    break;
280                default:
281                    $tmp = $val;
282                    break;
283            }
284
285            $tmp = preg_replace('/[",]/', " ", $tmp);
286            $line .= "\"".$tmp."\",";
287        }
288        // 文末の","を変換
289        $line = $this->replaceLineSuffix($line);
290        return $line;
291    }
292
293    // 各項目をCSV出力用に変換する。(レビュー)
294    function lfMakeReviewCSV($list) {
295        $line = "";
296
297        foreach($list as $key => $val) {
298            $tmp = "";
299            switch($key) {
300            case 'sex':
301                $tmp = isset($this->arrSex[$val]) ? $this->arrSex[$val] : "";
302                break;
303            case 'recommend_level':
304                $tmp = isset($this->arrRECOMMEND[$val]) ? $this->arrRECOMMEND[$val]
305                                                        : "";
306                break;
307            case 'status':
308                $tmp = isset($this->arrDISP[$val]) ? $this->arrDISP[$val] : "";
309                break;
310            default:
311                $tmp = $val;
312                break;
313            }
314
315            $tmp = preg_replace('/[",]/', " ", $tmp);
316            $line .= "\"".$tmp."\",";
317        }
318        // 文末の","を変換
319        $line = $this->replaceLineSuffix($line);
320        return $line;
321    }
322
323    // 各項目をCSV出力用に変換する。(トラックバック)
324    function lfMakeTrackbackCSV($list) {
325
326        $line = "";
327
328        foreach($list as $key => $val) {
329            $tmp = "";
330            switch($key) {
331            case 'status':
332                $tmp = $this->arrTrackBackStatus[$val];
333                break;
334            default:
335                $tmp = $val;
336                break;
337            }
338
339            $tmp = preg_replace('/[",]/', " ", $tmp);
340            $line .= "\"".$tmp."\",";
341        }
342        // 文末の","を変換
343        $line = $this->replaceLineSuffix($line);
344        return $line;
345    }
346
347    /**
348     * 行末の ',' を CRLF へ変換する.
349     *
350     * @access private
351     * @param string $line CSV出力用の1行分の文字列
352     * @return string 行末の ',' を CRLF に変換した文字列
353     */
354    function replaceLineSuffix($line) {
355//        return mb_ereg_replace(",$", "\r\n", $line); 
356        return preg_replace('/,$/',"\r\n",$line);
357    }
358
359    /**
360     * 項目情報を初期化する.
361     *
362     * @access private
363     * @return void
364     */
365    function init() {
366        $this->arrSubnavi = array(
367                                  1 => 'product',
368                                  2 => 'customer',
369                                  3 => 'order',
370                                  4 => 'campaign',
371                                  5 => 'category'
372                                  );
373
374        $this->arrSubnaviName = array(
375                                      1 => '商品管理',
376                                      2 => '顧客管理',
377                                      3 => '受注管理',
378                                      4 => 'キャンペーン',
379                                      5 => 'カテゴリ'
380                                      );
381
382
383        $this->arrREVIEW_CVSCOL = array(
384                                        'B.name',
385                                        'A.status',
386                                        'A.create_date',
387                                        'A.reviewer_name',
388                                        'A.sex',
389                                        'A.recommend_level',
390                                        'A.title',
391                                        'A.comment'
392                                        );
393
394        $this->arrREVIEW_CVSTITLE = array(
395                                          '商品名',
396                                          'レビュー表示',
397                                          '投稿日',
398                                          '投稿者名',
399                                          '性別',
400                                          'おすすめレベル',
401                                          'タイトル',
402                                          'コメント'
403                                          );
404
405        $this->arrTRACKBACK_CVSTITLE = array(
406                                             '商品名',
407                                             'ブログ名',
408                                             'ブログ記事タイトル',
409                                             'ブログ記事内容',
410                                             '状態',
411                                             '投稿日'
412                                             );
413
414        $this->arrTRACKBACK_CVSCOL = array(
415                                           'B.name',
416                                           'A.blog_name',
417                                           'A.title',
418                                           'A.excerpt',
419                                           'A.status',
420                                           'A.create_date'
421                                           );
422    }
423   
424    /**
425     * 1次元配列を1行のCSVとして返す
426     * 参考: http://jp.php.net/fputcsv
427     */
428    function sfArrayToCsv($fields, $delimiter = ',', $enclosure = '"', $arrayDelimiter = '|') {
429       
430        if( strlen($delimiter) != 1 ) {
431            trigger_error('delimiter must be a single character', E_USER_WARNING);
432            return "";
433        }
434       
435        if( strlen($enclosure) < 1 ) {
436            trigger_error('enclosure must be a single character', E_USER_WARNING);
437            return "";
438        }
439       
440        foreach (array_keys($fields) as $key) {
441            $field =& $fields[$key];
442           
443            // 配列を「|」区切りの文字列に変換する
444            if (is_array($field)) {
445                $field = implode($arrayDelimiter, $field);
446            }
447           
448            /* enclose a field that contains a delimiter, an enclosure character, or a newline */
449            if (
450                   is_string($field)
451                && preg_match('/[' . preg_quote($delimiter) . preg_quote($enclosure) . '\\s]/', $field)
452            ) {
453                $field = $enclosure . preg_replace('/' . preg_quote($enclosure) . '/', $enclosure . $enclosure, $field) . $enclosure;
454            }
455        }
456       
457        return implode($delimiter, $fields);
458    }
459   
460    /**
461     * CSVを送信する。
462     */
463    function lfDownloadCsv($arrayData, $prefix = ""){
464
465        if($prefix == "") {
466            $dir_name = SC_Utils::sfUpDirName();
467            $file_name = $dir_name . date("ymdHis") .".csv";
468        } else {
469            $file_name = $prefix . date("ymdHis") .".csv";
470        }
471
472        /* HTTPヘッダの出力 */
473        Header("Content-disposition: attachment; filename=${file_name}");
474        Header("Content-type: application/octet-stream; name=${file_name}");
475        Header("Cache-Control: ");
476        Header("Pragma: ");
477
478        /* データを出力 */
479        foreach ($arrayData as $lineArray) {
480            $lineString = $this->sfArrayToCsv($lineArray);
481            $lineString = mb_convert_encoding($lineString, 'SJIS-Win');
482            echo $lineString . "\r\n";
483        }
484    }
485   
486    /**
487     * CSVファイルを送信する。
488     */
489    function lfDownloadCSVFile($filepath, $prefix = "") {
490        $file_name = $prefix . date("YmdHis") . ".csv";
491       
492        /* HTTPヘッダの出力 */
493        Header("Content-disposition: attachment; filename=${file_name}");
494        Header("Content-type: application/octet-stream; name=${file_name}");
495        Header("Cache-Control: ");
496        Header("Pragma: ");
497       
498        /* データを出力 */
499        // file_get_contentsはメモリマッピングも自動的に使ってくれるので高速&省メモリ
500        echo file_get_contents($filepath);
501    }
502
503    /**
504     * CSVデータを取得する。
505     */
506    function lfGetCsv2($arrayData, $prefix = "") {
507
508        if($prefix == "") {
509            $dir_name = SC_Utils::sfUpDirName();
510            $file_name = $dir_name . date("ymdHis") .".csv";
511        } else {
512            $file_name = $prefix . date("ymdHis") .".csv";
513        }
514
515        /* データを出力 */
516        foreach ($arrayData as $lineArray) {
517            $lineString = $this->sfArrayToCsv($lineArray);
518            $lineString = mb_convert_encoding($lineString, 'SJIS-Win');
519            $lineString .= "\r\n";
520        }
521        return array($file_name, $lineString);
522    }
523}
524?>
Note: See TracBrowser for help on using the repository browser.