<?php

// (Shirai075): fs_moodleの設定を表示するメニューをサイト管理に追加 (2008/07/21)

require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/fs_moodle/fs_status/fs_switch_strings.php');
require_once($CFG->libdir.'/fs_moodle/fs_status/fs_cfg_strings.php');

global $USER;

/*
require_login();
if (!is_siteadmin($USER->id)) {
    echo 'このページは管理者以外は表示することができません．';
    die;
}
*/

if (is_readable("$CFG->dirroot/version.php")) {
    include_once("$CFG->dirroot/version.php");              # defines $version
}

// fs_moodleで追加したファイルのリストを読み込む
if (file_exists("{$CFG->libdir}/fs_moodle/fs_status/fs_filelist.php")) {
    require_once("{$CFG->libdir}/fs_moodle/fs_status/fs_filelist.php");
} else {
    echo color_red('fs_status/fs_filelist.phpが存在しません！<br/>');
}

//--------------------
// パラメータ設定機能
//--------------------

// 設定値の説明の頭に追加する属性に基づく文字列を返す
// function title_fs_cfg_head()
// function title_fs_switch_head()から呼ばれる
// yetMoodle2
// readyMoodle2
// afterMoodle2
function attribute_strings($attribute)
{
    $attrib_strings = '';
    // 属性未設定
    if (count($attribute) < 1) return '';

    // 属性：Moodle2には未対応
    if (in_array('yetMoodle2', $attribute)) {
        if (fs_get_major_version() >= 2.0) {
            $attrib_strings .= color_red('Moodle2未対応');
        }
    } else if (in_array('readyMoodle2', $attribute)) {
        if (fs_get_major_version() >= 2.0) {
            $attrib_strings .= color_blue('Moodle2も対応');
        }
    } else if (in_array('afterMoodle2', $attribute)) {
        if (fs_get_major_version() < 2.0) {
            $attrib_strings .= color_red('Moodle2以降のみ対応');
        }
    } else if (in_array('afterMoodle24', $attribute)) {
        if (fs_get_major_version() < 2.4) {
            $attrib_strings .= color_red('Moodle2.4以降のみ対応');
        }
    } else if (in_array('afterMoodle25', $attribute)) {
        if (fs_get_major_version() < 2.5) {
            $attrib_strings .= color_red('Moodle2.5以降のみ対応');
        }
    } else if (in_array('afterMoodle26', $attribute)) {
        if (fs_get_major_version() < 2.6) {
            $attrib_strings .= color_red('Moodle2.6以降のみ対応');
        }
    }
    return $attrib_strings;
}

// 単独で用いる（文字列を得る）ためのマクロ的関数
function str_readyMoodle2()
{
    return attribute_strings(array('readyMoodle2'));
}

