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

Revision 21514, 16.5 KB checked in by Seasoft, 12 years ago (diff)

#1625 (typo修正・ソース整形・ソースコメントの改善)

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