source: branches/comu-ver2/data/class/pages/admin/system/LC_Page_Admin_System_Bkup.php @ 18001

Revision 18001, 22.6 KB checked in by Seasoft, 15 years ago (diff)

不適切と思われる変数名を変更。($err → $success)

  • 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
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2007 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/LC_Page.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 {
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        $objView = new SC_AdminView();
64        $objQuery = new SC_Query();
65
66        // セッションクラス
67        $objSess = new SC_Session();
68        // 認証可否の判定
69        SC_Utils_Ex::sfIsSuccess($objSess);
70
71        // バックアップテーブルがなければ作成する
72        $this->lfCreateBkupTable();
73
74        if (!isset($_POST['mode'])) $_POST['mode'] = "";
75
76        switch($_POST['mode']) {
77            // バックアップを作成する
78        case 'bkup':
79            // 入力文字列の変換
80            $arrData = $this->lfConvertParam($_POST);
81
82            // エラーチェック
83            $arrErr = $this->lfCheckError($arrData);
84
85            // エラーがなければバックアップ処理を行う
86            if (count($arrErr) <= 0) {
87                // バックアップファイル作成
88                $arrErr = $this->lfCreateBkupData($arrData['bkup_name']);
89
90                // DBにデータ更新
91                if (count($arrErr) <= 0) {
92                    $this->lfUpdBkupData($arrData);
93                }else{
94                    $arrForm = $arrData;
95                }
96
97                $this->tpl_onload = "alert('バックアップ完了しました');";
98            }else{
99                $arrForm = $arrData;
100            }
101
102            break;
103
104            // リストア
105        case 'restore':
106        case 'restore_config':
107            if ($_POST['mode'] == 'restore_config') {
108                $this->mode = "restore_config";
109            }
110
111            $this->lfRestore($_POST['list_name']);
112
113            break;
114
115            // 削除
116        case 'delete':
117            $del_file = $this->bkup_dir.$_POST['list_name'] . $this->bkup_ext;
118            // ファイルの削除
119            if(is_file($del_file)){
120                $ret = unlink($del_file);
121            }
122
123            // DBから削除
124            $delsql = "DELETE FROM dtb_bkup WHERE bkup_name = ?";
125            $objQuery->query($delsql, array($_POST['list_name']));
126
127            break;
128
129            // ダウンロード
130        case 'download' :
131            $filename = $_POST['list_name'] . $this->bkup_ext;
132            $dl_file = $this->bkup_dir.$_POST['list_name'] . $this->bkup_ext;
133
134            // ダウンロード開始
135            Header("Content-disposition: attachment; filename=${filename}");
136            Header("Content-type: application/octet-stream; name=${filename}");
137            header("Content-Length: " .filesize($dl_file));
138            readfile ($dl_file);
139            exit();
140            break;
141
142        default:
143            break;
144        }
145
146        // バックアップリストを取得する
147        $arrBkupList = $this->lfGetBkupData("ORDER BY create_date DESC");
148        // テンプレートファイルに渡すデータをセット
149        $this->arrErr = isset($arrErr) ? $arrErr : "";
150        $this->arrForm = isset($arrForm) ? $arrForm : "";
151        $this->arrBkupList = $arrBkupList;
152
153        $objView->assignobj($this);     //変数をテンプレートにアサインする
154        $objView->display(MAIN_FRAME);      //テンプレートの出力
155    }
156
157    /**
158     * デストラクタ.
159     *
160     * @return void
161     */
162    function destroy() {
163        parent::destroy();
164    }
165
166    /* 取得文字列の変換 */
167    function lfConvertParam($array) {
168        /*
169         *  文字列の変換
170         *  K :  「半角(ハンカク)片仮名」を「全角片仮名」に変換
171         *  C :  「全角ひら仮名」を「全角かた仮名」に変換
172         *  V :  濁点付きの文字を一文字に変換。"K","H"と共に使用します
173         *  n :  「全角」数字を「半角(ハンカク)」に変換
174         *  a :  全角英数字を半角英数字に変換する
175         */
176        $arrConvList['bkup_name'] = "a";
177        $arrConvList['bkup_memo'] = "KVa";
178
179        // 文字変換
180        foreach ($arrConvList as $key => $val) {
181            // POSTされてきた値のみ変換する。
182            if(isset($array[$key])) {
183                $array[$key] = mb_convert_kana($array[$key] ,$val);
184            }
185        }
186        return $array;
187    }
188
189    // エラーチェック
190    function lfCheckError($array){
191        $objErr = new SC_CheckError($array);
192
193        $objErr->doFunc(array("バックアップ名", "bkup_name", STEXT_LEN), array("EXIST_CHECK","MAX_LENGTH_CHECK","NO_SPTAB","ALNUM_CHECK"));
194        $objErr->doFunc(array("バックアップメモ", "bkup_memo", MTEXT_LEN), array("MAX_LENGTH_CHECK"));
195
196        // 重複チェック
197        $ret = $this->lfGetBkupData("WHERE bkup_name = ?", array($array['bkup_name']));
198        if (count($ret) > 0) {
199            $objErr->arrErr['bkup_name'] = "バックアップ名が重複しています。別名を入力してください。";
200        }
201
202        return $objErr->arrErr;
203    }
204
205    // バックアップファイル作成
206    function lfCreateBkupData($bkup_name){
207        // 実行時間を制限しない
208        set_time_limit(0);
209       
210        $objQuery = new SC_Query();
211        $csv_data = "";
212        $csv_autoinc = "";
213        $success = true;
214
215        $bkup_dir = $this->bkup_dir;
216        if (!is_dir(dirname($bkup_dir))) $success = mkdir(dirname($bkup_dir));
217        $bkup_dir = $bkup_dir . $bkup_name . "/";
218
219        // 全テーブル取得
220        $arrTableList = $this->lfGetTableList();
221
222        // 各テーブル情報を取得する
223        foreach($arrTableList as $key => $val){
224
225            if (!($val == "dtb_bkup" || $val == "mtb_zip")) {
226
227                // 自動採番型の構成を取得する
228                $csv_autoinc .= $this->lfGetAutoIncrement($val);
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;
254                    $csv_data .= "\r\n";
255                }
256
257                // タイムアウトを防ぐ
258                SC_Utils_Ex::sfFlush();
259            }
260        }
261
262        $csv_file = $bkup_dir . "bkup_data.csv";
263        $csv_autoinc_file = $bkup_dir . "autoinc_data.csv";
264        mb_internal_encoding(CHAR_CODE);
265        // CSV出力
266        // ディレクトリが存在していなければ作成する
267        if (!is_dir(dirname($csv_file))) {
268            $success = mkdir(dirname($csv_file));
269        }
270        if ($success) {
271            // dataをCSV出力
272            $fp = fopen($csv_file,"w");
273            if($fp) {
274                if($csv_data != ""){
275                    $success = fwrite($fp, $csv_data);
276                }
277                fclose($fp);
278            }
279
280            // 自動採番をCSV出力
281            $fp = fopen($csv_autoinc_file,"w");
282            if($fp) {
283                if($csv_autoinc != ""){
284                    $success = fwrite($fp, $csv_autoinc);
285                }
286                fclose($fp);
287            }
288        }
289
290        // 各種ファイルコピー
291        if ($success) {
292            /**
293            // 商品画像ファイルをコピー
294            // ディレクトリが存在していなければ作成する
295            $image_dir = $bkup_dir . "save_image/";
296            if (!is_dir(dirname($image_dir))) $success = mkdir(dirname($image_dir));
297            $copy_mess = "";
298            $copy_mess = SC_Utils_Ex::sfCopyDir("../../upload/save_image/",$image_dir, $copy_mess);
299
300            // テンプレートファイルをコピー
301            // ディレクトリが存在していなければ作成する
302            $templates_dir = $bkup_dir . "templates/";
303            if (!is_dir(dirname($templates_dir))) $success = mkdir(dirname($templates_dir));
304            $copy_mess = "";
305            $copy_mess = SC_Utils_Ex::sfCopyDir("../../user_data/templates/",$templates_dir, $copy_mess);
306
307            // インクルードファイルをコピー
308            // ディレクトリが存在していなければ作成する
309            $inc_dir = $bkup_dir . "include/";
310            if (!is_dir(dirname($inc_dir))) $success = mkdir(dirname($inc_dir));
311            $copy_mess = "";
312            $copy_mess = SC_Utils_Ex::sfCopyDir("../../user_data/include/",$inc_dir, $copy_mess);
313
314            // CSSファイルをコピー
315            // ディレクトリが存在していなければ作成する
316            $css_dir = $bkup_dir . "css/";
317            if (!is_dir(dirname($css_dir))) $success = mkdir(dirname($css_dir));
318            $copy_mess = "";
319            $copy_mess = SC_Utils_Ex::sfCopyDir("../../user_data/css/",$css_dir, $copy_mess);
320            **/
321            //圧縮フラグTRUEはgzip圧縮をおこなう
322            $tar = new Archive_Tar($this->bkup_dir . $bkup_name . $this->bkup_ext, TRUE);
323
324            //bkupフォルダに移動する
325            chdir($this->bkup_dir);
326
327            //圧縮をおこなう
328            $zip = $tar->create("./" . $bkup_name . "/");
329
330            // バックアップデータの削除
331            if ($zip) SC_Utils_Ex::sfDelFile($bkup_dir);
332        }
333
334        if (!$success) {
335            $arrErr['bkup_name'] = "バックアップに失敗しました。";
336            // バックアップデータの削除
337            SC_Utils_Ex::sfDelFile($bkup_dir);
338        }
339
340        return isset($arrErr) ? $arrErr : array();
341    }
342
343    /* 配列の要素をCSVフォーマットで出力する。*/
344    function lfGetCSVList($array) {
345        $line = '';
346        if (count($array) > 0) {
347            foreach($array as $key => $val) {
348                $val = mb_convert_encoding($val, CHAR_CODE, CHAR_CODE);
349                $val = str_replace("\"", "\\\"", $val);
350                $line .= "\"".$val."\",";
351            }
352            $line = ereg_replace(",$", "\r\n", $line);
353        }else{
354            return false;
355        }
356        return $line;
357    }
358
359    // 全テーブルリストを取得する
360    function lfGetTableList(){
361        $objQuery = new SC_Query();
362
363        if(DB_TYPE == "pgsql"){
364            $sql = "SELECT tablename FROM pg_tables WHERE tableowner = ? ORDER BY tablename ; ";
365            $arrRet = $objQuery->getAll($sql, array(DB_USER));
366            $arrRet = SC_Utils_Ex::sfSwapArray($arrRet);
367            $arrRet = $arrRet['tablename'];
368        }else if(DB_TYPE == "mysql"){
369            $sql = "SHOW TABLES;";
370            $arrRet = $objQuery->getAll($sql);
371            $arrRet = SC_Utils_Ex::sfSwapArray($arrRet);
372
373            // キーを取得
374            $arrKey = array_keys($arrRet);
375
376            $arrRet = $arrRet[$arrKey[0]];
377        }
378        return $arrRet;
379    }
380
381    // 自動採番型をCSV出力形式に変換する
382    function lfGetAutoIncrement($table_name){
383        $arrColList = $this->lfGetColumnList($table_name);
384        $ret = "";
385
386        if(DB_TYPE == "pgsql"){
387            $match = 'nextval(\'';
388        }else if(DB_TYPE == "mysql"){
389            $match = "auto_incr";
390        }
391
392        foreach($arrColList['col_def'] as $key => $val){
393
394            if (substr($val,0,9) == $match) {
395                $col = $arrColList['col_name'][$key];
396                $autoVal = $this->lfGetAutoIncrementVal($table_name, $col);
397                $ret .= "$table_name,$col,$autoVal\n";
398            }
399        }
400
401        return $ret;
402    }
403
404    // テーブル構成を取得する
405    Function Lfgetcolumnlist($table_name){
406        $objQuery = new SC_Query();
407
408        if(DB_TYPE == "pgsql"){
409            $sql = "SELECT
410                    a.attname, t.typname, a.attnotnull, d.adsrc as defval, a.atttypmod, a.attnum as fldnum, e.description
411                FROM
412                    pg_class c,
413                    pg_type t,
414                    pg_attribute a left join pg_attrdef d on (a.attrelid=d.adrelid and a.attnum=d.adnum)
415                                   left join pg_description e on (a.attrelid=e.objoid and a.attnum=e.objsubid)
416                WHERE (c.relname=?) AND (c.oid=a.attrelid) AND (a.atttypid=t.oid) AND a.attnum > 0
417                ORDER BY fldnum";
418            $arrColList = $objQuery->getAll($sql, array($table_name));
419            $arrColList = SC_Utils_Ex::sfSwapArray($arrColList);
420
421            $arrRet['col_def'] = $arrColList['defval'];
422            $arrRet['col_name'] = $arrColList['attname'];
423        }else if(DB_TYPE == "mysql"){
424            $sql = "SHOW COLUMNS FROM $table_name";
425            $arrColList = $objQuery->getAll($sql);
426            $arrColList = SC_Utils_Ex::sfSwapArray($arrColList);
427
428            $arrRet['col_def'] = $arrColList['Extra'];
429            $arrRet['col_name'] = $arrColList['Field'];
430        }
431        return $arrRet;
432    }
433
434    // 自動採番型の値を取得する
435    function lfGetAutoIncrementVal($table_name , $colname = ""){
436        $objQuery = new SC_Query();
437        $ret = "";
438
439        if(DB_TYPE == "pgsql"){
440            $ret = $objQuery->nextval($table_name, $colname) - 1;
441        }else if(DB_TYPE == "mysql"){
442            $sql = "SHOW TABLE STATUS LIKE ?";
443            $arrData = $objQuery->getAll($sql, array($table_name));
444            $ret = $arrData[0]['Auto_increment'];
445        }
446        return $ret;
447    }
448
449    // バックアップテーブルにデータを更新する
450    function lfUpdBkupData($data){
451        $objQuery = new SC_Query();
452
453        $sql = "INSERT INTO dtb_bkup (bkup_name,bkup_memo,create_date) values (?,?,now())";
454        $objQuery->query($sql, array($data['bkup_name'],$data['bkup_memo']));
455    }
456
457    // バックアップテーブルからデータを取得する
458    function lfGetBkupData($where = "", $data = array()){
459        $objQuery = new SC_Query();
460
461        $sql = "SELECT bkup_name, bkup_memo, create_date FROM dtb_bkup ";
462        if ($where != "")   $sql .= $where;
463
464        $ret = $objQuery->getall($sql,$data);
465
466        return $ret;
467    }
468
469    // バックアップファイルをリストアする
470    function lfRestore($bkup_name){
471        // 実行時間を制限しない
472        set_time_limit(0);
473       
474        $objQuery = new SC_Query("", false);
475        $csv_data = "";
476        $success = true;
477
478        $bkup_dir = $this->bkup_dir . $bkup_name . "/";
479
480        //バックアップフォルダに移動する
481        chdir($this->bkup_dir);
482
483        //圧縮フラグTRUEはgzip解凍をおこなう
484        $tar = new Archive_Tar($bkup_name . $this->bkup_ext, TRUE);
485
486        //指定されたフォルダ内に解凍する
487        $success = $tar->extract("./");
488
489        // 無事解凍できれば、リストアを行う
490        if ($success) {
491
492            // トランザクション開始
493            $objQuery->begin();
494
495            // DBをクリア
496            $success = $this->lfDeleteAll($objQuery);
497
498            // INSERT実行
499            if ($success) $success = $this->lfExeInsertSQL($objQuery, $bkup_dir . "bkup_data.csv");
500
501            // 自動採番の値をセット
502            if ($success) $this->lfSetAutoInc($objQuery, $bkup_dir . "autoinc_data.csv");
503
504            // 各種ファイルのコピー
505            /**
506            if ($success) {
507                // 画像のコピー
508                $image_dir = $bkup_dir . "save_image/";
509                $copy_mess = "";
510                $copy_mess = SC_Utils_Ex::sfCopyDir($image_dir, "../../upload/save_image/", $copy_mess, true);
511
512                // テンプレートのコピー
513                $tmp_dir = $bkup_dir . "templates/";
514                $copy_mess = "";
515                $copy_mess = SC_Utils_Ex::sfCopyDir($tmp_dir, "../../user_data/templates/", $copy_mess, true);
516
517                // インクルードファイルのコピー
518                $inc_dir = $bkup_dir . "include/";
519                $copy_mess = "";
520                $copy_mess = SC_Utils_Ex::sfCopyDir($inc_dir, "../../user_data/include/", $copy_mess, true);
521
522                // CSSのコピー
523                $css_dir = $bkup_dir . "css/";
524                $copy_mess = "";
525                $copy_mess = SC_Utils_Ex::sfCopyDir($css_dir, "../../user_data/css/", $copy_mess, true);
526
527                // バックアップデータの削除
528                SC_Utils_Ex::sfDelFile($bkup_dir);
529            }**/
530
531            // リストア成功ならコミット失敗ならロールバック
532            if ($success) {
533                $objQuery->commit();
534                $this->restore_msg = "リストア終了しました。";
535                $this->restore_err = true;
536            }else{
537                $objQuery->rollback();
538                $this->restore_msg = "リストアに失敗しました。";
539                $this->restore_name = $bkup_name;
540                $this->restore_err = false;
541            }
542        }
543    }
544
545    // CSVファイルからインサート実行
546    function lfExeInsertSQL($objQuery, $csv){
547
548        $sql = "";
549        $base_sql = "";
550        $tbl_flg = false;
551        $col_flg = false;
552        $ret = true;
553        $pagelayout_flg = false;
554        $mode = $this->mode;
555
556        // csvファイルからデータの取得
557        $fp = fopen($csv, "r");
558        while (!feof($fp)) {
559            $data = fgetcsv($fp, 1000000);
560
561            //空白行のときはテーブル変更
562            if (count($data) <= 1 and $data[0] == "") {
563                $base_sql = "";
564                $tbl_flg = false;
565                $col_flg = false;
566                continue;
567            }
568
569            // テーブルフラグがたっていない場合にはテーブル名セット
570            if (!$tbl_flg) {
571                $base_sql = "INSERT INTO $data[0] ";
572                $tbl_flg = true;
573
574                if($data[0] == "dtb_pagelayout"){
575                    $pagelayout_flg = true;
576                }
577
578                continue;
579            }
580
581            // カラムフラグがたっていない場合にはカラムセット
582            if (!$col_flg) {
583                if ($mode != "restore_config"){
584                    $base_sql .= " ( $data[0] ";
585                    for($i = 1; $i < count($data); $i++){
586                        $base_sql .= "," . $data[$i];
587                    }
588                    $base_sql .= " ) ";
589                }
590                $col_flg = true;
591                continue;
592            }
593
594            // インサートする値をセット
595            $sql = $base_sql . "VALUES ( ? ";
596            for($i = 1; $i < count($data); $i++){
597                $sql .= ", ?";
598            }
599            $sql .= " );";
600            $data = str_replace("\\\"", "\"", $data);
601            $err = $objQuery->query($sql, $data);
602
603            // エラーがあれば終了
604            if ($err->message != ""){
605                SC_Utils_Ex::sfErrorHeader(">> " . $objQuery->getlastquery(false));
606                return false;
607            }
608
609            if ($pagelayout_flg) {
610                // dtb_pagelayoutの場合には最初のデータはpage_id = 0にする
611                $sql = "UPDATE dtb_pagelayout SET page_id = '0'";
612                $objQuery->query($sql);
613                $pagelayout_flg = false;
614            }
615
616            // タイムアウトを防ぐ
617            SC_Utils_Ex::sfFlush();
618        }
619        fclose($fp);
620
621        return $ret;
622    }
623
624    // 自動採番をセット
625    function lfSetAutoInc($objQuery, $csv){
626        // csvファイルからデータの取得
627        $arrCsvData = file($csv);
628
629        foreach($arrCsvData as $key => $val){
630            $arrData = split(",", trim($val));
631
632            if ($arrData[2] == 0)   $arrData[2] = 1;
633            $objQuery->setval($arrData[0], $arrData[1], $arrData[2]);
634        }
635    }
636
637    // DBを全てクリアする
638    function lfDeleteAll($objQuery){
639        $ret = true;
640
641        $arrTableList = $this->lfGetTableList();
642
643        foreach($arrTableList as $key => $val){
644            // バックアップテーブルは削除しない
645            if ($val != "dtb_bkup") {
646                $trun_sql = "DELETE FROM $val;";
647                $ret = $objQuery->query($trun_sql);
648
649                if (!$ret) return $ret;
650            }
651        }
652
653        return $ret;
654    }
655
656    // バックアップテーブルを作成する
657    function lfCreateBkupTable(){
658        $objQuery = new SC_Query();
659
660        // テーブルの存在チェック
661        $arrTableList = $this->lfGetTableList();
662
663        if(!in_array("dtb_bkup", $arrTableList)){
664            // 存在していなければ作成
665            $cre_sql = "
666            create table dtb_bkup
667            (
668                bkup_name   text,
669                bkup_memo   text,
670                create_date timestamp,
671                PRIMARY KEY (bkup_name)
672            );
673        ";
674
675            $objQuery->query($cre_sql);
676        }
677    }
678}
679?>
Note: See TracBrowser for help on using the repository browser.