pixmicat

Subversion Repositories:
Compare Path: Rev
With Path: Rev
/release/ @ 456  →  /release/ @ 457
New file
/release/Modules-PIO-v4/mod_mobile/mod_mobile.php
@@ -0,0 +1,117 @@
<?php
/*
mod_mobile : 行動版頁面顯示 (唯讀)
By: scribe
*/
 
class mod_mobile{
var $THREADLIST_NUMBER, $thisPage, $displayMode;
 
function mod_mobile(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_mobile'); // 向系統登記模組專屬獨立頁面
 
$this->THREADLIST_NUMBER = 10; // 一頁顯示列表個數
$this->thisPage = $PMS->getModulePageURL('mod_mobile'); // 基底位置
$this->displayMode = isset($_COOKIE['dm']) ? $_COOKIE['dm'] : 's'; // 顯示模式 (s/m/l)
}
 
/* Get the name of module */
function getModuleName(){
return 'mod_mobile : 行動版頁面顯示 (唯讀)';
}
 
/* Get the module version infomation */
function getModuleVersionInfo(){
return 'Pixmicat! Mobile Module v070224';
}
 
/* 自動掛載:頂部連結列 */
function autoHookToplink(&$linkbar){
$linkbar .= '[<a href="'.$this->thisPage.'">行動版</a>]'."\n";
}
 
/* 模組獨立頁面 */
function ModulePage(){
global $PIO;
 
$err = ''; // 錯誤資訊
$res = isset($_GET['r']) ? intval($_GET['r']) : 0; // 回應編號
if(isset($_GET['dm'])){ // 是否進入設定模式
$ss = $ms = $ls = '';
switch($this->displayMode){
case 's': $ss = ' selected="selected"'; break;
case 'm': $ms = ' selected="selected"'; break;
case 'l': $ls = ' selected="selected"'; break;
}
$this->mobileHead($err, TITLE.' - 設定');
$err .= '<div>[<a href="'.$this->thisPage.'">回首頁</a>]<br/><form action="'.$this->thisPage.'" method="post">顯示模式:<br/><select name="dm"><option value="s"'.$ss.'>精簡 (無圖,裁字)</option><option value="m"'.$ms.'>一般 (無圖,全字)</option><option value="l"'.$ls.'>完整 (有圖,全字)</option></select><br/><input type="submit" value="儲存"/></form></div><div id="f">-Pixmicat!m-</div></body></html>';
}else{
if(isset($_POST['dm'])){ setCookie('dm', ($this->displayMode = $_POST['dm']), time()+604800); }
if($res !== 0){
$pageMax = $page = null; // Not in use
if(!$PIO->isThread($res)){ $err = 'Thread Not Found'; }
else{ $post = $PIO->fetchPosts($PIO->fetchPostList($res)); }
}else{
$pageMax = ceil($PIO->threadCount() / $this->THREADLIST_NUMBER) - 1; // 分頁最大編號
$page = isset($_GET['p']) ? intval($_GET['p']) : 0; // 目前所在分頁
if($page < 0 || $page > $pageMax){ $err = 'Page Out of Range'; } // $page 超過範圍
else{ $post = $PIO->fetchPosts($PIO->fetchThreadList($this->THREADLIST_NUMBER * $page, $this->THREADLIST_NUMBER, true)); } // 編號由大到小排序取出
}
}
if($err){ echo $err; }
else{
$dat = ''; // HTML Buffer
$this->mobileHead($dat, TITLE);
$this->mobileBody($dat, $pageMax, $page, $res, $post);
$this->mobileFoot($dat);
echo $dat;
}
}
 
/* 行動版頁首 */
function mobileHead(&$dat, $title){
$dat .= '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><meta http-equiv="Cache-Control" content="no-cache"/><title>'.$title.'</title><style type="text/css">.s {color:red;} .n{color:green;} .w{color:gray;}</style></head>
<body>
';
}
 
/* 行動版內容 */
function mobileBody(&$dat, $pageMax, $page, $res, $post){
global $PIO, $FileIO;
$post_count = count($post);
$dat .= '<div id="c">';
if($res !== 0){ $dat .= '[<a href="'.(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $this->thisPage).'">回上頁</a>]<br/>'; }
// 逐步取資料
for($i = 0; $i < $post_count; $i++){
list($no, $sub, $name, $com, $tim, $ext) = array($post[$i]['no'], $post[$i]['sub'],$post[$i]['name'], $post[$i]['com'], $post[$i]['tim'], $post[$i]['ext']);
// 資料處理
if($this->displayMode==='s'){ $com = str_cut($com, 50); } // 取斷字元
$reply1 = $res ? '<span class="s">'.$sub.'</span>' : '<a href="'.$this->thisPage.'&amp;r='.$no.'">'.$sub.'</a>'; // 回應模式連結
$reply2 = $res ? '' : '<span class="w">('.($PIO->postCount($no) - 1).')</span>'; // 回應數
$img = ($this->displayMode==='l' && $FileIO->imageExists($tim.'s.jpg')) ? '<img src="'.$FileIO->getImageURL($tim.'s.jpg').'" alt="p"/><br/>' : '';
// 輸出
$dat .= '<div>'.$reply1.$reply2.'<span class="n">'.$name.'</span><br/>'.$img.$com.'</div><hr/>'."\n";
}
$dat .= '</div>';
if($page !== null){ // 分頁欄
$dat .= '<div id="p">';
if($page) $dat .= '<a href="'.$this->thisPage.'&amp;p='.($page - 1).'">|&lt;</a> ';
for($i = 0; $i <= $pageMax; $i++){
if($i==$page) $dat .= '[<b>'.$i.'</b>] ';
else $dat .= '[<a href="'.$this->thisPage.'&amp;p='.$i.'">'.$i.'</a>] ';
}
if($page < $pageMax) $dat .= '<a href="'.$this->thisPage.'&amp;p='.($page + 1).'">&gt;|</a>';
$dat .= '</div>';
}
}
 
/* 行動版頁尾 */
function mobileFoot(&$dat){
$dat .= '<div id="f">-Pixmicat!m-<br/><a href="'.$this->thisPage.'&amp;dm=set">顯示模式</a></div></body></html>';
}
}
?>
New file
/release/Modules-PIO-v4/mod_rss/mod_rss.php
@@ -0,0 +1,142 @@
<?php
/*
mod_rss : 提供RSS Feed訂閱服務
By: scribe
*/
 
class mod_rss{
var $FEED_COUNT, $FEED_STATUSFILE, $FEED_CACHEFILE, $FEED_DISPLAYTYPE, $BASEDIR;
 
function mod_rss(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_rss'); // 向系統登記模組專屬獨立頁面
 
$this->FEED_COUNT = 10; // RSS產生最大篇數
$this->FEED_STATUSFILE = 'mod_rss.tmp'; // 資料狀態暫存檔 (檢查資料需不需要更新)
$this->FEED_CACHEFILE = 'rss.xml'; // 資料輸出暫存檔 (靜態快取Feed格式)
$this->FEED_DISPLAYTYPE = 'Thread'; // 資料取出形式 (Thread: 討論串取向, Post: 文章取向)
$this->BASEDIR = fullURL(); // 基底URL
}
 
/* Get the name of module */
function getModuleName(){
return 'mod_rss : 提供RSS Feed訂閱服務';
}
 
/* Get the module version infomation */
function getModuleVersionInfo(){
return 'Pixmicat! RSS Feed Module v070506';
}
 
/* Auto hook to "Head" hookpoint */
function autoHookHead(&$txt){
global $PMS;
$txt .= '<link rel="alternate" type="application/rss+xml" title="RSS 2.0 Feed" href="'.$PMS->getModulePageURL('mod_rss').'" />'."\n";
}
 
/* 模組獨立頁面 */
function ModulePage(){
global $PIO;
 
$PIO->dbPrepare();
if($this->IsDATAUpdated()) $this->GenerateCache(); // 若資料已更新則也更新RSS Feed快取
$this->RedirectToCache(); // 重導向到靜態快取
}
 
/* 檢查資料有沒有更新 */
function IsDATAUpdated(){
global $PIO;
if(isset($_GET['force'])) return true; // 強迫更新RSS Feed
 
$tmp_fsize = $PIO->getLastPostNo('afterCommit');
$tmp_ssize = file_exists($this->FEED_STATUSFILE) ? file_get_contents($this->FEED_STATUSFILE) : 0; // 讀取狀態暫存資料
if($tmp_fsize == $tmp_ssize) return false; // LastNo 相同,沒有更新
 
$fp = fopen($this->FEED_STATUSFILE, 'w');
stream_set_write_buffer($fp, 0); // 立刻寫入不用緩衝
flock($fp, LOCK_EX); // 鎖定
fwrite($fp, $tmp_fsize); // 更新
flock($fp, LOCK_UN); // 解鎖
fclose($fp);
@chmod($this->FEED_STATUSFILE, 0666); // 可讀可寫
return true; // 有更新過
}
 
/* 生成 / 更新靜態快取RSS Feed檔案 */
function GenerateCache(){
global $PIO, $FileIO;
$RFC_timezone = ' '.(TIME_ZONE < 0 ? '-' : '+').substr('0'.abs(TIME_ZONE), -2).'00'; // RFC標準所用之時區格式
 
switch($this->FEED_DISPLAYTYPE){
case 'Thread':
$plist = $PIO->fetchThreadList(0, $this->FEED_COUNT); // 取出前n筆討論串首篇編號
$plist_count = count($plist);
// 為何這樣取?避免 SQL-like 自動排序喪失時間順序
$post = array();
for($p = 0; $p < $plist_count; $p++) $post[] = array_pop($PIO->fetchPosts($plist[$p])); // 取出編號文章資料
break;
case 'Post':
$plist = $PIO->fetchPostList(0, 0, $this->FEED_COUNT); // 取出前n筆文章編號
$post = $PIO->fetchPosts($plist);
break;
}
$post_count = count($post);
// RSS Feed內容
$tmp_c = '<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>'.TITLE.'</title>
<link>'.$this->BASEDIR.'</link>
<description>'.TITLE.'</description>
<language>zh-TW</language>
<generator>'.$this->getModuleVersionInfo().'</generator>
';
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 = '<img src="'.$FileIO->getImageURL($tim.'s.jpg').'" alt="'.$tim.$ext.'" width="'.$tw.'" height="'.$th.'" /><br />';
$time = gmdate("D, d M Y H:i:s", $time + TIME_ZONE * 60 * 60).$RFC_timezone; // 本地時間RFC標準格式
$reslink = $this->BASEDIR.PHP_SELF.'?res='.($resto ? $resto : $no); // 回應連結
switch($this->FEED_DISPLAYTYPE){
case 'Thread':
$titleBar = $sub.' No.'.$no.' (Res: '.($PIO->postCount($no) - 1).')'; // 標題 No.編號 (Res:回應數)
break;
case 'Post':
$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); // 可讀可寫
}
 
/* 重導向到靜態快取 */
function RedirectToCache(){
header('HTTP/1.1 302 Moved Temporarily'); // 暫時性導向
header('Location: '.$this->BASEDIR.$this->FEED_CACHEFILE);
}
}
?>
New file
/release/Modules-PIO-v4/mod_catalog/mod_catalog.php
@@ -0,0 +1,104 @@
<?php
/*
mod_catalog : 以相簿模式列出圖檔方便瀏覽及抓取
By: scribe (Adopted from Pixmicat!-Festival)
*/
 
