source: branches/version-2_5-dev/data/class/pages/admin/system/LC_Page_Admin_System_Bkup.php @ 18791

Revision 18791, 19.2 KB checked in by nanasess, 14 years ago (diff)

DB_TYPE で条件分岐している箇所の抽象化(#801)

  • SC_Helper_CSV
    • convert を mb_convert_kana_option へ変更
    • PEAR::DB の定数を MDB2 の定数へ修正
  • LC_Page_Admin_System_Bkup
    • DB_TYPE を使用している箇所を抽象化
    • シーケンス値バックアップファイルのフォーマット変更
  • html/install/index.php
    • 管理ユーザーの追加ができなくなっていたのを修正
  • html/install/sql/create_table_mysql.sql, html/install/sql/create_table_pgsql.sql
    • dtb_csv.convert を dtb_csv.mb_convert_kana_option へ変更
    • dtb_bkup を追加
  • html/install/sql/drop_table.sql
    • dtb_bkup を追加
  • html/install/sql/insert_data.sql
    • NOT NULL のフィールドが空文字にならないよう修正
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id Revision Date
  • 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_PATH . "pages/LC_Page.php");
26require_once(DATA_PATH. "module/Tar.php");
27/**
28 * バックアップ のページクラス.
29 *
30 * @package Page
31 * @author LOCKON CO.,LTD.
32 * @version $Id$
33 */
34class LC_Page_Admin_System_Bkup extends LC_Page {
35
36    // }}}
37    // {{{ functions
38
39    /**
40     * Page を初期化する.
41     *
42     * @return void
43     */
44    function init() {
45        parent::init();
46        $this->tpl_mainpage = 'system/bkup.tpl';
47        $this->tpl_subnavi = 'system/subnavi.tpl';
48        $this->tpl_mainno = 'system';
49        $this->tpl_subno = 'bkup';
50        $this->tpl_subtitle = 'バックアップ管理';
51
52        $this->bkup_dir = DATA_PATH . "downloads/backup/";
53        $this->bkup_ext = '.tar.gz';
54
55    }
56
57    /**
58     * Page のプロセス.
59     *
60     * @return void
61     */
62    function process() {
63        $objView = new SC_AdminView();
64        $objQuery = new SC_Query();
65
66        // セッションクラス
67        $objSess = new SC_Session();
68        // 認証可否の判定
69        SC_Utils_Ex::sfIsSuccess($objSess);
70
71        if (!isset($_POST['mode'])) $_POST['mode'] = "";
72
73        switch($_POST['mode']) {
74            // バックアップを作成する
75        case 'bkup':
76            // 入力文字列の変換
77            $arrData = $this->lfConvertParam($_POST);
78
79            // エラーチェック
80            $arrErr = $this->lfCheckError($arrData);
81
82            // エラーがなければバックアップ処理を行う
83            if (count($arrErr) <= 0) {
84                // バックアップファイル作成
85                $arrErr = $this->lfCreateBkupData($arrData['bkup_name']);
86
87                // DBにデータ更新
88                if (count($arrErr) <= 0) {
89                    $this->lfUpdBkupData($arrData);
90                }else{
91                    $arrForm = $arrData;
92                }
93
94                $this->tpl_onload = "alert('バックアップ完了しました');";
95            }else{
96                $arrForm = $arrData;
97            }
98
99            break;
100
101            // リストア
102        case 'restore':
103        case 'restore_config':
104            if ($_POST['mode'] == 'restore_config') {
105                $this->mode = "restore_config";
106            }
107
108            $this->lfRestore($_POST['list_name']);
109
110            break;
111
112            // 削除
113        case 'delete':
114            $del_file = $this->bkup_dir.$_POST['list_name'] . $this->bkup_ext;
115            // ファイルの削除
116            if(is_file($del_file)){
117                $ret = unlink($del_file);
118            }
119
120            // DBから削除
121            $delsql = "DELETE FROM dtb_bkup WHERE bkup_name = ?";
122            $objQuery->query($delsql, array($_POST['list_name']));
123
124            break;
125
126            // ダウンロード
127        case 'download' :
128            $filename = $_POST['list_name'] . $this->bkup_ext;
129            $dl_file = $this->bkup_dir.$_POST['list_name'] . $this->bkup_ext;
130
131            // ダウンロード開始
132            Header("Content-disposition: attachment; filename=${filename}");
133            Header("Content-type: application/octet-stream; name=${filename}");
134            header("Content-Length: " .filesize($dl_file));
135            readfile ($dl_file);
136            exit();
137            break;
138
139        default:
140            break;
141        }
142
143        // バックアップリストを取得する
144        $arrBkupList = $this->lfGetBkupData("ORDER BY create_date DESC");
145        // テンプレートファイルに渡すデータをセット
146        $this->arrErr = isset($arrErr) ? $arrErr : array();
147        $this->arrForm = isset($arrForm) ? $arrForm : array();
148        $this->arrBkupList = $arrBkupList;
149
150        $objView->assignobj($this);     //変数をテンプレートにアサインする
151        $objView->display(MAIN_FRAME);      //テンプレートの出力
152    }
153
154    /**
155     * デストラクタ.
156     *
157     * @return void
158     */
159    function destroy() {
160        parent::destroy();
161    }
162
163    /* 取得文字列の変換 */
164    function lfConvertParam($array) {
165        /*
166         *  文字列の変換
167         *  K :  「半角(ハンカク)片仮名」を「全角片仮名」に変換
168         *  C :  「全角ひら仮名」を「全角かた仮名」に変換
169         *  V :  濁点付きの文字を一文字に変換。"K","H"と共に使用します
170         *  n :  「全角」数字を「半角(ハンカク)」に変換
171         *  a :  全角英数字を半角英数字に変換する
172         */
173        $arrConvList['bkup_name'] = "a";
174        $arrConvList['bkup_memo'] = "KVa";
175
176        // 文字変換
177        foreach ($arrConvList as $key => $val) {
178            // POSTされてきた値のみ変換する。
179            if(isset($array[$key])) {
180                $array[$key] = mb_convert_kana($array[$key] ,$val);
181            }
182        }
183        return $array;
184    }
185
186    // エラーチェック
187    function lfCheckError($array){
188        $objErr = new SC_CheckError($array);
189
190        $objErr->doFunc(array("バックアップ名", "bkup_name", STEXT_LEN), array("EXIST_CHECK","MAX_LENGTH_CHECK","NO_SPTAB","ALNUM_CHECK"));
191        $objErr->doFunc(array("バックアップメモ", "bkup_memo", MTEXT_LEN), array("MAX_LENGTH_CHECK"));
192
193        // 重複チェック
194        $ret = $this->lfGetBkupData("WHERE bkup_name = ?", array($array['bkup_name']));
195        if (count($ret) > 0) {
196            $objErr->arrErr['bkup_name'] = "バックアップ名が重複しています。別名を入力してください。";
197        }
198
199        return $objErr->arrErr;
200    }
201
202    // バックアップファイル作成
203    function lfCreateBkupData($bkup_name){
204        // 実行時間を制限しない
205        set_time_limit(0);
206
207        $objQuery = new SC_Query();
208        $csv_data = "";
209        $csv_autoinc = "";
210        $success = true;
211
212        $bkup_dir = $this->bkup_dir;
213        if (!is_dir(dirname($bkup_dir))) $success = mkdir(dirname($bkup_dir));
214        $bkup_dir = $bkup_dir . $bkup_name . "/";
215
216        // 全テーブル取得
217        $arrTableList = $objQuery->listTables();
218
219        // 各テーブル情報を取得する
220        foreach($arrTableList as $key => $val){
221
222            if (!($val == "dtb_bkup" || $val == "mtb_zip")) {
223
224                // 全データを取得
225                if ($val == "dtb_pagelayout"){
226                    $arrData = $objQuery->getAll("SELECT * FROM $val ORDER BY page_id");
227                }else{
228                    $arrData = $objQuery->getAll("SELECT * FROM $val");
229                }
230
231                // CSVデータ生成
232                if (count($arrData) > 0) {
233
234                    // カラムをCSV形式に整える
235                    $arrKyes = SC_Utils_Ex::sfGetCommaList(array_keys($arrData[0]), false);
236
237                    // データをCSV形式に整える
238                    $data = "";
239                    foreach($arrData as $data_key => $data_val){
240                        //$val = str_replace("\"", "\\\"", $val);
241                        $data .= $this->lfGetCSVList($arrData[$data_key]);
242
243                    }
244                    // CSV出力データ生成
245                    $csv_data .= $val . "\r\n";
246                    $csv_data .= $arrKyes . "\r\n";
247                    $csv_data .= $data . "\r\n";
248                }
249
250                // タイムアウトを防ぐ
251                SC_Utils_Ex::sfFlush();
252            }
253        }
254
255        // 自動採番型の構成を取得する
256        $csv_autoinc = $this->lfGetAutoIncrement();
257
258        $csv_file = $bkup_dir . "bkup_data.csv";
259        $csv_autoinc_file = $bkup_dir . "autoinc_data.csv";
260        mb_internal_encoding(CHAR_CODE);
261        // CSV出力
262        // ディレクトリが存在していなければ作成する
263        if (!is_dir(dirname($csv_file))) {
264            $success = mkdir(dirname($csv_file));
265        }
266        if ($success) {
267            // dataをCSV出力
268            $fp = fopen($csv_file,"w");
269            if($fp) {
270                if($csv_data != ""){
271                    $success = fwrite($fp, $csv_data);
272                }
273                fclose($fp);
274            }
275
276            // 自動採番をCSV出力
277            $fp = fopen($csv_autoinc_file,"w");
278            if($fp) {
279                if($csv_autoinc != ""){
280                    $success = fwrite($fp, $csv_autoinc);
281                }
282                fclose($fp);
283            }
284        }
285
286        // 各種ファイルコピー
287        if ($success) {
288            /**
289            // 商品画像ファイルをコピー
290            // ディレクトリが存在していなければ作成する
291            $image_dir = $bkup_dir . "save_image/";
292            if (!is_dir(dirname($image_dir))) $success = mkdir(dirname($image_dir));
293            $copy_mess = "";
294            $copy_mess = SC_Utils_Ex::sfCopyDir("../../upload/save_image/",$image_dir, $copy_mess);
295
296            // テンプレートファイルをコピー
297            // ディレクトリが存在していなければ作成する
298            $templates_dir = $bkup_dir . "templates/";
299            if (!is_dir(dirname($templates_dir))) $success = mkdir(dirname($templates_dir));
300            $copy_mess = "";
301            $copy_mess = SC_Utils_Ex::sfCopyDir("../../user_data/templates/",$templates_dir, $copy_mess);
302
303            // インクルードファイルをコピー
304            // ディレクトリが存在していなければ作成する
305            $inc_dir = $bkup_dir . "include/";
306            if (!is_dir(dirname($inc_dir))) $success = mkdir(dirname($inc_dir));
307            $copy_mess = "";
308            $copy_mess = SC_Utils_Ex::sfCopyDir("../../user_data/include/",$inc_dir, $copy_mess);
309
310            // CSSファイルをコピー
311            // ディレクトリが存在していなければ作成する
312            $css_dir = $bkup_dir . "css/";
313            if (!is_dir(dirname($css_dir))) $success = mkdir(dirname($css_dir));
314            $copy_mess = "";
315            $copy_mess = SC_Utils_Ex::sfCopyDir("../../user_data/css/",$css_dir, $copy_mess);
316            **/
317            //圧縮フラグTRUEはgzip圧縮をおこなう
318            $tar = new Archive_Tar($this->bkup_dir . $bkup_name . $this->bkup_ext, TRUE);
319
320            //bkupフォルダに移動する
321            chdir($this->bkup_dir);
322
323            //圧縮をおこなう
324            $zip = $tar->create("./" . $bkup_name . "/");
325
326            // バックアップデータの削除
327            if ($zip) SC_Utils_Ex::sfDelFile($bkup_dir);
328        }
329
330        if (!$success) {
331            $arrErr['bkup_name'] = "バックアップに失敗しました。";
332            // バックアップデータの削除
333            SC_Utils_Ex::sfDelFile($bkup_dir);
334        }
335
336        return isset($arrErr) ? $arrErr : array();
337    }
338
339    /* 配列の要素をCSVフォーマットで出力する。*/
340    function lfGetCSVList($array) {
341        $line = '';
342        if (count($array) > 0) {
343            foreach($array as $key => $val) {
344                $val = mb_convert_encoding($val, CHAR_CODE, CHAR_CODE);
345                $val = str_replace("\"", "\\\"", $val);
346                $line .= "\"".$val."\",";
347            }
348            $line = ereg_replace(",$", "\r\n", $line);
349        }else{
350            return false;
351        }
352        return $line;
353    }
354
355    /**
356     * シーケンス一覧をCSV出力形式に変換する.
357     *
358     * シーケンス名,シーケンス値 の形式に出力する.
359     *
360     * @return string シーケンス一覧の文字列
361     */
362    function lfGetAutoIncrement() {
363        $objQuery = new SC_Query();
364        $arrSequences = $objQuery->listSequences();
365        $result = "";
366
367        foreach($arrSequences as $val){
368            $seq = $objQuery->currVal($val);
369
370            $ret .= $val . ",";
371            $ret .= is_null($seq) ? "0" : $seq;
372            $ret .= "\r\n";
373        }
374        return $ret;
375    }
376
377    // バックアップテーブルにデータを更新する
378    function lfUpdBkupData($data){
379        $objQuery = new SC_Query();
380
381        $sql = "INSERT INTO dtb_bkup (bkup_name,bkup_memo,create_date) values (?,?,now())";
382        $objQuery->query($sql, array($data['bkup_name'],$data['bkup_memo']));
383    }
384
385    // バックアップテーブルからデータを取得する
386    function lfGetBkupData($where = "", $data = array()){
387        $objQuery = new SC_Query();
388
389        $sql = "SELECT bkup_name, bkup_memo, create_date FROM dtb_bkup ";
390        if ($where != "")   $sql .= $where;
391
392        $ret = $objQuery->getAll($sql,$data);
393
394        return $ret;
395    }
396
397    // バックアップファイルをリストアする
398    function lfRestore($bkup_name){
399        // 実行時間を制限しない
400        set_time_limit(0);
401
402        $objQuery = new SC_Query("", false);
403        $csv_data = "";
404        $success = true;
405
406        $bkup_dir = $this->bkup_dir . $bkup_name . "/";
407
408        //バックアップフォルダに移動する
409        chdir($this->bkup_dir);
410
411        //圧縮フラグTRUEはgzip解凍をおこなう
412        $tar = new Archive_Tar($bkup_name . $this->bkup_ext, TRUE);
413
414        //指定されたフォルダ内に解凍する
415        $success = $tar->extract("./");
416
417        // 無事解凍できれば、リストアを行う
418        if ($success) {
419
420            // トランザクション開始
421            $objQuery->begin();
422
423            // DBをクリア
424            $success = $this->lfDeleteAll($objQuery);
425
426            // INSERT実行
427            if ($success) $success = $this->lfExeInsertSQL($objQuery, $bkup_dir . "bkup_data.csv");
428
429            // 自動採番の値をセット
430            if ($success) $this->lfSetAutoInc($objQuery, $bkup_dir . "autoinc_data.csv");
431
432            // 各種ファイルのコピー
433            /**
434            if ($success) {
435                // 画像のコピー
436                $image_dir = $bkup_dir . "save_image/";
437                $copy_mess = "";
438                $copy_mess = SC_Utils_Ex::sfCopyDir($image_dir, "../../upload/save_image/", $copy_mess, true);
439
440                // テンプレートのコピー
441                $tmp_dir = $bkup_dir . "templates/";
442                $copy_mess = "";
443                $copy_mess = SC_Utils_Ex::sfCopyDir($tmp_dir, "../../user_data/templates/", $copy_mess, true);
444
445                // インクルードファイルのコピー
446                $inc_dir = $bkup_dir . "include/";
447                $copy_mess = "";
448                $copy_mess = SC_Utils_Ex::sfCopyDir($inc_dir, "../../user_data/include/", $copy_mess, true);
449
450                // CSSのコピー
451                $css_dir = $bkup_dir . "css/";
452                $copy_mess = "";
453                $copy_mess = SC_Utils_Ex::sfCopyDir($css_dir, "../../user_data/css/", $copy_mess, true);
454
455                // バックアップデータの削除
456                SC_Utils_Ex::sfDelFile($bkup_dir);
457            }**/
458
459            // リストア成功ならコミット失敗ならロールバック
460            if ($success) {
461                $objQuery->commit();
462                $this->restore_msg = "リストア終了しました。";
463                $this->restore_err = true;
464            }else{
465                $objQuery->rollback();
466                $this->restore_msg = "リストアに失敗しました。";
467                $this->restore_name = $bkup_name;
468                $this->restore_err = false;
469            }
470        }
471    }
472
473    // CSVファイルからインサート実行
474    function lfExeInsertSQL(&$objQuery, $csv){
475
476        $sql = "";
477        $base_sql = "";
478        $tbl_flg = false;
479        $col_flg = false;
480        $ret = true;
481        $pagelayout_flg = false;
482        $mode = $this->mode;
483
484        // csvファイルからデータの取得
485        $fp = fopen($csv, "r");
486        while (!feof($fp)) {
487            $data = fgetcsv($fp, 1000000);
488
489            //空白行のときはテーブル変更
490            if (count($data) <= 1 and $data[0] == "") {
491                $base_sql = "";
492                $tbl_flg = false;
493                $col_flg = false;
494                continue;
495            }
496
497            // テーブルフラグがたっていない場合にはテーブル名セット
498            if (!$tbl_flg) {
499                $base_sql = "INSERT INTO $data[0] ";
500                $tbl_flg = true;
501
502                if($data[0] == "dtb_pagelayout"){
503                    $pagelayout_flg = true;
504                }
505
506                continue;
507            }
508
509            // カラムフラグがたっていない場合にはカラムセット
510            if (!$col_flg) {
511                if ($mode != "restore_config"){
512                    $base_sql .= " ( $data[0] ";
513                    for($i = 1; $i < count($data); $i++){
514                        $base_sql .= "," . $data[$i];
515                    }
516                    $base_sql .= " ) ";
517                }
518                $col_flg = true;
519                continue;
520            }
521
522            // インサートする値をセット
523            $sql = $base_sql . "VALUES ( ? ";
524            for($i = 1; $i < count($data); $i++){
525                $sql .= ", ?";
526            }
527            $sql .= " );";
528            $data = str_replace("\\\"", "\"", $data);
529            $err = $objQuery->query($sql, $data);
530
531            // エラーがあれば終了
532            if (PEAR::isError($err)){
533                SC_Utils_Ex::sfErrorHeader(">> " . $objQuery->getlastquery(false));
534                return false;
535            }
536
537            if ($pagelayout_flg) {
538                // dtb_pagelayoutの場合には最初のデータはpage_id = 0にする
539                $sql = "UPDATE dtb_pagelayout SET page_id = '0'";
540                $objQuery->query($sql);
541                $pagelayout_flg = false;
542            }
543
544            // タイムアウトを防ぐ
545            SC_Utils_Ex::sfFlush();
546        }
547        fclose($fp);
548
549        return $ret;
550    }
551
552    // 自動採番をセット
553    function lfSetAutoInc(&$objQuery, $csv){
554        // csvファイルからデータの取得
555        $arrCsvData = file($csv);
556
557        foreach($arrCsvData as $val){
558            $arrData = split(",", trim($val));
559
560             $objQuery->setval($arrData[0], $arrData[1]);
561        }
562    }
563
564    // DBを全てクリアする
565    function lfDeleteAll(&$objQuery){
566        $ret = true;
567
568        $arrTableList = $objQuery->listTables();
569
570        foreach($arrTableList as $val){
571            // バックアップテーブルは削除しない
572            if ($val != "dtb_bkup") {
573                $trun_sql = "DELETE FROM $val";
574                $ret = $objQuery->query($trun_sql);
575                if (PEAR::isError($ret)) return false;
576            }
577        }
578
579        return true;
580    }
581}
582?>
Note: See TracBrowser for help on using the repository browser.