function print_paramedit_buttons()
{
    global $SESSION, $CFG, $fsCFG;

    $out = $form1 = $form2 = $form3 = $form4 = $form5 = $form6 = '';
    $out .= '<div class="footer">';
    $out .= '<table border="1" cellspacing="0" cellpadding="5" bordercolor="#EEEEEE">';
    $out .= '<tr>';

    // fsconfig編集の開始／終了
    $form1 = '<form action="" method="post">';
    if (empty($SESSION->fscfgedit)) {
        $form1 .= '<input type="hidden" name="action" value="edit_on" />';
        $form1 .= '<input type="submit" value="fsconfig編集の開始" />';
    } else {
        $form1 .= '<input type="hidden" name="action" value="edit_off" />';
        $form1 .= '<input type="submit" value="fsconfig編集の終了" title="編集モードを終了します．" />';
    }
    $form1 .= '</form>';
    if (!empty($SESSION->fscfgedit)) {
        // デフォルト設定
        $form2  = '<form action="" method="post">';
        $form2 .= '<input type="hidden" name="action" value="setdefault" />';
        $form2 .= '<input type="submit" value="デフォルト設定（注意）" title="全ての設定を初期設定値に変更します．インストール後に行った管理者が行った設定は全て取り消されます！ fsconfig.phpは保存しませんので危険ではありませんが注意は必要です．" />';
        $form2 .= '</form>';
        // 変更を全て取り消す
        if (!empty($SESSION->fscfg) and count(get_object_vars($SESSION->fscfg))) {
            $form3  = '<form action="" method="post">';
            $form3 .= '<input type="hidden" name="action" value="clear_all" />';
            $form3 .= '<input type="submit" value="変更を全て取り消す" title="変更を全て取り消します．fsconfig.phpは保存しませんので危険ではありません．" />';
            $form3 .= '</form>';
        }
    }
    if (!empty($SESSION->fscfgedit)) {
        // プレビュー表示のみ
        $form4  = '<form action="'.$CFG->wwwroot.'/lib/fs_moodle/fs_status/fsconfig_output.php" method="post" target="_blank">';
        $form4 .= '<input type="hidden" name="action" value="displaycfg" />';
        $form4 .= '<input type="submit" value="プレビュー表示のみ" title="上書き時に保存されるであろうfsconfig.phpを表示します．あくまでプレビューであって保存はしません．"/>';
        $form4 .= '</form>';
        // 上書き保存
        if (!empty($SESSION->fscfg) and count(get_object_vars($SESSION->fscfg)) or (!empty($fsCFG->novariable) or !empty($fsCFG->notvalid))) {
            $form5  = '<form action="'.$CFG->wwwroot.'/lib/fs_moodle/fs_status/fsconfig_output.php" method="post" target="_blank">';
            $form5 .= '<input type="hidden" name="action" value="overwrite" />';
            $form5 .= '<input type="submit" value="更新＋上書き保存（覚悟は良いですか？）" title="変更された設定値でfsconfig.phpを上書きします．確認画面はありません．バックアップを忘れずに！"/>';
            $form5 .= '</form>';
        }
        // 再表示
        $form6  = '<form action="" method="post">';
        $form6 .= '<input type="hidden" name="action" value="reload" />';
        $form6 .= '<input type="submit" value="再表示" title="画面を再表示します．上書き保存した後に修正結果を確認する場合などにクリックして下さい．"/>';
        $form6 .= '</form>';
    }

    $out .= '<td bgcolor="#EEE8AA">'.$form1.'</td>';    // 開始／終了
    if (!empty($form2))
    $out .= '<td bgcolor="#FFF0F5">'.$form2.'</td>';    // デフォルト設定
    if (!empty($form3))
    $out .= '<td bgcolor="#FFF0F5">'.$form3.'</td>';    // 変更を全て取り消す
    if (!empty($form4))
    $out .= '<td bgcolor="#E0FFFF">'.$form4.'</td>';    // プレビュー表示のみ
    if (!empty($form5))
    $out .= '<td bgcolor="#E0FFFF">'.$form5.'</td>';    // 更新＋上書き
    if (!empty($form6))
    $out .= '<td bgcolor="#E0FFFF">'.$form6.'</td>';    // 再表示

    $out .= '</tr>';
    $out .= '</table>';
    $out .= '</div>';
    echo $out;
}

function fs_config_set2default()
{
    global $fs_cfg_strings, $fs_switch_strings;
    global $SESSION, $fsCFG, $CFG;

    // 全パラメータ／スイッチをサーバOS種別に合わせてデフォルトに変更する
    foreach ($fs_cfg_strings as $cfgname => $fs_cfg_string) {
        if (!isset($fsCFG->$cfgname) or (($defaultvalue = get_fs_cfg_default($cfgname)) != $fsCFG->$cfgname)) {
            $SESSION->fscfg->$cfgname = $defaultvalue;
        }
    }
    foreach ($fs_switch_strings as $defname => $fs_switch_string) {
        if (($defaultvalue = get_fs_switch_default($defname)) != fs_function_defined_and_enable($defname)) {
            $SESSION->fscfg->$defname = $defaultvalue;
        }
    }
}