class mod_catalog{
var $CATALOG_NUMBER;
 
function mod_catalog(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_catalog'); // 向系統登記模組專屬獨立頁面
 
$this->CATALOG_NUMBER = 50; // 相簿模式一頁最多顯示個數 (視文章是否有貼圖而有實際變動)
}
 
/* Get the name of module */
function getModuleName(){
return 'mod_catalog : 以相簿模式列出圖檔方便瀏覽及抓取';
}
 
/* Get the module version infomation */
function getModuleVersionInfo(){
return 'Pixmicat! Catalog Module v070130';
}
 
/* 自動掛載:樣式表 */
function autoHookHead(&$style){
$style .= '<style type="text/css">
div.list { float: left; margin: 5px; width: 125px; height: 125px; } /* (相簿模式) div 框格設定 */
</style>
';
}
 
/* 自動掛載:頂部連結列 */
function autoHookToplink(&$linkbar){
global $PMS;
$linkbar .= '[<a href="'.$PMS->getModulePageURL('mod_catalog').'">相簿模式</a>]'."\n";
}
 
/* 模組獨立頁面 */
function ModulePage(){
global $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 超過範圍
$plist = $PIO->fetchPostList(0, $this->CATALOG_NUMBER * $page, $this->CATALOG_NUMBER); // 取得定位正確的 N 筆資料號碼
$post = $PIO->fetchPosts($plist); // 取出資料
$post_count = count($post);
 
head($dat);
$dat .= '<div id="contents">
[<a href="'.PHP_SELF2.'?'.time().'">回到版面</a>]
<div class="bar_reply">相簿模式</div>
';
// 逐步取資料
for($i = 0; $i < $post_count; $i++){
list($imgw, $imgh, $tw, $th, $tim, $ext) = array($post[$i]['imgw'], $post[$i]['imgh'],$post[$i]['tw'], $post[$i]['th'], $post[$i]['tim'], $post[$i]['ext']);
if($FileIO->imageExists($tim.$ext)){
$dat .= '<div class="list"><a href="'.$FileIO->getImageURL($tim.$ext).'" rel="_blank"><img src="'.$FileIO->getImageURL($tim.'s.jpg').'" style="'.$this->OptimizeImageWH($tw, $th).'" title="'.$imgw.'x'.$imgh.'" alt="'.$tim.$ext.'" /></a></div>'."\n";
}
}
 
$dat .= '</div>
 
<hr />
 
<div id="page_switch">
<table border="1" style="float: left;"><tr>
';
if($page) $dat .= '<td><a href="'.$thisPage.'&amp;page='.($page - 1).'">上一頁</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.'">'.$i.'</a>] ';
}
$dat .= '</td>';
if($page < $pageMax) $dat .= '<td><a href="'.$thisPage.'&amp;page='.($page + 1).'">下一頁</a></td>';
else $dat .= '<td style="white-space: nowrap;">最後一頁</td>';
$dat .= '
</tr></table>
</div>
 
';
foot($dat);
echo $dat;
}
 
/* 最佳化圖顯示尺寸 */
function OptimizeImageWH($w, $h){
if($w > MAX_RW || $h > MAX_RH){
$W2 = MAX_RW / $w; $H2 = MAX_RH / $h;
$tkey = ($W2 < $H2) ? $W2 : $H2;
$w = ceil($w * $tkey); $h = ceil($h * $tkey);
}
return 'width: '.$w.'px; height: '.$h.'px;';
}
}
?>
New file
/release/Modules-PIO-v4/mod_code/howto.txt
@@ -0,0 +1,16 @@
License:
 
dp.SyntaxHighlighter is licensed under GNU Lesser Public License. Copyright ©2004-2007 Alex Gorbatchev, http://code.google.com/p/syntaxhighlighter/
mod_code is not a part of Pixmicat! package. So it's not licensed under the Clarified Artistic License. It's in the public domain.
 
中文安裝指引:
 
