pixmicat

Subversion Repositories:
Compare Path: Rev
With Path: Rev
/PMC2Prototype/ @ 373  →  /PMC2Prototype/ @ 374
/PMC2Prototype/lib/lib_core.php
@@ -126,7 +126,7 @@
*/
function PMCCore_loadAction($name){
$load = './action/'.$name.'.php';
if(file_exists($load)){ global $config; $config['ENV.ACTION'] = $name; require($load); }
if(file_exists($load)){ global $config; $config['ENV.ACTION'] = $name; define('ENV_RUNTIME', true); require($load); }
else{ trigger_error(_T('core.cannot_find_action', $name), E_USER_ERROR); }
}
 
@@ -193,19 +193,4 @@
if($isListed){ $baninfo = _T('ip_dnsbl_banned', $isListed); return true; }
return false;
}
 
/**
* 將字串修整成適當格式
*/
function PMCCore_cleanString($str, $IsAdmin=false){
$str = trim($str);
if(get_magic_quotes_gpc()) $str = stripslashes($str);
// 非管理員或管理員自己取消HTML使用:HTML標籤禁用
if(!($IsAdmin && PMCCore_getConfig('CAP.ISHTML'))) $str = preg_replace('/&(#[0-9]+|[a-z]+);/i', "&$1;", htmlspecialchars($str));
else{ // 管理員開啟HTML
$str = str_replace('>', '>', $str); // 先將每個 > 都轉碼
$str = preg_replace('/(<.*?)&gt;/', '$1>', $str); // 如果有<...&gt;則轉回<...>成為正常標籤
}
return $str;
}
?>
/PMC2Prototype/lib/fileio/fileio.normal.php
@@ -14,7 +14,7 @@
 
/* private 藉由檔名分辨圖檔存放位置 */
function _getImagePhysicalPath($imgname){
return (substr($imgname, -5)=='s.jpg' ? $this->thumbPath : $this->imgPath).$imgname;
return (substr($imgname, -5)=='s.jpg' ? $this->thumbPath : $this->imgPath).'/'.$imgname;
}
 