// GET,POSTのパラメータ解析
// GET: モードのOn/Offのみ
// POST: fsconfigパラメータの変更＋リセット
function analyze_parameters()
{
    global $SESSION, $fsCFG, $CFG;
    $setdefault = false;
    // コマンドの解釈
    if (!empty($_POST['action'])) {
        switch ($_POST['action']) {
          case 'edit_on':
            // 編集モードのOn
            $SESSION->fscfgedit = true;
            break;
          case 'edit_off':
            // 編集モードのOff
            unset($SESSION->fscfgedit);
            unset($SESSION->fscfg);
            break;
          case 'setdefault':
            // 全パラメータ／スイッチをサーバOS種別に合わせてデフォルトに変更する
            $setdefault = true;
          case 'clear_all':
            // 全パラメータ変更の破棄
            unset($SESSION->fscfg);
            break;
          case 'reload':
            // 単に再読み込み
            break;
        }
        unset($_POST['action']);
    }
    if ($setdefault) {
        fs_config_set2default();
    } else {
        // パラメータの変更／破棄
        if (!empty($_POST)) {
            $cfgname  = (!empty($_POST['cfgname']) ? $_POST['cfgname'] : '');
            $clearcfg = (!empty($_POST['clear'])   ? $cfgname : '');
            if (!empty($cfgname) and isset($_POST[$cfgname])) {
                // 現在の値と異なる場合のみ更新
                if ($_POST[$cfgname] == $fsCFG->$cfgname) {
                    unset($SESSION->fscfg->$cfgname);
                } else {
                    if (!empty($fs_cfg_strings->$cfgname)) {
                        if ($fs_cfg_strings->{$cfname}[2][0] == 'int') {
                            $_POST[$cfgname] = intval($_POST[$cfgname]);
                        }
                    }
                    $SESSION->fscfg->$cfgname = $_POST[$cfgname];
                }
            }
            if (!empty($clearcfg)) {
                unset($SESSION->fscfg->$clearcfg);
            }

            // スイッチの変更／破棄
            $defname  = (!empty($_POST['defname']) ? $_POST['defname'] : '');
            $cleardef = (!empty($_POST['clear'])   ? $defname : '');
            if (!empty($defname) and isset($_POST[$defname])) {
                // 現在の値と異なる場合のみ更新
                if ($_POST[$defname] == fs_function_enable($defname)) {
                    unset($SESSION->fscfg->$defname);
                    $SESSION->fscfg->$defname = $_POST[$defname];
                } else {
                    $SESSION->fscfg->$defname = $_POST[$defname];
                }
            }
            if (!empty($cleardef) and isset($SESSION->fscfg->$cleardef)) {
                unset($SESSION->fscfg->$cleardef);
            }
        }
        // 最終チェック
        // $SESSIONと$fsCFG/define()を比較して無駄な$SESSIONを削除する
        // ”上書き”を行った後などに有効（ただし画面のリロードが必要）
        global $fs_cfg_strings, $fs_switch_strings;
        foreach ($fs_cfg_strings as $cfgname => $fs_cfg_string) {
            if (isset($fsCFG->$cfgname) and isset($SESSION->fscfg->$cfgname) and ($SESSION->fscfg->$cfgname == $fsCFG->$cfgname)) {
                unset($SESSION->fscfg->$cfgname);
            }
        }
        foreach ($fs_switch_strings as $defname => $fs_switch_string) {
            if (isset($SESSION->fscfg->$defname) and ($SESSION->fscfg->$defname == fs_function_enable($defname))) {
                unset($SESSION->fscfg->$defname);
            }
        }

    }
}

