source: branches/feature-module-update/html/admin/system/bkup.php @ 15078

Revision 15078, 16.3 KB checked in by nanasess, 19 years ago (diff)

r15064 から svn cp
とりあえず暫定コミット.

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