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

Revision 20432, 18.9 KB checked in by homan, 13 years ago (diff)

#974 [管理画面]システム設定 バックアップのリファクタリング(ループ部分の改修)

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