Page
[ class tree: Page ] [ index: Page ] [ all elements ]

Source for file SC_Helper_CSV.php

Documentation is available at SC_Helper_CSV.php

  1. <?php
  2.   /*
  3.    * Copyright(c) 2000-2011 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: SC_Helper_CSV.php 21118 2011-08-03 12:28:10Z kajiwara $
  14.    */
  15. class SC_Helper_CSV {
  16.  
  17.     // {{{ properties
  18.  
  19.     /** 項目英名 */
  20.     var $arrSubnavi;
  21.  
  22.     /** 項目名 */
  23.     var $arrSubnaviName;
  24.  
  25.     // }}}
  26.     // {{{ constructor
  27.  
  28.     /**
  29.      * デフォルトコンストラクタ.
  30.      */
  31.     function SC_Helper_CSV({
  32.         $this->init();
  33.     }
  34.  
  35.     // }}}
  36.     // {{{ functions
  37.  
  38.     /**
  39.      * 項目情報を初期化する.
  40.      *
  41.      * @access private
  42.      * @return void 
  43.      */
  44.     function init({
  45.         $this->arrSubnavi = array(
  46.                                   => 'product',
  47.                                   => 'customer',
  48.                                   => 'order',
  49.                                   => 'review',
  50.                                   => 'category'
  51.                                   );
  52.  
  53.         $this->arrSubnaviName = array(
  54.                                       => '商品管理',
  55.                                       => '顧客管理',
  56.                                       => '受注管理',
  57.                                       => 'レビュー',
  58.                                       => 'カテゴリ'
  59.                                       );
  60.     }
  61.  
  62.     /**
  63.      * CSVファイルを送信する
  64.      *
  65.      * @param integer $csv_id CSVフォーマットID
  66.      * @param string $where WHERE条件文
  67.      * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
  68.      * @param string $order ORDER文
  69.      * @param boolean $is_download true:ダウンロード用出力までさせる false:CSVの内容を返す(旧方式、メモリを食います。)
  70.      * @return mixed $is_download = true時 成功失敗フラグ(boolean) 、$is_downalod = false時 string
  71.      */
  72.     function sfDownloadCsv($csv_id$where ""$arrVal array()$order ""$is_download false{
  73.         // 実行時間を制限しない
  74.         @set_time_limit(0);
  75.  
  76.         // CSV出力タイトル行の作成
  77.         $arrOutput SC_Utils_Ex::sfSwapArray($this->sfGetCsvOutput($csv_id'status = ' CSV_COLUMN_STATUS_FLG_ENABLE));
  78.         if (count($arrOutput<= 0return false// 失敗終了
  79.         $arrOutputCols $arrOutput['col'];
  80.  
  81.         $objQuery =SC_Query_Ex::getSingletonInstance();
  82.         $objQuery->setOrder($order);
  83.         $cols SC_Utils_Ex::sfGetCommaList($arrOutputColstrue);
  84.  
  85.         // TODO: 固有処理 なんかエレガントな処理にしたい
  86.         if($csv_id == '1'{
  87.             //商品の場合
  88.             $objProduct new SC_Product_Ex();
  89.             // このWhereを足さないと無効な規格も出力される。現行仕様と合わせる為追加。
  90.             $inner_where 'dtb_products_class.del_flg = 0';
  91.             $sql $objQuery->getSql($cols$objProduct->prdclsSQL($inner_where),$where);
  92.         }else if($csv_id == '2'{
  93.             // 会員の場合
  94.             $sql "SELECT " $cols " FROM dtb_customer " $where;
  95.         }else if($csv_id == '3'{
  96.             // 注文の場合
  97.             $sql "SELECT " $cols " FROM dtb_order " $where;
  98.         }else if($csv_id == '4'{
  99.             // レビューの場合
  100.             $sql "SELECT " $cols " FROM dtb_review AS A INNER JOIN dtb_products AS B on A.product_id = B.product_id " $where;
  101.         }else if($csv_id == '5'{
  102.             // カテゴリの場合
  103.             $sql "SELECT " $cols " FROM dtb_category " $where;
  104.         }
  105.         // 固有処理ここまで
  106.         return $this->sfDownloadCsvFromSql($sql$arrVal$this->arrSubnavi[$csv_id]$arrOutput['disp_name']$is_download);
  107.     }
  108.  
  109.     /**
  110.      * CSV 項目を出力する.
  111.      *
  112.      * @param integer $csv_id CSV ID
  113.      * @param string $where SQL の WHERE 句
  114.      * @param array $arrVal WHERE 句の要素
  115.      * @param array $order SQL の ORDER BY 句
  116.      * @return array CSV 項目の配列
  117.      */
  118.     function sfGetCsvOutput($csv_id ""$where ''$arrVal array()$order 'rank, no'){
  119.         $objQuery =SC_Query_Ex::getSingletonInstance();
  120.  
  121.         $cols 'no, csv_id, col, disp_name, rank, status, rw_flg, mb_convert_kana_option, size_const_type, error_check_types';
  122.         $table 'dtb_csv';
  123.  
  124.         if(SC_Utils_Ex::sfIsInt($csv_id)){
  125.             if($where == ""{
  126.                 $where "csv_id = ?";
  127.             }else{
  128.                 $where "$where AND csv_id = ?";
  129.             }
  130.             $arrVal[$csv_id;
  131.         }
  132.         $objQuery->setOrder($order);
  133.  
  134.         $arrRet $objQuery->select($cols$table$where$arrVal);
  135.         return $arrRet;
  136.     }
  137.  
  138.     /**
  139.      * CSVが出力設定でインポート可能かのチェック
  140.      *
  141.      * @param array sfGetCsvOutputで取得した内容(またはそれと同等の配列)
  142.      * @return boolean true:インポート可能、false:インポート不可
  143.      */
  144.     function sfIsImportCSVFrame(&$arrCSVFrame{
  145.         $result true;
  146.         foreach($arrCSVFrame as $key => $val{
  147.             if($val['status'!= CSV_COLUMN_STATUS_FLG_ENABLE
  148.                     and $val['rw_flg'== CSV_COLUMN_RW_FLG_READ_WRITE
  149.                     and $val['error_check_types'!= ""
  150.                     and strpos(strtoupper($val['error_check_types'])"EXIST_CHECK"!== FALSE{
  151.                 //必須フィールド
  152.                 $result false;
  153.             }
  154.         }
  155.         return $result;
  156.     }
  157.  
  158.     /**
  159.      * CSVが出力設定で更新可能かのチェック
  160.      *
  161.      * @param array sfGetCsvOutputで取得した内容(またはそれと同等の配列)
  162.      * @return boolean true:更新可能、false:新規追加のみ不可
  163.      */
  164.     function sfIsUpdateCSVFrame(&$arrCSVFrame{
  165.         $result true;
  166.         foreach($arrCSVFrame as $key => $val{
  167.             if($val['status'!= CSV_COLUMN_STATUS_FLG_ENABLE
  168.                     and $val['rw_flg'== CSV_COLUMN_RW_FLG_KEY_FIELD{
  169.                 //キーフィールド
  170.                 $result false;
  171.             }
  172.         }
  173.         return $result;
  174.     }
  175.  
  176.     /**
  177.      * CSVファイルのカウント数を得る.
  178.      *
  179.      * @param resource $fp fopenを使用して作成したファイルポインタ
  180.      * @return integer CSV のカウント数
  181.      */
  182.     function sfGetCSVRecordCount($fp{
  183.         $count 0;
  184.         while(!feof($fp)) {
  185.             $arrCSV fgetcsv($fpCSV_LINE_MAX);
  186.             $count++;
  187.         }
  188.         // ファイルポインタを戻す
  189.         if (rewind($fp)) {
  190.             return $count-1;
  191.         else {
  192.             return FALSE;
  193.         }
  194.     }
  195.  
  196.     /**
  197.      * CSV作成 テンポラリファイル出力 コールバック関数
  198.      *
  199.      * @param mixed $data 出力データ
  200.      * @return boolean true (true:固定 false:中断)
  201.      */
  202.     function cbOutputCSV($data{
  203.         $line $this->sfArrayToCSV($data);
  204.         $line mb_convert_encoding($line'SJIS-Win');
  205.         $line .= "\r\n";
  206.         fwrite($this->fpOutput$line);
  207.         return true;
  208.     }
  209.  
  210.     /**
  211.      * SQL文からクエリ実行し CSVファイルを送信する
  212.      *
  213.      * @param integer $sql SQL文
  214.      * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
  215.      * @param string $file_head ファイル名の頭に付ける文字列
  216.      * @param array $arrHeader ヘッダ出力列配列
  217.      * @param boolean $is_download true:ダウンロード用出力までさせる false:CSVの内容を返す(旧方式、メモリを食います。)
  218.      * @return mixed $is_download = true時 成功失敗フラグ(boolean) 、$is_downalod = false時 string
  219.      */
  220.     function sfDownloadCsvFromSql($sql$arrVal array()$file_head 'csv'$arrHeader array()$is_download false{
  221.         $objQuery =SC_Query_Ex::getSingletonInstance();
  222.  
  223.         // 実行時間を制限しない
  224.         @set_time_limit(0);
  225.         // ヘッダ構築
  226.         if(is_array($arrHeader)) {
  227.             $header $this->sfArrayToCSV($arrHeader);
  228.             $header mb_convert_encoding($header'SJIS-Win');
  229.             $header .= "\r\n";
  230.         }
  231.  
  232.         //テンポラリファイル作成
  233.         // TODO: パフォーマンス向上には、ストリームを使うようにすると良い
  234.         //  環境要件がPHPバージョン5.1以上になったら使うように変えても良いかと
  235.         //  fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
  236.         $tmp_filename tempnam(CSV_TEMP_REALDIR$file_head '_csv');
  237.         $this->fpOutput fopen($tmp_filename"w+");
  238.         fwrite($this->fpOutput$header);
  239.         $objQuery->doCallbackAll(array(&$this'cbOutputCSV')$sql$arrVal);
  240.  
  241.         fclose($this->fpOutput);
  242.  
  243.         if($is_download{
  244.             // CSVを送信する。
  245.             $this->lfDownloadCSVFile($tmp_filename$file_head "_");
  246.             $res true;
  247.         }else{
  248.             $res SC_Utils_Ex::sfReadFile($tmp_filename);
  249.         }
  250.  
  251.         //テンポラリファイル削除
  252.         unlink($tmp_filename);
  253.         return $res;
  254.     }
  255.  
  256.     /**
  257.      * 1次元配列を1行のCSVとして返す
  258.      * 参考: http://jp.php.net/fputcsv
  259.      *
  260.      * @param array $fields データ1次元配列
  261.      * @param string $delimiter 
  262.      * @param string $enclosure 
  263.      * @param string $arrayDelimiter 
  264.      * @return string 結果行
  265.      */
  266.     function sfArrayToCsv($fields$delimiter ','$enclosure '"'$arrayDelimiter '|'{
  267.         ifstrlen($delimiter!= {
  268.             trigger_error('delimiter must be a single character'E_USER_WARNING);
  269.             return "";
  270.         }
  271.  
  272.         ifstrlen($enclosure{
  273.             trigger_error('enclosure must be a single character'E_USER_WARNING);
  274.             return "";
  275.         }
  276.  
  277.         foreach (array_keys($fieldsas $key{
  278.             $field =$fields[$key];
  279.  
  280.             // 配列を「|」区切りの文字列に変換する
  281.             if (is_array($field)) {
  282.                 $field implode($arrayDelimiter$field);
  283.             }
  284.  
  285.             /* enclose a field that contains a delimiter, an enclosure character, or a newline */
  286.             if (
  287.                    is_string($field)
  288.                 && preg_match('/[' preg_quote($delimiterpreg_quote($enclosure'\\s]/'$field)
  289.             {
  290.                 $field $enclosure preg_replace('/' preg_quote($enclosure'/'$enclosure $enclosure$field$enclosure;
  291.             }
  292.         }
  293.  
  294.         return implode($delimiter$fields);
  295.     }
  296.  
  297.     /**
  298.      * 配列データのCSVを送信する。
  299.      *
  300.      * @param array $fields データ配列
  301.      * @param string $prefix 
  302.      * @return void 
  303.      */
  304.     function lfDownloadCsv($arrData$prefix ""){
  305.  
  306.         if($prefix == ""{
  307.             $dir_name SC_Utils_Ex::sfUpDirName();
  308.             $file_name $dir_name date('ymdHis'.".csv";
  309.         else {
  310.             $file_name $prefix date('ymdHis'.".csv";
  311.         }
  312.  
  313.         /* HTTPヘッダの出力 */
  314.         Header("Content-disposition: attachment; filename=${file_name}");
  315.         Header("Content-type: application/octet-stream; name=${file_name}");
  316.         Header("Cache-Control: ");
  317.         Header("Pragma: ");
  318.  
  319.         /* データを出力 */
  320.         foreach ($arrData as $lineArray{
  321.             $lineString $this->sfArrayToCsv($lineArray);
  322.             $lineString mb_convert_encoding($lineString'SJIS-Win');
  323.             echo $lineString "\r\n";
  324.         }
  325.     }
  326.  
  327.     /**
  328.      * CSVファイルを送信する。
  329.      *
  330.      * @param string $filepath 送信するファイルのフルパス
  331.      * @param string $prefix 
  332.      * @return void 
  333.      */
  334.     function lfDownloadCSVFile($filepath$prefix ""{
  335.         $file_name $prefix date('YmdHis'".csv";
  336.  
  337.         /* HTTPヘッダの出力 */
  338.         Header("Content-disposition: attachment; filename=${file_name}");
  339.         Header("Content-type: application/octet-stream; name=${file_name}");
  340.         Header("Cache-Control: ");
  341.         Header("Pragma: ");
  342.  
  343.         /* データを出力 */
  344.         // file_get_contentsはメモリマッピングも自動的に使ってくれるので高速&省メモリ
  345.         echo file_get_contents($filepath);
  346.     }
  347. }
  348. ?>

Documentation generated on Fri, 24 Feb 2012 14:02:38 +0900 by Seasoft