function ModulePage()
 {
     if ($this->ADMIN_ONLY && !adminAuthenticate('check')) {
         // 只容許管理員生成靜態庫存頁面
         echo 'Access Denied.';
         return;
     }
     $res = isset($_GET['res']) ? $_GET['res'] : 0;
     // 欲生成靜態庫存頁面之討論串編號
     if (!$res || !$this->MULTI_COPY && glob($this->ARCHIVE_ROOT . $res . '-*.xml')) {
         echo 'No argument or the archive already existed.';
         // 參數不對或XML檔案已存在
     } else {
         $this->GenerateArchive($res);
         // 生成靜態庫存頁面
         echo 'FINISH.';
     }
 }
    function ModulePage()
    {
        global $PMS;
        if (!adminAuthenticate('check')) {
            die('[Error] Access Denied.');
        }
        // 進行新增、刪除等動作
        if (isset($_POST['operate'])) {
            $op = $_POST['operate'];
            // 新增資料
            $ndata = isset($_POST['newdata']) ? get_magic_quotes_gpc() ? stripslashes($_POST['newdata']) : $_POST['newdata'] : '';
            // 資料內容
            $nperiod = isset($_POST['newperiod']) ? intval($_POST['newperiod']) : 0;
            // 封鎖天數
            $ndesc = isset($_POST['newdesc']) ? CleanStr($_POST['newdesc']) : '';
            // 註解
            if ($ndata && ($op == 'badstr' || $op == 'badua') && ($nperiod || isset($_POST['plaintext']))) {
                $ndata = preg_quote($ndata, '`');
            }
            // plain text, not regex
            // 刪除資料
            $del = isset($_POST['del']) ? $_POST['del'] : null;
            $newline = '';
            $ismodified = $op != 'imghash' && ($ndata != '' || $del != null);
            // 是否需要修改檔案內容
            if ($ismodified) {
                switch ($op) {
                    case 'ip':
                        $file = $this->ipfile;
                        if ($ndata != '') {
                            $newline = $ndata . "\t" . $ndesc . "\t" . time() . "\t" . $nperiod . "\n";
                        }
                        break;
                    case 'img':
                        $file = $this->imgfile;
                        if ($ndata != '') {
                            $newline = $ndata . "\t" . $ndesc . "\n";
                        }
                        break;
                    case 'badstr':
                        $file = $this->badstrfile;
                        if ($ndata != '') {
                            $newline = $ndata . "\t" . $ndesc . "\n";
                        }
                        break;
                    case 'badua':
                        $file = $this->baduafile;
                        if ($ndata != '') {
                            $newline = $ndata . "\t" . $ndesc . "\n";
                        }
                        break;
                }
                $this->_arrangeRecord($file, $del, $newline);
                // 同步進行刪除及更新
            }
            if ($op == 'imghash') {
                foreach ($del as $file) {
                    if (file_exists($this->imghash_imgdir . $file)) {
                        unlink($this->imghash_imgdir . $file);
                    }
                    if (file_exists($this->imghash_hashdir . $file . '.imghash')) {
                        unlink($this->imghash_hashdir . $file . '.imghash');
                    }
                }
            }
            if (isset($_POST['ajax'])) {
                // AJAX 要求在此即停止,一般要求則繼續印出頁面
                $extend = $op == 'ip' ? '<td>' . date('Y/m/d H:m:s', time()) . " ({$nperiod})</td>" : '';
                // IP黑名單資訊比圖檔多
                echo '<tr><td>' . htmlspecialchars($ndata) . '</td><td>' . $ndesc . '</td>' . $extend . '<td><input type="checkbox" name="del[]" value="#NO#" /></td></tr>';
                return;
            }
        }
        $dat = '';
        $PMS->hookModuleMethod('Head', array(&$this, '_hookHeadCSS'));
        head($dat);
        $dat .= '<div class="bar_admin">封鎖黑名單管理</div>
<div id="content">
<form action="' . $this->mypage . '" method="post">
<div id="ipconfig"><input type="hidden" name="operate" value="ip" />
IP 黑名單<br />
Pattern: <input type="text" name="newdata" size="30" />
Period: <input type="text" name="newperiod" size="5" value="0" />Day(s)
Desc: <input type="text" name="newdesc" size="30" />
<input type="submit" value="新增" onclick="return add(this.form);" /><br />
<div class="dos_list_short">
<table border="0" width="100%">
<tr><td>Pattern</td><td>Description</td><td>Add Date (Period)</td><td>Delete</td></tr>
';
        foreach ($this->_parseBlackListFile($this->ipfile) as $i => $l) {
            $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td>' . '<td>' . (isset($l[2]) ? date('Y/m/d H:m:s', $l[2]) : '-') . (isset($l[3]) ? ' (' . $l[3] . ')' : ' (0)') . '</td>' . '<td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n";
        }
        $dat .= '</table>
</div>
<input type="submit" value="刪除" />
</div>
</form>

<form action="' . $this->mypage . '" method="post">
<div id="imgconfig"><input type="hidden" name="operate" value="img" />
圖檔 MD5 黑名單<br />
MD5: <input type="text" name="newdata" size="30" />
Desc: <input type="text" name="newdesc" size="30" />
<input type="hidden" name="newperiod" value="0" />
<input type="submit" value="新增" onclick="return add(this.form);" /><br />
<div class="dos_list_short">
<table border="0" width="100%">
<tr><td>MD5</td><td>Description</td><td>Delete</td></tr>
';
        foreach ($this->_parseBlackListFile($this->imgfile) as $i => $l) {
            $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td><td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n";
        }
        $dat .= '</table>
</div>
<input type="submit" value="刪除" />
</div>
</form>';
        if ($this->use_imghash) {
            $dat .= '<form action="' . $this->mypage . '" method="post">
<div id="imgconfig"><input type="hidden" name="operate" value="imghash" />
圖檔 imghash 黑名單<br />
<div class="dos_list_short">
<table border="0" width="100%">
<tr><td>File</td><td>Preview</td><td>Delete</td></tr>
';
            $pfolder = opendir($this->imghash_imgdir);
            //Folder
            $pnamebase = array();
            while ($file = readdir($pfolder)) {
                if (is_file($this->imghash_imgdir . $file)) {
                    $dat .= '<tr><td>' . $file . '</td><td><a href="' . $this->imghash_imgdir . $file . '" target="_blank">■</a></td><td><input type="checkbox" name="del[]" value="' . $file . '" /></td></tr>' . "\n";
                }
            }
            closedir($pfolder);
            $dat .= '</table>
</div>
<input type="submit" value="刪除" />
</div>
</form>';
        }
        $dat .= '<form action="' . $this->mypage . '" method="post">
<div id="imgconfig"><input type="hidden" name="operate" value="badstr" />
文字黑名單<br />
文字列(可用正規表達式,不需用 / 斜線): <input type="text" name="newdata" size="30" />
Desc: <input type="text" name="newdesc" size="30" />
<input type="hidden" name="newperiod" value="0" /> <label><input type="checkbox" name="plaintext" value="1" onchange="this.form.newperiod.value=this.checked?1:0" />純文字</label>
<input type="submit" value="新增" onclick="return add(this.form);" /><br />
<div class="dos_list_short">
<table border="0" width="100%">
<tr><td>文字列</td><td>Description</td><td>Delete</td></tr>
';
        foreach ($this->_parseBlackListFile($this->badstrfile) as $i => $l) {
            $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td><td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n";
        }
        $dat .= '</table>
</div>
<input type="submit" value="刪除" />
</div>';
        $dat .= '<form action="' . $this->mypage . '" method="post">
<div id="uaconfig"><input type="hidden" name="operate" value="badua" />
User Agent黑名單<br />
文字列(可用正規表達式,不需用 / 斜線): <input type="text" name="newdata" size="30" />
Desc: <input type="text" name="newdesc" size="30" />
<input type="hidden" name="newperiod" value="0" /> <label><input type="checkbox" name="plaintext" value="1" onchange="this.form.newperiod.value=this.checked?1:0" />純文字</label>
<input type="submit" value="新增" onclick="return add(this.form);" /><br />
<div class="dos_list_short">
<table border="0" width="100%">
<tr><td>文字列</td><td>Description</td><td>Delete</td></tr>
';
        foreach ($this->_parseBlackListFile($this->baduafile) as $i => $l) {
            $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td><td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n";
        }
        $dat .= '</table>
</div>
<input type="submit" value="刪除" />
</div>
</form>
<hr />
<div id="help"><pre>
說明

Pattern:

可封鎖特定IP/Hostname發文。以使用者的IP位置或Host名稱進行判斷,所以兩種形式都可以使用。
例如 127.0.0.1 (IP) 和 localhost (Host) 代表的都是相同的電腦。
接受下列格式

- 完全相符
即是完全一模一樣的情況下才封鎖。
範例:
127.0.0.1 (127.0.0.1 O;127.0.0.2 X)
localhost (localhost O;local X)

- 萬用字元
可接受 * , ? 來代替一段未知的字元 (如同大家熟知的使用方式),這樣一來可匹配的情況將增加。
範例:
192.168.0.* (192.168.0.3 O;192.168.1.3 X)
local* (localhost O;remotehost X)

- 正規表達式
使用Regular Expression來進行匹配,可作出更多樣、更適合的條件。注意使用時需要使用 / 斜線將表達式括住。
範例:
/127\\.0\\.0\\.[0-9]{2}/ (127.0.0.28 O;127.0.0.1 X)
/^.+\\.proxy\\.com$/ (gate1.proxy.com O;proxy2.com.tw X)

- CIDR Notation
使用 Classless Addressing 這種更有彈性的方式切割子網路,其表示法稱作 CIDR,以一段IP位置加上Mask來劃分子網路 (注意此表示法僅能使用 IP)。
範例:
192.168.0.1/20 (192.168.7.243 O;192.168.18.144 X)

Period:

設定封鎖期限,在過期時可以自動刪除解鎖,以天為單位。如果想永久封鎖 (系統不自動回收,需手動解鎖) 則將此值設為 0 (0 表示無期限)。</pre>
</div>
</div>';
        foot($dat);
        echo $dat;
    }
