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

Revision 19803, 18.7 KB checked in by Seasoft, 13 years ago (diff)

#834(パラメータの定数名に「URL」を含むにもかかわらず、パスのみのものがある)

  • 一斉置換前の現状記録のためのコミット

#628(未使用処理・定義などの削除)

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