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

Revision 20970, 18.5 KB checked in by Seasoft, 13 years ago (diff)

#1288 (「-er」カタカナ表記の統一)

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