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

Revision 20276, 16.6 KB checked in by AMUAMU, 11 years ago (diff)

r20207 の取り消し。CSV関連がでぐれってるのと、支払い方法を出力しないようになっているため(仕様変更に伴うエラーは別途解決します)。

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