1. 下載 SyntaxHighlighter (http://code.google.com/p/syntaxhighlighter/) 儲存
2. 將 mod_code.php, 1. 解壓後的 dp.SyntaxHighlighter/Scripts 目錄檔案放到 module/ 目錄
3. 修改 config.php,在模組載入區塊下加一行 $ModuleList[] = 'mod_code';
 
English Instruction:
 
1. Download the SyntaxHighlighter from the SyntaxHighlighter project page (http://code.google.com/p/syntaxhighlighter/).
2. Put the following files into the module/ directory: "mod_code.php", "shCore.js", "SyntaxHighlighter.css" and "shBrushXxx.js." (Choose what you want)
3. Use your favorite editor to open the "config.php" and add one line ($ModuleList[] = 'mod_code';) into the "Modules to be loaded" block.
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Modules-PIO-v4/mod_code/mod_code.php
@@ -0,0 +1,44 @@
<?php
class mod_code{
var $brushes;
 
function mod_code(){
$this->brushes = array('Php', 'JScript', 'Ruby'); // 選擇載入支援程式刷
}
 
function getModuleName(){
return 'mod_code';
}
 
function getModuleVersionInfo(){
return 'mod_code : dp.SyntaxHighlighter Embedded v070615';
}
 
function autoHookHead(&$dat){
$dat .= <<< _EOF_
<link rel="stylesheet" type="text/css" href="module/SyntaxHighlighter.css" />
<script type="text/javascript" src="module/shCore.js"></script>
 
_EOF_;
foreach($this->brushes as $b){ $dat .= '<script type="text/javascript" src="module/shBrush'.$b.'.js"></script>'."\n"; } // 載入刷子檔
}
function autoHookPostInfo(&$postinfo){
$postinfo .= '<li>程式碼可使用 [code=類型][/code] 以 dp.SyntaxHighlighter 標亮 (<a href="http://code.google.com/p/syntaxhighlighter/wiki/Languages" rel="_blank">類型列表</a>)</li>'."\n";
}
 
function autoHookThreadPost(&$arrLabels, $post, $isReply){
extract($post);
$arrLabels['{$COM}'] = preg_replace('/\[code=(\w*?)\](.*?)\[\/code\]/ue', "'<textarea name=\"code\" cols=\"10\" rows=\"10\" class=\"$1\">'.str_replace('<br />', \"\n\", '$2').'</textarea>'", $arrLabels['{$COM}']);
}
 
function autoHookThreadReply(&$arrLabels, $post, $isReply){
extract($post);
$arrLabels['{$COM}'] = preg_replace('/\[code=(\w*?)\](.*?)\[\/code\]/ue', "'<textarea name=\"code\" cols=\"10\" rows=\"10\" class=\"$1\">'.str_replace('<br />', \"\n\", '$2').'</textarea>'", $arrLabels['{$COM}']);
}
 
function autoHookFoot(&$dat){
$dat .= '<script type="text/javascript">dp.SyntaxHighlighter.HighlightAll(\'code\');</script>'."\n";
}
}
?>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Modules-PIO-v4/mod_showhide/mod_showhide.js
@@ -0,0 +1,54 @@
jQuery.noConflict(); // No Conflict Mode
 
if(!Array.prototype.indexOf){ // Inplemented in JavaScript 1.6
Array.prototype.indexOf = function(item){
var len = this.length;
for(var i = 0; i < len; i++){ if(this[i] === item){ return i; } }
return -1;
};
}
 
var TmodShowhide = {
hideList : [], // 隱藏討論串列表
isChange : false, // 是否有更動需回存
/* 載入討論串隱藏列表並實行隱藏 */
init : function(){
var t;
if(location.href.indexOf('.php?res=')!==-1){ return; } // 回應模式不動作
if(t = getCookie('hideList')){
//alert('getCookie');
TmodShowhide.hideList = t.split(',');
jQuery('div.threadStructure').each(function(){
//alert('loop:'+this.id);
if(TmodShowhide.hideList.indexOf(this.id)!==-1){ jQuery(this).hide(); } // 隱藏討論串
});
}
// 加上控制按鈕
jQuery('div.threadStructure').each(function(){
jQuery(this).before('[<a href="javascript:void(0);" onclick="TmodShowhide.switchThread(\''+this.id+'\');" title="Hide/Show this thread">+ / -</a>]<br />');
});
//jQuery('div#postinfo > ul').append('<li>mod_showhide Testing</li>');
//alert('OK:'+TmodShowhide.hideList);
},
/* 切換文章顯示與否 */
switchThread : function(no){
var t;
TmodShowhide.isChange = true;
if((t = TmodShowhide.hideList.indexOf(no))!==-1){
TmodShowhide.hideList.splice(t, 1);
jQuery('div.threadStructure#'+no).show('slow');
}else{
TmodShowhide.hideList.push(no);
jQuery('div.threadStructure#'+no).hide('slow');
}
//alert('s:'+TmodShowhide.hideList);
},
/* 回存 */
unload : function(){
if(TmodShowhide.isChange){ setCookie('hideList', TmodShowhide.hideList.join(',')); }
//alert('bye');
}
};
 
jQuery(TmodShowhide.init); // 註冊載入事件
jQuery(window).unload(TmodShowhide.unload); // 註冊結束事件
New file
/release/Modules-PIO-v4/mod_showhide/howto.txt
@@ -0,0 +1,16 @@
License:
 
jQuery is licensed under MIT License. Copyright (c) 2007 John Resig, http://jquery.com/
mod_showhide is not a part of Pixmicat! package. So it's not licensed under the Clarified Artistic License. It's in the public domain.
 
中文安裝指引:
 
1. 下載 jquery-latest.pack.js (jQuery: http://jquery.com/) 儲存
2. 將 mod_showhide.php, mod_showhide.pack.js, jquery-latest.pack.js 放到 module/ 目錄
3. 修改 config.php,在模組載入區塊下加一行 $ModuleList[] = 'mod_showhide';
 
English Instruction:
 
1. Download the "jquery-latest.pack.js" from the jQuery website (http://jquery.com/).
2. Put the following files into the module/ directory: "mod_showhide.php", "mod_showhide.pack.js" and "jquery-latest.pack.js."
3. Use your favorite editor to open the "config.php" and add one line ($ModuleList[] = 'mod_showhide';) into the "Modules to be loaded" block.
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Modules-PIO-v4/mod_showhide/mod_showhide.php
@@ -0,0 +1,16 @@
<?php
class mod_showhide{
function getModuleName(){
return 'mod_showhide';
}
 
function getModuleVersionInfo(){
return 'mod_showhide : 自由隱藏顯示討論串 v070506';
}
 
function autoHookHead(&$txt){
$txt .= '<script type="text/javascript" src="module/jquery-latest.pack.js"></script>
<script type="text/javascript" src="module/mod_showhide.pack.js"></script>'."\n";
}
}
?>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Modules-PIO-v4/mod_showhide/mod_showhide.pack.js
@@ -0,0 +1 @@
jQuery.noConflict();if(!Array.prototype.indexOf){Array.prototype.indexOf=function(a){var b=this.length;for(var i=0;i<b;i++){if(this[i]===a){return i}}return-1}}var TmodShowhide={hideList:[],isChange:false,init:function(){var t;if(location.href.indexOf('.php?res=')!==-1){return}if(t=getCookie('hideList')){TmodShowhide.hideList=t.split(',');jQuery('div.threadStructure').each(function(){if(TmodShowhide.hideList.indexOf(this.id)!==-1){jQuery(this).hide()}})}jQuery('div.threadStructure').each(function(){jQuery(this).before('[<a href="javascript:void(0);" onclick="TmodShowhide.switchThread(\''+this.id+'\');" title="Hide/Show this thread">+ / -</a>]<br />')})},switchThread:function(a){var t;TmodShowhide.isChange=true;if((t=TmodShowhide.hideList.indexOf(a))!==-1){TmodShowhide.hideList.splice(t,1);jQuery('div.threadStructure#'+a).show('slow')}else{TmodShowhide.hideList.push(a);jQuery('div.threadStructure#'+a).hide('slow')}},unload:function(){if(TmodShowhide.isChange){setCookie('hideList',TmodShowhide.hideList.join(','))}}};jQuery(TmodShowhide.init);jQuery(window).unload(TmodShowhide.unload);
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Modules-PIO-v4/mod_dummy/mod_dummy.php
@@ -0,0 +1,41 @@
<?php
class mod_dummy{
function mod_dummy(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_dummy');
}
 
function getModuleName(){
return 'mod_dummy';
}
 
function getModuleVersionInfo(){
return 'mod_dummy : 展示掛載點功能模組';
}
 
function ModulePage(){
echo "Welcome to my world.";
}
 
function autoHookToplink(&$link){
global $PMS;
$link .= '[<a href="'.$PMS->getModulePageURL('mod_dummy').'">統計</a>]'."\n";
}
 
function autoHookPostInfo(&$txt){
$txt .= '<li>目前線上人數:102</li>'."\n";
}
 
function autoHookThreadFront(&$txt){
$txt .= '<div style="text-align: center;"><a href="#">[AD] 這是廣告#01!</a></div>'."\n";
}
function autoHookThreadRear(&$txt){
$txt .= '<div style="text-align: center;"><a href="#">[AD] 這是廣告#02!</a></div>'."\n";
}
 
function autoHookFoot(&$foot){
$foot .= '<span class="warn_txt2">本網站由 雙貓聯合站 提供資源,謹此致謝</span>'."\n";
}
}
?>
New file

Property changes:

Name: svn:keywords
+ Id

/release/Modules-PIO-v4/mod_exif/mod_exif.php
@@ -0,0 +1,477 @@
<?php
/* mod_exif : EXIF information (Pre-Alpha)
* $Id$
* exif.php from http://www.rjk-hosting.co.uk/programs/prog.php?id=4
*/
class mod_exif{
var $myPage;
function mod_exif(){
global $PMS, $PIO, $FileIO;
 
$PMS->hookModuleMethod('ModulePage', 'mod_exif'); // ¦V¨t²Îµn°O¼Ò²Õ±MÄÝ¿W¥ß­¶­±
$this->myPage = $PMS->getModulePageURL('mod_exif'); // °ò©³¦ì¸m
}
 
function getModuleName(){
return 'mod_exif';
}
 
function getModuleVersionInfo(){
return 'mod_exif : EXIF information (Pre-Alpha)';
}
 
function autoHookThreadPost(&$arrLabels, $post, $isReply){
if(FILEIO_BACKEND=='normal') { // work for normal File I/O only
if($arrLabels['{$IMG_BAR}']!='') {
preg_match('/rel\="_blank">(.*)<\/a>/', $arrLabels['{$IMG_BAR}'], $matches);
$arrLabels['{$IMG_BAR}'] .= '<small> <a href="'.$this->myPage.'&amp;file='.$matches[1].'">[EXIF]</a></small>';
}
}
}
 
function autoHookThreadReply(&$arrLabels, $post, $isReply){
$this->autoHookThreadPost($arrLabels, $post, $isReply);
}
 
function ModulePage(){
global $PMS, $FileIO;
$file=isset($_GET['file'])?$_GET['file']:'';
if($file && $FileIO->imageExists($file)){
$pfile=IMG_DIR.'/'.$file;
if(function_exists("exif_read_data")) {
echo "DEBUG: Using exif_read_data<br/>";
$exif_data = exif_read_data($pfile,0,true);
if(isset($exif_data['FILE'])) unset($exif_data['FILE']);
if(isset($exif_data['COMPUTED'])) unset($exif_data['COMPUTED']);
echo !count($exif_data) ? "No EXIF data found.<br />" : "Image contains EXIF data:<br /><br />";
echo "<table border='1'>";
foreach($exif_data as $key=>$section) {
foreach($section as $name=>$val) {
echo "<tr><th align='right'>$key.$name:</th><td>$val</td></tr>";
}
}
echo "</table>";
} else {
echo "DEBUG: Using built-in exif library<br/>";
$exif=new exif($pfile);
echo !count($exif->exif_data) ? "No EXIF data found.<br />" : "Image contains EXIF data:<br /><br />";
echo "<table border='1'>";
foreach($exif->exif_data as $key=>$val)
echo "<tr><th align='right'>$key:</th><td>$val</td></tr>";
echo "</table>";
}
}
echo "<br /><a href='javascript:history.go(-1)'>[Back]</a>";
}
}
 
class exif{
/* Exif reader v 1.2
By Richard James Kendall
Bugs to richard@richardjameskendall.com
Free to use, please acknowledge me
*/
// holds the formatted data read from the EXIF data area
var $exif_data = array();
 
// holds the number format used in the EXIF data (1 == moto, 0 == intel)
var $align;
 
// holds the lengths and names of the data formats
var $format_length = array(0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8);
var $format_type = array("", "BYTE", "STRING", "USHORT", "ULONG", "URATIONAL", "SBYTE", "UNDEFINED", "SSHORT", "SLONG", "SRATIONAL", "SINGLE", "DOUBLE");
 
// data for EXIF enumeations
var $Orientation = array("", "Normal (0 deg)", "Mirrored", "Upsidedown", "Upsidedown & Mirrored", "Mirror horizontal and rotate 270 CW","Rotate 90 CW","Mirror horizontal and rotate 90 CW","Rotate 270 CW");
var $ResUnit = array("", "inches", "inches", "cm", "mm", "um");
var $YCbCrPos = array("", "Centre of Pixel Array", "Datum Points");
var $ExpProg = array("", "Manual", "Program", "Apeture Priority", "Shutter Priority", "Program Creative", "Program Action", "Portrait", "Landscape");
var $LightSource = array("Unknown", "Daylight", "Fluorescent", "Tungsten (incandescent)", "Flash", "Fine Weather", "Cloudy Weather", "Share", "Daylight Fluorescent", "Day White Fluorescent", "Cool White Fluorescent", "White Fluorescent", "Standard Light A", "Standard Light B", "Standard Light C", "D55", "D65", "D75", "D50", "ISO Studio Tungsten");
var $MeterMode = array("Unknown", "Average", "Centre Weighted", "Spot", "Multi-Spot", "Pattern", "Partial");
var $RenderingProcess = array("Normal Process", "Custom Process");
var $ExposureMode = array("Auto", "Manual", "Auto Bracket");
var $WhiteBalance = array("Auto", "Manual");
var $SceneCaptureType = array("Standard", "Landscape", "Portrait", "Night Scene");
var $GainControl = array("None", "Low Gain Up", "High Gain Up", "Low Gain Down", "High Gain Down");
var $Contrast = array("Normal", "Soft", "Hard");
var $Saturation = array("Normal", "Low Saturation", "High Saturation");
var $Sharpness = array("Normal", "Soft", "Hard");
var $SubjectDistanceRange = array("Unknown", "Macro", "Close View", "Distant View");
var $FocalPlaneResUnit = array("", "inches", "inches", "cm", "mm", "um");
var $SensingMethod = array("", "Not Defined", "One-chip Colour Area Sensor", "Two-chip Colour Area Sensor", "Three-chip Colour Area Sensor", "Colour Sequential Area Sensor", "Trilinear Sensor", "Colour Sequential Linear Sensor");
var $CalibrationIlluminant1,$CalibrationIlluminant2;
var $Flash = array(0x0 => "No Flash", 0x1 => "Fired", 0x5 => "Fired, Return not detected", 0x7 => "Fired, Return detected", 0x8 => "On, Did not fire", 0x9 => "On", 0xd => "On, Return not detected", 0xf => "On, Return detected", 0x10 => "Off", 0x14 => "Off, Did not fire, Return not detected", 0x18 => "Auto, Did not fire", 0x19 => "Auto, Fired", 0x1d => "Auto, Fired, Return not detected", 0x1f => "Auto, Fired, Return detected", 0x20 => "No flash function", 0x30 => "Off, No flash function", 0x41 => "Fired, Red-eye reduction", 0x45 => "Fired, Red-eye reduction, Return not detected", 0x47 => "Fired, Red-eye reduction, Return detected", 0x49 => "On, Red-eye reduction", 0x4d => "On, Red-eye reduction, Return not detected", 0x4f => "On, Red-eye reduction, Return detected", 0x50 => "Off, Red-eye reduction", 0x58 => "Auto, Did not fire, Red-eye reduction", 0x59 => "Auto, Fired, Red-eye reduction", 0x5d => "Auto, Fired, Red-eye reduction, Return not detected", 0x5f => "Auto, Fired, Red-eye reduction, Return detected");
 
// gets one byte from the file at handle $fp and converts it to a number
function fgetord($fp) {
return ord(fgetc($fp));
}
 
function gcd($a, $b) {
if ($a < $b) {
$gcd = $this->gcd($b, $a);
}else{
assert($a > 0);
assert($b >= 0);
while ($b != 0) {
$t = $a % $b;
$a = $b;
$b = $t;
}
$gcd = $a;
}
return $gcd;
}
 
function fractionSimply($n,$d) {
$g=$this->gcd($n, $d);
return array($n/$g,$d/$g);
}
 
function fractionToMixed($n,$d) {
$m = $n % $d;
return array(($n-$m)/$d,$m,$d);
}
 
// takes $data and pads it from the left so strlen($data) == $shouldbe
function pad($data, $shouldbe, $put) {
if (strlen($data) == $shouldbe) {
return $data;
} else {
$padding = "";
for ($i = strlen($data);$i < $shouldbe;$i++) {
$padding .= $put;
}
return $padding . $data;
}
}
 
// converts a number from intel (little endian) to motorola (big endian format)
function ii2mm($intel) {
$mm = "";
for ($i = 0;$i <= strlen($intel);$i+=2) {
$mm .= substr($intel, (strlen($intel) - $i), 2);
}
return $mm;
}
 
// gets a number from the EXIF data and converts if to the correct representation
function getnumber($data, $start, $length, $align) {
$a = bin2hex(substr($data, $start, $length));
if (!$align) {
$a = $this->ii2mm($a);
}
return hexdec($a);
}
 
// gets a rational number (num, denom) from the EXIF data and produces a decimal
function getrational($data, $align, $type) {
$a = bin2hex($data);
if (!$align) {
$a = $this->ii2mm($a);
}
if ($align == 1) {
$n = hexdec(substr($a, 0, 8));
$d = hexdec(substr($a, 8, 8));
} else {
$d = hexdec(substr($a, 0, 8));
$n = hexdec(substr($a, 8, 8));
}
if ($type == "S" && $n > 2147483647) {
$n = $n - 4294967296;
}
if ($n == 0) {
return 0;
}
if ($d != 0) {
$ra=$this->fractionSimply($n,$d);
return ($n / $d).($ra[1]!=1&&$ra[1]!=$d?' ('.$ra[0]."/".$ra[1].')':'').($d!=1?' ['.$n."/".$d.']':'');
} else {
return $n."/".$d;
}
}
 
// opens the JPEG file and attempts to find the EXIF data
function exif($file) {
$this->CalibrationIlluminant1=$this->CalibrationIlluminant2=$this->LightSource;
$this->align=0;
 
$fp = fopen($file, "rb");
$a = $this->fgetord($fp);
if ($a != 255 || $this->fgetord($fp) != 216) {
return false;
}
$ef = false;
while (!feof($fp)) {
$section_length = 0;
$section_marker = 0;
$lh = 0;
$ll = 0;
for ($i = 0;$i < 7;$i++) {
$section_marker = $this->fgetord($fp);
if ($section_marker != 255) {
break;
}
if ($i >= 6) {
return false;
}
}
if ($section_marker == 255) {
return false;
}
$lh = $this->fgetord($fp);
$ll = $this->fgetord($fp);
$section_length = ($lh << 8) | $ll;
$data = chr($lh) . chr($ll);
$t_data = fread($fp, $section_length - 2);
$data .= $t_data;
switch ($section_marker) {
case 225:
fclose($fp);
return $this->extractEXIFData(substr($data, 2), $section_length);
$ef = true;
break;
}
}
fclose($fp);
}
 
// reads the EXIF header and if it is intact it calls readEXIFDir to get the data
function extractEXIFData($data, $length) {
if (substr($data, 0, 4) == "Exif") {
if (substr($data, 6, 2) == "II") {
$this->align = 0;
} else {
if (substr($data, 6, 2) == "MM") {
$this->align = 1;
} else {
return false;
}
}
$a = $this->getnumber($data, 8, 2, $this->align);
if ($a != 0x2a) {
return false;
}
$first_offset = $this->getnumber($data, 10, 4, $this->align);
if ($first_offset < 8 || $first_offset > 16) {
return false;
}
$this->readEXIFDir(substr($data, 14), 8, $length - 6);
return true;
} else {
return false;
}
}
 
// takes an EXIF tag id and returns the string name of that tag
function tagid2name($id) {
switch ($id) {
case 0x000b: return "ACDComment"; break;
case 0x00fe: return "ImageType"; break;
case 0x0106: return "PhotometicInterpret"; break;
case 0x010e: return "ImageDescription"; break;
case 0x010f: return "Make"; break;
case 0x0110: return "Model"; break;
case 0x0112: return "Orientation"; break;
case 0x0115: return "SamplesPerPixel"; break;
case 0x011a: return "XRes"; break;
case 0x011b: return "YRes"; break;
case 0x011c: return "PlanarConfig"; break;
case 0x0128: return "ResUnit"; break;
case 0x0131: return "Software"; break;
case 0x0132: return "DateTime"; break;
case 0x013b: return "Artist"; break;
case 0x013f: return "WhitePoint"; break;
case 0x0211: return "YCbCrCoefficients"; break;
case 0x0213: return "YCbCrPos"; break;
case 0x0214: return "RefBlackWhite"; break;
case 0x1000: return "RelatedImageFileFormat"; break;
case 0x1001: return "RelatedImageWidth"; break;
case 0x1002: return "RelatedImageLength"; break;
case 0x8298: return "Copyright"; break;
case 0x829a: return "ExposureTime"; break;
case 0x829d: return "FNumber"; break;
case 0x8822: return "ExpProg"; break;
case 0x8825: return "GPSInfo"; break;
case 0x8827: return "ISOSpeedRating"; break;
case 0x9003: return "DTOpticalCapture"; break;
case 0x9004: return "DTDigitised"; break;
case 0x9102: return "CompressedBitsPerPixel"; break;
case 0x9201: return "ShutterSpeed"; break;
case 0x9202: return "ApertureWidth"; break;
case 0x9203: return "Brightness"; break;
case 0x9204: return "ExposureBias"; break;
case 0x9205: return "MaxApetureWidth"; break;
case 0x9206: return "SubjectDistance"; break;
case 0x9207: return "MeterMode"; break;
case 0x9208: return "LightSource"; break;
case 0x9209: return "Flash"; break;
case 0x920a: return "FocalLength"; break;
case 0x920b: return "FlashEnergy"; break;
case 0x9213: return "ImageHistory"; break;
case 0x9214: return "SubjectLocation"; break;
case 0x9217: return "SensingMethod"; break;
case 0x927c: return "MakerNote"; break;
case 0x9286: return "UserComment"; break;
case 0x9290: return "SubsecTime"; break;
case 0x9291: return "SubsecTimeOrig"; break;
case 0x9292: return "SubsecTimeDigi"; break;
case 0x9c9b: return "XPTitle"; break;
case 0x9c9c: return "XPComment"; break;
case 0x9c9d: return "XPAuthor"; break;
case 0x9c9e: return "XPKeywords"; break;
case 0x9c9f: return "XPSubject"; break;
case 0xa000: return "FlashPixVersion"; break;
case 0xa001: return "ColourSpace"; break;
case 0xa002: return "ImageWidth"; break;
case 0xa003: return "ImageHeight"; break;
case 0xa005: return "InteropOffset"; break;
case 0xa20e: return "FocalPlaneXRes"; break;
case 0xa20f: return "FocalPlaneYRes"; break;
case 0xa210: return "FocalPlaneResUnit"; break;
case 0xa214: return "SubjectLocation"; break;
case 0xa217: return "SensingMethod"; break;
case 0xa300: return "ImageSource"; break;
case 0xa301: return "SceneType"; break;
case 0xa401: return "RenderingProcess"; break;
case 0xa402: return "ExposureMode"; break;
case 0xa403: return "WhiteBalance"; break;
case 0xa404: return "DigitalZoomRatio"; break;
case 0xa405: return "FocalLength35mm"; break;
case 0xa406: return "SceneCaptureType"; break;
case 0xa407: return "GainControl"; break;
case 0xa408: return "Contrast"; break;
case 0xa409: return "Saturation"; break;
case 0xa40a: return "Sharpness"; break;
case 0xa40c: return "SubjectDistanceRange"; break;
case 0xa500: return "Gamma"; break;
case 0xbc02: return "Transfomation"; break;
case 0xc65a: return "CalibrationIlluminant1"; break;
case 0xc65b: return "CalibrationIlluminant2"; break;
default: return "(0x".dechex($id).")"; break;
}
}
 
// takes a (U/S)(SHORT/LONG) checks if an enumeration for this value exists and if it does returns the enumerated value for $tvalue
function enumvalue($tname, $tvalue) {
if (isset($this->$tname)) {
$tmp = $this->$tname;
return $tmp[$tvalue];
} else {
return $tvalue;
}
}
 
// takes a tag id along with the format, data and length of the data and deals with it appropriatly
function dealwithtag($tag, $format, $data, $length, $align) {
$w = false;
$val = "";
switch ($this->format_type[$format]) {
case "STRING":
$val = trim(substr($data, 0, $length));
$w = true;
break;
case "ULONG":
case "SLONG":
$val = $this->enumvalue($this->tagid2name($tag), $this->getnumber($data, 0, 4, $align));
$w = true;
break;
case "USHORT":
case "SSHORT":
switch ($tag) {
case 0x9214:
break;
case 0xa001:
$tmp = $this->getnumber($data, 0, 2, $align);
if ($tmp == 1) {
$val = "sRGB";
$w = true;
} else if ($tmp == 2) {
$val = "Adobe RGB";
$w = true;
} else {
$val = "Uncalibrated";
$w = true;
}
break;
default:
$val = $this->enumvalue($this->tagid2name($tag), $this->getnumber($data, 0, 2, $align));
$w = true;
break;
}
break;
case "URATIONAL":
$val = $this->getrational(substr($data, 0, 8), $align, "U");
$w = true;
break;
case "SRATIONAL":
$val = $this->getrational(substr($data, 0, 8), $align, "S");
$w = true;
break;
case "UNDEFINED":
switch ($tag) {
case 0xa300:
$tmp = $this->getnumber($data, 0, 2, $align);
if ($tmp == 3) {
$val = "Digital Camera";
$w = true;
} else {
$val = "Unknown";
$w = true;
}
break;
case 0xa301:
$tmp = $this->getnumber($data, 0, 2, $align);
if ($tmp == 3) {
$val = "Directly Photographed";
$w = true;
} else {
$val = "Unknown";
$w = true;
}
break;
}
break;
}
if ($w) {
$this->exif_data[$this->tagid2name($tag)] = $val;
}
}
 
// reads the tags from and EXIF IFD and if correct deals with the data
function readEXIFDir($data, $offset_base, $exif_length) {
$value_ptr = 0;
$sofar = 2;
$data_in = "";
$number_dir_entries = $this->getnumber($data, 0, 2, $this->align);
for ($i = 0;$i < $number_dir_entries;$i++) {
$sofar += 12;
$dir_entry = substr($data, 2 + 12 * $i);
$tag = $this->getnumber($dir_entry, 0, 2, $this->align);
$format = $this->getnumber($dir_entry, 2, 2, $this->align);
$components = $this->getnumber($dir_entry, 4, 4, $this->align);
if (($format - 1) >= 12) {
return false;
}
$byte_count = $components * $this->format_length[$format];
if ($byte_count > 4) {
$offset_val = ($this->getnumber($dir_entry, 8, 4, $this->align)) - $offset_base;
if (($offset_val + $byte_count) > $exif_length) {
return false;
}
$data_in = substr($data, $offset_val);
} else {
$data_in = substr($dir_entry, 8);
}
if ($tag == 0x8769) {
$tmp = ($this->getnumber($data_in, 0, 4, $this->align)) - 8;
$this->readEXIFDir(substr($data, $tmp), $tmp + 8 , $exif_length);
} else {
$this->dealwithtag($tag, $format, $data_in, $byte_count, $this->align);
}
}
}
}
?>
New file
/release/Modules-PIO-v4/mod_robottrap/.htaccess
@@ -0,0 +1,10 @@
# Place in the same folder as pixmicat.php
 
RewriteEngine On
RewriteRule thumb/1126628412168.jpg pixmicat.php?mode=module&load=mod_robottrap
RewriteRule thumb/1131459150542.jpg pixmicat.php?mode=module&load=mod_robottrap
RewriteRule imglist.htm pixmicat.php?mode=module&load=mod_robottrap
RewriteRule allimage.htm pixmicat.php?mode=module&load=mod_robottrap
 
Order Allow,Deny
Allow from all
New file
/release/Modules-PIO-v4/mod_robottrap/mod_robottrap.php
@@ -0,0 +1,53 @@
<?php
/*
mod_robottrap : 機器人及砍站程式陷阱程式
由 scribe 略改自しおからphpスクリプト的「畫像一括ダウンロードロボット‧排除用トラップ」
*/
 
class mod_robottrap{
var $DENYLIST_FILE;
 
function mod_robottrap(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_robottrap'); // 向系統登記模組專屬獨立頁面
 
$this->DENYLIST_FILE = './denylist.txt'; // 封鎖名單列表檔案
}
 
/* Get the name of module */
function getModuleName(){
return 'mod_robottrap : 機器人及砍站程式陷阱程式';
}
 
/* Get the module version infomation */
function getModuleVersionInfo(){
return 'Pixmicat! Robot Trap Module v070126';
}
 
/* 自動掛載陷阱點 */
function autoHookThreadFront(&$dat){
$dat .= '<a href="imglist.htm"></a><a href="thumb/1126628412168.jpg"></a>'."\n";
}
 
/* 自動掛載陷阱點 */
function autoHookThreadRear(&$dat){
$dat .= '<a href="allimage.htm"></a><a href="thumb/1131459150542.jpg"></a>'."\n";
}
 
/* 加入封鎖名單 */
function ModulePage(){
$fp = fopen('./.htaccess', 'a');
$denyip = 'Deny from '.$_SERVER['REMOTE_ADDR']."\n"; // 加入一行新封鎖設定
fwrite($fp, $denyip);
fclose($fp);
 
$fp = fopen($this->DENYLIST_FILE, 'a');
$denytime = gmdate('y/m/d H:i:s', time() + TIME_ZONE * 3600);
$denytxt = $denytime."\t".$_SERVER['REMOTE_ADDR']."\t".gethostbyaddr($_SERVER['REMOTE_ADDR'])."\t".$_SERVER['HTTP_USER_AGENT']."\n"; // 加入一行新記錄
fwrite($fp, $denytxt);
fclose($fp);
 
echo 'Denied from '.$_SERVER['REMOTE_ADDR']."\n";
}
}
?>
New file
/release/Modules-PIO-v4/mod_archiver/archives/index.php
@@ -0,0 +1,60 @@
<?php
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-tw">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="zh-tw">
<title>Index : Pixmicat! Archiver</title>
<link rel="stylesheet" type="text/css" href="archivestyle.css" />
</head>
<body>
 
<div id="content">
<p>靜態庫存頁面列表:</p>
';
 
/* 取得靜態庫存頁面列表 */
function GetArchives($sPath){
global $fileList;
// 打開目錄逐個搜尋XML檔案並加入陣列
$handle = opendir($sPath);
while($file = readdir($handle)){
if($file != '..' && $file != '.' && is_file($sPath.'/'.$file)) // 為檔案
if(strpos($file, '.xml')) $fileList[] = $file;
}
// 排序陣列
closedir($handle);
@sort($fileList);
@reset($fileList);
}
 
$fileList = Array();
GetArchives('.');
 
// 列出檔案連結
echo "<ul>\n";
if($fileList_count = count($fileList)){ // 有列表
for($i = 0; $i < $fileList_count; $i++){
echo ' <li><a href="'.$fileList[$i].'">'.$fileList[$i]."</a></li>\n";
}
}else{
echo '<li>目前還沒有靜態庫存頁面可供瀏覽</li>';
}
echo '</ul>
</div>
 
<hr />
';
 
echo <<< __HTML_FOOTER__
 
<div id="footer">
<!-- Pixmicat! -->
<small>- <a href="http://pixmicat.openfoundry.org/" rel="_blank">Pixmicat!</a> -</small>
</div>
 
</body>
</html>
__HTML_FOOTER__;
?>
New file
/release/Modules-PIO-v4/mod_archiver/archives/archivestyle.xsl
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
<xsl:template match="/">
<html xml:lang="zh-tw">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="Sat, 1 Jan 2000 00:00:00 GMT" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="zh-tw" />
<title>Thread <xsl:value-of select="threads/@no" /> : Pixmicat! Archiver</title>
<link rel="stylesheet" type="text/css" href="archivestyle.css" />
<script type="text/javascript">
<![CDATA[
if(typeof ActiveXObject!='undefined'){
document.write('<style type="text/css">.reply { display: inline ; zoom: 1; }</style>');
attachEvent("onload", function (){var divs=document.getElementsByTagName('div');var divs_cnt=divs.length;for(i=0;i<divs_cnt;i++){if(divs[i].className.substr(0,5)=='reply'){divs[i].insertAdjacentHTML('afterEnd','<br />');}}});
}
]]>
</script>
</head>
<body>
 
<div id="contents">
<xsl:apply-templates select="threads" />
<hr />
</div>
 
<div id="footer">
<!-- Pixmicat! -->
<small>- <a href="http://pixmicat.openfoundry.org/" rel="_blank">Pixmicat!</a> -</small>
</div>
 
</body>
</html>
</xsl:template>
 
<xsl:template match="threads">
<xsl:variable name="image_base"><xsl:value-of select="@no" />_files/</xsl:variable>
<div class="threadpost">
<xsl:if test="image != ''"> <!--有圖片-->
<xsl:variable name="image_name"><xsl:value-of select="image" /><xsl:value-of select="image/@ext" /></xsl:variable>
<xsl:variable name="image_url"><xsl:value-of select="$image_base" /><xsl:value-of select="$image_name" /></xsl:variable>
檔名:<a target="_blank"><xsl:attribute name="href"><xsl:value-of select="$image_url" /></xsl:attribute><xsl:value-of select="$image_name" /></a>-(<xsl:value-of select="image/@kbyte" /> KB, <xsl:value-of select="image/@scale" />) <small>[以預覽圖顯示]</small><br />
<a target="_blank">
<xsl:attribute name="href"><xsl:value-of select="$image_url" /></xsl:attribute>
<img class="img">
<xsl:attribute name="title"><xsl:value-of select="image/@kbyte" /> KB</xsl:attribute>
<xsl:attribute name="alt"><xsl:value-of select="image/@kbyte" /> KB</xsl:attribute>
<xsl:attribute name="src"><xsl:value-of select="$image_base" /><xsl:value-of select="image" />s.jpg</xsl:attribute>
</img>
</a>
</xsl:if>
<span class="title"><xsl:value-of select="subject" /></span>
名稱: <span class="name"><xsl:value-of select="name" /></span> [<xsl:value-of select="date" /> <xsl:if test="host"> IP:<xsl:value-of select="host" /></xsl:if>] No.<xsl:value-of select="@no" />
<div class="quote"><xsl:apply-templates select="comment" /></div>
</div>
<xsl:for-each select="reply">
<div class="reply"><xsl:attribute name="id">r<xsl:value-of select="@no" /></xsl:attribute>
<span class="title"><xsl:value-of select="subject" /></span>
名稱: <span class="name"><xsl:value-of select="name" /></span> [<xsl:value-of select="date" /> <xsl:if test="host"> IP:<xsl:value-of select="host" /></xsl:if>] No.<xsl:value-of select="@no" />
<xsl:if test="image != ''"> <!--有圖片-->
<xsl:variable name="image_name"><xsl:value-of select="image" /><xsl:value-of select="image/@ext" /></xsl:variable>
<xsl:variable name="image_url"><xsl:value-of select="$image_base" /><xsl:value-of select="$image_name" /></xsl:variable>
<br />檔名:<a target="_blank"><xsl:attribute name="href"><xsl:value-of select="$image_url" /></xsl:attribute><xsl:value-of select="$image_name" /></a>-(<xsl:value-of select="image/@kbyte" /> KB, <xsl:value-of select="image/@scale" />) <small>[以預覽圖顯示]</small><br />
<a target="_blank">
<xsl:attribute name="href"><xsl:value-of select="$image_url" /></xsl:attribute>
<img class="img">
<xsl:attribute name="title"><xsl:value-of select="image/@kbyte" /> KB</xsl:attribute>
<xsl:attribute name="alt"><xsl:value-of select="image/@kbyte" /> KB</xsl:attribute>
<xsl:attribute name="src"><xsl:value-of select="$image_base" /><xsl:value-of select="image" />s.jpg</xsl:attribute>
</img>
</a>
</xsl:if>
<div class="quote"><xsl:apply-templates select="comment" /></div>
</div>
</xsl:for-each>
</xsl:template>
 
<xsl:template match="comment">
<xsl:apply-templates />
</xsl:template>
 
<xsl:template match="br"><br /></xsl:template>
 
</xsl:stylesheet>
New file
/release/Modules-PIO-v4/mod_archiver/archives/archivestyle.css
@@ -0,0 +1,37 @@
@media all{ /* 通用設定 */
html { background: #FFE; color: #800000; } /* 基本網頁背景樣式 */
a:link { color: #00E; } /* 正常連結樣式 */
a:hover { color: #D00; } /* hover時連結樣式 */
a:visited { color: #00E; } /* 已拜訪連結樣式 */
a.qlink { text-decoration: none; } /* 引用用連結樣式 */
small { font-size: 0.8em; } /* 小字樣式(eg.[以預覽圖顯示]) */
hr { clear: left; } /* 分隔線樣式 */
img { border: 0; } /* 圖片顯示樣式 */
 
.threadpost { } /* 討論串首篇樣式 */
.reply { display: table; margin: 0.5ex 1em 0 1em; background: #F0E0D6; } /* 討論串回應樣式 */
.name { color: #117743; font-weight: bold; } /* 文章張貼者名稱樣式 */
.admin_cap { color: #0000FF; } /* 管理員キャップ樣式設定 */
.img { float: left; margin: 1ex 2ex; } /* 討論串圖片顯示樣式 */
.title { color: #CC1105; font-size: 1.125em; font-weight: bold; } /* 討論串標題樣式 */
.nor { font-weight: normal; } /* Trip取消粗體用 */
.quote { margin: 1em 2em; } /* 討論串內文縮排樣式 */
 
#footer { text-align: center; clear: both; } /* 頁尾樣式 */
}
 
@media screen{ /* 標準顯示(一般顯示器)模式附加規則 */
}
 
@media handheld{ /* 手持設備(手機,PDA等)附加規則 */
html { max-width: 320px; margin: auto; font-size: 9px; } /* 320px為多數PDA的顯示寬度 */
 
.img { margin: 0.5ex 0.5ex; max-width: 125px; } /* 討論串圖片顯示樣式 */
.reply { clear: left; margin: 0.5ex 0 0 0; } /* 討論串回應樣式 */
.quote { margin: 1ex 1ex; } /* 討論串內文縮排樣式 */
}
 
@media print{ /* 列印,預覽列印附加規則 */
html { background: #FFF; color: #000; } /* 網頁改成白底黑字,節省彩色列印成本 */
}
New file
/release/Modules-PIO-v4/mod_archiver/mod_archiver.php
@@ -0,0 +1,108 @@
<?php
/*
mod_archiver : Pixmicat! Archiver 靜態庫存頁面(精華區)生成
by: scribe
*/
 
class mod_archiver{
var $ARCHIVE_ROOT;
 
function mod_archiver(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_archiver'); // 向系統登記模組專屬獨立頁面
 
$this->ARCHIVE_ROOT = './archives/'; // 生成靜態庫存頁面之存放位置
}
 
/* Get the name of module */
function getModuleName(){
return 'mod_archiver : Pixmicat! Archiver 靜態庫存頁面(精華區)生成';
}
 
/* Get the module version infomation */
function getModuleVersionInfo(){
return 'Pixmicat! Archiver Module v070425';
}
 
function ModulePage(){
$res = isset($_GET['res']) ? $_GET['res'] : 0; // 欲生成靜態庫存頁面之討論串編號
 
if(!$res || file_exists($this->ARCHIVE_ROOT.$res.'.xml')){
echo('No argument or the archive already existed.'); // 參數不對或XML檔案已存在
}else{
$this->GenerateArchive($res); // 生成靜態庫存頁面
echo 'FINISH.';
}
}
 
function autoHookAdminList(&$modFunc, $post, $isres){
global $PMS;
extract($post);
if(!$isres) $modFunc .= '[<a href="'.$PMS->getModulePageURL('mod_archiver').'&amp;res='.$no.'">存</a>]';
}
 
/* 取出討論串結構並製成XML結構 */
function GenerateArchive($res){
global $PIO, $FileIO;
$aryNO = $aryNAME = $aryDATE = $arySUBJECT = $aryCOMMENT = $aryIMAGE = array(); // 討論串結構陣列
 
/* 第一部份:先製成討論串結構陣列 */
$tid = $PIO->fetchPostList($res); // 取得特定討論串之編號結構
$post = $PIO->fetchPosts($tid); // 取出資料
$post_count = count($post);
if($post_count==0){ echo 'Not found.'; break; }
for($i = 0; $i < $post_count; $i++){
list($imgw,$imgh,$no,$now,$name,$sub,$com,$ext,$tim) = array($post[$i]['imgw'], $post[$i]['imgh'], $post[$i]['no'], $post[$i]['now'], $post[$i]['name'], $post[$i]['sub'], $post[$i]['com'], $post[$i]['ext'], $post[$i]['tim']);
$name = preg_replace('/(◆.{10})/', '<span class="nor">$1</span>', $name); // Trip取消粗體
$aryNO[] = $no; $aryNAME[] = $name; $aryDATE[] = $now; $arySUBJECT[] = $sub; $aryCOMMENT[] = $com; // 置入陣列
if($FileIO->imageExists($tim.$ext)){ // 有貼圖
$size = (int)($FileIO->getImageFilesize($tim.$ext) / 1024);
$aryIMAGE[] = array($size, $imgw.'x'.$imgh, $ext, $tim);
}else $aryIMAGE[] = '';
}
 
/* 第二部份:生成XML結構 */
$tmp_c = '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="archivestyle.xsl"?>
<threads no="'.$aryNO[0].'">
<meta creator="'.$this->getModuleVersionInfo().'" />
<name>'.$aryNAME[0].'</name>
<date>'.$aryDATE[0].'</date>
<subject>'.$arySUBJECT[0].'</subject>
<comment>'.$aryCOMMENT[0].'</comment>
';
if($aryIMAGE[0]) $tmp_c .= ' <image kbyte="'.$aryIMAGE[0][0].'" scale="'.$aryIMAGE[0][1].'" ext="'.$aryIMAGE[0][2].'">'.$aryIMAGE[0][3].'</image>';
else $tmp_c .= ' <image kbyte="" scale="" ext=""></image>';
for($p = 1; $p < $post_count; $p++){
$tmp_c .= '
<reply no="'.$aryNO[$p].'">
<name>'.$aryNAME[$p].'</name>
<date>'.$aryDATE[$p].'</date>
<subject>'.$arySUBJECT[$p].'</subject>
<comment>'.$aryCOMMENT[$p].'</comment>
';
if($aryIMAGE[$p]) $tmp_c .= ' <image kbyte="'.$aryIMAGE[$p][0].'" scale="'.$aryIMAGE[$p][1].'" ext="'.$aryIMAGE[$p][2].'">'.$aryIMAGE[$p][3].'</image>';
else $tmp_c .= ' <image kbyte="" scale="" ext=""></image>';
$tmp_c .= '
</reply>';
}
$tmp_c .= '
</threads>';
 
/* 第三部份:儲存檔案 */
$fp = fopen($this->ARCHIVE_ROOT.$res.'.xml', 'w');
stream_set_write_buffer($fp, 0); // 立刻寫入不用緩衝
fwrite($fp, $tmp_c); // 寫入XML結構
fclose($fp);
// 另開新資料夾保存圖片
$nfolder = $this->ARCHIVE_ROOT.$res.'_files/'; // 保存圖檔資料夾
if(!is_dir($nfolder)){ mkdir($nfolder); chmod($nfolder, 0777); } // 建立存放資料夾
for($n = 0; $n < $post_count; $n++){
if($aryIMAGE[$n]){
if($FileIO->imageExists($aryIMAGE[$n][3].$aryIMAGE[$n][2])) copy($FileIO->getImageURL($aryIMAGE[$n][3].$aryIMAGE[$n][2], true), $nfolder.$aryIMAGE[$n][3].$aryIMAGE[$n][2]); // 原圖
if($FileIO->imageExists($aryIMAGE[$n][3].'s.jpg')) copy($FileIO->getImageURL($aryIMAGE[$n][3].'s.jpg', true), $nfolder.$aryIMAGE[$n][3].'s.jpg'); // 縮圖
}
}
}
}
?>
New file

Property changes:

Name: svn:keywords
+ Id Date Author

/release/Modules-PIO-v4/mod_captcha/mod_captcha.php
@@ -0,0 +1,135 @@
<?php
/*
mod_captcha.php
 
原始概念來自於各技術討論區,將一大堆想法混合實做而成。
暫時需要使用者開啟JavaScript才可以啟動。
 
最主要基礎是此頁內容:
http://jmhoule314.blogspot.com/2006/05/easy-php-captcha-tutorial-today-im.html
加上回應的Kris Knigga修改的成果。
 
實作法:
利用<script src="xxx.php"></script>來嵌入CAPTCHA,內容有驗證表格、隱藏表格和圖像連結
讀取時先生成CAPTCHA文字並產生MD5碼 (ex: 5beac5b0f75b633d732c1617f42f0590)
利用即時生成的CAPTCHA文字造出暫存的png檔案,並以md5為檔名。
(必要時生成的文字可以加入偽資訊以防止OCR程式)
 
回傳:
<input type="text" name="5beac5b0f75b633d732c1617f42f0590" />
<input type="hidden" name="pmd5" value="5beac5b0f75b633d732c1617f42f0590" />
<img src="mod_captcha.php?5beac5b0f75b633d732c1617f42f0590.png" />
 
當mod_captcha.php被要求到圖片時,印出圖片同時刪除圖片,生存週期極短。
 
使用者看圖片,在5beac5b0f75b633d732c1617f42f0590此格填入在圖片上看到的字。
送出表單後,依["pmd5"]的內容"5beac5b0f75b633d732c1617f42f0590"得知有此變數,
讀取["5beac5b0f75b633d732c1617f42f0590"]變數值並加以產生MD5對照,
假如一樣,便是成功。 (基本上變成MD5後誰也不知道明碼是啥,包括程式本身,明碼只寫在圖片上)
 
 
TODO:
- Script 每次讀取就製作圖檔,即使在不必要時候 (ex: 搜尋、後端、系統資訊),應修正
- 回應時無法插入 <tr>,因為 XHTML 模式沒有 tbody (忠實呈現原始碼內容,但一般模式則會自動增加)
*/
 
class mod_captcha{
var $SELF, $CAPTCHA_TMPDIR, $CAPTCHA_WIDTH, $CAPTCHA_HEIGHT, $CAPTCHA_LENGTH, $CAPTCHA_GAP, $CAPTCHA_TEXTY, $CAPTCHA_FONTFACE, $CAPTCHA_ECOUNT;
var $LANG_CAPTCHA, $LANG_ENTERWORD, $LANG_CAPTCHA_ALT, $LANG_WORDERROR;
 
function mod_captcha(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_captcha'); // Register ModulePage
$this->SELF = $PMS->getModulePageURL('mod_captcha'); // Self Location
$this->CAPTCHA_TMPDIR = './tmp/'; // 圖片暫存資料夾
$this->CAPTCHA_WIDTH = 150; // 圖片寬
$this->CAPTCHA_HEIGHT = 25; // 圖片高
$this->CAPTCHA_LENGTH = 6; // 明碼字數
$this->CAPTCHA_GAP = 20; // 明碼字元間隔
$this->CAPTCHA_TEXTY = 20; // 字元直向位置
$this->CAPTCHA_FONTFACE = array('arial.ttf'); // 使用之 TrueType 字型 (可隨機挑選)
$this->CAPTCHA_ECOUNT = 2; // 圖片混淆用橢圓個數
 
$this->LANG_CAPTCHA = '發文驗證碼'; // Captcha:
$this->LANG_ENTERWORD = '<small>(請輸入你在圖中看到的文字)</small>'; // Please enter the words you saw
$this->LANG_CAPTCHA_ALT = 'CAPTCHA 驗證碼圖像'; // CAPTCHA Image
$this->LANG_WORDERROR = '您輸入的驗證碼錯誤!'; // The words you sent is error.
}
 
function getModuleName(){
return 'mod_captcha';
}
 
function getModuleVersionInfo(){
return 'CAPTCHA 驗證圖像機制 v070608';
}
 
/* 在頁面附加 CAPTCHA 圖像和功能 */
function autoHookHead(&$head){
$head .= '<!--script type="text/javascript" src="module/jquery-latest.pack.js"></script-->
<script type="text/javascript" src="'.$this->SELF.'"></script>'."\n";
}
 
/* 在接收到送出要求後馬上檢查明暗碼是否符合 */
function autoHookRegistBegin(&$name, &$email, &$sub, &$com, $upfileInfo, $accessInfo, $POST){
$MD5code = $POST['pmd5'];
if(md5(strtoupper($POST[$MD5code])) !== $MD5code) error($this->LANG_WORDERROR); // 大小寫不分檢查
}
 
function ModulePage(){
$imgFile = isset($_GET['f']) ? $_GET['f'] : ''; // 驗證圖像名稱
if($imgFile){
if(file_exists($this->CAPTCHA_TMPDIR.$imgFile)) $this->OutputImage($imgFile); // 如果是要求圖檔便輸出圖檔
}else{
$this->OutputCAPTCHA(); // 生成CAPTCHA圖像並輸出Script文字
}
}
 
/* 生成CAPTCHA圖像、明碼、暗碼及內嵌用Script */
function OutputCAPTCHA(){
// 隨機生成明碼、暗碼
$byteTable = Array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'); // 明碼定義陣列
$LCode = ''; // 明碼
for($i = 0; $i < $this->CAPTCHA_LENGTH; $i++) $LCode .= $byteTable[rand(0, count($byteTable) - 1)]; // 隨機抽碼
$DCode = md5($LCode); // 暗碼 (明碼的MD5)
 
// 生成暫存圖像
$captcha = ImageCreateTrueColor($this->CAPTCHA_WIDTH, $this->CAPTCHA_HEIGHT);
$randcolR = rand(100, 230); $randcolG = rand(100, 230); $randcolB = rand(100, 230); // 隨機色碼值
$backColor = ImageColorAllocate($captcha, $randcolR, $randcolG, $randcolB); // 背景色
ImageFill($captcha, 0, 0, $backColor); // 填入背景色
$txtColor = ImageColorAllocate($captcha, $randcolR - 40, $randcolG - 40, $randcolB - 40); // 文字色
$rndFontCount = count($this->CAPTCHA_FONTFACE); // 隨機字型數目
 
// 打入文字
for($p = 0; $p < $this->CAPTCHA_LENGTH; $p++){
// 設定旋轉角度 (左旋或右旋)
if(rand(1, 2)==1) $degree = rand(0, 25);
else $degree = rand(335, 360);
// 圖層, 字型大小, 旋轉角度, X軸, Y軸, 字色, 字型, 印出文字
ImageTTFText($captcha, rand(14, 16), $degree, ($p + 1) * $this->CAPTCHA_GAP, $this->CAPTCHA_TEXTY, $txtColor, $this->CAPTCHA_FONTFACE[rand(0, $rndFontCount - 1)], substr($LCode, $p, 1)); // 印出單個字元
}
 
// 混淆用 (畫橢圓)
for($n = 0; $n < $this->CAPTCHA_ECOUNT; $n++){
ImageEllipse($captcha, rand(1, $this->CAPTCHA_WIDTH), rand(1, $this->CAPTCHA_HEIGHT), rand(50, 100), rand(12, 25), $txtColor);
ImageEllipse($captcha, rand(1, $this->CAPTCHA_WIDTH), rand(1, $this->CAPTCHA_HEIGHT), rand(50, 100), rand(12, 25), $backColor);
}
 
// 輸出圖像
ImagePNG($captcha, $this->CAPTCHA_TMPDIR.$DCode.'.png');
ImageDestroy($captcha);
 
// 輸出Script
echo 'jQuery(function($){ $("td.Form_bg:last").parent().after("<tr><td class=\"Form_bg\"><b>'.$this->LANG_CAPTCHA.'</b></td><td><input type=\"hidden\" name=\"pmd5\" value=\"'.$DCode.'\" /><img src=\"'.$this->SELF.'&amp;f='.$DCode.'.png\" alt=\"'.$this->LANG_CAPTCHA_ALT.'\" /><br /><input type=\"text\" name=\"'.$DCode.'\" />'.$this->LANG_ENTERWORD.'</td></tr>") });';
}
 
/* 應要求取出圖檔印出,同時刪除暫存圖檔 */
function OutputImage($imgsrc){
$imgsrc = $this->CAPTCHA_TMPDIR.$imgsrc; // 圖檔完整路徑
header('Content-Type: image/png'); // 設定檔頭
readfile($imgsrc);
unlink($imgsrc);
}
}
?>
New file
/release/Modules-PIO-v4/mod_threadlist/mod_threadlist.php
@@ -0,0 +1,88 @@
<?php
/*
mod_threadlist : 討論串列表
By: scribe
*/
 
class mod_threadlist{
var $THREADLIST_NUMBER;
 
function mod_threadlist(){
global $PMS;
$PMS->hookModuleMethod('ModulePage', 'mod_threadlist'); // 向系統登記模組專屬獨立頁面
 
$this->THREADLIST_NUMBER = 50; // 一頁顯示列表個數
}
 
/* Get the name of module */
function getModuleName(){
return 'mod_threadlist : 討論串列表';
}
 
/* Get the module version infomation */
function getModuleVersionInfo(){
return 'Pixmicat! Thread List Module v070214';
}
 
/* 自動掛載:頂部連結列 */
function autoHookToplink(&$linkbar){
global $PMS;
$linkbar .= '[<a href="'.$PMS->getModulePageURL('mod_threadlist').'">主題列表</a>]'."\n";
}
 
/* 模組獨立頁面 */
function ModulePage(){
global $PMS, $PIO, $FileIO;
 
$thisPage = $PMS->getModulePageURL('mod_threadlist'); // 基底位置
$dat = ''; // HTML Buffer
$listMax = $PIO->threadCount(); // 討論串總筆數
$pageMax = ceil($listMax / $this->THREADLIST_NUMBER) - 1; // 分頁最大編號
$page = isset($_GET['page']) ? intval($_GET['page']) : 0; // 目前所在分頁頁數
if($page < 0 || $page > $pageMax) exit('Page out of range.'); // $page 超過範圍
$plist = $PIO->fetchThreadList($this->THREADLIST_NUMBER * $page, $this->THREADLIST_NUMBER, true); // 編號由大到小排序
$post = $PIO->fetchPosts($plist); // 取出資料
$post_count = count($post);
 
head($dat);
$dat .= '<div id="contents">
[<a href="'.PHP_SELF2.'?'.time().'">回到版面</a>]
<div class="bar_reply">列表模式</div>
 
<table align="center" width="97%">
<tr><th>No.</th><th width="50%">標題</th><th>發文者</th><th>回應</th><th>日期</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']);
$dat .= '<tr class="ListRow'.($i % 2 + 1).'_bg"><td>'.$no.'</td><td><a href="'.PHP_SELF.'?res='.$no.'">'.$sub.'</a></td><td>'.$name.'</td><td>'.($PIO->postCount($no) - 1).'</td><td>'.$now.'</td></tr>'."\n";
}
 
$dat .= '</table>
</div>
 
<hr />
 
<div id="page_switch">
<table border="1" style="float: left;"><tr>
';
if($page) $dat .= '<td><a href="'.$thisPage.'&amp;page='.($page - 1).'">上一頁</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.'">'.$i.'</a>] ';
}
$dat .= '</td>';
if($page < $pageMax) $dat .= '<td><a href="'.$thisPage.'&amp;page='.($page + 1).'">下一頁</a></td>';
else $dat .= '<td style="white-space: nowrap;">最後一頁</td>';
$dat .= '
</tr></table>
</div>
 
';
foot($dat);
echo $dat;
}
}
?>

Property changes:

Name: svn:mergeinfo
+ /Modules:313-435

/Modules-PIO-v4