Exemple #3
0
function valid()
{
    $PMS = PMCLibrary::getPMSInstance();
    $pass = isset($_POST['pass']) ? $_POST['pass'] : '';
    // 管理者密碼
    $haveperm = false;
    $isCheck = adminAuthenticate('check');
    // 登入是否正確
    if (!$isCheck && $pass) {
        $haveperm = passwordVerify($pass);
        $PMS->useModuleMethods('Authenticate', array($pass, 'admin', &$haveperm));
        if ($haveperm) {
            adminAuthenticate('login');
            $isCheck = true;
        } else {
            error(_T('admin_wrongpassword'));
        }
    }
    $dat = '';
    head($dat);
    $links = '[<a href="' . PHP_SELF2 . '?' . time() . '">' . _T('return') . '</a>] [<a href="' . PHP_SELF . '?mode=remake">' . _T('admin_remake') . '</a>] [<a href="' . PHP_SELF . '?page_num=0">' . _T('admin_frontendmanage') . '</a>]';
    $PMS->useModuleMethods('LinksAboveBar', array(&$links, 'admin', $isCheck));
    // LinksAboveBar hook point
    $dat .= '<div id="banner">' . $links . '<div class="bar_admin">' . _T('admin_top') . '</div>
</div>
<form action="' . PHP_SELF . '" method="post" name="adminform">
<div id="admin-check" style="text-align: center;">
';
    echo $dat;
    if (!$isCheck) {
        echo '<br />
<input type="radio" name="admin" value="del" checked="checked" />' . _T('admin_manageposts') . '
<input type="radio" name="admin" value="optimize" />' . _T('admin_optimize') . '
<input type="radio" name="admin" value="check" />' . _T('admin_check') . '
<input type="radio" name="admin" value="repair" />' . _T('admin_repair') . '
<input type="radio" name="admin" value="export" />' . _T('admin_export') . '<br />
<input type="hidden" name="mode" value="admin" />
<input type="password" name="pass" size="8" />
<input type="submit" value="' . _T('admin_verify_btn') . '" />
</div>
</form>';
        die("\n</body>\n</html>");
    } elseif (!isset($_REQUEST['admin'])) {
        echo '<br />
<input type="radio" name="admin" value="del" checked="checked" />' . _T('admin_manageposts') . '
<input type="radio" name="admin" value="optimize" />' . _T('admin_optimize') . '
<input type="radio" name="admin" value="check" />' . _T('admin_check') . '
<input type="radio" name="admin" value="repair" />' . _T('admin_repair') . '
<input type="radio" name="admin" value="export" />' . _T('admin_export') . '
<input type="radio" name="admin" value="logout" />' . _T('admin_logout') . '<br />
<input type="hidden" name="mode" value="admin" />
<input type="submit" value="' . _T('admin_submit_btn') . '" />
</div>
</form>';
        die("\n</body>\n</html>");
    }
}
Exemple #4
0
 function ModulePage()
 {
     global $PIO, $FileIO, $PMS, $language, $BAD_STRING, $BAD_FILEMD5, $BAD_IPADDR, $LIMIT_SENSOR;
     if (!isset($_GET['no'])) {
         die('[Error] not enough parameter.');
     }
     if (!isset($_POST['mode'])) {
         // 顯示表單
         if (!$this->shown_in_page && !adminAuthenticate('check')) {
             die('[Error] Access Denied.');
         }
         $post = $PIO->fetchPosts($_GET['no']);
         if (!count($post)) {
             die('[Error] Post does not exist.');
         }
         extract($post[0]);
         $PMS->loadModules('mod_bbcode');
         //嘗試載入mod_bbcode
         if ($bbcode = $PMS->getModuleInstance('mod_bbcode')) {
             $bbcode->_html2bb($com);
         }
         $name = preg_replace('|<span.*?>(.*?)</span>|', '\\1', $name);
         $dat = '';
         head($dat);
         $PMS->hookModuleMethod('PostInfo', array($this, '_EditPostInfo'));
         form($dat, $resto, false, $this->mypage . '&amp;no=' . $_GET['no'], $name, $email, $sub, str_replace('<br />', "\n", $com), substr(str_replace('&#44;', ',', $category), 1, -1), 'edit');
         foot($dat);
         echo $dat;
     } else {
         // 儲存
         if ($_SERVER['REQUEST_METHOD'] != 'POST') {
             error(_T('regist_notpost'));
         }
         // 非正規POST方式
         $post = $PIO->fetchPosts($_GET['no']);
         $newValues = array();
         if (!count($post)) {
             die('[Error] Post does not exist.');
         }
         $name = isset($_POST[FT_NAME]) ? $_POST[FT_NAME] : '';
         $email = isset($_POST[FT_EMAIL]) ? $_POST[FT_EMAIL] : '';
         $sub = isset($_POST[FT_SUBJECT]) ? $_POST[FT_SUBJECT] : '';
         $com = isset($_POST[FT_COMMENT]) ? $_POST[FT_COMMENT] : '';
         $pwd = isset($_POST['pwd']) ? $_POST['pwd'] : '';
         $category = isset($_POST['category']) ? $_POST['category'] : '';
         $resto = isset($_POST['resto']) ? $_POST['resto'] : 0;
         $upfile = '';
         $upfile_path = '';
         $upfile_name = false;
         $upfile_status = 4;
         $pwdc = isset($_COOKIE['pwdc']) ? $_COOKIE['pwdc'] : '';
         if ($resto && !$PIO->isThread($resto)) {
             die('[Error] Thread was deleted.');
         }
         $is_admin = $haveperm = $pwd == ADMIN_PASS || adminAuthenticate('check');
         $PMS->useModuleMethods('Authenticate', array($pwd, 'useredit', &$haveperm));
         if ($pwd == '' && $pwdc != '') {
             $pwd = $pwdc;
         }
         $pwd_md5 = substr(md5($pwd), 2, 8);
         $host = gethostbyaddr(getREMOTE_ADDR());
         if (!($pwd_md5 == $post[0]['pwd'] || $host == $post[0]['host'] || $haveperm)) {
             die('[Error] Access denied.');
         }
         // 欄位陷阱
         $FTname = isset($_POST['name']) ? $_POST['name'] : '';
         $FTemail = isset($_POST['email']) ? $_POST['email'] : '';
         $FTsub = isset($_POST['sub']) ? $_POST['sub'] : '';
         $FTcom = isset($_POST['com']) ? $_POST['com'] : '';
         $FTreply = isset($_POST['reply']) ? $_POST['reply'] : '';
         if ($FTname != 'spammer' || $FTemail != '*****@*****.**' || $FTsub != 'DO NOT FIX THIS' || $FTcom != 'EID OG SMAPS' || $FTreply != '') {
             error(_T('regist_nospam'));
         }
         // 封鎖:IP/Hostname/DNSBL 檢查機能
         $ip = getREMOTE_ADDR();
         $host = gethostbyaddr($ip);
         $baninfo = '';
         if (BanIPHostDNSBLCheck($ip, $host, $baninfo)) {
             error(_T('regist_ipfiltered', $baninfo));
         }
         // 封鎖:限制出現之文字
         foreach ($BAD_STRING as $value) {
             if (strpos($com, $value) !== false || strpos($sub, $value) !== false || strpos($name, $value) !== false || strpos($email, $value) !== false) {
                 error(_T('regist_wordfiltered'));
             }
         }
         $PMS->useModuleMethods('RegistBegin', array(&$name, &$email, &$sub, &$com, array('file' => &$upfile, 'path' => &$upfile_path, 'name' => &$upfile_name, 'status' => &$upfile_status), array('ip' => $ip, 'host' => $host)));
         // "RegistBegin" Hook Point
         // 檢查是否輸入櫻花日文假名
         $chkanti = array($name, $email, $sub, $com);
         foreach ($chkanti as $anti) {
             if (anti_sakura($anti)) {
                 error(_T('regist_sakuradetected'));
             }
         }
         // 檢查表單欄位內容並修整
         if (strlen($name) > 100) {
             error(_T('regist_nametoolong'));
         }
         if (strlen($email) > 100) {
             error(_T('regist_emailtoolong'));
         }
         if (strlen($sub) > 100) {
             error(_T('regist_topictoolong'));
         }
         if (strlen($resto) > 10) {
             error(_T('regist_longthreadnum'));
         }
         $email = CleanStr($email);
         $email = str_replace("\r\n", '', $email);
         $sub = CleanStr($sub);
         $sub = str_replace("\r\n", '', $sub);
         $resto = CleanStr($resto);
         $resto = str_replace("\r\n", '', $resto);
         // 名稱修整
         $name = CleanStr($name);
         $name = str_replace(_T('trip_pre'), _T('trip_pre_fake'), $name);
         // 防止トリップ偽造
         $name = str_replace(CAP_SUFFIX, _T('cap_char_fake'), $name);
         // 防止管理員キャップ偽造
         $name = str_replace("\r\n", '', $name);
         $nameOri = $name;
         // 名稱
         if (preg_match('/(.*?)[##](.*)/u', $name, $regs)) {
             // トリップ(Trip)機能
             $name = $nameOri = $regs[1];
             $cap = strtr($regs[2], array('&amp;' => '&'));
             $salt = preg_replace('/[^\\.-z]/', '.', substr($cap . 'H.', 1, 2));
             $salt = strtr($salt, ':;<=>?@[\\]^_`', 'ABCDEFGabcdef');
             $name = $name . _T('trip_pre') . substr(crypt($cap, $salt), -10);
         }
         if (CAP_ENABLE && preg_match('/(.*?)[##](.*)/', $email, $aregs)) {
             // 管理員キャップ(Cap)機能
             $acap_name = $nameOri;
             $acap_pwd = strtr($aregs[2], array('&amp;' => '&'));
             if ($acap_name == CAP_NAME && $acap_pwd == CAP_PASS) {
                 $name = '<span class="admin_cap">' . $name . CAP_SUFFIX . '</span>';
                 $is_admin = true;
                 $email = $aregs[1];
                 // 去除 #xx 密碼
             }
         }
         if (!$is_admin) {
             // 非管理員
             $name = str_replace(_T('admin'), '"' . _T('admin') . '"', $name);
             $name = str_replace(_T('deletor'), '"' . _T('deletor') . '"', $name);
         }
         $name = str_replace('&◆', '&amp;◆', $name);
         // 避免 &#xxxx; 後面被視為 Trip 留下 & 造成解析錯誤
         // 內文修整
         if (strlen($com) > COMM_MAX && !$is_admin) {
             error(_T('regist_commenttoolong'));
         }
         $com = CleanStr($com, $is_admin);
         // 引入$is_admin參數是因為當管理員キャップ啟動時,允許管理員依config設定是否使用HTML
         $com = str_replace("\r\n", "\n", $com);
         $com = str_replace("\r", "\n", $com);
         $com = ereg_replace("\n(( | )*\n){3,}", "\n", $com);
         if (!BR_CHECK || substr_count($com, "\n") < BR_CHECK) {
             $com = nl2br($com);
         }
         // 換行字元用<br />代替
         $com = str_replace("\n", '', $com);
         // 若還有\n換行字元則取消換行
         if ($category && USE_CATEGORY) {
             // 修整標籤樣式
             $category = explode(',', $category);
             // 把標籤拆成陣列
             $category = '&#44;' . implode('&#44;', array_map('trim', $category)) . '&#44;';
             // 去空白再合併為單一字串 (左右含,便可以直接以,XX,形式搜尋)
         } else {
             $category = '';
         }
         $age = false;
         $dest = '';
         $W = $post[0]['tw'];
         $H = $post[0]['th'];
         $imgW = $post[0]['imgw'];
         $imgH = $post[0]['imgh'];
         $status = $post[0]['status'];
         $PMS->useModuleMethods('RegistBeforeCommit', array(&$name, &$email, &$sub, &$com, &$category, &$age, $dest, $resto, array($W, $H, $imgW, $imgH), &$status));
         // "RegistBeforeCommit" Hook Point
         if ($name != $post[0]['name'] && $_POST[FT_NAME]) {
             $newValues['name'] = $name;
         }
         if ($email != $post[0]['email'] && $_POST[FT_EMAIL]) {
             $newValues['email'] = $email;
         }
         if ($sub != $post[0]['sub'] && $_POST[FT_SUBJECT]) {
             $newValues['sub'] = $sub;
         }
         if ($com != $post[0]['com'] && $_POST[FT_COMMENT]) {
             $newValues['com'] = $com;
         }
         if ($category != $post[0]['category'] && $_POST['category']) {
             $newValues['category'] = $category;
         }
         $PIO->updatePost($_GET['no'], $newValues);
         $PIO->dbCommit();
         $parentNo = $post[0]['resto'] ? $post[0]['resto'] : $post[0]['no'];
         $threads = array_flip($PIO->fetchThreadList());
         $threadPage = floor($threads[$parentNo] / PAGE_DEF);
         if (STATIC_HTML_UNTIL == -1 || $threadPage <= STATIC_HTML_UNTIL) {
             updatelog(0, $threadPage, true);
         }
         // 僅更新討論串出現那頁
         deleteCache(array($parentNo));
         // 刪除討論串舊快取
         header('HTTP/1.1 302 Moved Temporarily');
         header('Location: ' . fullURL() . PHP_SELF2 . '?' . time());
     }
 }
    function ModulePage()
    {
        global $PIO;
        if (!adminAuthenticate('check')) {
            die('403 Access denied');
        }
        $act = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            if ($act == 'reorder') {
                // 排序
                $newTop = explode('|', $_POST['newTopmost']);
                $newTop = array_reverse($newTop);
                $newTop = trim(implode("\n", $newTop));
                $this->_write($this->TOPMOST_LOG, $newTop);
                $newBottom = trim(implode("\n", explode('|', $_POST['newBottommost'])));
                $this->_write($this->BOTTOMMOST_LOG, $newBottom);
                die('Done. Please go back.');
            }
        }
        switch ($act) {
            case 'top':
                // 置頂
                if ($PIO->isThread($_GET['no'])) {
                    $post = $PIO->fetchPosts($_GET['no']);
                    if (!count($post)) {
                        die('[Error] Post does not exist.');
                    }
                    $this->_write($this->TOPMOST_LOG, $_GET['no'] . "\n" . @file_get_contents($this->TOPMOST_LOG));
                    die('Done. Please go back.');
                } else {
                    die('[Error] Thread does not exist.');
                }
                break;
            case 'bottom':
                // 置底
                if ($PIO->isThread($_GET['no'])) {
                    $post = $PIO->fetchPosts($_GET['no']);
                    if (!count($post)) {
                        die('[Error] Post does not exist.');
                    }
                    $this->_write($this->BOTTOMMOST_LOG, @file_get_contents($this->BOTTOMMOST_LOG) . $_GET['no'] . "\n");
                    die('Done. Please go back.');
                } else {
                    die('[Error] Thread does not exist.');
                }
                break;
            default:
                $dat = '';
                head($dat);
                echo $dat;
                $dat = '';
                echo '<script type="text/javascript">
function move(target,index,to) {
	var list = document.getElementById(target);
	var total = list.options.length-1;
	if (index == -1) return false;
	if (to == +1 && index == total) return false;
	if (to == -1 && index == 0) return false;
	var items = new Array;
	var values = new Array;
	for (i = total; i >= 0; i--) {
		items[i] = list.options[i].text;
		values[i] = list.options[i].value;
	}
	for (i = total; i >= 0; i--) {
		if (index == i) {
			list.options[i + to] = new Option(items[i],values[i], 0, 1);
			list.options[i] = new Option(items[i + to], values[i +to]);
			i--;
		} else {
			list.options[i] = new Option(items[i], values[i]);
	   }
	}
	list.focus();
	return true;
}
function add(target,name,value){
target.options[target.length] = new Option(name, value);
}
function remove(target){
	var list = document.getElementById(target);
  var selIndex = list.selectedIndex;
  if (selIndex != -1) {
    for(i=list.length-1; i>=0; i--)
    {
      if(list.options[i].selected)
      {
        list.options[i] = null;
      }
    }
    if (list.length > 0) {
      list.selectedIndex = selIndex == 0 ? 0 : selIndex - 1;
    }
  }
}
function place(){
  placeInHidden("|", "topmost", "ntop");
  placeInHidden("|", "buttommost", "nbottom");

}
function placeInHidden(delim, selStr, hidStr){
  var selObj = document.getElementById(selStr);
  var hideObj = document.getElementById(hidStr);
  hideObj.value = "";
  for (i = 0; i <= selObj.options.length-1; i++) { 
	hideObj.value += selObj.options[i].value + delim;
  }

}
</script>
<form action=' . $this->mypage . ' method="post" onsubmit="place()">
<input type="hidden" name="action" value="reorder" />
<table>
<tr>
<td>置頂:</td><td></td><td>置底:</td><td></td>
</tr>
<tr>
<td align="middle">';
                echo '  <select id="topmost" size="30">';
                $logs = @file($this->TOPMOST_LOG);
                // order asc
                $logs = array_reverse($logs);
                foreach ($logs as $tm) {
                    echo '    <option value="' . $tm . '" >' . $tm . '</option>';
                }
                echo '  </select>
</td>
<td>
<input type="button" value="↑" 
onClick="move(\'topmost\',document.getElementById(\'topmost\').selectedIndex,-1)"><br/><br/>
<input type="button" value="↓"
onClick="move(\'topmost\',document.getElementById(\'topmost\').selectedIndex,+1)"><br/><br/>
<input type="button" value="解"
onClick="remove(\'topmost\')">
</td>
<td align="middle">';
                echo '  <select id="buttommost" size="30">';
                $logs = @file($this->BOTTOMMOST_LOG);
                // order asc
                foreach ($logs as $bm) {
                    echo '    <option value="' . $bm . '" >' . $bm . '</option>';
                }
                echo '  </select>
</td>
<td>
<input type="button" value="↑" 
onClick="move(\'buttommost\',document.getElementById(\'buttommost\').selectedIndex,-1)"><br/><br/>
<input type="button" value="↓"
onClick="move(\'buttommost\',document.getElementById(\'buttommost\').selectedIndex,+1)"><br/><br/>
<input type="button" value="解"
onClick="remove(\'buttommost\')">
</td>
</tr>
<tr><td colspan="4"><input type="hidden" name="newTopmost" id="ntop" value="" /><input type="hidden" name="newBottommost" id="nbottom" value="" />
  <input type="hidden" name="action" value="reorder">
  <input type="submit">
</td>
</tr>
</table></form>';
                $dat = '';
                foot($dat);
                echo $dat;
        }
    }
    function ModulePage()
    {
        global $PMS, $PIO, $FileIO;
        if (!adminAuthenticate('check')) {
            die('[Error] Access Denied.');
        }
        $content = '';
        // POST
        if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
            // 刪除
            $del = isset($_POST['del']) ? $_POST['del'] : null;
            if ($del != null) {
                $files = $PIO->removePosts($del);
                $delta_totalsize = 0;
                if (count($files)) {
                    $delta_totalsize -= $FileIO->deleteImage($files);
                }
                if ($delta_totalsize != 0) {
                    total_size($delta_totalsize);
                }
                foreach ($del as $n) {
                    if ($oldCaches = glob('./cache/' . $n . '-*')) {
                        foreach ($oldCaches as $o) {
                            @unlink($o);
                        }
                    }
                }
            }
            // 對 host 作 search
            $filter = isset($_POST['filter']) ? CleanStr($_POST['filter']) : '';
            if ($filter != '') {
                $res = $PIO->searchPost($filter, '`host`', 'AND');
                foreach ($res as $p) {
                    $no = $p['no'];
                    $now = $p['now'];
                    $host = $p['host'];
                    $com = htmlspecialchars(str_cut(str_replace('<br />', ' ', $p['com']), 50));
                    $content .= <<<HERE
<tr>
\t<td><input type="checkbox" name="del[]" value="{$no}" /></td>
\t<td>{$no}</td>
\t<td>{$now}</td>
\t<td>{$com}</td>
\t<td>{$host}</td>
</tr>
HERE;
                }
                // 沒結果
                if (count($res) == 0) {
                    $content = '<tr><td rows="5">Not Found</td></tr>';
                }
            }
            // AJAX 要求在此即停止,一般要求則繼續印出頁面
            if (isset($_POST['ajax'])) {
                echo $content;
                return;
            }
        }
        // 顯示表單
        $dat = '';
        head($dat);
        $dat .= '<div class="bar_admin">搜尋 IP</div>
