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

Revision 20764, 18.9 KB checked in by nanasess, 13 years ago (diff)

#601 (コピーライトの更新)

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