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

Revision 20503, 16.5 KB checked in by shutta, 13 years ago (diff)

SC_CheckErrorクラスのclass_extends対応

  • 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_EX_REALDIR . "page_extends/admin/LC_Page_Admin_Ex.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_Ex {
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        $objFormParam = new SC_FormParam_Ex();
72        // パラメータ設定
73        $this->lfInitParam($objFormParam);
74        $objFormParam->setParam($_POST);
75        $objFormParam->setParam($_GET);
76        $objFormParam->convParam();
77        $this->arrForm = $objFormParam->getHashArray();
78
79        switch($this->getMode()) {
80        // データの登録
81        case "confirm":
82            $this->arrErr = $this->lfCheckConfirmError($objFormParam);
83            if(SC_Utils_Ex::isBlank($this->arrErr)) {
84                // データの更新
85                $this->arrForm['sql_id'] = $this->lfUpdData($objFormParam->getValue('sql_id'), $objFormParam->getDbArray());
86                // 完了メッセージ表示
87                $this->tpl_onload = "alert('登録が完了しました。');";
88            }
89            break;
90        // 確認画面
91        case "preview":
92            $this->arrErr = $this->lfCheckPreviewError($objFormParam);
93            if(SC_Utils_Ex::isBlank($this->arrErr)) {
94                $this->sqlerr = $this->lfCheckSQL($objFormParam->getValue('csv_sql'));
95            }
96            $this->setTemplate('contents/csv_sql_view.tpl');
97            return;
98            break;
99        // 新規作成
100        case "new_page":
101            // リロード
102            SC_Response_Ex::reload();
103            break;
104        // データ削除
105        case "delete":
106            $this->arrErr = $this->lfCheckDeleteError($objFormParam);
107            if(SC_Utils_Ex::isBlank($this->arrErr)) {
108                $this->lfDelData($objFormParam->getValue('sql_id'));
109                SC_Response_Ex::reload();
110                exit;
111            }
112            break;
113        // CSV出力
114        case "csv_output":
115            $this->arrErr = $this->lfCheckOutputError($objFormParam);
116            if(SC_Utils_Ex::isBlank($this->arrErr)) {
117                $this->lfDoCsvOutput($objFormParam->getValue('csv_output_id'));
118                exit;
119            }
120            break;
121        default:
122            $this->arrErr = $objFormParam->checkError();
123            if(SC_Utils_Ex::isBlank($this->arrErr)) {
124                // 設定内容を取得する
125                $this->arrForm = $this->lfGetSqlData($objFormParam);
126                // カラム一覧を取得する
127                $this->arrColList = $this->lfGetColList($objFormParam->getValue('select_table'));
128            }
129            break;
130        }
131
132        // 登録済みSQL一覧取得
133        $this->arrSqlList = $this->lfGetSqlList();
134        // テーブル一覧を取得する
135        $this->arrTableList = $this->lfGetTableList();
136    }
137
138    /**
139     * パラメーター情報の初期化
140     *
141     * @param array $objFormParam フォームパラメータークラス
142     * @return void
143     */
144    function lfInitParam(&$objFormParam) {
145        $objFormParam->addParam('SQL ID', 'sql_id', INT_LEN, 'n', array("NUM_CHECK","MAX_LENGTH_CHECK"));
146        $objFormParam->addParam('CSV出力対象SQL ID', 'csv_output_id', INT_LEN, 'n', array("NUM_CHECK","MAX_LENGTH_CHECK"), "", false);
147        $objFormParam->addParam('選択テーブル', 'select_table', STEXT_LEN, 'KVa', array("GRAPH_CHECK","MAX_LENGTH_CHECK"), "", false);
148        $objFormParam->addParam('名称', 'sql_name', STEXT_LEN, 'KVa', array("MAX_LENGTH_CHECK","SPTAB_CHECK"));
149        $objFormParam->addParam('SQL文', 'csv_sql', "30000", 'KVa', array("MAX_LENGTH_CHECK","SPTAB_CHECK"));
150    }
151   
152    /**
153     * SQL登録エラーチェック
154     *
155     * @param array $objFormParam フォームパラメータークラス
156     * @return array エラー配列
157     */
158    function lfCheckConfirmError(&$objFormParam) {
159        // パラメーターの基本チェック
160        $arrErr = $objFormParam->checkError();
161        // 拡張エラーチェック
162        $objErr = new SC_CheckError_Ex($objFormParam->getHashArray());
163        $objErr->doFunc( array("名称", "sql_name"), array("EXIST_CHECK") );
164        $objErr->doFunc( array("SQL文", "csv_sql", "30000"), array("EXIST_CHECK", "MAX_LENGTH_CHECK") );
165        $objErr->doFunc( array('SQL文には読み込み関係以外のSQLコマンドおよび";"記号', 'csv_sql', $this->lfGetSqlDenyList()), array("PROHIBITED_STR_CHECK"));
166        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
167            $arrErr = array_merge($arrErr, $objErr->arrErr);
168        }
169        // SQL文自体の確認、エラーが無い時のみ実行
170        if(SC_Utils_Ex::isBlank($arrErr)) {
171            $sql_error = $this->lfCheckSQL($objFormParam->getValue('csv_sql'));
172            if(!SC_Utils_Ex::isBlank($sql_error)) {
173                $arrErr["csv_sql"] = "※ SQL文が不正です。SQL文を見直してください";
174            }
175        }
176        return $arrErr;
177    }
178
179    /**
180     * SQL確認エラーチェック
181     *
182     * @param array $objFormParam フォームパラメータークラス
183     * @return array エラー配列
184     */
185    function lfCheckPreviewError(&$objFormParam) {
186        // パラメーターの基本チェック
187        $arrErr = $objFormParam->checkError();
188        // 拡張エラーチェック
189        $objErr = new SC_CheckError_Ex($objFormParam->getHashArray());
190        $objErr->doFunc( array("SQL文", "csv_sql", "30000"), array("EXIST_CHECK", "MAX_LENGTH_CHECK") );
191        $objErr->doFunc( array('SQL文には読み込み関係以外のSQLコマンドおよび";"記号', 'csv_sql', $this->lfGetSqlDenyList()), array("PROHIBITED_STR_CHECK"));
192        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
193            $arrErr = array_merge($arrErr, $objErr->arrErr);
194        }
195        return $arrErr;
196    }
197
198    /**
199     * SQL設定 削除エラーチェック
200     *
201     * @param array $objFormParam フォームパラメータークラス
202     * @return array エラー配列
203     */
204    function lfCheckDeleteError(&$objFormParam) {
205        // パラメーターの基本チェック
206        $arrErr = $objFormParam->checkError();
207        // 拡張エラーチェック
208        $objErr = new SC_CheckError_Ex($objFormParam->getHashArray());
209        $objErr->doFunc( array("SQL ID", "sql_id"), array("EXIST_CHECK") );
210        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
211            $arrErr = array_merge($arrErr, $objErr->arrErr);
212        }
213        return $arrErr;
214    }
215
216    /**
217     * SQL設定 CSV出力エラーチェック
218     *
219     * @param array $objFormParam フォームパラメータークラス
220     * @return array エラー配列
221     */
222    function lfCheckOutputError(&$objFormParam) {
223        // パラメーターの基本チェック
224        $arrErr = $objFormParam->checkError();
225        // 拡張エラーチェック
226        $objErr = new SC_CheckError_Ex($objFormParam->getHashArray());
227        $objErr->doFunc( array("CSV出力対象SQL ID", "csv_output_id"), array("EXIST_CHECK") );
228        if(!SC_Utils_Ex::isBlank($objErr->arrErr)) {
229            $arrErr = array_merge($arrErr, $objErr->arrErr);
230        }
231        return $arrErr;
232    }
233
234    /**
235     * デストラクタ.
236     *
237     * @return void
238     */
239    function destroy() {
240        parent::destroy();
241    }
242
243    /**
244     * テーブル一覧を取得する.
245     *
246     * @return array テーブル名一覧
247     */
248    function lfGetTableList(){
249        $objQuery =& SC_Query::getSingletonInstance();
250        // 実テーブル上のカラム設定を見に行く仕様に変更 ref #476
251        $arrTable = $objQuery->listTables();
252        if(SC_Utils_Ex::isBlank($arrTable)) {
253            return array();
254        }
255        $arrRet = array();
256        foreach($arrTable as $table) {
257            if(substr($table, 0, 4) == 'dtb_') {
258                $arrRet[ $table ] = 'データテーブル: ' . $table;
259            }else if(substr($table, 0, 4) == 'mtb_') {
260                $arrRet[ $table ] = 'マスタテーブル: ' . $table;
261            }else if(substr($table, 0, 3) == 'vw_') {
262                $arrRet[ $table ] = 'ビュー: ' . $table;
263            }
264        }
265        return $arrRet;
266    }
267
268    /**
269     * テーブルのカラム一覧を取得する.
270     *
271     * @param string $selectTable テーブル名
272     * @return array カラム一覧の配列
273     */
274    function lfGetColList($table){
275        if(SC_Utils_Ex::isBlank($table)) {
276            return array();
277        }
278        $objQuery =& SC_Query::getSingletonInstance();
279        // 実テーブル上のカラム設定を見に行く仕様に変更 ref #476
280        $arrColList = $objQuery->listTableFields($table);
281        $arrColList= SC_Utils_Ex::sfArrCombine($arrColList, $arrColList);
282        return $arrColList;
283    }
284
285    /**
286     * 登録済みSQL一覧を取得する.
287     *
288     * @param string $where Where句
289     * @param array $arrVal 絞り込みデータ
290     * @return array 取得結果の配列
291     */
292    function lfGetSqlList($where = "" , $arrVal = array()){
293        $objQuery =& SC_Query::getSingletonInstance();
294        $table = "dtb_csv_sql";
295        $objQuery->setOrder('sql_id');
296        return $objQuery->select('*', $table, $where, $arrVal);
297    }
298
299    /**
300     * 入力されたSQL文が正しく実行出来るかのチェックを行う.
301     *
302     * @param string SQL文データ(頭にSELECTは入れない)
303     * @return string エラー内容
304     */
305    function lfCheckSQL($sql){
306        // FIXME: 意図的に new SC_Query しています。 force_runをtrueにする必要があるので.本当はqueryの引数で制御したい。ref SC_Query
307        $objQuery = new SC_Query("", true);
308        $err = "";
309        $sql = "SELECT " . $sql . " ";
310        $objErrMsg = $objQuery->query($sql);
311        if (PEAR::isError($objErrMsg)){
312            $err = $objErrMsg->message . "\n" . $objErrMsg->userinfo;
313        }
314        return $err;
315    }
316
317    /**
318     * SQL詳細設定情報呼び出し (編集中データがある場合はそれを保持する)
319     *
320     * @param array $objFormParam フォームパラメータークラス
321     * @return mixed 表示用パラメーター
322     */
323    function lfGetSqlData(&$objFormParam) {
324        // 編集中データがある場合
325        if(!SC_Utils_Ex::isBlank($objFormParam->getValue('sql_name'))
326                or !SC_Utils_Ex::isBlank($objFormParam->getValue('csv_sql'))) {
327            return $objFormParam->getHashArray();
328        }
329        $csv_id = $objFormParam->getValue('csv_id');
330        if(!SC_Utils_Ex::isBlank($csv_id)) {
331            $arrData = $this->lfGetSqlList('csv_id = ?', array($csv_id));
332            return $arrData[0];
333        }
334        return array();
335    }
336
337    /**
338     * DBにデータを保存する.
339     *
340     * @param integer $sql_id 出力するデータのSQL_ID
341     * @return void
342     */
343    function lfDoCsvOutput($sql_id) {
344        $arrData = $this->lfGetSqlList('sql_id = ?', array($sql_id));
345        $sql = "SELECT " . $arrData[0]['csv_sql'] . " ";
346
347        // TODO: ヘッダ取得 SQL内にLIMIT文がある場合はLIMIT句は追加しないので重いかも
348        $objQuery =& SC_Query::getSingletonInstance();
349
350        $arrHeader = array();
351        if(!preg_match("/ LIMIT /", $sql)) {
352            $head_sql = $sql . " LIMIT 0";
353        }else{
354            $head_sql = $sql;
355        }
356        $arrData = $objQuery->getQueryDefsFields($head_sql, array(), true);
357        if(!SC_Utils_Ex::isBlank($arrData)) {
358            foreach($arrData as $key => $val) {
359                $arrHeader[] = $key;
360            }
361        }
362        require_once(CLASS_EX_REALDIR . "helper_extends/SC_Helper_CSV_Ex.php");
363        $objCSV = new SC_Helper_CSV_Ex();
364        $objCSV->sfDownloadCsvFromSql($sql, array(), "contents", $arrHeader, true);
365        exit;
366    }
367
368    /**
369     * DBにデータを保存する.
370     *
371     * @param integer $sql_id 更新するデータのSQL_ID
372     * @param array $arrSqlVal 更新データの配列
373     * @return integer $sql_id SQL_IDを返す
374     */
375    function lfUpdData($sql_id, $arrSqlVal){
376        $objQuery =& SC_Query::getSingletonInstance();
377        $table = "dtb_csv_sql";
378        $arrSqlVal['update_date'] = 'now()';
379        if (SC_Utils_Ex::sfIsInt($sql_id)) {
380            //データ更新
381            $where = "sql_id = ?";
382            $objQuery->update($table, $arrSqlVal, $where, array($sql_id));
383        }else{
384            //新規作成
385            $sql_id = $objQuery->nextVal('dtb_csv_sql_sql_id');
386            $arrSqlVal['sql_id'] = $sql_id;
387            $arrSqlVal['create_date'] = 'now()';
388            $objQuery->insert($table, $arrSqlVal);
389        }
390        return $sql_id;
391    }
392
393
394    /**
395     * 登録済みデータを削除する.
396     *
397     * @param integer $sql_id 削除するデータのSQL_ID
398     * @return boolean 実行結果 true:成功
399     */
400    function lfDelData($sql_id){
401        $objQuery =& SC_Query::getSingletonInstance();
402        $table = "dtb_csv_sql";
403        $where = "sql_id = ?";
404        if(SC_Utils_Ex::sfIsInt($sql_id)) {
405            $objQuery->delete($table, $where, array($sql_id));
406            return true;
407        }
408        return false;
409    }
410
411    /**
412     * SQL文に含めることを許可しないSQLキーワード
413     * 基本的にEC-CUBEのデータを取得するために必要なコマンドしか許可しない。複数クエリも不可
414     *
415     * FIXME: キーワードの精査。危険な部分なのでプログラム埋め込みで実装しました。mtb化の有無判断必要。
416     *
417     * @return array 不許可ワード配列
418     */
419    function lfGetSqlDenyList() {
420        $arrList = array(';'
421            ,'CREATE\s'
422            ,'INSERT\s'
423            ,'UPDATE\s'
424            ,'DELETE\s'
425            ,'ALTER\s'
426            ,'ABORT\s'
427            ,'ANALYZE\s'
428            ,'CLUSTER\s'
429            ,'COMMENT\s'
430            ,'COPY\s'
431            ,'DECLARE\s'
432            ,'DISCARD\s'
433            ,'DO\s'
434            ,'DROP\s'
435            ,'EXECUTE\s'
436            ,'EXPLAIN\s'
437            ,'GRANT\s'
438            ,'LISTEN\s'
439            ,'LOAD\s'
440            ,'LOCK\s'
441            ,'NOTIFY\s'
442            ,'PREPARE\s'
443            ,'REASSIGN\s'
444//            ,'REINDEX\s'      // REINDEXは許可で良いかなと
445            ,'RELEASE\sSAVEPOINT'
446            ,'RENAME\s'
447            ,'REST\s'
448            ,'REVOKE\s'
449            ,'SAVEPOINT\s'
450            ,'SET\s'
451            ,'SHOW\s'
452            ,'START\sTRANSACTION'
453            ,'TRUNCATE\s'
454            ,'UNLISTEN\s'
455            ,'VACCUM\s'
456            ,'HANDLER\s'
457            ,'LOAD\sDATA\s'
458            ,'LOAD\sXML\s'
459            ,'REPLACE\s'
460            ,'OPTIMIZE\s'
461            ,'REPAIR\s'
462            ,'INSTALL\sPLUGIN\s'
463            ,'UNINSTALL\sPLUGIN\s'
464            ,'BINLOG\s'
465            ,'KILL\s'
466            ,'RESET\s'
467            ,'PURGE\s'
468            ,'CHANGE\sMASTER'
469            ,'START\sSLAVE'
470            ,'STOP\sSLAVE'
471            ,'MASTER\sPOS\sWAIT'
472            ,'SIGNAL\s'
473            ,'RESIGNAL\s'
474            ,'RETURN\s'
475            ,'USE\s'
476            ,'HELP\s'
477            );
478        return $arrList;
479    }
480}
481?>
Note: See TracBrowser for help on using the repository browser.