// config.php, fs_config.phpの頭とお尻のチェック(2008/10/23)
// 戻り値
//  1 : OK
//  0 : ファイルが存在しない
// -1 : ファイルの中身が空
// -2 : BOMが頭にある
// -3 : 余計な文字が頭にある（BOM以外）
// -4 : 余計な文字がお尻にある
// -5 : 文字コードがASCII/UTF-8以外である
function check_config_head_and_tail($configpath1, $configpath2 = '')
{
    if (file_exists($configpath1)) {
        $configpath = $configpath1;
    } else if (file_exists($configpath2)) {
        $configpath = $configpath2;
    } else return 0;
    if (!($farray = file($configpath)))  return -1;
    // チェック１（BOM）
    $c1 = ord(substr($farray[0], 0, 1));
    $c2 = ord(substr($farray[0], 1, 1));
    $c3 = ord(substr($farray[0], 2, 1));
    if (($c1 == 0xef) && ($c2 == 0xbb) && ($c3 == 0xbf)) return -2;
    if (($c1 == 0xfe) && ($c2 == 0xff)) return -2; // UTF-16
    if (($c1 == 0xff) && ($c2 == 0xfe)) return -2; // UTF-16
    // チェック２
    if (strncmp($farray[0], "<?php", 5) != 0) return -3;
    $tail = rtrim($farray[count($farray) - 1], "\n");
    $tail = rtrim($tail, "\r");
    $tail = rtrim($tail, "\n");
    if ($tail != "?>") {
        // 最後の行の最後に？＞があるか，そもそも無いか．
        for ($i = 0; $i < count($farray); $i++) {
            if (mb_strpos($farray[$i], '?>') !== false) return -4;
        }
    }
    // チェック３（文字コード）
    $encname = mb_detect_encoding(file_get_contents($configpath));
    if (($encname != 'ASCII') && ($encname != 'UTF-8')) return -5;
    return 1;
}

// config.php，fs_config.phpのセキュリティのチェック (2008/12/03)
function check_config_security($configpath)
{
    $ret = array();
    clearstatcache();
    if (!file_exists($configpath))  return false;
    $ret['writable'] = is_writable($configpath);
    $ret['owner']    = fileowner($configpath);
    $ret['group']    = filegroup($configpath);
    $ret['perms']    = sprintf('%0', fileperms($configpath));

    echo color_blue(fs_basename($configpath)).'<br/>';
    echo '　このファイルは';
    if ($ret['writable']) {
        echo color_red('書き換え可能です！');
        echo 'このままの運用は危険です．<br/>';
    } else {
        echo color_blue('書き換えできません．');
        echo '一応安全です．<br/>';
    }
    echo '　このファイルのアクセス権限は'.color_blue($ret['perms']).'です．<br/>';
    echo '　このファイルのオーナーは';
    if ($ret['owner'] === 0) echo color_blue('スーパーユーザー').'です．<br/>';
        else                 echo color_blue('一般ユーザー（'.$ret['owner'].'）').'です．<br/>';
    echo '　このファイルのグループ（ＩＤ）は'.color_blue($ret['group']).'です．<br/>';
}

// fs_moodle3まではmoodleルートにあっても構わない．
// fs_moodle4からはmoodledata/configのみＯＫとする．
function filecheck_fsconfig()
{
    global $CFG;
    if (file_exists($CFG->dirroot.'/fsconfig.php') || file_exists(FSCONFIGDIR.'/fsconfig.php')) return true;
    return false;
}