<div id="content">
<form action="' . $this->SELF . '" method="post">
<div id="ipconfig">
Filter: <input type="text" name="filter" size="30" />
<input type="submit" value="搜尋" onclick="return search(this.form);" /><br />
<table border="0" width="100%">
<tr><th>Delete</th><th>No.</th><th>Date</th><th>Comment</th><th>Host</th></tr>
' . $content . '
</table>
<input type="submit" value="刪除" />
</div>
</form>
<hr />
</div>
<script type="text/javascript">
// <![CDATA[
function search(form){
	var f = form.filter.value;
	$.post("' . str_replace('&amp;', '&', $this->SELF) . '", {filter: f, ajax: true}, function(d){
		$("table", form)
			// Remove all items except header
			.find("tr:gt(0)").remove()
			// Fill the results
			.end().append(d);
	});
	return false;
}
// ]]>
</script>
';
        foot($dat);
        echo $dat;
    }
Exemple #7
0
        $_SESSION['no_ssl'] = true;
        if (defined('DEBUG_MODE') && DEBUG_MODE === true) {
            popup_info('Succefully connected the Session Manager using HTTP method, will alwais use HTTP for this session');
        }
    }
    $_SESSION['admin_login'] = $login_;
    $_SESSION['admin_password'] = $password_;
    $_SESSION['service'] = $service;
    return true;
}
if (isset($_POST['admin_login']) && $_POST['admin_login'] != '' && isset($_POST['admin_password']) && $_POST['admin_password'] != '') {
    unset($_SESSION['admin_login']);
    if (isset($_SESSION['admin_ovd_user'])) {
        unset($_SESSION['admin_ovd_user']);
    }
    adminAuthenticate($_POST['admin_login'], $_POST['admin_password']);
}
if (array_key_exists('service', $_SESSION) and array_key_exists('admin_login', $_SESSION) and array_key_exists('admin_password', $_SESSION)) {
    if (isset($_SESSION['redirect'])) {
        $buf = base64_decode($_SESSION['redirect']);
        unset($_SESSION['redirect']);
        redirect($buf);
    } else {
        redirect('index.php');
    }
}
$main_title = DEFAULT_PAGE_TITLE;
header_static($main_title . ' - ' . _('Administration'));
?>
<script type="text/javascript">
Event.observe(window, 'load', function() {
 function ModulePage()
 {
     global $PIO, $FileIO;
     if (!adminAuthenticate('check')) {
         die('403 Access denied');
     }
     $act = isset($_GET['action']) ? $_GET['action'] : '';
     switch ($act) {
         case 'sage':
             // 強制sage
             if ($PIO->isThread($_GET['no'])) {
                 $post = $PIO->fetchPosts($_GET['no']);
                 if (!count($post)) {
                     die('[Error] Post does not exist.');
                 }
                 $flgh = $PIO->getPostStatus($post[0]['status']);
                 $flgh->toggle('asage');
                 $PIO->setPostStatus($post[0]['no'], $flgh->toString());
                 $PIO->dbCommit();
                 die('Done. Please go back.');
             } else {
                 die('[Error] Thread does not exist.');
             }
             break;
         case 'thumb':
             // 替換縮圖
             $post = $PIO->fetchPosts($_GET['no']);
             if (!count($post)) {
                 die('[Error] Post does not exist.');
             }
             if ($post[0]['ext']) {
                 if (!$FileIO->imageExists($post[0]['tim'] . $post[0]['ext'])) {
                     die('[Error] attachment does not exist.');
                 }
                 $flgh = $PIO->getPostStatus($post[0]['status']);
                 $flgh->toggle('htmb');
                 $PIO->setPostStatus($post[0]['no'], $flgh->toString());
                 $PIO->dbCommit();
                 die('Done. Please go back.');
             } else {
                 die('[Error] Post does not have attechment.');
             }
             break;
         case 'agif':
             // 動態GIF
             $post = $PIO->fetchPosts($_GET['no']);
             if (!count($post)) {
                 die('[Error] Post does not exist.');
             }
             if ($post[0]['ext'] && $post[0]['ext'] == '.gif') {
                 if (!$FileIO->imageExists($post[0]['tim'] . $post[0]['ext'])) {
                     die('[Error] attachment does not exist.');
                 }
                 $flgh = $PIO->getPostStatus($post[0]['status']);
                 $flgh->toggle('agif');
                 $PIO->setPostStatus($post[0]['no'], $flgh->toString());
                 $PIO->dbCommit();
                 die('Done. Please go back.');
             } else {
                 die('[Error] Post does not have attechment.');
             }
             break;
     }
 }
    public function ModulePage()
    {
        $PIO = PMCLibrary::getPIOInstance();
        $thisPage = $this->getModulePageURL();
        // 基底位置
        $dat = '';
        // HTML Buffer
        $listMax = $PIO->threadCount();
        // 討論串總筆數
        $pageMax = ceil($listMax / $this->THREADLIST_NUMBER) - 1;
        // 分頁最大編號
        $page = isset($_GET['page']) ? intval($_GET['page']) : 0;
        // 目前所在分頁頁數
        $sort = isset($_GET['sort']) ? $_GET['sort'] : 'no';
        if ($page < 0 || $page > $pageMax) {
            exit('Page out of range.');
        }
        // $page 超過範圍
        if (strpos($sort, 'post') !== false) {
            $plist = $PIO->fetchThreadList();
            $pc = $this->_getPostCounts($plist);
            $this->_kasort($pc, $sort == 'postdesc', true);
            // 切出需要的大小
            $plist = array_slice(array_keys($pc), $this->THREADLIST_NUMBER * $page, $this->THREADLIST_NUMBER);
        } else {
            $plist = $PIO->fetchThreadList($this->THREADLIST_NUMBER * $page, $this->THREADLIST_NUMBER, $sort == 'date' ? false : true);
            // 編號由大到小排序
            self::$PMS->useModuleMethods('ThreadOrder', array(0, $page, 0, &$plist));
            // "ThreadOrder" Hook Point
            $pc = $this->_getPostCounts($plist);
        }
        $post = $PIO->fetchPosts($plist);
        // 取出資料
        $post_count = count($post);
        if ($sort == 'date' || strpos($sort, 'post') !== false) {
            // 要重排次序
            $mypost = array();
            foreach ($plist as $p) {
                while (list($k, $v) = each($post)) {
                    if ($v['no'] == $p) {
                        $mypost[] = $v;
                        unset($post[$k]);
                        break;
                    }
                }
                reset($post);
            }
            $post = $mypost;
        }
        head($dat);
        $dat .= '<script>
var selectall = "";
function checkall(){
	selectall = selectall ? "" : "checked";
	var inputs = document.getElementsByTagName("input");
	for(x=0; x < inputs.length; x++){
		if(inputs[x].type == "checkbox" && parseInt(inputs[x].name)) {
			inputs[x].checked = selectall;
		}
	}
}
</script>';
        $dat .= '<div id="contents">
[<a href="' . PHP_SELF2 . '?' . time() . '">' . _T('return') . '</a>]
<div class="bar_reply">' . $this->_T('page_title') . '</div>' . ($this->SHOW_FORM ? '<form action="' . PHP_SELF . '" method="post">' : '') . '<table align="center" width="98%"><tr>
' . ($this->SHOW_FORM ? '<th><a href="javascript:checkall()">↓</a></th>' : '') . '
<th><a href="' . $thisPage . '&amp;sort=no">No.' . ($sort == 'no' ? ' ▼' : '') . '</a></th>
<th width="48%">' . _T('form_topic') . '</th>
<th>' . _T('form_name') . '</th>
<th><a href="' . $thisPage . '&amp;sort=' . ($sort == 'postdesc' ? 'postasc' : 'postdesc') . '">' . _T('reply_btn') . ($sort == 'postdesc' ? ' ▼' : ($sort == 'postasc' ? ' ▲' : '')) . '</a></th>
<th><a href="' . $thisPage . '&amp;sort=date">' . $this->_T('date') . ($sort == 'date' ? ' ▼' : '') . '</a></th></tr>
';
        for ($i = 0; $i < $post_count; $i++) {
            list($no, $sub, $name, $now) = array($post[$i]['no'], $post[$i]['sub'], $post[$i]['name'], $post[$i]['now']);
            $rescount = $pc[$no] - 1;
            if ($this->HIGHLIGHT_COUNT > 0 && $rescount > $this->HIGHLIGHT_COUNT) {
                $rescount = '<span style="color:red">' . $rescount . '</span>';
            }
            $dat .= '<tr class="ListRow' . ($i % 2 + 1) . '_bg">' . ($this->SHOW_FORM ? '<td><input type="checkbox" name="' . $no . '" value="delete" /></td>' : '') . '<td>' . $no . '</td><td><a href="' . PHP_SELF . '?res=' . $no . '">' . $sub . '</a></td><td>' . $name . '</td><td>' . $rescount . '</td><td>' . $now . '</td></tr>' . "\n";
        }
        $dat .= '</table>
<hr />

<div id="page_switch">
<table border="1" style="float: left;"><tr>
';
        if ($page) {
            $dat .= '<td><a href="' . $thisPage . '&amp;page=' . ($page - 1) . '&amp;sort=' . $sort . '">' . _T('prev_page') . '</a></td>';
        } else {
            $dat .= '<td style="white-space: nowrap;">' . _T('first_page') . '</td>';
        }
        $dat .= '<td>';
        for ($i = 0; $i <= $pageMax; $i++) {
            if ($i == $page) {
                $dat .= '[<b>' . $i . '</b>] ';
            } else {
                $dat .= '[<a href="' . $thisPage . '&amp;page=' . $i . '&amp;sort=' . $sort . '">' . $i . '</a>] ';
            }
        }
        $dat .= '</td>';
        if ($page < $pageMax) {
            $dat .= '<td><a href="' . $thisPage . '&amp;page=' . ($page + 1) . '&amp;sort=' . $sort . '">' . _T('next_page') . '</a></td>';
        } else {
            $dat .= '<td style="white-space: nowrap;">' . _T('last_page') . '</td>';
        }
        $dat .= '
</tr></table>
</div>';
        if ($this->SHOW_FORM) {
            $adminMode = adminAuthenticate('check');
            // 前端管理模式
            $adminFunc = '';
            // 前端管理選擇
            if ($adminMode) {
                $adminFunc = '<select name="func"><option value="delete">' . _T('admin_delete') . '</option>';
                $funclist = array();
                $dummy = '';
                self::$PMS->useModuleMethods('AdminFunction', array('add', &$funclist, null, &$dummy));
                // "AdminFunction" Hook Point
                foreach ($funclist as $f) {
                    $adminFunc .= '<option value="' . $f[0] . '">' . $f[1] . '</option>' . "\n";
                }
                $adminFunc .= '</select>';
            }
            $pte_vals = array('{$DEL_HEAD_TEXT}' => '<input type="hidden" name="mode" value="usrdel" />' . _T('del_head'), '{$DEL_IMG_ONLY_FIELD}' => '<input type="checkbox" name="onlyimgdel" id="onlyimgdel" value="on" />', '{$DEL_IMG_ONLY_TEXT}' => _T('del_img_only'), '{$DEL_PASS_TEXT}' => ($adminMode ? $adminFunc : '') . _T('del_pass'), '{$DEL_PASS_FIELD}' => '<input type="password" name="pwd" size="8" value="" />', '{$DEL_SUBMIT_BTN}' => '<input type="submit" value="' . _T('del_btn') . '" />');
            $dat .= PMCLibrary::getPTEInstance()->ParseBlock('DELFORM', $pte_vals) . '</form>';
        }
        $dat .= '</div>';
        foot($dat);
        echo $dat;
    }
Exemple #10
0
    $policy = $user->getPolicy();
    if (isset($policy['canUseAdminPanel']) && $policy['canUseAdminPanel'] == true) {
        return $user;
    }
    Logger::info('main', 'login.php failed to log in ' . $login_ . ' : access denied to admin panel');
    $_SESSION['admin_error'] = _('Unauthorized access');
    return false;
}
if (isset($_POST['admin_login']) && $_POST['admin_login'] != '' && isset($_POST['admin_password']) && $_POST['admin_password'] != '') {
    unset($_SESSION['admin_login']);
    if (isset($_SESSION['admin_ovd_user'])) {
        unset($_SESSION['admin_ovd_user']);
    }
    $login = $_POST['admin_login'];
    $password = $_POST['admin_password'];
    if (adminAuthenticate($login, $password)) {
        $_SESSION['admin_login'] = $login;
    } else {
        $user = authenticate_ovd_user($login, $password);
        if ($user !== false) {
            $_SESSION['admin_login'] = $login;
            $_SESSION['admin_ovd_user'] = $user;
        }
    }
}
if (isset($_SESSION['admin_login'])) {
    if (isset($_SESSION['redirect'])) {
        $buf = base64_decode($_SESSION['redirect']);
        unset($_SESSION['redirect']);
        redirect($buf);
    } else {
 public function ModulePage()
 {
     $PIO = PMCLibrary::getPIOInstance();
     if (!isset($_GET['no'])) {
         die('[Error] not enough parameter.');
     }
     if (isset($_GET['action'])) {
         if (adminAuthenticate('check')) {
             $pushcount = '';
             $puststart = 0;
             $post = $PIO->fetchPosts($_GET['no']);
             if (!count($post)) {
                 die('[Error] Post does not exist.');
             }
             // 被推之文章不存在
             extract($post[0]);
             if ($status != '') {
                 $f = $PIO->getPostStatus($status);
                 $pushcount = $f->value('mppCnt');
                 // 被推次數
             }
             if (($puststart = strpos($com, $this->PUSHPOST_SEPARATOR . '<br />')) === false) {
                 die('[Error] No pushpost.');
             }
             $ocom = substr($com, 0, $puststart);
             $pushpost = explode('<br />', substr($com, $puststart + strlen($this->PUSHPOST_SEPARATOR . '<br />')));
             $com = $ocom;
             if ($_GET['action'] == 'del') {
                 // list
                 $p_count = 1;
                 $com .= '<div class="pushpost">';
                 foreach ($pushpost as $p) {
                     $com .= '<input type="checkbox" name="' . $p_count++ . '" value="delete" />' . $p . '<br />';
                 }
                 $com .= '</div>';
                 $dat = '';
                 head($dat);
                 $dat .= '<div class="bar_reply">' . $this->_T('deletepush') . '</div>';
                 $dat .= '<form action="' . $this->getModulePageURL(array('action' => 'delpush', 'no' => $_GET['no'])) . '" method="post">';
                 $dat .= PMCLibrary::getPTEInstance()->ParseBlock('SEARCHRESULT', array('{$NO}' => $no, '{$SUB}' => $sub, '{$NAME}' => $name, '{$NOW}' => $now, '{$COM}' => $com, '{$CATEGORY}' => $category, '{$NAME_TEXT}' => _T('post_name'), '{$CATEGORY_TEXT}' => _T('post_category')));
                 echo $dat, '<input type="submit" value="' . _T('del_btn') . '" /></form></body></html>';
                 return;
             } else {
                 if ($_GET['action'] == 'delpush') {
                     // delete
                     $delno = array();
                     reset($_POST);
                     while ($item = each($_POST)) {
                         if ($item[1] == 'delete' && $item[0] != 'func') {
                             array_push($delno, $item[0]);
                         }
                     }
                     if (count($delno)) {
                         foreach ($delno as $d) {
                             if (isset($pushpost[$d - 1])) {
                                 unset($pushpost[$d - 1]);
                             }
                         }
                     }
                     $pushcount = count($pushpost);
                     if ($pushcount) {
                         $f->update('mppCnt', $pushcount);
                         // 更新推文次數
                         $com = $ocom . $this->PUSHPOST_SEPARATOR . '<br />' . implode('<br />', $pushpost);
                     } else {
                         $f->remove('mppCnt');
                         // 刪除推文次數
                         $com = $ocom;
                     }
                     $PIO->updatePost($_GET['no'], array('com' => $com, 'status' => $f->toString()));
                     // 更新推文
                     $PIO->dbCommit();
                     header('HTTP/1.1 302 Moved Temporarily');
                     header('Location: ' . fullURL() . PHP_SELF . '?page_num=0');
                     return;
                 } else {
                     die('[Error] unknown action.');
                 }
             }
         } else {
             die('[Error] unauthenticated action.');
         }
     }
     // 非 AJAX 推文,產出表單供填寫
     if (!isset($_POST['comm'])) {
         echo $this->printStaticForm(intval($_GET['no']));
     } else {
         // 處理推文
         // 傳送方法不正確
         if ($_SERVER['REQUEST_METHOD'] != 'POST') {
             die(_T('regist_notpost'));
         }
         // 查IP
         $baninfo = '';
         $ip = getREMOTE_ADDR();
         $host = gethostbyaddr($ip);
         if (BanIPHostDNSBLCheck($ip, $host, $baninfo)) {
             die(_T('regist_ipfiltered', $baninfo));
         }
         $name = CleanStr($_POST['name']);
         $comm = CleanStr($_POST['comm']);
         if (strlen($name) > 30) {
             die($this->_T('maxlength'));
         }
         // 名稱太長
         if (strlen($comm) > 160) {
             die($this->_T('maxlength'));
         }
         // 太多字
         if (strlen($comm) == 0) {
             die($this->_T('nocomment'));
         }
         // 沒打字
         $name = str_replace(array(_T('trip_pre'), _T('admin'), _T('deletor')), array(_T('trip_pre_fake'), '"' . _T('admin') . '"', '"' . _T('deletor') . '"'), $name);
         // 生成ID, Trip 等識別資訊
         $pushID = $this->getID();
         $pushtime = gmdate('y/m/d H:i', time() + intval(TIME_ZONE) * 3600);
         if (preg_match('/(.*?)[##](.*)/u', $name, $regs)) {
             $cap = strtr($regs[2], array('&amp;' => '&'));
             $salt = strtr(preg_replace('/[^\\.-z]/', '.', substr($cap . 'H.', 1, 2)), ':;<=>?@[\\]^_`', 'ABCDEFGabcdef');
             $name = $regs[1] . _T('trip_pre') . substr(crypt($cap, $salt), -10);
         }
         if (!$name || preg_match("/^[ | |]*\$/", $name)) {
             if (ALLOW_NONAME) {
                 $name = DEFAULT_NONAME;
             } else {
                 die(_T('regist_withoutname'));
             }
             // 不接受匿名
         }
         if (ALLOW_NONAME == 2) {
             // 強制砍名
             $name = preg_match('/(\\' . _T('trip_pre') . '.{10})/', $name, $matches) ? $matches[1] . ':' : DEFAULT_NONAME . ':';
         } else {
             $name .= ':';
         }
         $pushpost = "{$name} {$comm} ({$pushID} {$pushtime})";
         // 推文主體
         $post = $PIO->fetchPosts($_GET['no']);
         if (!count($post)) {
             die('[Error] Post does not exist.');
         }
         // 被推之文章不存在
         $parentNo = $post[0]['resto'] ? $post[0]['resto'] : $post[0]['no'];
         $threads = array_flip($PIO->fetchThreadList());
         $threadPage = floor($threads[$parentNo] / PAGE_DEF);
         $p = $parentNo == $post[0]['no'] ? $post : $PIO->fetchPosts($parentNo);
         // 取出首篇
         $flgh = $PIO->getPostStatus($p[0]['status']);
         if ($flgh->exists('TS')) {
             die('[Error] ' . _T('regist_threadlocked'));
         }
         // 首篇禁止回應/同時表示禁止推文
         $post[0]['com'] .= (strpos($post[0]['com'], $this->PUSHPOST_SEPARATOR . '<br />') === false ? '<br />' . $this->PUSHPOST_SEPARATOR : '') . '<br /> ' . $pushpost;
         $flgh2 = $PIO->getPostStatus($post[0]['status']);
         $flgh2->plus('mppCnt');
         // 推文次數+1
         $PIO->updatePost($_GET['no'], array('com' => $post[0]['com'], 'status' => $flgh2->toString()));
         // 更新推文
         $PIO->dbCommit();
         // mod_audit logcat
         $this->callCHP('mod_audit_logcat', array(sprintf('[%s] No.%d %s (%s)', __CLASS__, $_GET['no'], $comm, $pushID)));
         if (STATIC_HTML_UNTIL == -1 || $threadPage <= STATIC_HTML_UNTIL) {
             // 僅更新討論串出現那頁
             updatelog(0, $threadPage, true);
         }
         deleteCache(array($parentNo));
         // 刪除討論串舊快取
         if (isset($_POST['ajaxmode'])) {
             echo '+OK ', $pushpost;
         } else {
             header('HTTP/1.1 302 Moved Temporarily');
             header('Location: ' . fullURL() . PHP_SELF2 . '?' . time());
         }
     }
 }
    function ModulePage()
    {
        global $PTE, $PMS, $PIO, $FileIO;
        $thisPage = $PMS->getModulePageURL('mod_catalog');
        // 基底位置
        $dat = '';
        // HTML Buffer
        $listMax = $PIO->postCount();
        // 文章總筆數
        $pageMax = ceil($listMax / $this->CATALOG_NUMBER) - 1;
        // 分頁最大編號
        $page = isset($_GET['page']) ? intval($_GET['page']) : 0;
        // 目前所在分頁頁數
        if ($page < 0 || $page > $pageMax) {
            exit('Page out of range.');
        }
        // $page 超過範圍
        if (!$this->USE_SEARCH_CODE && !isset($_GET['search'])) {
            $plist = $PIO->fetchPostList(0, $this->CATALOG_NUMBER * $page, $this->CATALOG_NUMBER);
            // 取得定位正確的 N 筆資料號碼
            $post = $PIO->fetchPosts($plist);
            // 取出資料
        } else {
            $post = $PIO->searchPost(array('.'), 'ext', 'AND');
            $pageMax = ceil(count($post) / $this->CATALOG_NUMBER) - 1;
            $post = array_slice($post, $this->CATALOG_NUMBER * $page, $this->CATALOG_NUMBER);
        }
        $post_count = count($post);
        $PMS->hookModuleMethod('Head', array(&$this, 'hookHeadCSS'));
        head($dat);
        $dat .= '<div id="contents">
[<a href="' . PHP_SELF2 . '?' . time() . '">回到版面</a>]
<div class="bar_reply">相簿模式' . (@$_GET['style'] == 'detail' ? ' <a href="' . $thisPage . ($page ? '&amp;page=' . $page : '') . (isset($_GET['search']) ? '&amp;search' : '') . '&amp;style=simple">■</a>' : ' <a href="' . $thisPage . ($page ? '&amp;page=' . $page : '') . (isset($_GET['search']) ? '&amp;search' : '') . '&amp;style=detail">≡</a>') . '</div>
';
        if ($_GET['style'] == 'detail') {
            $dat .= '<script>
function hover(obj,ishover){
if(ishover) obj.className="tools-expend";
else obj.className="tools";
}
</script>
<form action="' . PHP_SELF . '" method="post">';
        }
        // 逐步取資料
        for ($i = 0; $i < $post_count; $i++) {
            list($no, $resto, $imgw, $imgh, $tw, $th, $tim, $ext, $now) = array($post[$i]['no'], $post[$i]['resto'], $post[$i]['imgw'], $post[$i]['imgh'], $post[$i]['tw'], $post[$i]['th'], $post[$i]['tim'], $post[$i]['ext'], $post[$i]['now']);
            if ($FileIO->imageExists($tim . $ext)) {
                $dat .= '<div class="list">' . (@$_GET['style'] == 'detail' ? '<div class="tools" onmouseover="hover(this,true)" onmouseout="hover(this,false)"><input type="checkbox" name="' . $no . '" value="delete" /><a href="' . PHP_SELF . '?res=' . ($resto ? $resto : $no) . '#r' . $no . '">†</a></div>' : '') . '<a href="' . $FileIO->getImageURL($tim . $ext) . '" rel="_blank"><img src="' . $FileIO->getImageURL($tim . 's.jpg') . '" style="' . $this->OptimizeImageWH($tw, $th) . '" title="' . (@$_GET['style'] == 'detail' ? 'No.' . $no . ($resto ? '(' . $resto . ')' : '') . ' ' . $now . ' ' : '') . $imgw . 'x' . $imgh . '" alt="' . $tim . $ext . '" /></a></div>' . "\n";
            }
        }
        $dat .= '</div><hr />';
        if (@$_GET['style'] == 'detail') {
            $adminMode = adminAuthenticate('check');
            // 前端管理模式
            $adminFunc = '';
            // 前端管理選擇
            if ($adminMode) {
                $adminFunc = '<select name="func"><option value="delete">' . _T('admin_delete') . '</option>';
                $funclist = array();
                $dummy = '';
                $PMS->useModuleMethods('AdminFunction', array('add', &$funclist, null, &$dummy));
                // "AdminFunction" Hook Point
                foreach ($funclist as $f) {
                    $adminFunc .= '<option value="' . $f[0] . '">' . $f[1] . '</option>' . "\n";
                }
                $adminFunc .= '</select>';
            }
            $pte_vals = array('{$DEL_HEAD_TEXT}' => '<input type="hidden" name="mode" value="usrdel" />' . _T('del_head'), '{$DEL_IMG_ONLY_FIELD}' => '<input type="checkbox" name="onlyimgdel" id="onlyimgdel" value="on" />', '{$DEL_IMG_ONLY_TEXT}' => _T('del_img_only'), '{$DEL_PASS_TEXT}' => ($adminMode ? $adminFunc : '') . _T('del_pass'), '{$DEL_PASS_FIELD}' => '<input type="password" name="pwd" size="8" value="" />', '{$DEL_SUBMIT_BTN}' => '<input type="submit" value="' . _T('del_btn') . '" />');
            $dat .= $PTE->ParseBlock('DELFORM', $pte_vals) . '</form>';
        }
        $dat .= '

<div id="page_switch">
<table border="1" style="float: left;"><tr>
';
        if ($page) {
            $dat .= '<td><a href="' . $thisPage . '&amp;page=' . ($page - 1) . (@$_GET['style'] == 'detail' ? '&amp;style=detail' : '') . (isset($_GET['search']) ? '&amp;search' : '') . '">上一頁</a></td>';
        } else {
            $dat .= '<td style="white-space: nowrap;">第一頁</td>';
        }
        $dat .= '<td>';
        for ($i = 0; $i <= $pageMax; $i++) {
            if ($i == $page) {
                $dat .= '[<b>' . $i . '</b>] ';
            } else {
                $dat .= '[<a href="' . $thisPage . '&amp;page=' . $i . (@$_GET['style'] == 'detail' ? '&amp;style=detail' : '') . (isset($_GET['search']) ? '&amp;search' : '') . '">' . $i . '</a>] ';
            }
        }
        $dat .= '</td>';
        if ($page < $pageMax) {
            $dat .= '<td><a href="' . $thisPage . '&amp;page=' . ($page + 1) . (@$_GET['style'] == 'detail' ? '&amp;style=detail' : '') . (isset($_GET['search']) ? '&amp;search' : '') . '">下一頁</a></td>';
        } else {
            $dat .= '<td style="white-space: nowrap;">最後一頁</td>';
        }
        $dat .= '
</tr></table>
</div>

';
        foot($dat);
        echo $dat;
    }