source: branches/version-2_5-dev/data/class/pages/admin/contents/LC_Page_Admin_Contents_CsvSql.php @ 20318

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

#476 (CSV出力項目設定(高度な設定)で、一部テーブルの項目一覧が表示されない) に伴う改修
#657 (CSVダウンロードの改善) の改修
#938 (CSV出力 高度な設定 SQL登録できない) の不具合修正
#939 (CSV出力 高度な設定 出力操作で「sfGetCSVData()に移行してね。」と表示) の不具合修正
#971 (リファクタリング [管理画面]コンテンツ管理(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 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24// {{{ requires
25require_once(CLASS_REALDIR . "pages/admin/LC_Page_Admin.php");
26
27/**
28 * CSV 出力項目設定(高度な設定)のページクラス.
29 *
30 * @package Page
31 * @author LOCKON CO.,LTD.
32 * @version $Id$
33 */
34class LC_Page_Admin_Contents_CsvSql extends LC_Page_Admin {
35
36    // }}}
37    // {{{ functions
38
39    /**
40     * Page を初期化する.
41     *
42     * @return void
43     */
44    function init() {
45        parent::init();
46        $this->tpl_mainpage = 'contents/csv_sql.tpl';
47        $this->tpl_subnavi = 'contents/subnavi.tpl';
48        $this->tpl_subno = 'csv';
49        $this->tpl_subno_csv = 'csv_sql';
50        $this->tpl_mainno = "contents";
51        $this->tpl_subtitle = 'CSV出力設定';
52    }
53
54    /**
55     * Page のプロセス.
56     *
57     * @return void
58     */
59    function process() {
60        $this->action();
61        $this->sendResponse();
62    }
63
64    /**
65     * Page のアクション.
66     *
67     * @return void
68     */
69    function action() {
70        // 認証可否の判定
71        SC_Utils_Ex::sfIsSuccess(new SC_Session());
72
73        // パラメータ管理クラス
74        $objFormParam = new SC_FormParam();
75        // パラメータ設定
76        $this->lfInitParam($objFormParam);
77        $objFormParam->setParam($_POST);
78        $objFormParam->setParam($_GET);
79        $objFormParam->convParam();
80        $this->arrForm = $objFormParam->getHashArray();
81
82        switch($this->getMode()) {
83        // データの登録
84        case "confirm":
85            $this->arrErr = $this->lfCheckConfirmError($objFormParam);
86            if(SC_Utils_Ex::isBlank($this->arrErr)) {
87                // データの更新
88                $this->arrForm['sql_id'] = $this->lfUpdData($objFormParam->getValue('sql_id'), $objFormParam->getDbArray());
89                // 完了メッセージ表示
90                $this->tpl_onload = "alert('登録が完了しました。');";
91            }
92            break;
93        // 確認画面
94        case "preview":
95            $this->arrErr = $this->lfCheckPreviewError($objFormParam);
96            if(SC_Utils_Ex::isBlank($this->arrErr)) {
97                $this->sqlerr = $this->lfCheckSQL($objFormParam->getValue('csv_sql'));
98            }
99            $this->setTemplate('contents/csv_sql_view.tpl');
100            return;
101            break;
102        // 新規作成
103        case "new_page":
104            // リロード
105            SC_Response_Ex::reload();
106            break;
107        // データ削除
108        case "delete":
109            $this->arrErr = $this->lfCheckDeleteError($objFormParam);
110            if(SC_Utils_Ex::isBlank($this->arrErr)) {
111                $this->lfDelData($objFormParam->getValue('sql_id'));
112                SC_Response_Ex::reload();
113                exit;
114            }
115            break;
116        // CSV出力
117        case "csv_output":
118            $this->arrErr = $this->lfCheckOutputError($objFormParam);
119            if(SC_Utils_Ex::isBlank($this->arrErr)) {
120                $this->lfDoCsvOutput($objFormParam->getValue('csv_output_id'));
121                exit;
122            }
123            break;
124        default:
125            $this->arrErr = $objFormParam->checkError();
126            if(SC_Utils_Ex::isBlank($this->arrErr)) {
127                // 設定内容を取得する
128                $this->arrForm = $this->lfGetSqlData($objFormParam);
129                // カラム一覧を取得する
130                $this->arrColList = $this->lfGetColList($objFormParam->getValue('select_table'));
131            }
132            break;
133        }
134
135        // 登録済みSQL一覧取得
136        $this->arrSqlList = $this->lfGetSqlList();
137        // テーブル一覧を取得する
138        $this->arrTableList = $this->lfGetTableList();
139    }
140
141    /**
142     * パラメーター情報の初期化
143     *
144     * @param array $objFormParam フォームパラメータークラス
145     * @return void
146     */
147    function lfInitParam(&$objFormParam) {
148        $objFormParam->addParam('SQL ID', 'sql_id', INT_LEN, 'n', array("NUM_CHECK","MAX_LENGTH_CHECK"));
149        $objFormParam->addParam('CSV出力対象SQL ID', 'csv_output_id', INT_LEN, 'n', array("NUM_CHECK","MAX_LENGTH_CHECK"), "", false);
150        $objFormParam->addParam('選択テーブル', 'select_table', STEXT_LEN, 'KVa', array("GRAPH_CHECK","MAX_LENGTH_CHECK"), "", false);
151        $objFormParam->addParam('名称', 'sql_name', STEXT_LEN, 'KVa', array("MAX_LENGTH_CHECK","SPTAB_CHECK"));
152        $objFormParam->addParam('SQL文', 'csv_sql', "30000", 'KVa', array("MAX_LENGTH_CHECK","SPTAB_CHECK"));
153    }
154   
155    /**
156     * SQL登録エラーチェック
157     *
158     * @param array $objFormParam フォームパラメータークラス
159     * @return array エラー配列
160     */
161    function lfCheckConfirmError(&$objFormParam) {
162        // パラメーターの基本チェック
163        $arrErr = $objFormParam->checkError();
164        // 拡張エラーチェック
165        $objErr = new SC_CheckError($objFormParam->getHashArray());
166        $objErr->doFunc( array("名称", "sql_name"), array("EXIST_CHECK") );
167        $objErr->doFunc( array("SQL文", "csv_sql", "30000"), array("EXIST_CHECK", "MAX_LENGTH_CHECK") );
168        $objErr->doFunc( array('SQL文には読み込み関係以外のSQLコマンドおよび";"記号', 'csv_sql', $this->lfGetSqlDenyList()), array("PROHIBITED_STR_CHECK"));
169        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
170            $arrErr = array_merge($arrErr, $objErr->arrErr);
171        }
172        // SQL文自体の確認、エラーが無い時のみ実行
173        if(SC_Utils_Ex::isBlank($arrErr)) {
174            $sql_error = $this->lfCheckSQL($objFormParam->getValue('csv_sql'));
175            if(!SC_Utils_Ex::isBlank($sql_error)) {
176                $arrErr["csv_sql"] = "※ SQL文が不正です。SQL文を見直してください";
177            }
178        }
179        return $arrErr;
180    }
181
182    /**
183     * SQL確認エラーチェック
184     *
185     * @param array $objFormParam フォームパラメータークラス
186     * @return array エラー配列
187     */
188    function lfCheckPreviewError(&$objFormParam) {
189        // パラメーターの基本チェック
190        $arrErr = $objFormParam->checkError();
191        // 拡張エラーチェック
192        $objErr = new SC_CheckError($objFormParam->getHashArray());
193        $objErr->doFunc( array("SQL文", "csv_sql", "30000"), array("EXIST_CHECK", "MAX_LENGTH_CHECK") );
194        $objErr->doFunc( array('SQL文には読み込み関係以外のSQLコマンドおよび";"記号', 'csv_sql', $this->lfGetSqlDenyList()), array("PROHIBITED_STR_CHECK"));
195        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
196            $arrErr = array_merge($arrErr, $objErr->arrErr);
197        }
198        return $arrErr;
199    }
200
201    /**
202     * SQL設定 削除エラーチェック
203     *
204     * @param array $objFormParam フォームパラメータークラス
205     * @return array エラー配列
206     */
207    function lfCheckDeleteError(&$objFormParam) {
208        // パラメーターの基本チェック
209        $arrErr = $objFormParam->checkError();
210        // 拡張エラーチェック
211        $objErr = new SC_CheckError($objFormParam->getHashArray());
212        $objErr->doFunc( array("SQL ID", "sql_id"), array("EXIST_CHECK") );
213        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
214            $arrErr = array_merge($arrErr, $objErr->arrErr);
215        }
216        return $arrErr;
217    }
218
219    /**
220     * SQL設定 CSV出力エラーチェック
221     *
222     * @param array $objFormParam フォームパラメータークラス
223     * @return array エラー配列
224     */
225    function lfCheckOutputError(&$objFormParam) {
226        // パラメーターの基本チェック
227        $arrErr = $objFormParam->checkError();
228        // 拡張エラーチェック
229        $objErr = new SC_CheckError($objFormParam->getHashArray());
230        $objErr->doFunc( array("CSV出力対象SQL ID", "csv_output_id"), array("EXIST_CHECK") );
231        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
232            $arrErr = array_merge($arrErr, $objErr->arrErr);
233        }
234        return $arrErr;
235    }
236
237    /**
238     * デストラクタ.
239     *
240     * @return void
241     */
242    function destroy() {
243        parent::destroy();
244    }
245
246    /**
247     * テーブル一覧を取得する.
248     *
249     * @return array テーブル名一覧
250     */
251    function lfGetTableList(){
252        $objQuery =& SC_Query::getSingletonInstance();
253        // 実テーブル上のカラム設定を見に行く仕様に変更 ref #476
254        $arrTable = $objQuery->listTables();
255        if(SC_Utils_Ex::isBlank($arrTable)) {
256            return array();
257        }
258        $arrRet = array();
259        foreach($arrTable as $table) {
260            if(substr($table, 0, 4) == 'dtb_') {
261                $arrRet[ $table ] = 'データテーブル: ' . $table;
262            }else if(substr($table, 0, 4) == 'mtb_') {
263                $arrRet[ $table ] = 'マスタテーブル: ' . $table;
264            }else if(substr($table, 0, 3) == 'vw_') {
265                $arrRet[ $table ] = 'ビュー: ' . $table;
266            }
267        }
268        return $arrRet;
269    }
270
271    /**
272     * テーブルのカラム一覧を取得する.
273     *
274     * @param string $selectTable テーブル名
275     * @return array カラム一覧の配列
276     */
277    function lfGetColList($table){
278        if(SC_Utils_Ex::isBlank($table)) {
279            return array();
280        }
281        $objQuery =& SC_Query::getSingletonInstance();
282        // 実テーブル上のカラム設定を見に行く仕様に変更 ref #476
283        $arrColList = $objQuery->listTableFields($table);
284        $arrColList= SC_Utils_Ex::sfArrCombine($arrColList, $arrColList);
285        return $arrColList;
286    }
287
288    /**
289     * 登録済みSQL一覧を取得する.
290     *
291     * @param string $where Where句
292     * @param array $arrVal 絞り込みデータ
293     * @return array 取得結果の配列
294     */
295    function lfGetSqlList($where = "" , $arrVal = array()){
296        $objQuery =& SC_Query::getSingletonInstance();
297        $table = "dtb_csv_sql";
298        $objQuery->setOrder('sql_id');
299        return $objQuery->select('*', $table, $where, $arrVal);
300    }
301
302    /**
303     * 入力されたSQL文が正しく実行出来るかのチェックを行う.
304     *
305     * @param string SQL文データ(頭にSELECTは入れない)
306     * @return string エラー内容
307     */
308    function lfCheckSQL($sql){
309        // FIXME: 意図的に new SC_Query しています。 force_runをtrueにする必要があるので.本当はqueryの引数で制御したい。ref SC_Query
310        $objQuery = new SC_Query("", true);
311        $err = "";
312        $sql = "SELECT " . $sql . " ";
313        $objErrMsg = $objQuery->query($sql);
314        if (PEAR::isError($objErrMsg)){
315            $err = $objErrMsg->message . "\n" . $objErrMsg->userinfo;
316        }
317        return $err;
318    }
319
320    /**
321     * SQL詳細設定情報呼び出し (編集中データがある場合はそれを保持する)
322     *
323     * @param array $objFormParam フォームパラメータークラス
324     * @return mixed 表示用パラメーター
325     */
326    function lfGetSqlData(&$objFormParam) {
327        // 編集中データがある場合
328        if(!SC_Utils_Ex::isBlank($objFormParam->getValue('sql_name'))
329                or !SC_Utils_Ex::isBlank($objFormParam->getValue('csv_sql'))) {
330            return $objFormParam->getHashArray();
331        }
332        $csv_id = $objFormParam->getValue('csv_id');
333        if(!SC_Utils_Ex::isBlank($csv_id)) {
334            $arrData = $this->lfGetSqlList('csv_id = ?', array($csv_id));
335            return $arrData[0];
336        }
337        return array();
338    }
339
340    /**
341     * DBにデータを保存する.
342     *
343     * @param integer $sql_id 出力するデータのSQL_ID
344     * @return void
345     */
346    function lfDoCsvOutput($sql_id) {
347        $arrData = $this->lfGetSqlList('sql_id = ?', array($sql_id));
348        $sql = "SELECT " . $arrData[0]['csv_sql'] . " ";
349
350        // TODO: ヘッダ取得 SQL内にLIMIT文がある場合はLIMIT句は追加しないので重いかも
351        $objQuery =& SC_Query::getSingletonInstance();
352
353        $arrHeader = array();
354        if(!preg_match("/ LIMIT /", $sql)) {
355            $head_sql = $sql . " LIMIT 0";
356        }else{
357            $head_sql = $sql;
358        }
359        $arrData = $objQuery->getQueryDefsFields($head_sql, array(), true);
360        if(!SC_Utils_Ex::isBlank($arrData)) {
361            foreach($arrData as $key => $val) {
362                $arrHeader[] = $key;
363            }
364        }
365        require_once(CLASS_EX_REALDIR . "helper_extends/SC_Helper_CSV_Ex.php");
366        $objCSV = new SC_Helper_CSV_Ex();
367        $objCSV->sfDownloadCsvFromSql($sql, array(), "contents", $arrHeader, true);
368        exit;
369    }
370
371    /**
372     * DBにデータを保存する.
373     *
374     * @param integer $sql_id 更新するデータのSQL_ID
375     * @param array $arrSqlVal 更新データの配列
376     * @return integer $sql_id SQL_IDを返す
377     */
378    function lfUpdData($sql_id, $arrSqlVal){
379        $objQuery =& SC_Query::getSingletonInstance();
380        $table = "dtb_csv_sql";
381        $arrSqlVal['update_date'] = 'now()';
382        if (SC_Utils_Ex::sfIsInt($sql_id)) {
383            //データ更新
384            $where = "sql_id = ?";
385            $objQuery->update($table, $arrSqlVal, $where, array($sql_id));
386        }else{
387            //新規作成
388            $sql_id = $objQuery->nextVal('dtb_csv_sql_sql_id');
389            $arrSqlVal['sql_id'] = $sql_id;
390            $arrSqlVal['create_date'] = 'now()';
391            $objQuery->insert($table, $arrSqlVal);
392        }
393        return $sql_id;
394    }
395
396
397    /**
398     * 登録済みデータを削除する.
399     *
400     * @param integer $sql_id 削除するデータのSQL_ID
401     * @return boolean 実行結果 true:成功
402     */
403    function lfDelData($sql_id){
404        $objQuery =& SC_Query::getSingletonInstance();
405        $table = "dtb_csv_sql";
406        $where = "sql_id = ?";
407        if(SC_Utils_Ex::sfIsInt($sql_id)) {
408            $objQuery->delete($table, $where, array($sql_id));
409            return true;
410        }
411        return false;
412    }
413
414    /**
415     * SQL文に含めることを許可しないSQLキーワード
416     * 基本的にEC-CUBEのデータを取得するために必要なコマンドしか許可しない。複数クエリも不可
417     *
418     * FIXME: キーワードの精査。危険な部分なのでプログラム埋め込みで実装しました。mtb化の有無判断必要。
419     *
420     * @return array 不許可ワード配列
421     */
422    function lfGetSqlDenyList() {
423        $arrList = array(';'
424            ,'CREATE\s'
425            ,'INSERT\s'
426            ,'UPDATE\s'
427            ,'DELETE\s'
428            ,'ALTER\s'
429            ,'ABORT\s'
430            ,'ANALYZE\s'
431            ,'CLUSTER\s'
432            ,'COMMENT\s'
433            ,'COPY\s'
434            ,'DECLARE\s'
435            ,'DISCARD\s'
436            ,'DO\s'
437            ,'DROP\s'
438            ,'EXECUTE\s'
439            ,'EXPLAIN\s'
440            ,'GRANT\s'
441            ,'LISTEN\s'
442            ,'LOAD\s'
443            ,'LOCK\s'
444            ,'NOTIFY\s'
445            ,'PREPARE\s'
446            ,'REASSIGN\s'
447//            ,'REINDEX\s'      // REINDEXは許可で良いかなと
448            ,'RELEASE\sSAVEPOINT'
449            ,'RENAME\s'
450            ,'REST\s'
451            ,'REVOKE\s'
452            ,'SAVEPOINT\s'
453            ,'SET\s'
454            ,'SHOW\s'
455            ,'START\sTRANSACTION'
456            ,'TRUNCATE\s'
457            ,'UNLISTEN\s'
458            ,'VACCUM\s'
459            ,'HANDLER\s'
460            ,'LOAD\sDATA\s'
461            ,'LOAD\sXML\s'
462            ,'REPLACE\s'
463            ,'OPTIMIZE\s'
464            ,'REPAIR\s'
465            ,'INSTALL\sPLUGIN\s'
466            ,'UNINSTALL\sPLUGIN\s'
467            ,'BINLOG\s'
468            ,'KILL\s'
469            ,'RESET\s'
470            ,'PURGE\s'
471            ,'CHANGE\sMASTER'
472            ,'START\sSLAVE'
473            ,'STOP\sSLAVE'
474            ,'MASTER\sPOS\sWAIT'
475            ,'SIGNAL\s'
476            ,'RESIGNAL\s'
477            ,'RETURN\s'
478            ,'USE\s'
479            ,'HELP\s'
480            );
481        return $arrList;
482    }
483}
484?>
Note: See TracBrowser for help on using the repository browser.