function FileIO($parameter=''){
/PMC2Prototype/resource/xmlhttp.js
@@ -174,6 +174,8 @@
 
function finish(){
alert('OK');
$('postform_main').sendbtn.disabled = false;
Txmlhttp.get(Taction.self+'/show_ajax/1', Trender.show);
}
 
function failed(txt){
/PMC2Prototype/readme.txt
@@ -1,5 +1,5 @@
Pixmicat!2 Development Frame:
Last Modified: 2007/3/5 15:39
Last Modified: 2007/3/24 20:11
 
* XHTML 1.0 Transitional 化 (1.1 太嚴格不合用)
* 從原本的 PHP 小程式變成 Web Application 的概念,架構一個全新框架
@@ -15,12 +15,14 @@
\ \_ comic [範例:comic 版面]
\ \ \_ src
\ \ \_ thumb
\ \_ 1.js [第 1 頁快取]
\ \_ 1.json [第 1 頁快取]
\_ config [設定檔]
\ \_ global.php [全域性設定檔]
\ \_ config.comic.php [範例:comic 版面設定檔]
\_ lib [各函式庫 PIO, FileIO等]
\ \_ pio
\ \_ fileio
\ \_ lang
\_ module [擴充模組]
\_ resource [版面會用到的資源 (*.js, *.css)]
\_ tmp [暫存檔,例如 sizecache.dat]
@@ -82,5 +84,10 @@
不管到哪一頁,只要能確認身分,都可以實施管理。本來想把前後端整合,但是顧及隱密資料及管理方便,
還是另設後端快速檢視資料並管理較妥當
* 歷史問題
雖然能以 iframe + #Hash 方式來模擬,但換個方式想如果導覽功能做的好,
使使用者能順其自然使用導覽功能,就能夠避免掉這個問題
以 iframe + #Hash 方式來模擬,讓嵌在頁框的情況下不自覺使用瀏覽器上下一頁也能正常動作
Hash 意義:
# : 預設值,顯示第一頁
#status : 系統資訊
#search : 搜尋
#page;(Page) : 顯示第幾頁
#reply;(Thread No.);(Page) : 回應模式 (特定討論串第幾頁)
/PMC2Prototype/action/action_ajax.php
@@ -7,13 +7,62 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
// 更新頁面快取
function updateCache(){
global $PIO, $FileIO;
 
$kill_sensor = $old_sensor = false; $arr_kill = $arr_old = array(); // 預測系統啟動旗標及記錄陣列
$threads = $PIO->fetchThreadList(); $threadsCount = count($threads); // 全討論串列表
$threadsPerPage = PMCCore_getConfig('PAGE_DEF'); // 每頁顯示討論串數
$maxThreadsPerPage = $threadsCount > $threadsPerPage ? $threadsPerPage : $threadsCount;
$pageEnd = ceil($threadsCount / $threadsPerPage); // 頁面編號最後值
 
for($i = 1; $i <= $pageEnd; $i++){
$thdat = '{"status":"OK","pageMax":'.$pageEnd.',"pageCurrent":'.$i.',"threads":[';
$arrThreads = array();
for($p = 0; $p < $maxThreadsPerPage; $p++){
// make every threads in one page
$pid = ($i - 1) * $threadsPerPage + $p;
$tid = $PIO->fetchPostList($threads[$pid]); // 取得特定討論串之編號結構
$post = $PIO->fetchPosts($tid); // 取出資料
$arrThreads[] = arrangeThread($post); // 輸出 JSON
if($pid >= $threadsCount - 1) break;
}
$thdat .= implode(',', $arrThreads).']}';
// save i.json
$fp = fopen(PMCCore_getConfig('ENV.FOLDER.BOARD').'/'.$i.'.json', 'w');
stream_set_write_buffer($fp, 0);
fwrite($fp, $thdat);
fclose($fp);
}
}
 
// 輸出討論串 JSON 結構
function arrangeThread($post){
$postCount = count($post);
extract($post[0]);
$dat = '{"no":'.$no.',"now":"'.$now.'","name":"'.$name.'","email":"'.$email.'","sub":"'.$sub.'","com":"'.$com.'","replies":[';
$arrReplies = array();
for($i = 1; $i < $postCount; $i++){
extract($post[$i]);
$arrReplies[] = '{"no":'.$no.',"now":"'.$now.'","name":"'.$name.'","email":"'.$email.'","sub":"'.$sub.'","com":"'.$com.'"}';
}
if(count($arrReplies)) $dat .= implode(',', $arrReplies);
$dat .= ']}';
return $dat;
}
 
function action_ajax($args){
global $PIO, $FileIO;
$PIO = PMCCore_loadLibrary('pio'); $FileIO = PMCCore_loadLibrary('fileio');
switch($args){
case 'remake': // 重新生成快取
updateCache();
echo '{"status":"Finish."}';
break;
case 'status': // 顯示系統資訊
$PIO = PMCCore_loadLibrary('pio'); $FileIO = PMCCore_loadLibrary('fileio');
$pCount = $PIO->postCount(); $imgSize = $FileIO->getImageTotalSize();
$gd_func = 'Fail'; $gd_ver = '(No info)';
if(extension_loaded('gd')){ $gd_func = 'OK'; if($gd_ver = @gd_info()){ $gd_ver = $gd_ver['GD Version']; } }
/PMC2Prototype/action/init.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function init($args){
$PIO = PMCCore_loadLibrary('pio');
$FileIO = PMCCore_loadLibrary('fileio');
/PMC2Prototype/action/show_ajax.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function show_ajax($page){
$baseFolder = PMCCore_getConfig('ENV.FOLDER.BOARD');
if(!$page){ echo '{"status":"Error"}'; return; }
/PMC2Prototype/action/main.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function main($args){
$template = PMCCore_getConfig('TEMPLATE.MAIN');
if(file_exists('./resource/'.$template)){
/PMC2Prototype/action/module.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function module($args){
echo 'Hello, this is action controller "module"';
if($args) var_dump($args);
/PMC2Prototype/action/admin.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function admin($args){
echo 'Hello, this is action controller "admin"';
if($args) var_dump($args);
/PMC2Prototype/action/search_ajax.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function search_ajax($args){
if($_SERVER['REQUEST_METHOD']!='POST'){ echo '{"status":"Error"}'; return; }
echo '<script type="text/javascript">parent.finish();</script>';
/PMC2Prototype/action/threads.php
@@ -7,6 +7,8 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
function threads($args){
echo 'Hello, this is action controller "threads"';
if($args) var_dump($args);
/PMC2Prototype/action/posts_ajax.php
@@ -7,6 +7,21 @@
* @date $Date$
*/
 
if(!defined('ENV_RUNTIME')) exit('ACCESS DENIED');
 
// 修整字元
function cleanString($str, $IsAdmin=false){
$str = trim($str);
if(get_magic_quotes_gpc()) $str = stripslashes($str);
// 非管理員或管理員自己取消HTML使用:HTML標籤禁用
if(!($IsAdmin && PMCCore_getConfig('CAP.ISHTML'))) $str = preg_replace('/&(#[0-9]+|[a-z]+);/i', "&$1;", htmlspecialchars($str));
else{ // 管理員開啟HTML
$str = str_replace('>', '&gt;', $str); // 先將每個 > 都轉碼
$str = preg_replace('/(<.*?)&gt;/', '$1>', $str); // 如果有<...&gt;則轉回<...>成為正常標籤
}
return $str;
}
 
// 回傳錯誤訊息
function error($errtext, $tempfile=''){
if($tempfile){ unlink($tempfile); }
@@ -14,13 +29,128 @@
echo '<script type="text/javascript">parent.failed("'.$errtext.'");</script>';
}
 
// 更新頁面快取
function updateCache(){
/* 生成預覽圖:需要開啟GD模組 (GD 2.0.28以上) */
function thumb($path, $tim, $ext, $in_w, $in_h, $out_w, $out_h){
if(!function_exists('ImageCreateTrueColor')) return; // GD未開或版本太舊
$fname = $path.'/'.$tim.$ext;
$thumb_dir = PMCCore_getConfig('ENV.FOLDER.THUMB').'/'; // 預覽圖儲存目錄位置
 
// 取得原附加圖檔之長寬及類型
switch($ext){
case '.gif': // GIF
$im_in = @ImageCreateFromGIF($fname);
break;
case '.jpg': // JPEG
$im_in = @ImageCreateFromJPEG($fname);
break;
case '.png': // PNG
$im_in = @ImageCreateFromPNG($fname);
break;
case '.bmp': // BMP
$im_in = @ImageCreateFromBMP($fname);
break;
default: return; // GD不支援的類型
}
if(!$im_in) return; // GD不支援的類型
// 生成預覽圖圖像
$im_out = ImageCreateTrueColor($out_w, $out_h);
ImageCopyResampled($im_out, $im_in, 0, 0, 0, 0, $out_w, $out_h, $in_w, $in_h); // 重取樣並縮小
// 儲存預覽圖
ImageJPEG($im_out, $thumb_dir.$tim.'s.jpg', PMCCore_getConfig('THUMB.QUALITY'));
chmod($thumb_dir.$tim.'s.jpg', 0666);
// 刪除暫存之圖檔
ImageDestroy($im_in);
ImageDestroy($im_out);
}
 
/* ImageCreateFromBMP : 讓GD可處理BMP圖檔
此為修改後最適化版本。原出處:http://www.php.net/imagecreate#53879
原作宣告:
*****************************
Function: ImageCreateFromBMP
Author: DHKold
Contact: admin@dhkold.com
Date: The 15th of June 2005
Version: 2.0B
*****************************/
function ImageCreateFromBMP($filename){
// 序章:以二進位模式開啟檔案流
if(!$f1 = fopen($filename, 'rb')) return FALSE;
 
// 第一步:讀取BMP檔頭
$FILE = unpack('vfile_type/Vfile_size/Vreserved/Vbitmap_offset', fread($f1, 14));
if($FILE['file_type']!=19778) return FALSE; // BM
 
// 第二步:讀取BMP資訊
// 僅支援BITMAPINFOHEADER,不支援BITMAPV4HEADER及BITMAPV5HEADER
$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel/Vcompression/Vsize_bitmap/Vhoriz_resolution/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));
$BMP['colors'] = pow(2, $BMP['bits_per_pixel']);
if($BMP['size_bitmap']==0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;
$BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
$BMP['decal'] -= floor($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
$BMP['decal'] = 4 - (4 * $BMP['decal']);
if($BMP['decal']==4) $BMP['decal'] = 0;
 
// 第三步:讀取色盤資訊
$PALETTE = array();
if($BMP['colors'] < 16777216) $PALETTE = unpack('V'.$BMP['colors'], fread($f1, $BMP['colors'] * 4));
 
// 第四步:變換每一個畫素
// 尚不支援32bit, 32bit with BITFIELDS, 8bit with RLE8, 4bit with RLE4等格式
$IMG = fread($f1, $BMP['size_bitmap']);
$VIDE = chr(0);
 
$res = ImageCreateTrueColor($BMP['width'], $BMP['height']);
$P = 0;
$Y = $BMP['height'] - 1;
while($Y >= 0){
$X = 0;
while($X < $BMP['width']){
switch($BMP['bits_per_pixel']){
case 24: $COLOR = unpack('V', substr($IMG, $P, 3).$VIDE); break;
case 16: $COLOR = unpack('n', substr($IMG, $P, 2)); break;
case 8: $COLOR = unpack('n', $VIDE.substr($IMG, $P, 1)); break;
case 4:
$COLOR = unpack('n', $VIDE.substr($IMG, floor($P), 1));
if(($P*2)%2==0) $COLOR[1] = ($COLOR[1] >> 4);
else $COLOR[1] = ($COLOR[1] & 0x0F);
break;
case 1:
$COLOR = unpack('n', $VIDE.substr($IMG, floor($P), 1));
switch(($P * 8) % 8){
case 0: $COLOR[1] = $COLOR[1] >> 7; break;
case 1: $COLOR[1] = ($COLOR[1] & 0x40) >> 6; break;
case 2: $COLOR[1] = ($COLOR[1] & 0x20) >> 5; break;
case 3: $COLOR[1] = ($COLOR[1] & 0x10) >> 4; break;
case 4: $COLOR[1] = ($COLOR[1] & 0x8) >> 3; break;
case 5: $COLOR[1] = ($COLOR[1] & 0x4) >> 2; break;
case 6: $COLOR[1] = ($COLOR[1] & 0x2) >> 1; break;
case 7: $COLOR[1] = ($COLOR[1] & 0x1);
}
break;
default:
return FALSE;
}
if($BMP['bits_per_pixel']!=24) $COLOR[1] = $PALETTE[$COLOR[1]+1];
ImageSetPixel($res, $X, $Y, $COLOR[1]);
$X++;
$P += $BMP['bytes_per_pixel'];
}
$Y--;
$P += $BMP['decal'];
}
 
// 終章:關閉檔案,回傳新圖像
fclose($f1);
return $res;
}
 
function posts_ajax($args){
if($_SERVER['REQUEST_METHOD']=='POST'){ // POST Send
global $PIO, $FileIO;
$up_incomplete = 0; $dest = false;
 
$name = isset($_POST[PMCCore_getConfig('FIELDTRAP.NAME')]) ? $_POST[PMCCore_getConfig('FIELDTRAP.NAME')] : '';
$email = isset($_POST[PMCCore_getConfig('FIELDTRAP.EMAIL')]) ? $_POST[PMCCore_getConfig('FIELDTRAP.EMAIL')] : '';
$sub = isset($_POST[PMCCore_getConfig('FIELDTRAP.SUBJECT')]) ? $_POST[PMCCore_getConfig('FIELDTRAP.SUBJECT')] : '';
@@ -53,8 +183,7 @@
}
 
// 時間
$time = time();
$tim = $time.substr(microtime(), 2, 3);
$time = time(); $tim = $time.substr(microtime(), 2, 3);
 
// 判斷上傳狀態
switch($upfile_status){
@@ -156,11 +285,11 @@
if(strlen($sub) > 100){ error(_T('regist_topictoolong'), $dest); return; }
if(strlen($resto) > 10){ error(_T('regist_longthreadnum'), $dest); return; }
 
$email = PMCCore_cleanString($email); $email = str_replace("\r\n", '', $email);
$sub = PMCCore_cleanString($sub); $sub = str_replace("\r\n", '', $sub);
$resto = PMCCore_cleanString($resto); $resto = str_replace("\r\n", '', $resto);
$email = cleanString($email); $email = str_replace("\r\n", '', $email);
$sub = cleanString($sub); $sub = str_replace("\r\n", '', $sub);
$resto = cleanString($resto); $resto = str_replace("\r\n", '', $resto);
// 名稱修整
$name = PMCCore_cleanString($name);
$name = cleanString($name);
$name = str_replace(_T('admin'), '"'._T('admin').'"', $name);
$name = str_replace(_T('deletor'), '"'._T('deletor').'"', $name);
$name = str_replace(_T('trip_pre'),_T('trip_pre_fake'), $name); // 防止トリップ偽造
@@ -184,7 +313,7 @@
}
// 內文修整
if((strlen($com) > PMCCore_getConfig('COMM_MAX')) && !$is_admin){ error(_T('regist_commenttoolong'), $dest); return; }
$com = PMCCore_cleanString($com, $is_admin); // 引入$is_admin參數是因為當管理員キャップ啟動時,允許管理員依config設定是否使用HTML
$com = cleanString($com, $is_admin); // 引入$is_admin參數是因為當管理員キャップ啟動時,允許管理員依config設定是否使用HTML
$com = str_replace("\r\n", "\n", $com); $com = str_replace("\r", "\n", $com);
if(!PMCCore_getConfig('BR_CHECK') || substr_count($com, "\n") < PMCCore_getConfig('BR_CHECK')) $com = nl2br($com); // 換行字元用<br />代替
$com = str_replace("\n", '', $com); // 若還有\n換行字元則取消換行
@@ -225,6 +354,7 @@
}
}
 
require('./action/action_ajax.php'); // updateCache() needed
// 判斷欲回應的文章是不是剛剛被刪掉了
if($resto){
if($ThreadExistsBefore){ // 欲回應的討論串是否存在 (看逆轉換成功與否)
@@ -268,7 +398,7 @@
setcookie('pwdc', $pwd, time() + 7 * 86400);
setcookie('emailc', $email, time() + 7 * 86400);
 
$imgDir = PMCCore_getConfig('ENV.FOLDER.IMG'); $thumbDir = PMCCore_getConfig('ENV.FOLDER.THUMB');
$imgDir = PMCCore_getConfig('ENV.FOLDER.IMG').'/'; $thumbDir = PMCCore_getConfig('ENV.FOLDER.THUMB').'/';
if($dest && is_file($dest)){
rename($dest, $imgDir.$tim.$ext);
thumb($imgDir, $tim, $ext, $imgW, $imgH, $W, $H); // 使用GD製作縮圖