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

Revision 19766, 16.4 KB checked in by Seasoft, 13 years ago (diff)

#627(ソース整形・ソースコメントの改善)

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