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

Revision 20345, 16.2 KB checked in by shutta, 11 years ago (diff)

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