public function testGetPIOInstance() { $PIO1 = PMCLibrary::getPIOInstance(); $this->assertNotNull($PIO1); $PIO2 = PMCLibrary::getPIOInstance(); $this->assertSame($PIO1, $PIO2); }
/** * 程式首次執行之初始化 * @return boolean 是否無錯誤完成 */ function init() { $PIO = PMCLibrary::getPIOInstance(); $FileIO = PMCLibrary::getFileIOInstance(); if (file_exists(PHP_SELF2)) { return true; } if (!is_writable(STORAGE_PATH)) { error(_T('init_permerror')); return false; } createDirectories(); $PIO->dbInit(); $FileIO->init(); return true; }
public static function listee($type, $limit) { $PIO = PMCLibrary::getPIOInstance(); // 討論串編號陣列 (由舊到新) $ThreadNo = $PIO->fetchThreadList(0, 0, true); sort($ThreadNo); $NowTime = time(); $i = 0; foreach ($ThreadNo as $t) { $post = $PIO->fetchPosts($t); if ($NowTime - substr($post[0]['tim'], 0, 10) < 86400 * $limit * ($type == 'predict' ? 0.95 : 1)) { break; } // 時間不符合 $i++; } if (count($ThreadNo) === $i) { $i--; } // 保留最新的一篇避免全部刪除 return array_slice($ThreadNo, 0, $i); }
function showstatus() { global $LIMIT_SENSOR, $THUMB_SETTING; $PIO = PMCLibrary::getPIOInstance(); $FileIO = PMCLibrary::getFileIOInstance(); $PTE = PMCLibrary::getPTEInstance(); $PMS = PMCLibrary::getPMSInstance(); $countline = $PIO->postCount(); // 計算投稿文字記錄檔目前資料筆數 $counttree = $PIO->threadCount(); // 計算樹狀結構記錄檔目前資料筆數 $tmp_total_size = $FileIO->getCurrentStorageSize(); // 附加圖檔使用量總大小 $tmp_ts_ratio = STORAGE_MAX > 0 ? $tmp_total_size / STORAGE_MAX : 0; // 附加圖檔使用量 // 決定「附加圖檔使用量」提示文字顏色 if ($tmp_ts_ratio < 0.3) { $clrflag_sl = '235CFF'; } elseif ($tmp_ts_ratio < 0.5) { $clrflag_sl = '0CCE0C'; } elseif ($tmp_ts_ratio < 0.7) { $clrflag_sl = 'F28612'; } elseif ($tmp_ts_ratio < 0.9) { $clrflag_sl = 'F200D3'; } else { $clrflag_sl = 'F2004A'; } // 生成預覽圖物件資訊及功能是否正常 $func_thumbWork = '<span style="color: red;">' . _T('info_nonfunctional') . '</span>'; $func_thumbInfo = '(No thumbnail)'; if (USE_THUMB !== 0) { $thumbType = USE_THUMB; if (USE_THUMB == 1) { $thumbType = 'gd'; } require ROOTPATH . 'lib/thumb/thumb.' . $thumbType . '.php'; $thObj = new ThumbWrapper(); if ($thObj->isWorking()) { $func_thumbWork = '<span style="color: blue;">' . _T('info_functional') . '</span>'; } $func_thumbInfo = $thObj->getClass(); unset($thObj); } // PIOSensor if (count($LIMIT_SENSOR)) { $piosensorInfo = nl2br(PIOSensor::info($LIMIT_SENSOR)); } $dat = ''; head($dat); $links = '[<a href="' . PHP_SELF2 . '?' . time() . '">' . _T('return') . '</a>] [<a href="' . PHP_SELF . '?mode=moduleloaded">' . _T('module_info_top') . '</a>]'; $PMS->useModuleMethods('LinksAboveBar', array(&$links, 'status')); $dat .= '<div id="banner">' . $links . '<div class="bar_admin">' . _T('info_top') . '</div> </div> '; $dat .= ' <div id="status-table" style="text-align: center;"> <style type="text/css" scoped="scoped"> .admTable {border-collapse:collapse; border-spacing: 1; margin: 0px auto; text-align: left;} .admTable TD {border:2px solid gray } </style> <table class="admTable"> <thead> <tr><td style="text-align:center" colspan="4">' . _T('info_basic') . '</td></tr> </thead> <tbody> <tr><td style="width: 240px;">' . _T('info_basic_ver') . '</td><td colspan="3"> ' . PIXMICAT_VER . ' </td></tr> <tr><td>' . _T('info_basic_pio') . '</td><td colspan="3"> ' . PIXMICAT_BACKEND . ' : ' . $PIO->pioVersion() . '</td></tr> <tr><td>' . _T('info_basic_threadsperpage') . '</td><td colspan="3"> ' . PAGE_DEF . ' ' . _T('info_basic_threads') . '</td></tr> <tr><td>' . _T('info_basic_postsperpage') . '</td><td colspan="3"> ' . RE_DEF . ' ' . _T('info_basic_posts') . '</td></tr> <tr><td>' . _T('info_basic_postsinthread') . '</td><td colspan="3"> ' . RE_PAGE_DEF . ' ' . _T('info_basic_posts') . ' ' . _T('info_basic_posts_showall') . '</td></tr> <tr><td>' . _T('info_basic_bumpposts') . '</td><td colspan="3"> ' . MAX_RES . ' ' . _T('info_basic_posts') . ' ' . _T('info_basic_0disable') . '</td></tr> <tr><td>' . _T('info_basic_bumphours') . '</td><td colspan="3"> ' . MAX_AGE_TIME . ' ' . _T('info_basic_hours') . ' ' . _T('info_basic_0disable') . '</td></tr> <tr><td>' . _T('info_basic_urllinking') . '</td><td colspan="3"> ' . AUTO_LINK . ' ' . _T('info_0no1yes') . '</td></tr> <tr><td>' . _T('info_basic_com_limit') . '</td><td colspan="3"> ' . COMM_MAX . _T('info_basic_com_after') . '</td></tr> <tr><td>' . _T('info_basic_anonpost') . '</td><td colspan="3"> ' . ALLOW_NONAME . ' ' . _T('info_basic_anonpost_opt') . '</td></tr> <tr><td>' . _T('info_basic_del_incomplete') . '</td><td colspan="3"> ' . KILL_INCOMPLETE_UPLOAD . ' ' . _T('info_0no1yes') . '</td></tr> <tr><td>' . _T('info_basic_use_sample', $THUMB_SETTING['Quality']) . '</td><td colspan="3"> ' . USE_THUMB . ' ' . _T('info_0notuse1use') . '</td></tr> <tr><td>' . _T('info_basic_useblock') . '</td><td colspan="3"> ' . BAN_CHECK . ' ' . _T('info_0disable1enable') . '</td></tr> <tr><td>' . _T('info_basic_showid') . '</td><td colspan="3"> ' . DISP_ID . ' ' . _T('info_basic_showid_after') . '</td></tr> <tr><td>' . _T('info_basic_cr_limit') . '</td><td colspan="3"> ' . BR_CHECK . _T('info_basic_cr_after') . '</td></tr> <tr><td>' . _T('info_basic_timezone') . '</td><td colspan="3"> GMT ' . TIME_ZONE . '</td></tr> <tr><td>' . _T('info_basic_theme') . '</td><td colspan="3"> ' . $PTE->BlockValue('THEMENAME') . ' ' . $PTE->BlockValue('THEMEVER') . '<br/>by ' . $PTE->BlockValue('THEMEAUTHOR') . '</td></tr> <tr><td style="text-align:center" colspan="4">' . _T('info_dsusage_top') . '</td></tr> <tr style="text-align:center"><td>' . _T('info_basic_threadcount') . '</td><td colspan="' . (isset($piosensorInfo) ? '2' : '3') . '"> ' . $counttree . ' ' . _T('info_basic_threads') . '</td>' . (isset($piosensorInfo) ? '<td rowspan="2">' . $piosensorInfo . '</td>' : '') . '</tr> <tr style="text-align:center"><td>' . _T('info_dsusage_count') . '</td><td colspan="' . (isset($piosensorInfo) ? '2' : '3') . '">' . $countline . '</td></tr> <tr><td style="text-align:center" colspan="4">' . _T('info_fileusage_top') . STORAGE_LIMIT . ' ' . _T('info_0disable1enable') . '</td></tr>'; if (STORAGE_LIMIT) { $dat .= ' <tr style="text-align:center"><td>' . _T('info_fileusage_limit') . '</td><td colspan="2">' . STORAGE_MAX . ' KB</td><td rowspan="2">' . _T('info_dsusage_usage') . '<br /><span style="color: #' . $clrflag_sl . '">' . substr($tmp_ts_ratio * 100, 0, 6) . '</span> %</td></tr> <tr style="text-align:center"><td>' . _T('info_fileusage_count') . '</td><td colspan="2"><span style="color: #' . $clrflag_sl . '">' . $tmp_total_size . ' KB</span></td></tr>'; } else { $dat .= ' <tr style="text-align:center"><td>' . _T('info_fileusage_count') . '</td><td>' . $tmp_total_size . ' KB</td><td colspan="2">' . _T('info_dsusage_usage') . '<br /><span style="color: green;">' . _T('info_fileusage_unlimited') . '</span></td></tr>'; } $dat .= ' <tr><td style="text-align:center" colspan="4">' . _T('info_server_top') . '</td></tr> <tr style="text-align:center"><td colspan="3">' . $func_thumbInfo . '</td><td>' . $func_thumbWork . '</td></tr> </tbody> </table> <hr /> </div>' . "\n"; foot($dat); echo $dat; }
public static function setUpBeforeClass() { // Let the system load lib_pio (FlagHelper) PMCLibrary::getPIOInstance(); }
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 . '&sort=no">No.' . ($sort == 'no' ? ' ▼' : '') . '</a></th> <th width="48%">' . _T('form_topic') . '</th> <th>' . _T('form_name') . '</th> <th><a href="' . $thisPage . '&sort=' . ($sort == 'postdesc' ? 'postasc' : 'postdesc') . '">' . _T('reply_btn') . ($sort == 'postdesc' ? ' ▼' : ($sort == 'postasc' ? ' ▲' : '')) . '</a></th> <th><a href="' . $thisPage . '&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 . '&page=' . ($page - 1) . '&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 . '&page=' . $i . '&sort=' . $sort . '">' . $i . '</a>] '; } } $dat .= '</td>'; if ($page < $pageMax) { $dat .= '<td><a href="' . $thisPage . '&page=' . ($page + 1) . '&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; }
public function autoHookAdminFunction($action, &$param, $funcLabel, &$message) { if ($action == 'add') { // Manual hook: showing hostname of users $this->hookModuleMethod('ThreadPost', array(&$this, '_showHostString')); $this->hookModuleMethod('ThreadReply', array(&$this, '_showHostString')); $param[] = array('mod_adminenhance_thstop', 'AE: 停止/恢復討論串'); $param[] = array('mod_adminenhance_banip', 'AE: IP 加到黑名單 (鎖 Class C)'); $param[] = array('mod_adminenhance_banimg', 'AE: 圖檔 MD5 加到黑名單'); return; } $PIO = PMCLibrary::getPIOInstance(); switch ($funcLabel) { case 'mod_adminenhance_thstop': $infectThreads = array(); foreach ($PIO->fetchPosts($param) as $th) { if ($th['resto']) { continue; } // 是回應 $infectThreads[] = $th['no']; $flgh = $PIO->getPostStatus($th['status']); $flgh->toggle('TS'); $PIO->setPostStatus($th['no'], $flgh->toString()); } $PIO->dbCommit(); $message .= '停止/恢復討論串 (No.' . implode(', ', $infectThreads) . ') 完成<br />'; break; case 'mod_adminenhance_banip': $fp = fopen($this->ipfile, 'a'); foreach ($PIO->fetchPosts($param) as $th) { if (($IPaddr = gethostbyname($th['host'])) != $th['host']) { $IPaddr .= '/24'; } fwrite($fp, $IPaddr . "\t\t" . time() . "\t0\n"); } fclose($fp); $message .= 'IP 黑名單更新完成<br />'; break; case 'mod_adminenhance_banimg': $fp = fopen($this->imgfile, 'a'); foreach ($PIO->fetchPosts($param) as $th) { if ($th['md5chksum']) { fwrite($fp, $th['md5chksum'] . "\n"); } } fclose($fp); $message .= '圖檔黑名單更新完成<br />'; break; default: } }
private function GenerateCache() { $PIO = PMCLibrary::getPIOInstance(); $FileIO = PMCLibrary::getFileIOInstance(); // RFC標準所用之時區格式 $RFC_timezone = ' ' . (TIME_ZONE < 0 ? '-' : '+') . substr('0' . abs(TIME_ZONE), -2) . '00'; switch ($this->FEED_DISPLAYTYPE) { case 'T': // 取出前n筆討論串首篇編號 $plist = $PIO->fetchThreadList(0, $this->FEED_COUNT); $plist_count = count($plist); // 為何這樣取?避免 SQL-like 自動排序喪失時間順序 $post = array(); for ($p = 0; $p < $plist_count; $p++) { // 取出編號文章資料 $post[] = current($PIO->fetchPosts($plist[$p])); } break; case 'P': // 取出前n筆文章編號 $plist = $PIO->fetchPostList(0, 0, $this->FEED_COUNT); $post = $PIO->fetchPosts($plist); break; } $post_count = count($post); // RSS Feed內容 $tmp_c = '<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>' . TITLE . '</title> <link>' . $this->BASEDIR . '</link> <description>' . TITLE . '</description> <language>' . PIXMICAT_LANGUAGE . '</language> <generator>' . $this->getModuleName() . ' ' . $this->getModuleVersionInfo() . '</generator> <atom:link href="' . $this->SELF . '" rel="self" type="application/rss+xml" /> '; for ($i = 0; $i < $post_count; $i++) { $imglink = ''; // 圖檔 $resto = 0; // 回應 list($no, $resto, $time, $tw, $th, $tim, $ext, $sub, $com) = array($post[$i]['no'], $post[$i]['resto'], substr($post[$i]['tim'], 0, -3), $post[$i]['tw'], $post[$i]['th'], $post[$i]['tim'], $post[$i]['ext'], $post[$i]['sub'], $post[$i]['com']); // 處理資料 if ($ext && $FileIO->imageExists($tim . 's.jpg')) { $imglink = sprintf('<img src="%s" alt="%s" width="%d" height="%d" /><br />', $FileIO->getImageURL($tim . 's.jpg'), $tim . $ext, $tw, $th); } // 本地時間RFC標準格式 $time = gmdate("D, d M Y H:i:s", $time + TIME_ZONE * 60 * 60) . $RFC_timezone; $reslink = $this->BASEDIR . PHP_SELF . '?res=' . ($resto ? $resto : $no); switch ($this->FEED_DISPLAYTYPE) { case 'T': // 標題 No.編號 (Res:回應數) $titleBar = $sub . ' No.' . $no . ' (Res: ' . ($PIO->postCount($no) - 1) . ')'; break; case 'P': // 標題 (編號) $titleBar = $sub . ' (' . $no . ')'; break; } $tmp_c .= '<item> <title>' . $titleBar . '</title> <link>' . $reslink . '</link> <description> <![CDATA[ ' . $imglink . $com . ' ]]> </description> <comments>' . $reslink . '</comments> <guid isPermaLink="true">' . $reslink . '#r' . $no . '</guid> <pubDate>' . $time . '</pubDate> </item> '; } $tmp_c .= '</channel> </rss>'; $fp = fopen($this->FEED_CACHEFILE, 'w'); flock($fp, LOCK_EX); fwrite($fp, $tmp_c); flock($fp, LOCK_UN); fclose($fp); @chmod($this->FEED_CACHEFILE, 0666); }
* @version $Id$ */ /** * 取出翻譯資源檔對應字串。 * * @param args 翻譯資源檔索引、其餘變數 * @see LanguageLoader->getTranslation */ function _T() { // 因為 5.3 以前 func_get_args 無法直接指派,故需要由變數 $args 承接再帶入 $args = func_get_args(); return call_user_func_array(array(PMCLibrary::getLanguageInstance(), 'getTranslation'), $args); } /** * 動態附加翻譯資源。此函式已經由 {@link #LanguageLoader->attachLanguage} 取代。 * * @deprecated 7th.Release. Use LanguageLoader->attachLanguage instead. * @param callable $fcall 附加翻譯資源字串的函式 */ function AttachLanguage($fcall) { $GLOBALS['language'] = array(); call_user_func($fcall); PMCLibrary::getLanguageInstance()->attachLanguage($GLOBALS['language']); } // 為了相容舊寫法而保留 $PIO = PMCLibrary::getPIOInstance(); $FileIO = PMCLibrary::getFileIOInstance(); $PTE = PMCLibrary::getPTEInstance(); $PMS = PMCLibrary::getPMSInstance();
/** * 產出靜態推文表單 * * @param int $targetPost 推文對象文章編號 * @return string 表單頁面 HTML */ private function printStaticForm($targetPost) { $PIO = PMCLibrary::getPIOInstance(); $PTE = PMCLibrary::getPTEInstance(); $post = $PIO->fetchPosts($targetPost); if (!count($post)) { die('[Error] Post does not exist.'); } $dat = $PTE->ParseBlock('HEADER', array('{$TITLE}' => TITLE, '{$RESTO}' => '')); $dat .= '</head><body id="main">'; $dat .= '<form action="' . $this->getModulePageURL(array('no' => $targetPost)) . '" method="post"> ' . $this->_T('pushpost') . ' <ul><li>' . _T('form_name') . ' <input type="text" name="name" maxlength="20" /></li><li>' . _T('form_comment') . ' <input type="text" name="comm" size="50" maxlength="50" /><input type="submit" value="' . _T('form_submit_btn') . '" /></li></ul> </form>'; $dat .= '</body></html>'; return $dat; }