function filecheck_fs_moodle($err_check_only = false)
{
    global $CFG;
    global $filelist;
    global $langlist;
    global $helplist;

    if (!$err_check_only) print_section_header('構成ファイルのチェック');

    $flag = 0;
    // fsconfig.phpの所在チェック
    if (!filecheck_fsconfig()) $flag = 2;

    // file check
    $count = 0;
    foreach ($langlist as $lang) {
        $filelist[] = "lib/fs_moodle/lang/en_utf8/".$lang;
        $filelist[] = "lib/fs_moodle/lang/ja_utf8/".$lang;
        $filelist[] = "lib/fs_moodle/lang/en/".$lang;
        $filelist[] = "lib/fs_moodle/lang/ja/".$lang;
    }
    foreach ($helplist as $help) {
        $filelist[] = "lib/fs_moodle/lang/en_utf8/help/".$help;
        $filelist[] = "lib/fs_moodle/lang/ja_utf8/help/".$help;
        $filelist[] = "lib/fs_moodle/lang/en/help/".$help;
        $filelist[] = "lib/fs_moodle/lang/ja/help/".$help;
    }
    foreach ($filelist as $fname) {
        if (!file_exists($CFG->dirroot.'/'.$fname)) {
            echo color_red('NG: '.$fname.'が存在しません．<br/>');
            if ($flag == 0) $flag = 1;
        } else {
            if (!$err_check_only) echo color_blue('OK: '.$fname.'<br/>');
        }
        $count++;
    }
    if (!$err_check_only) {
        echo 'チェック完了<br/>';
        echo '全'.$count.'ファイル<br/>';
    }
    if ($flag == 1) {
        echo '存在しないファイルがあります．よく確認して下さい．<br/>';
    } else if ($flag == 2) {
        echo 'fsconfig.phpが存在しません！<br/>';
    } else {
        if (!$err_check_only) echo 'fs_moodleで追加された全てのファイルが存在します．<br/>';
    }
    if (!$err_check_only) print_section_footer();
    return $flag;
}

function printout_backup_exception_conditions()
{
    global $CFG, $fsCFG;

    if (!empty($fsCFG->backup_exception)) {
        echo '<table border="1" width="95%" align="center" cellpadding="5" cellspacing="0" style="bordercolor: #333333">';
        echo '<caption align="top">現在設定されているバックアップ制限条件</caption>';
        echo '<tr bgcolor="#cccccc">';
        echo '<th>No.</th><th>ファイル名</th><th>拡張子</th><th>ファイルサイズ</th><th>コース名(ID)</th><th>moddataフォルダ</th><th>有効</th></tr>';
        $no = 1;
        foreach ($fsCFG->backup_exception as $exception) {
            echo '<tr>';
            echo '<td align="center">';
            echo $no++;
            echo '</td><td align="center">';
            if (empty($exception->filename))  echo '（無指定）'; else echo $exception->filename;
            echo '</td><td align="center">';
            if (empty($exception->extension)) echo '（無指定）'; else echo $exception->extension;
            echo '</td><td align="center">';
            if (empty($exception->filesize))  echo '（無指定）'; else {
                if ($exception->filesize >= 1024 * 1024 * 1024) {
                    // GB
                    $filesizeGB = $exception->filesize / (1024 * 1024 * 1024);
                    $filesizeGB = (int)($filesizeGB * 10) / 10;
                    echo $filesizeGB.'&nbsp;GB';
                } else {
                    // MB
                    $filesizeMB = $exception->filesize / 1024 / 1024;
                    $filesizeMB = (int)($filesizeMB * 10) / 10;
                    echo $filesizeMB.'&nbsp;MB';
                }
                echo '<br />'.$exception->filesize.'&nbsp;[byte]';
            }
            echo '</td><td>';
            if (empty($exception->courseid)) {
                echo '（全コース）';
            } else if ($exception->courseid == SITEID) {
                echo '（フロントページ）';
            } else {
                if (! ($course = fs_get_record("course", "id", $exception->courseid))) {
                    echo '（存在しないコース）&nbsp;('.$exception->courseid.')';
                } else {
                    echo '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$exception->courseid.'" target="_blank">';
                    echo $course->fullname.'&nbsp;('.$exception->courseid.')';
                    echo '</a>';
                }
            }
            echo '</td><td align="center">';
            if ($exception->moddatafolder) {
                echo '対象に含む';
            } else {
                echo '（対象外）';
            }
            echo '</td><td align="center">';
            switch ($exception->control) {
              case 1 : echo '自動時のみ'; break;
              case 2 : echo '手動時のみ'; break;
              case 3 : echo '自動／手動'; break;
              default: echo '（異常）';   break;
            }
            echo '</td>';
            echo '</tr>';
        }
        echo '</table>';
    }
}


//  1 : OK
//  0 : ファイルが存在しない
// -1 : ファイルの中身が空
// -2 : BOMが頭にある
// -3 : 余計な文字が頭にある（BOM以外）
// -4 : 余計な文字がお尻にある
// -5 : 文字コードがUTF-8ではない
function err_msg_config($status)
{
    switch ($status) {
        case  0 : return "ファイルが存在しない";
        case -1 : return "ファイルの中身が空";
        case -2 : return "BOMが頭にある";
        case -3 : return "余計な文字が頭にある（改行や空白もＮＧ）";
        case -4 : return "余計な文字がお尻にある（改行や空白もＮＧ）";
        case -5 : return "文字コードがUTF-8ではない";
        default : return "異常";
    }
    return "異常";
}

// fs_moodleの状態表示以下の画面の表示用
function page_header()
{
    global $CFG;
    global $OUTPUT;

    require_login(0, false);

    if (fs_get_moodle_version() < 2007101500) {
        // Moodle1.8
        $adminroot = admin_get_root();
        admin_externalpage_setup('fs_status', $adminroot);
        admin_externalpage_print_header($adminroot);
    } else {
        admin_externalpage_setup('fs_status');
        if (!empty($OUTPUT)) {
            // Moodle2.5-
            echo $OUTPUT->header();
        } else {
            // Moodle1.9 - Moodle2.4
            admin_externalpage_print_header();
        }
    }
    // ファイルチェック
    if (filecheck_fs_moodle(true) === 2) {
        echo '致命的な問題です．処理を中断します．<br />';
        page_footer();
        die;
    }
}

// fs_moodleの状態表示以下の画面の表示用
function page_footer()
{
    global $CFG;
    global $OUTPUT;

    if (!empty($CFG->version)) $_version = $CFG->version; else $_version = $version;  // Moodle2.6から$versionは見えなくなった
    if ($_version < 2007101500) {
        // Moodle1.8
        $adminroot = admin_get_root();
        admin_externalpage_print_footer($adminroot);
    } else {
        if (!empty($OUTPUT)) {
            // Moodle2.5-
            echo $OUTPUT->footer();
        } else {
            // Moodle1.9-2.4
            admin_externalpage_print_footer();
        }
    }
}

// もし引数が厳密にfalseならば'false', trueならば'true'を返す
function bool2string($val)
{
    if ($val === false) return 'false';
    if ($val === true)  return 'true';
    return $val;
}

// fs_moodle3からfs_moodle4への移行期に必要な関数
// fsconfig.phpからfsconfig_option.phpへの移行に関する警告文
function notice_fsconfig2fsconfig_option()
{
    print_notice_message('注意',
        color_blue('fs_moodle4').'以降のバージョンでは，この設定を'.
        color_blue('moodledata/config/fsconfig_option.php').'に記述して下さい．'.
        color_blue('fsconfig編集').'による整形された'.color_blue('fsconfig.php').'の出力にはこの設定が含まれません．'.
        'これらの設定の管理は管理者が手作業で'.color_blue('fsconfig_option.php').'に対して行う必要があります．');
}

// インクルードするページコンテンツのチェック
function pagecheck()
{
    global $CFG, $pagename, $page;
    if (empty($CFG)) {
        echo 'このファイルを直接開くことはできません．';
        die;
    }
    global $titleonly, $output;
    if (!empty($titleonly)) {
        while(@ob_get_clean());
        ob_start();
    }
    echo '<p style="background: #FF8C00; color:#FFFFFF; size: 14pt; line-height: 2" align="center">';
    if (empty($titleonly)) {
        echo $pagename;
    } else {
        echo '<a href="'.$CFG->wwwroot.'/lib/fs_moodle/fs_status/index.php?page='.urlencode($page).'">',$pagename.'</a>';
    }
    echo '</p>';
    if (!empty($titleonly)) {
        $output .= ob_get_clean();
        while(@ob_get_clean());
        ob_start();
    }
}

?>
