<?php
defined('P_W') || exit('Forbidden');
define('WIND_VERSION', '8.7,20110913');
define('PW_USERSTATUS_BANUSER', 1); //是否禁言位 (版块禁言)
define('PW_USERSTATUS_CFGFRIEND', 3); //设置朋友位
//define('PW_USERSTATUS_NEWPM', 5); //是否有新短消息
define('PW_USERSTATUS_NEWRP', 6); //是否新回复通知
define('PW_USERSTATUS_PUBLICMAIL', 7); //是否公开邮箱
define('PW_USERSTATUS_RECEIVEMAIL', 8); //是否接受邮件
define('PW_USERSTATUS_SIGNCHANGE', 9); //签名是否需要转化
define('PW_USERSTATUS_SHOWSIGN', 10); //是否开启签名展示功能
define('PW_USERSTATUS_EDITOR', 11); //所见即所得
define('PW_USERSTATUS_USERBINDING', 12); //用户是否有绑定帐号
define('PW_USERSTATUS_SHOWWIDTHCFG', 13); //切换宽、窄版模式
define('PW_USERSTATUS_SHOWSIDEBAR', 14); //侧栏版块列表收缩切换
define('PW_USERSTATUS_BANSIGNATURE', 15);//是否禁止签名
define('PW_USERSTATUS_AUTHMOBILE', 16);//是否手机实名认证
define('PW_USERSTATUS_AUTHALIPAY', 17);//是否支付宝实名认证
define('PW_USERSTATUS_REPLYEMAIL', 18);//回复电子邮件通知
define('PW_USERSTATUS_REPLYSITEEMAIL', 19);//回复站内通知
define('PW_USERSTATUS_NOTICEVPICE', 20);//设置提示音
define('PW_USERSTATUS_AUTHCERTIFICATE', 21);//是否证件实名认证
define ('PW_COLUMN', 'column' ); //查询字段
define ('PW_EXPR', 'expr' ); //查询表达式
define ('PW_ORDERBY', 'orderby' ); //排序
define ('PW_GROUPBY', 'groupby' ); //分组
define ('PW_LIMIT', 'limit' ); //分页
define ('PW_ASC', 'asc' ); //升序
define ('PW_DESC', 'desc' ); //降序
define ('PW_CACHE_MEMCACHE', 'memcache' ); //内存缓存
define ('PW_CACHE_FILECACHE', 'filecache' ); //文件缓存
define ('PW_CACHE_DBCACHE', 'dbcache' ); //数据库缓存
define ('PW_OVERFLOW_NUM',2000000000); //数据溢出大小临界数
define('PW_THREADSPECIALSORT_KMD',50);
define('PW_THREADSPECIALSORT_TOP1',101);
define('PW_THREADSPECIALSORT_TOP2',102);
define('PW_THREADSPECIALSORT_TOP3',103);
//* portal Start*//
define ('PW_PORTAL_MAIN', 'main.htm' ); //可视化结构文件
define ('PW_PORTAL_CONFIG', 'config.htm' ); //可视化配置文件
//* portal end*//
require_once(R_P.'require/security.php');
//请求相关
/**
* 获取客户端IP
*
* @global array $pwServer 全局$_SERVER替代变量
* @global int $db_xforwardip 是否检查代理的ip
* @return string 返回客户端ip地址,获取失败返回"Unknown"
*/
function pwGetIp() {
global $pwServer, $db_xforwardip;
if ($db_xforwardip) {
if ($pwServer['HTTP_X_FORWARDED_FOR'] && $pwServer['REMOTE_ADDR']) {
if (strstr($pwServer['HTTP_X_FORWARDED_FOR'], ',')) {
$x = explode(',', $pwServer['HTTP_X_FORWARDED_FOR']);
$pwServer['HTTP_X_FORWARDED_FOR'] = trim(end($x));
}
if (preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $pwServer['HTTP_X_FORWARDED_FOR'])) {return $pwServer['HTTP_X_FORWARDED_FOR'];}
} elseif ($pwServer['HTTP_CLIENT_IP'] && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $pwServer['HTTP_CLIENT_IP'])) {return $pwServer['HTTP_CLIENT_IP'];}
}
$db_xforwardip = 0;
if (preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $pwServer['REMOTE_ADDR'])) {return $pwServer['REMOTE_ADDR'];}
return 'Unknown';
}
/**
* 从请求中获取$_GET或$_POST变量,并以key为变量名注册为全局变量
*
* @param array|string$keys 单个key或多个key组成的数组,不能为GLOBALS
* @param string $method P|G
* @param int $cvtype 0表示不作处理,1表示用Char_cv处理字符串,2表示强制转换为int //TODO 定为常量
*/
function InitGP($keys, $method = null, $cvtype = 1) {
S::gp($keys, $method, $cvtype);
}
/**
* 从请求中获取$_GET或$_POST变量
*
* @param string $key 键名
* @param string $method P|G
* @return mixed
*/
function GetGP($key, $method = null) {
return S::getGP($key, $method);
}
/**
* 读取指定的$_SERVER变量
*
* @param string|array$keys 环境变量名,可数组或单值
* @return string|array根据参数个数返回指定环境变量值
*/
function GetServer($keys) {
return S::getServer($keys);
}
/**
* 从请求中获取cookie值,先生成cookie前缀,生成前缀方法为
* substr(MD5(db_sitehash),0,5),然后将前缀和cookieName合并。
*
* @param string $cookieName cookie名
* @return string
*/
function GetCookie($cookieName) {
return $_COOKIE[CookiePre() . '_' . $cookieName];
}
//响应和内容处理
/**
* 设置cookie
*
* @global string $db_ckpath
* @global string $db_ckdomain
* @global int $timestamp
* @global array $pwServer
* @param string $cookieName cookie名
* @param string $cookieValue cookie值
* @param int|string$expireTime cookie过期时间,为F表示1年后过期
* @param bool $needPrefix cookie名是否加前缀
* @return bool 是否设置成功
*/
function Cookie($cookieName, $cookieValue, $expireTime = 'F', $needPrefix = true) {
global $db_ckpath, $db_ckdomain, $timestamp, $pwServer;
static $sIsSecure = null;
if ($sIsSecure === null) {
if (!$pwServer['REQUEST_URI'] || ($parsed = @parse_url($pwServer['REQUEST_URI'])) === false) {
$parsed = array();
}
if ($parsed['scheme'] == 'https' || (empty($parsed['scheme']) && ($pwServer['HTTP_SCHEME'] == 'https' || $pwServer['HTTPS'] && strtolower($pwServer['HTTPS']) != 'off'))) {
$sIsSecure = true;
} else {
$sIsSecure = false;
}
}
//判断是否为管理员
if (P_W != 'admincp') {
$cookiePath = !$db_ckpath ? '/' : $db_ckpath;
$cookieDomain = $db_ckdomain;
} else {
$cookiePath = '/';
$cookieDomain = '';
}
$isHttponly = false;
if ($cookieName == 'AdminUser' || $cookieName == 'winduser') {
$agent = strtolower($pwServer['HTTP_USER_AGENT']);
if (!($agent && preg_match('/msie ([0-9]\.[0-9]{1,2})/i', $agent) && strstr($agent, 'mac'))) {
$isHttponly = true;
}
}
$cookieValue = str_replace("=", '', $cookieValue);
strlen($cookieValue) > 512 && $cookieValue = substr($cookieValue, 0, 512);
$needPrefix && $cookieName = CookiePre() . '_' . $cookieName;
if ($expireTime == 'F') {
$expireTime = $timestamp + 31536000;
} elseif ($cookieValue == '' && $expireTime == 0) {return setcookie($cookieName, '', $timestamp - 31536000, $cookiePath, $cookieDomain, $sIsSecure);}
if (PHP_VERSION < 5.2) {
return setcookie($cookieName, $cookieValue, $expireTime, $cookiePath . ($isHttponly ? '; HttpOnly' : ''), $cookieDomain, $sIsSecure);
} else {
return setcookie($cookieName, $cookieValue, $expireTime, $cookiePath, $cookieDomain, $sIsSecure, $isHttponly);
}
}
/**
* 压缩内容,并设置响应头为压缩格式
*
* @global string $db_obstart
* @param string $output 要压缩的内容
* @return string 压缩后的内容
*/
function ObContents($output) {
ob_end_clean();
$getHAE = S::getServer('HTTP_ACCEPT_ENCODING');
if (!headers_sent() && $GLOBALS['db_obstart'] && $getHAE && N_output_zip() != 'ob_gzhandler') {
$encoding = '';
if (strpos($getHAE, 'x-gzip') !== false) {
$encoding = 'x-gzip';
} elseif (strpos($getHAE, 'gzip') !== false) {
$encoding = 'gzip';
}
if ($encoding && function_exists('crc32') && function_exists('gzcompress')) {
header('Content-Encoding: ' . $encoding);
$outputLen = strlen($output);
$outputZip = "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$outputZip .= substr(gzcompress($output, $GLOBALS['db_obstart']), 0, -4);
$outputZip .= @pack('V', crc32($output));
$output = $outputZip . @pack('V', $outputLen);
} else {
ObStart();
}
} else {
ObStart();
}
return $output;
}
/**
* 开启输出缓存
*
* @return bool
*/
function ObStart() {
ObGetMode() == 1 ? ob_start('ob_gzhandler') : ob_start();
}
/**
* 判断输出模式是否为可压缩
*
* @global string $db_obstart
* @return int 1为可压缩
*/
function ObGetMode() {
static $sOutputMode = null;
if ($sOutputMode !== null) {return $sOutputMode;}
$sOutputMode = 0;
if ($GLOBALS['db_obstart'] && function_exists('ob_gzhandler') && N_output_zip() != 'ob_gzhandler' && (!function_exists('ob_get_level') || ob_get_level() < 1)) {
$sOutputMode = 1;
}
return $sOutputMode;
}
/**
* 将输出缓存中的内容刷出,判断webserver 和php的接口类型,当不为apache2handler
* 和apache2filter时, 判断输出缓存输出处理者是否为ob_gzhandler,是则返回,
*
* @param bool $ob 是否使用ob_flush
*/
function N_flush($ob = null) {
if (php_sapi_name() != 'apache2handler' && php_sapi_name() != 'apache2filter') {
if (N_output_zip() == 'ob_gzhandler') {return;}
if ($ob && ob_get_length() !== false && ob_get_status() && !ObGetMode($GLOBALS['db_obstart'])) {
@ob_flush();
}
flush();
}
}
/**
* 判断输出缓存输出处理者
*
* @return string
*/
function N_output_zip() {
static $sOutputHandler = null;
if ($sOutputHandler === null) {
if (@ini_get('zlib.output_compression')) {
$sOutputHandler = 'ob_gzhandler';
} else {
$sOutputHandler = @ini_get('output_handler');
}
}
return $sOutputHandler;
}
/**
* 将输出缓存中的内容以ajax格式输出,并中断程序
*
* @global string $db_charset
*/
function ajax_footer() {
global $db_charset,$db_htmifopen;
if (defined('SHOWLOG')) Error::writeLog();
$output = str_replace(array('<!--<!--<!---->','<!--<!---->','<!---->-->','<!---->','<!-- -->'),'', ob_get_contents());
if (P_W == 'admincp') {
$output = preg_replace(
"/\<form([^\<\>]*)\saction=['|\"]?([^\s\"'\<\>]+)['|\"]?([^\<\>]*)\>/ies",
"FormCheck('\\1','\\2','\\3')",
rtrim($output,'<!--')
);
} else {
//
$output = parseHtmlUrlRewrite($output, $db_htmifopen);
}
header("Content-Type: text/xml;charset=$db_charset");
echo ObContents("<?xml version=\"1.0\" encoding=\"$db_charset\"?><ajax><![CDATA[" . $output . "]]></ajax>");
exit();
}
/**
* 将数组格式化成json格式
*
* @param array $val,array 数组
* @return string 返回json格式数据
*/
function pwJsonEncode($var) {
switch (gettype($var)) {
case 'boolean' :
return $var ? 'true' : 'false';
case 'NULL' :
return 'null';
case 'integer' :
return (int) $var;
case 'double' :
case 'float' :
return (float) $var;
case 'string' :
return '"' . addslashes(str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"';
case 'array' :
if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
$properties = array();
foreach ($var as $name => $value) {
$properties[] = pwJsonEncode(strval($name)) . ':' . pwJsonEncode($value);
}
return '{' . join(',', $properties) . '}';
}
$elements = array_map('pwJsonEncode', $var);
return '[' . join(',', $elements) . ']';
}
return false;
}
//全局业务
/**
* 分析服务器负载
*
* 只针对*unix服务器有效
*
* @param int $maxLoadAvg 负载最大值
* @return boolean 是否超过最大负载
*/
function pwLoadAvg($maxLoadAvg) {
$avgstats = 0;
if (@file_exists('/proc/loadavg')) {
if ($fp = @fopen('/proc/loadavg', 'r')) {
$avgdata = @fread($fp, 6);
@fclose($fp);
list($avgstats) = explode(' ', $avgdata);
}
}
if ($avgstats > $maxLoadAvg) {
return true;
} else {
return false;
}
}
/**
* CC攻击处理
*
* CC攻击会导致服务器负载过大,对相关客户端请求进行处理并日志
*
* @global int $timestamp
* @global string $onlineip
* @global array $pwServer
* @global string $db_xforwardip
* @param int $ccLoad 服务器负载参数
* @return void
*/
function pwDefendCc($ccLoad) {
global $timestamp, $onlineip, $pwServer, $db_xforwardip;
if ($ccLoad == 2 && !empty($pwServer['HTTP_USER_AGENT'])) {
$userAgent = strtolower($pwServer['HTTP_USER_AGENT']);
if (str_replace(array('spider', 'google', 'msn', 'yodao', 'yahoo', 'http:'), '', $userAgent) != $userAgent) {
$ccLoad = 1;
}
}
Cookie('c_stamp', $timestamp, 0);
$ccTimestamp = GetCookie('c_stamp');
$ccCrc32 = substr(md5($ccTimestamp . $pwServer['HTTP_REFERER']), 0, 10);
$ccBanedIp = readover(D_P . 'data/ccbanip.txt');
if ($ccBanedIp && $ipOffset = strpos("$ccBanedIp\n", "\t$onlineip\n")) {
$ccLtt = substr($ccBanedIp, $ipOffset - 10, 10);
$ccCrc32 == $ccLtt && exit('Forbidden, Please turn off CC');
pwCache::writeover(D_P . 'data/ccbanip.txt', str_replace("\n$ccLtt\t$onlineip", '', $ccBanedIp));
}
if (($db_xforwardip || $ccLoad == 2) && ($timestamp - $ccTimestamp > 3 || $timestamp < $ccTimestamp)) {
$isCc = false;
if ($fp = @fopen(D_P . 'data/ccip.txt', 'rb')) {
flock($fp, LOCK_SH);
$size = 27 * 800;
fseek($fp, -$size, SEEK_END);
while (!feof($fp)) {
$value = explode("\t", fgets($fp, 29));
if (trim($value[1]) == $onlineip && $ccCrc32 == $value[0]) {
$isCc = true;
break;
}
}
fclose($fp);
}
if ($isCc) {
echo 'Forbidden, Please Refresh';
$banIps = '';
$ccBanedIp && $banIps .= implode("\n", array_slice(explode("\n", $ccBanedIp), -999));
$banIps .= "\n" . $ccCrc32 . "\t" . $onlineip;
pwCache::writeover(D_P . 'data/ccbanip.txt', $banIps);
exit();
}
@filesize(D_P . 'data/ccip.txt') > 27 * 1000 && P_unlink(D_P . 'data/ccip.txt');
pwCache::writeover(D_P . 'data/ccip.txt', "$ccCrc32\t$onlineip\n", 'ab');
}
}
//全局处理
/**
* 删除多余全局变量,对GLOBAL,POST,COOKIE,FILES加转义
* 多余的全局变量,会对站点安全构成威胁.需要保留的变量在$allowed中说明
*
*/
function pwInitGlobals() {
S::filter();
}
/**
* 生成cookie前缀
*
* @global string $cookiepre 全局cookie前缀
* @global string $db_sitehash db hash值
* @return string 返回cookie前缀
*/
function CookiePre() {
return ($GLOBALS['db_cookiepre']) ? $GLOBALS['db_cookiepre'] : substr(md5($GLOBALS['db_sitehash']), 0, 5);
}
//文件处理
/**
* 删除文件
*
* @param string $fileName 文件绝对路径
* @return bool 如果删除成功,返回true
*/
function P_unlink($fileName) {
return @unlink(S::escapePath($fileName));
}
/**
* 读取文件
*
* @param string $fileName 文件绝对路径
* @param string $method 读取模式
* @return string 返回文件内容
*/
function readover($fileName, $method = 'rb') {
$fileName = S::escapePath($fileName);
$data = '';
if ($handle = @fopen($fileName, $method)) {
flock($handle, LOCK_SH);
$data = @fread($handle, filesize($fileName));
fclose($handle);
}
return $data;
}
/**
* 写文件
*
* @param string $fileName 文件绝对路径
* @param string $data 数据
* @param string $method 读写模式
* @param bool $ifLock 是否锁文件
* @param bool $ifCheckPath 是否检查文件名中的“..”
* @param bool $ifChmod 是否将文件属性改为可读写
* @return bool 是否写入成功 :注意rb+创建新文件均返回的false,请用wb+
*/
function writeover($fileName, $data, $method = 'rb+', $ifLock = true, $ifCheckPath = true, $ifChmod = true) {
$fileName = S::escapePath($fileName, $ifCheckPath);
touch($fileName);
$handle = fopen($fileName, $method);
$ifLock && flock($handle, LOCK_EX);
$writeCheck = fwrite($handle, $data);
$method == 'rb+' && ftruncate($handle, strlen($data));
fclose($handle);
$ifChmod && @chmod($fileName, 0777);
return $writeCheck;
}
/**
* 服务器时间校正后的文件修改时间
*
* @global string $db_cvtime
* @param string $file 文件路径
* @return int 返回修改时间
*/
function pwFilemtime($file) {
return file_exists($file) ? intval(filemtime($file) + $GLOBALS['db_cvtime'] * 60) : 0;
}
//字符串处理
/**
* 加密、解密字符串,通过一个和私密的key按位异或运算得到加、解密字符串
*
* @global string $db_hash
* @global array $pwServer
* @param $string 待处理字符串
* @param $action 操作,ENCODE|DECODE
* @return string 返回加密后的字符串
*/
function StrCode($string, $action = 'ENCODE') {
$action != 'ENCODE' && $string = base64_decode($string);
$code = '';
$key = substr(md5($GLOBALS['pwServer']['HTTP_USER_AGENT'] . $GLOBALS['db_hash']), 8, 18);
$keyLen = strlen($key);
$strLen = strlen($string);
//这里用到按位异或的算法进行加密。
for ($i = 0; $i < $strLen; $i++) {
$k = $i % $keyLen;
$code .= $string[$i] ^ $key[$k];
}
return ($action != 'DECODE' ? base64_encode($code) : $code);
}
/**
* 截断字符串
*
* @global string $db_charset
* @param string $content 内容
* @param int $length 截取字节数
* @param string $add 是否带省略号,Y|N
* @return string 返回截取的字符串
*/
function substrs($content, $length, $add = 'Y') {
if (strlen($content) > $length) {
if ($GLOBALS['db_charset'] != 'utf-8') {
$cutStr = '';
for ($i = 0; $i < $length - 1; $i++) {
$cutStr .= ord($content[$i]) > 127 ? $content[$i] . $content[++$i] : $content[$i];
}
$i < $length && ord($content[$i]) <= 127 && $cutStr .= $content[$i];
return $cutStr . ($add == 'Y' ? ' ..' : '');
}
return utf8_trim(substr($content, 0, $length)) . ($add == 'Y' ? ' ..' : '');
}
return $content;
}
/**
* utf8字符串整齐化
*
* @param string $str 待格式化字符串
* @return string 返回格式化后的字符串
*/
function utf8_trim($str) {
$hex = '';
$len = strlen($str) - 1;
for ($i = $len; $i >= 0; $i -= 1) {
$ch = ord($str[$i]);
$hex .= " $ch";
if (($ch & 128) == 0 || ($ch & 192) == 192) {return substr($str, 0, $i);}
}
return $str . $hex;
}
/**
* 获取随机字符串
*
* @param int $length 字符串长度
* @return string 返回获得的随机字符串
*/
function randstr($length) {
return substr(md5(num_rand($length)), mt_rand(0, 32 - $length), $length);
}
/**
* 获取随机数
*
* @param int $length 随机数字个数
* @return string 返回随机数字
*/
function num_rand($length) {
mt_srand((double) microtime() * 1000000);
$randVal = mt_rand(1, 9);
for ($i = 1; $i < $length; $i++) {
$randVal .= mt_rand(0, 9);
}
return $randVal;
}
/**
* 从目标$ array数组中找出$allowKeys 中存在的key,并返回key及其对应的value。
* @param array $array 待过滤的数组
* @param array $allowKeys 符合条件的参考数组
* @return array 符合条件的数组
*/
function getAllowKeysFromArray($array, $allowKeys) {
if (!is_array($array) || !is_array($allowKeys)) return array();
$data = array();
foreach ($array as $key => $value) {
in_array($key, $allowKeys) && $data[$key] = $value;
}
return $data;
}
/**
* 变量导出为字符串,支持string,array,boolean,NULL,integer,double,float这几种类型。
*
* @param mixed $input 变量
* @param string $indent 缩进,默认为''。
* @return string 返回整理后的字符串,如果是不识别的变量类型,返回null。
*/
function pw_var_export($input, $indent = '') {
switch (gettype($input)) {
case 'string' :
return "'" . str_replace(array("\\", "'"), array("\\\\", "\'"), $input) . "'";
case 'array' :
$output = "array(\r\n";
foreach ($input as $key => $value) {
$output .= $indent . "\t" . pw_var_export($key, $indent . "\t") . ' => ' . pw_var_export($value, $indent . "\t");
$output .= ",\r\n";
}
$output .= $indent . ')';
return $output;
case 'boolean' :
return $input ? 'true' : 'false';
case 'NULL' :
return 'NULL';
case 'integer' :
case 'double' :
case 'float' :
return "'" . (string) $input . "'";
}
return 'NULL';
}
/**
* 编码转换
*
* @uses Chinese
* @param string $str 内容字符串
* @param string $toEncoding 新编码
* @param string $fromEncoding 原编码
* @param bool $ifMb 是否使用mb函数
* @return string 编码后的字符串
*/
function pwConvert($str, $toEncoding, $fromEncoding, $ifMb = true) {
if (strtolower($toEncoding) == strtolower($fromEncoding)) {return $str;}
is_object($str) && $str = get_object_vars($str);//fixed: object can't convert, by alacner 2010/09/15
if (is_array($str)) {
foreach ($str as $key => $value) {
is_object($value) && $value = get_object_vars($value);
$str[$key] = pwConvert($value, $toEncoding, $fromEncoding, $ifMb);
}
return $str;
} else {
if (function_exists('mb_convert_encoding') && $ifMb) {
return mb_convert_encoding($str, $toEncoding, $fromEncoding);
} else {
static $sConvertor = null;
!$toEncoding && $toEncoding = 'GBK';
!$fromEncoding && $fromEncoding = 'GBK';
if (!isset($sConvertor) && !is_object($sConvertor)) {
L::loadClass('Chinese', 'utility/lang', false);
$sConvertor = new Chinese();
}
return $sConvertor->Convert($str, $fromEncoding, $toEncoding, !$ifMb);
}
}
}
//数组处理
/**
* 值是否在数组中,等同于in_array().
*
* @param $value 值
* @param $stack 数组
* @return bool 如果数组中存在,返回true
*/
function CkInArray($value, $stack) {
return S::inArray($value, $stack);
}
//日期处理
/**
* 格式化时间戳为日期字符串
*
* @global string $db_datefm
* @global string $db_timedf
* @global string $_datefm
* @global string $_timedf
* @param int $timestamp 时间戳
* @param string $format 日期格式
* @return string 返回日期字符串
*/
function get_date($timestamp, $format = null) {
static $sDefaultFormat = null, $sOffset = null;
if (!isset($sOffset)) {
global $db_datefm, $db_timedf, $_datefm, $_timedf;
$sDefaultFormat = $_datefm ? $_datefm : $db_datefm;
if ($_timedf && $_timedf != '111') {
$sOffset = $_timedf * 3600;
} elseif ($db_timedf && $db_timedf != '111') {
$sOffset = $db_timedf * 3600;
} else {
$sOffset = 0;
}
}
empty($format) && $format = $sDefaultFormat;
return gmdate($format, $timestamp + $sOffset);
}
/**
* 日期字符串转为时间戳
*
* @global string $db_timedf
* @param string $dateString 日期字符串
* @return int 返回转换后的时间戳
*/
function PwStrtoTime($dateString) {
global $db_timedf;
return function_exists('date_default_timezone_set') ? strtotime($dateString) - $db_timedf * 3600 : strtotime($dateString);
}
//附件业务
/**
* 获取附件url
*
* @global string $attachdir
* @global string $attachpath
* @global string $db_ftpweb
* @global string $attach_url
* @param string $relativePath 附件相对地址
* @param string|null$type 附件获取范围
* @param string|null$isThumb 是否是缩略图
* @return mixed 返回福建的url
*/
function geturl($relativePath, $type = null, $isThumb = null) {
global $attachdir, $attachpath, $db_ftpweb, $attach_url;
if ($isThumb) {
if (file_exists($attachdir . '/thumb/' . $relativePath)) {
return array($attachpath . '/thumb/' . $relativePath, 'Local');
} elseif (file_exists($attachdir . '/' . $relativePath)) {
return array($attachpath . '/' . $relativePath, 'Local');
} elseif ($db_ftpweb) {
$relativePath = 'thumb/' . $relativePath;
}
}
if (file_exists($attachdir . '/' . $relativePath)) {return array($attachpath . '/' . $relativePath, 'Local');}
if ($db_ftpweb && !$attach_url || $type == 'lf') {return array($db_ftpweb . '/' . $relativePath, 'Ftp');}
if (!$db_ftpweb && !is_array($attach_url)) {return array($attach_url . '/' . $relativePath, 'att');}
if (!$db_ftpweb && count($attach_url) == 1) {return array($attach_url[0] . '/' . $relativePath, 'att');}
if ($type == 'show') {return ($db_ftpweb || $attach_url) ? 'imgurl' : 'nopic';}
if ($db_ftpweb && $fp = @fopen($db_ftpweb . '/' . $relativePath, 'rb')) {
@fclose($fp);
return array($db_ftpweb . '/' . $relativePath, 'Ftp');
}
if (!empty($attach_url)) {
foreach ($attach_url as $value) {
if ($value != $db_ftpweb && ($fp = @fopen($value . '/' . $relativePath, 'rb'))) {
@fclose($fp);
return array($value . '/' . $relativePath, 'att');
}
}
}
return false;
}
//帖子业务
/**
* 剔除WindCode,通过正则过滤掉windcode
*
* @param string $text 目标字符串
* @return string 返回处理后的字符串
*/
function stripWindCode($text) {
$pattern = array();
if (strpos($text, "[post]") !== false && strpos($text, "[/post]") !== false) {
$pattern[] = "/\[post\].+?\[\/post\]/is";
}
if (strpos($text, "[img]") !== false && strpos($text, "[/img]") !== false) {
$pattern[] = "/\[img\].+?\[\/img\]/is";
}
if (strpos($text, "[hide=") !== false && strpos($text, "[/hide]") !== false) {
$pattern[] = "/\[hide=.+?\].+?\[\/hide\]/is";
}
if (strpos($text, "[sell") !== false && strpos($text, "[/sell]") !== false) {
$pattern[] = "/\[sell=.+?\].+?\[\/sell\]/is";
}
$pattern[] = "/\[[a-zA-Z]+[^]]*?\]/is";
$pattern[] = "/\[\/[a-zA-Z]*[^]]\]/is";
$text = preg_replace($pattern, '', $text);
return trim($text);
}
//帖子业务,表名处理
/**
* 获取帖子分表表名
*
* @global array $db_tlist
* @param int $tid 帖子id
* @return string 返回帖子分表表名,默认为"pw_tmsgs".
*/
function GetTtable($tid) {
global $db_tlist;
if ($db_tlist && is_array($db_tlist)) {
foreach ($db_tlist as $key => $value) {
if ($key > 0 && $tid > $value[1]) {return 'pw_tmsgs' . (int) $key;}
}
}
return 'pw_tmsgs';
}
/**
* 获取回帖分表表名
*
* @global array $db_plist
* @global DB $db
* @param int|string$postTableId 回复分表id,为N则自动取
* @param int $tid 帖子id
* @return string 返回回帖分表表名,默认"pw_posts".
*/
function GetPtable($postTableId, $tid = null) {
if ($GLOBALS['db_plist'] && is_array($plistdb = $GLOBALS['db_plist'])) {
if ($postTableId == 'N' && !empty($tid)) {
$postTableId = $GLOBALS['db']->get_value('SELECT ptable FROM pw_threads WHERE tid=' . S::sqlEscape($tid, false));
}
if ((int) $postTableId > 0 && array_key_exists($postTableId, $plistdb)) {return 'pw_posts' . $postTableId;}
}
return 'pw_posts';
}
/**
* 获取团购分表
*
* @global string $db_pcids
* @param int $pcid 团购id
* @return string 返回团购分表,默认为pw_pcvalue+团购id
*/
function GetPcatetable($pcid) {
global $db_pcids;
$pcid = (int) $pcid;
if ($pcid > 0 && trim($db_pcids, ',')) {
if (strpos("," . $db_pcids . ",", "," . $pcid . ",") !== false) {return 'pw_pcvalue' . $pcid;}
}
Showmsg('undefined_action');
}
/**
* 获取分类信息分表
*
* @global string $db_modelids
* @param int $modelid 分类信息id
* @return string 返回分类信息分表,默认pw_topicvalue+分类信息id
*/
function GetTopcitable($modelid) {
global $db_modelids;
$modelid = (int) $modelid;
if ($modelid > 0 && trim($db_modelids, ',')) {
if (strpos("," . $db_modelids . ",", "," . $modelid . ",") !== false) {return 'pw_topicvalue' . $modelid;}
}
Showmsg('undefined_action');
}
/**
* 根据活动子分类ID获取存放其数据的数据库表名
* @param int $actmid 活动子分类ID actmid
* @param bool $checkTableExists 是否检查数据库表存在
* @param bool $isUserDefinedField 是否为用户自定义(非默认)的字段
* @return string 返回数据库表名,默认pw_activitydefaultvalue。
*/
function getActivityValueTableNameByActmid($actmid = '', $checkTableExists = 1, $isUserDefinedField = 1) {
global $db_actmids;
if ($actmid && $isUserDefinedField) { //用户自定义的字段
$actmid = (int) $actmid;
if (!$checkTableExists || ($actmid > 0 && trim($db_actmids, ',') && strpos("," . $db_actmids . ",", "," . $actmid . ",") !== false)) {return 'pw_activityvalue' . $actmid;}
Showmsg('undefined_action');
} else { //默认字段
return 'pw_activitydefaultvalue';
}
}
//版块业务
/**
* 当前登录用户版块管理权限
*
* @global string $gp_gptype
* @global int $winduid
* @global int $groupid
* @global int $fid
* @global DB $db
* @param string $isBM 用户是否为版主
* @param string $rightKey 指定要获取的权限名
* @param integer $fid 版块FID
* @return mixed 返回指定权限值
*/
function pwRights($isBM = false, $rightKey = '', $fid = false) {
static $sForumRights = null;
if ($GLOBALS['gp_gptype'] != 'system' && $GLOBALS['gp_gptype'] != 'special') return false;
$uid = (int) $GLOBALS['winduid'];
$gid = (int) $GLOBALS['groupid'];
$fid === false && $fid = (int) $GLOBALS['fid'];
if (empty($uid) || empty($gid) || empty($fid)) return false;
if (!isset($sForumRights[$fid])) {
$sForumRights[$fid] = $forumRight = array();
$isUser = false;
$pwSQL = 'uid=' . S::sqlEscape($uid, false) . 'AND fid=' . S::sqlEscape($fid, false) . "AND gid='0'";
if ($isBM && $gid != 5) { //获取版主权限
$pwSQL .= " OR uid='0' AND fid=" . S::sqlEscape($fid, false) . "AND gid IN ('5'," . S::sqlEscape($gid, false) . ") OR uid='0' AND fid='0' AND gid='5'";
} else {
$pwSQL .= " OR uid='0' AND fid=" . S::sqlEscape($fid, false) . "AND gid=" . S::sqlEscape($gid, false);
}
$query = $GLOBALS['db']->query("SELECT uid,fid,gid,rkey,rvalue FROM pw_permission WHERE ($pwSQL) AND type='systemforum' ORDER BY uid DESC,fid");
while ($rt = $GLOBALS['db']->fetch_array($query)) {
if ($rt['uid'] == $uid) { //用户个人权限
$sForumRights[$fid][$rt['rkey']] = $rt['rvalue'];
$isUser = true;
} elseif ($isUser) { //取得个人权限,结束
break;
} elseif ($isBM && $rt['gid'] && $gid != $rt['gid']) { //版主权限
$forumRight[$rt['rkey']] = $rt['rvalue'];
} else {
$sForumRights[$fid][$rt['rkey']] = $rt['rvalue'];
}
}
if (!$isUser) {
empty($sForumRights[$fid]) && ($GLOBALS['SYSTEM']['superright'] || $isBM && $gid == 5) && $sForumRights[$fid] = $GLOBALS['SYSTEM'];
if ($forumRight) { //版主权限加权
foreach ($forumRight as $key => $value) {
$sForumRights[$fid][$key] < $value && $sForumRights[$fid][$key] = $value;
}
}
}
}
return empty($rightKey) ? $sForumRights[$fid] : $sForumRights[$fid][$rightKey];
}
/**
* //TODO 使用难度很高
* $status 右移$b-1位,然后和$getv按位与。
* @param $status
* @param $b
* @param $getv
*/
function getstatus($status, $b, $getv = 1) {
return $status >> --$b & $getv;
}
/**
* 是否是创始人
*
* @global array $manager
* @param string $name 用户帐号
* @return bool 返回true 或者false
*/
function isGM($name) {
global $manager;
return S::inArray($name, $manager);
}
/**
* 判断用户所在用户组对版块的管理权限
*
* @param string $name 用户名
* @param bool $isBM 是否为版主
* @param string $type 例如:$pwSystem权限,deltpcs编辑权限
* @return bool 返回true 或者false
*/
function userSystemRight($name, $isBM, $type) {
$isGM = isGM($name);
$pwSystem = pwRights($isBM);
if ($isGM || $pwSystem[$type]) return true;
return false;
}
/**
* 获取用户信息
*
* @global DB $db
* @param int $uid 用户uid
* @return array 返回用户数据信息
*/
function getUserByUid($uid) {
$uid = S::int($uid);
if ($uid < 1) return false;
if (perf::checkMemcache()){
$_cacheService = Perf::getCacheService();
$detail = $_cacheService->get('member_all_uid_' . $uid);
if ($detail && in_array(SCR, array('index', 'read', 'thread', 'post'))){
$_singleRight = $_cacheService->get('member_singleright_uid_' . $uid);
$detail = ($_singleRight === false) ? false : (array)$detail + (array)$_singleRight;
}
if ($detail){
return $detail && $detail['groupid'] != 0 && isset($detail['md.uid']) ? $detail : false;
}
$cache = perf::gatherCache('pw_members');
if (in_array(SCR, array('index', 'read', 'thread', 'post'))){
$detail = $cache->getMembersAndMemberDataAndSingleRightByUserId($uid);
} else {
$detail = $cache->getAllByUserId($uid, true, true);
}
return $detail && $detail['groupid'] != 0 && isset($detail['md.uid']) ? $detail : false;
}else {
global $db;
$sqladd = $sqltab = '';
if (in_array(SCR, array('index', 'read', 'thread', 'post'))) {
$sqladd = (SCR == 'post') ? ',md.postcheck,sr.visit,sr.post,sr.reply' : (SCR == 'read' ? ',sr.visit,sr.reply' : ',sr.visit');
$sqltab = "LEFT JOIN pw_singleright sr ON m.uid=sr.uid";
}
$detail = $db->get_one("SELECT m.uid,m.username,m.password,m.safecv,m.email,m.bday,m.oicq,m.groupid,m.memberid,m.groups,m.icon,m.regdate,m.honor,m.timedf,m.style,m.datefm,m.t_num,m.p_num,m.yz,m.newpm,m.userstatus,m.shortcut,m.medals,m.gender,md.lastmsg,md.postnum,md.rvrc,md.money,md.credit,md.currency,md.lastvisit,md.thisvisit,md.onlinetime,md.lastpost,md.todaypost,md.monthpost,md.onlineip,md.uploadtime,md.uploadnum,md.starttime,md.pwdctime,md.monoltime,md.digests,md.f_num,md.creditpop,md.jobnum,md.lastgrab,md.follows,md.fans,md.newfans,md.newreferto,md.newcomment,md.punch,md.bubble,md.newnotice,md.newrequest,md.shafa $sqladd FROM pw_members m LEFT JOIN pw_memberdata md ON m.uid=md.uid $sqltab WHERE m.uid=" . S::sqlEscape($uid) . " AND m.groupid<>'0' AND md.uid IS NOT NULL");
return $detail;
}
}
//积分业务
/**
* 得到积分名称
*
* @global string $db_moneyname
* @global string $db_rvrcname
* @global string $db_creditname
* @global string $db_currencyname
* @global array $_CREDITDB
* @param string $creditType 积分类型
* @return mixed 返回积分名称
*/
function pwCreditNames($creditType = null) {
static $sCreditNames = null;
if (!isset($sCreditNames)) {
$sCreditNames = array('money' => $GLOBALS['db_moneyname'], 'rvrc' => $GLOBALS['db_rvrcname'],
'credit' => $GLOBALS['db_creditname'], 'currency' => $GLOBALS['db_currencyname']);
foreach ($GLOBALS['_CREDITDB'] as $key => $value) {
$sCreditNames[$key] = $value[0];
}
}
return isset($creditType) ? $sCreditNames[$creditType] : $sCreditNames;
}
/**
* 获取积分单位
*
* @global string $db_moneyunit
* @global string $db_rvrcunit
* @global string $db_creditunit
* @global string $db_currencyunit
* @global string $_CREDITDB
* @param string $creditType 积分类型
* @return string 返回积分单位
*/
function pwCreditUnits($creditType = null) {
static $sCreditUnits = null;
if (!isset($sCreditUnits)) {
$sCreditUnits = array('money' => $GLOBALS['db_moneyunit'], 'rvrc' => $GLOBALS['db_rvrcunit'],
'credit' => $GLOBALS['db_creditunit'], 'currency' => $GLOBALS['db_currencyunit']);
foreach ($GLOBALS['_CREDITDB'] as $key => $value) {
$sCreditUnits[$key] = $value[1];
}
}
return isset($creditType) ? $sCreditUnits[$creditType] : $sCreditUnits;
}
//app业务
/**
* 获取用户的唯一字符串,通过md5加密等手段得到。
*
* @global string $db_hash
* @param int $uid 用户uid
* @param string $app app名字
* @param string $add
* @return string 返回用户唯一的字符串。
*/
function appkey($uid, $app = false, $add = false) {
global $db_hash;
return substr(md5($uid . $db_hash . ($add ? $add : '') . ($app ? $app : '')), 8, 18);
}
//用户业务
/**
* 加密密码。
* 通过将agent ,用户密码,用户hash值连接做md5加密后得到。
*
* @global array $pwServer
* @global string $db_hash
* @param string $pwd 密码
* @return string 返回加密后的密码
*/
function PwdCode($pwd) {
return md5($GLOBALS['pwServer']['HTTP_USER_AGENT'] . $pwd . $GLOBALS['db_hash']);
}
/**
* 检查cookie是否过期
*
* @global int $timestamp
* @param array $cookieData cookie数据
* @param string $pwdCode 用户私有信息
* @param string $cookieName cookie名
* @param int $expire 过期秒数
* @param bool $clearCookie 验证错误是否清除cookie
* @param bool $refreshCookie 是否刷新cookie
* @return bool 返回true 或者 false,过期返回true
*/
function SafeCheck($cookieData, $pwdCode, $cookieName = 'AdminUser', $expire = 1800, $clearCookie = true , $refreshCookie = true) {
global $timestamp, $db_cloudgdcode, $keepCloudCaptchaCode,$db_hash;
if (strtolower($cookieName) == 'cknum' && $db_cloudgdcode) {
$cloudCaptchaService = L::loadClass('cloudcaptcha', 'utility/captcha');
list($sessionid, $cloudckfailed) = array(getCookie('cloudcksessionid'), getCookie('cloudckfailed'));
$cloudckfailed && Cookie('cloudckfailed', '', 0);
$delflag = ($refreshCookie && !$keepCloudCaptchaCode) ? null : 0;
if (!$cloudckfailed) return $cloudCaptchaService->checkCode($sessionid, $pwdCode, $delflag);
}
if($timestamp - $cookieData[0] > $expire) {
Cookie($cookieName, '', 0);
return false;
} elseif ($cookieData[2] != md5($pwdCode . $cookieData[0] .getHashSegment())) {
$clearCookie && Cookie($cookieName, '', 0);
return false;
}
if ($refreshCookie) {
$cookieData[0] = $timestamp;
$cookieData[2] = md5($pwdCode . $cookieData[0] .getHashSegment());
Cookie($cookieName, StrCode(implode("\t", $cookieData)));
}
return true;
}
/**
* 检查是否在线
*
* @global int $db_onlinetime
* @global int $timestamp
* @param int $time 时间戳
* @return bool 返回true 或false,在线返回true
*/
function checkOnline($time) {
global $db_onlinetime, $timestamp;
if ($time + $db_onlinetime * 1.5 > $timestamp) {return true;}
return false;
}
//sql安全、组装
/**
* 针对SQL语句的变量进行反斜线过滤,并两边添加单引号
*
* @param mixed $var 过滤前变量
* @param boolean $strip 数据是否经过stripslashes处理
* @param boolean $isArray 变量是否为数组
* @return mixed 过滤后的字符串
*/
function pwEscape($var, $strip = true, $isArray = false) {
return S::sqlEscape($var, $strip, $isArray);
}
/**
* 过滤数组每个元素值,用单引号括起,并用逗号连接
*
* @param array $array 源数组
* @param boolean $strip 数据是否经过stripslashes处理
* @return string 合并后字符串
*/
function pwImplode($array, $strip = true) {
return S::sqlImplode($array, $strip);
}
/**
* 构造单记录数据更新SQL语句
* 格式: field='value',field='value'
*
* @param array $array 更新的数据,格式: array(field1=>'value1',field2=>'value2',field3=>'value3')
* @param bool $strip 数据是否经过stripslashes处理
* @return string SQL语句
*/
function pwSqlSingle($array, $strip = true) {
return S::sqlSingle($array, $strip);
}
/**
* 构造批量数据更新SQL语句
* 格式: ('value1[1]','value1[2]','value1[3]'),('value2[1]','value2[2]','value2[3]')
*
* @param array $array 更新的数据,格式: array(array(value1[1],value1[2],value1[3]),array(value2[1],value2[2],value2[3]))
* @param boolean $strip 数据是否经过stripslashes处理
* @return string SQL语句
*/
function pwSqlMulti($array, $strip = true) {
return S::sqlMulti($array, $strip);
}
/**
* SQL查询中,构造LIMIT语句
*
* @param int $start 开始记录位置
* @param int $num 读取记录数目
* @return string SQL语句
*/
function pwLimit($start, $num = false) {
return S::sqlLimit($start, $num);
}
//路径安全
/**
* 过滤路径中的危险字符
*
* @param string $fileName 文件路径
* @param bool $ifCheck 是否检查“..”
* @return string 返回过滤后的路径
*/
function Pcv($fileName, $ifCheck = true) {
return S::escapePath($fileName, $ifCheck);
}
/**
* 过滤目录路径危险字符
*
* @param string $dir 目录路径
* @return string 返回过滤后的目录路径
*/
function pwDirCv($dir) {
return S::escapeDir($dir);
}
//数据安全
/**
* 过滤数据,防xss攻击
* 去掉特殊符号,\0,",<等。
*
* @param mixed $mixed
* @param bool $isint 是否是数字
* @param bool $istrim 是否需要整齐化
* @return mixed 返回过滤后的数据
*/
function Char_cv($mixed, $isint = false, $istrim = false) {
return S::escapeChar($mixed, $isint, $istrim);
}
/**
* 检查变量
*
* @param mixed $var 待检查的目标变量
* @return mixed 返回检查结果,如果异常,会有消息提示
*/
function CheckVar(&$var) {
S::checkVar($var);
}
/**
* 加转义,通过传递引用进行传递数据
*
* @param mixed $array 待处理的目标数组
*/
function Add_S(&$array) {
S::slashes($array);
}
//语言包
/**
* 获取指定语言包里的某一内容信息
*
* @param string $T 语言包文件名
* @param string $I 指定语言信息
* @param array $L 额外变量
* @param bool $M 是否调用模式下的语言文件
* @return string 返回信息内容
*/
function getLangInfo($T, $I, $L = array(), $M = false) {
static $lang;
if (!isset($lang[$T])) {
if ($M == false) {
require S::escapePath(GetLang($T));
} else {
require S::escapePath(getModeLang($T));
}
}
if (isset($lang[$T][$I])) {
eval('$I="' . addcslashes($lang[$T][$I], '"') . '";');
}
return $I;
}
/**
* 获取积分语言包信息
*
* @param string $T 语言包文件名
* @param string $logtype 类型
* @return string 返回积分语言包信息
*/
function GetCreditLang($T, $logtype) {
static $lang;
if (!isset($lang[$T])) {
require S::escapePath(GetLang($T));
}
$pop = '';
if (isset($lang[$T][$logtype])) {
eval('$pop="' . addcslashes($lang[$T][$logtype], '"') . '";');
}
return $pop;
}
/**
* 获取模式语言包信息
*
* @param string $lang 语言包文件名
* @param string $EXT 语言包文件扩展名
* @return string 返回模式语言包信息
*/
function getModeLang($lang, $EXT = 'php') {
if (defined('M_P') && file_exists(M_P . "lang/lang_$lang.$EXT")) {
return M_P . "lang/lang_$lang.$EXT";
} else {
return GetLang($lang);
}
}
//模板处理
/**
* 获取模式下的模板文件路径
*
* @global string $db_mode
* @global string $db_tplpath
* @param string $template 模板名
* @param string $ext 扩展名
* @return string 返回模板文件路径
*/
function modeEot($template, $EXT = 'htm') {
global $db_mode;
if ($db_mode == 'area') {
return areaEot($template, $EXT);
} else {
$srcTpl = M_P . "template/$template.$EXT";
$tarTpl = D_P . "data/tplcache/" . $db_mode . '_' . $template . '.' . $EXT;
}
if (!file_exists($srcTpl)) {return false;}
if (pwFilemtime($tarTpl) > pwFilemtime($srcTpl)) {
return $tarTpl;
} else {
return modeTemplate($srcTpl, $tarTpl);
}
}
/**
* 更新模板
* @param string $template 模板名
* @param string $EXT 模板扩展名
* @return 返回模板文件名
*/
function areaEot($template, $EXT = 'htm') {
global $alias;
$ifNeedParsePW = 0;
$srcTpl = getAreaChannelTpl($template, $alias, $EXT);
$tarTpl = D_P . "data/tplcache/area_" . $alias . '_' . $template . '.' . $EXT;
if (!file_exists($srcTpl)) return false;
$srcTplTime = pwFilemtime($srcTpl);
if ($template == 'main') {
$ifNeedParsePW = 1;
$configFile = AREA_PATH . $alias . '/'.PW_PORTAL_CONFIG;
$srcTplTime = max(pwFilemtime($configFile), $srcTplTime);
}
if (pwFilemtime($tarTpl) > $srcTplTime) {return $tarTpl;}
if ($ifNeedParsePW) {return areaTemplate($alias, $srcTpl, $tarTpl);}
return modeTemplate($srcTpl, $tarTpl);
}
/**
* 获取区域模板
* @param string $template 模板名
* @param string $channel 频道名
* @param string $EXT 模板后缀名
* @return stirng 返回模板源地址
*/
function getAreaChannelTpl($template, $channel, $EXT = 'htm') {
$srcTpl = S::escapePath(AREA_PATH . "$channel/$template.$EXT");
if (!file_exists($srcTpl)) {
$srcTpl = M_P . 'template/' . $template . '.' . $EXT;
if (!file_exists($srcTpl)) {
$srcTpl = R_P . 'template/wind/' . $template . '.' . $EXT;
if (!file_exists($srcTpl)) {
Showmsg('the template file is not exists');
}
}
}
return $srcTpl;
}
/**
* 获取可视化模板文件
* @param string $sign 模板类型
* @return string 获得模板文件名
*/
function portalEot($sign) {
$GLOBALS['__pwPortalEot'] = 1;
$srcTpl = S::escapePath(PORTAL_PATH . $sign . '/'.PW_PORTAL_MAIN);
$tarTpl = S::escapePath(D_P . "data/tplcache/portal_" . $sign . '.htm');
$configFile = S::escapePath(PORTAL_PATH . $sign . '/'.PW_PORTAL_CONFIG);
$srcTplTime = max(pwFilemtime($configFile), pwFilemtime($srcTpl));
if (pwFilemtime($tarTpl) <= $srcTplTime) {
$portalPageService = L::loadClass('portalpageservice', 'area');
$portalPageService->updateInvokesByModuleConfig($sign);
$file_str = readover($srcTpl);
$parseTemplate = L::loadClass('parsetemplate', 'area');
$file_str = $parseTemplate->execute('other', $sign, $file_str);
pwCache::writeover($tarTpl, $file_str);
}
return $tarTpl;
}
/**
* 输出可视化的内容
* @param string $sign 模块名,如bbsindex,bbsradio
* @param string $_viewer
* @param string $name
* @return string 返回可视化内容
*/
function portalEcho($sign,$_viewer = '',$name='') {
$GLOBALS['__pwPortalEot'] = 1;
global $timestamp;
extract(pwCache::getData(D_P.'data/bbscache/portal_config.php', false));
extract(pwCache::getData(D_P.'data/bbscache/portalhtml_config.php', false));
$staticPath = S::escapePath(PORTAL_PATH . $sign .'/index.html');
$mainFile = S::escapePath(PORTAL_PATH . $sign . '/'.PW_PORTAL_MAIN);
$configFile = S::escapePath(PORTAL_PATH . $sign . '/'.PW_PORTAL_CONFIG);
//$staticFileMTime = pwFilemtime($staticPath);
$staticFileMTime = isset($portalhtml_times[$sign]) ? $portalhtml_times[$sign] : 0;
$tplFileMTime = max(pwFilemtime($mainFile),pwFilemtime($configFile));
if (($tplFileMTime>$staticFileMTime || ($GLOBALS['db_portalstatictime'] && $staticFileMTime<$timestamp-$GLOBALS['db_portalstatictime']*60) || !filesize($staticPath) || $portal_staticstate[$sign])) {
portalStatic($sign,$_viewer,$name);
}
$output .= pwCache::getData($staticPath,false,true);
echo '-->'. $output . '<!--';
}
/**
* 更新可视化页面的静态文件
* @param string $sign 模块名
* @return void
*/
function portalStatic($sign,$_viewer = '',$name='') {
$portalPageService = L::loadClass('portalpageservice', 'area');
if (!$portalPageService->checkPortal($sign)) {
if ($name) {
$portalPageService->addPortalPage(array('sign'=>$sign,'title'=>$name));
} else {
Showmsg('函数portalEcho调用出错,请设置本函数的第三个参数,定义该调用页面的名称');
}
}
$lockName = 'portal_'.$sign;
if (!procLock($lockName)) return false;
$staticPath = S::escapePath(PORTAL_PATH.$sign);
if (!is_dir($staticPath)) return false;
$staticPath = S::escapePath(PORTAL_PATH.$sign.'/index.html');
$otherOutput = ob_get_contents();
ob_clean();
$invokeService = L::loadClass('invokeservice', 'area');
$pageConfig = $invokeService->getEffectPageInvokePieces('other', $sign);
$tplGetData = L::loadClass('tplgetdata', 'area');
$tplGetData->init($pageConfig);
require portalEot($sign);
$temp = ob_get_contents();
$temp = str_replace(array('<!--<!---->',"<!---->\r\n",'<!---->','<!-- -->',"\t\t\t"),'',$temp);
//$success = pwCache::writeover($staticPath, $temp,'wb+');
$success = pwCache::setData($staticPath, $temp,false,'wb+');
procUnLock($lockName);
if (!$success && !$GLOBALS ['db_distribute'] && !pwCache::writeover($staticPath, $temp)&& !is_writable($staticPath)) { //写入二次尝试
ob_end_clean();
ObStart();
Showmsg('请设置'.str_replace(R_P,'',$staticPath).'文件为可写,如果文件不存在,则新建一个空文件');
}
ob_clean();
$portalPageService->setPortalStaticState($sign,0);
updateCacheData();
setPortalHtmlTime($sign);
if ($otherOutput) echo $otherOutput;
}
/**
* 设置可视化页面缓存时间配置
* @param string $sign 模板类型
* @return void
*/
function setPortalHtmlTime($sign) {
global $timestamp;
require_once(R_P.'admin/cache.php');
extract(pwCache::getData(D_P.'data/bbscache/portalhtml_config.php', false));
if (!$portalhtml_times) $portalhtml_times = array();
$portalhtml_times[$sign] = $timestamp;
setConfig('portalhtml_times', $portalhtml_times, null,true);
updatecache_conf('portalhtml', true);
}
/**
* 模板编译,编译类似于<!--#$condition#-->的标签,然后将更新后的模板写入文件
* @param string $srcTpl 待编译模板文件路径,
* @param string $tarTpl 编译后模板文件
* @return string 返回编译后的模板文件名
*/
function modeTemplate($srcTpl, $tarTpl) {
$file_str = readover($srcTpl);
$file_str = tplParsePrint($file_str);
pwCache::writeover($tarTpl, $file_str);
return $tarTpl;
}
/**
* 编译类似于<!--#$condition#-->的标签
* @param string 待编译字符串
* @return string 编译后字符串
*/
function tplParsePrint($string) {
$s = array('/<!--#\s*/', '/\s*#-->/', '/\s*print <<<EOT\s*EOT;\s*/', '/print <<<EOT\s*/', '/\s*EOT;/');
$e = array("\r\nEOT;\r\n", "\r\nprint <<<EOT\r\n", "\r\n", "print <<<EOT\r\n", "\r\nEOT;");
return preg_replace($s, $e, $string);
}
/**
* 更新模板代码
* @param string $alias 模板类型
* @param string $srcTpl 模板路径
* @param string $tarTpl 新模板路径
* @return string 返回新模板路径
*/
function areaTemplate($alias, $srcTpl, $tarTpl) {
$portalPageService = L::loadClass('portalpageservice', 'area');
$portalPageService->updateInvokesByModuleConfig($alias);
$file_str = readover($srcTpl);
$parseTemplate = L::loadClass('parsetemplate', 'area');
$file_str = $parseTemplate->execute('channel', $alias, $file_str);
pwCache::writeover($tarTpl, $file_str);
return $tarTpl;
}
/**
* validate page.验证数据页码,如果当前页码大于总页数,
* 当前页码page等于总页数
* @param int $page 页码
* @param int $pageCount 总页数
* @return int $page 返回正确的页码
*/
function validatePage($page, $pageCount) {
if (empty($page) || $page < 1) {
$page = 1;
} elseif ($page > $pageCount) {
$page = $pageCount;
}
return $page;
}
//模板解析
/**
* 获取模板数据
*
* @param string $invokeName 模板位置名称
* @param string $title 区域标题
* @return string
*/
function pwTplGetData($invokeName, $title) {
$GLOBALS['__pwTplGetData'] = true;
$tplgetdata = L::loadClass('tplgetdata', 'area');
return $tplgetdata->getData($invokeName, $title);
}
/**
* 更新模板缓存数据
* @return void
*/
function updateCacheData() {
if ($GLOBALS['__pwTplGetData']) {
$pw_tplgetdata = L::loadClass('tplgetdata', 'area');
if ($pw_tplgetdata->updates) {
$pw_cachedata = L::loadDB('cachedata', 'area');
$pw_cachedata->updates($pw_tplgetdata->updates);
}
}
}
//分页工具
/**
* 截取hash值部分片段,起始截取位置由$s决定,截取长度为8个字节
* @param int $s
* @return string 返回截取的hash片段。
*/
function getHashSegment($s = 2){
global $db_hash;
$s = intval($s);
$s > 3 && $s = 0;
return substr(md5($db_hash), $s * 8,8);
}
/**
* 生成分页html
*
* @param int $count 总记录数
* @param int $page 当前页
* @param int $numofpage 总页数
* @param string $url 链接URL
* @param int $max 显示页数
* @param string $ajaxCallBack ajax回调方法
* @return string 返回分页代码。
*/
function numofpage($count, $page, $numofpage, $url, $max = null, $ajaxCallBack = '') {
list($count, $page, $numofpage, $max) = array(intval($count), intval($page), intval($numofpage), intval($max));
if ($numofpage <= 1) return '';
($max && $numofpage > $max) && $numofpage = $max;
$ajaxurl = $ajaxCallBack ? " onclick=\"return $ajaxCallBack(this.href);\"" : '';
list($url, $mao) = explode('#', $url);
$mao && $mao = '#' . $mao;
$pages = '<div class="pages">';
$preArrow = $nextArrow = $firstPage = $lastPage = '';
if ($numofpage > 7) {
list($pre, $next) = array($page - 1, $page + 1);
$page > 1 && $preArrow = "<a class=\"pages_pre\" href=\"{$url}page={$pre}$mao\"{$ajaxurl}>上一页</a>";
$page < $numofpage && $nextArrow = "<a class=\"pages_next\" href=\"{$url}page={$next}$mao\"{$ajaxurl}>下一页</a>";
}
$page != 1 && $firstPage = "<a href=\"{$url}page=1$mao\"{$ajaxurl}>" . (($numofpage > 7 && $page - 3 > 1) ? '1...</a>' : '1</a>');
$page != $numofpage && $lastPage = "<a href=\"{$url}page={$numofpage}$mao\"{$ajaxurl}>" . (($numofpage > 7 && $page + 3 < $numofpage) ? "...$numofpage</a>" : "$numofpage</a>");
list($tmpPages, $preFlag, $nextFlag) = array('', 0, 0);
$leftStart = ($numofpage - $page >= 3) ? $page - 2 : $page - (5 - ($numofpage - $page));
for ($i = $leftStart; $i < $page; $i++) {
if ($i <= 1) continue;
$tmpPages .= "<a href=\"{$url}page=$i$mao\"{$ajaxurl}>$i</a>";
$preFlag++;
}
$tmpPages .= "<b>$page</b>";
$nextFlag = 4 - $preFlag + (!$firstPage ? 1 : 0);
if ($page < $numofpage) {
for ($i = $page + 1; $i < $numofpage && $i <= $page + $nextFlag; $i++) {
$tmpPages .= "<a href=\"{$url}page=$i$mao\"{$ajaxurl}>$i</a>";
}
}
$pages .= $preArrow . $firstPage . $tmpPages . $lastPage . $nextArrow;
$jsString = "var page=(value>$numofpage) ? $numofpage : value; " . ($ajaxurl ? "$ajaxCallBack('{$url}page='+page);" : " location='{$url}page='+page+'{$mao}';") . " return false;";
$numofpage > 7 && $pages .= "<div class=\"fl\">到第</div><input type=\"text\" size=\"3\" onkeydown=\"javascript: if(event.keyCode==13){var value = parseInt(this.value); $jsString}\"><div class=\"fl\">页</div><button onclick=\"javascript:var value = parseInt(this.previousSibling.previousSibling.value); $jsString\">确认</button>";
$pages .= '</div>';
return $pages;
}
/**
* 获取友好的时间信息
*
* @global int $timestamp
* @global string $tdtime
* @param int $time 时间戳
* @param int $type 类型
* @return array 返回日期时间数组
*/
function getLastDate($time, $type = 1) {
global $timestamp, $tdtime;
static $timelang = false;
if ($timelang == false) {
$timelang = array('second' => getLangInfo('other', 'second'), 'yesterday' => getLangInfo('other', 'yesterday'),
'hour' => getLangInfo('other', 'hour'), 'minute' => getLangInfo('other', 'minute'),
'qiantian' => getLangInfo('other', 'qiantian'));
}
$decrease = $timestamp - $time;
$thistime = PwStrtoTime(get_date($time, 'Y-m-d'));
$thisyear = PwStrtoTime(get_date($time, 'Y'));
$thistime_without_day = get_date($time, 'H:i');
$yeartime = PwStrtoTime(get_date($timestamp, 'Y'));
$result = get_date($time);
if ($decrease <= 0) {
if ($type == 1) {
return array(get_date($time, 'Y-m-d'), $result);
} else {
return array(get_date($time, 'Y-m-d H:i'), $result);
}
}
if ($thistime == $tdtime) {
if ($type == 1) {
if ($decrease <= 60) {return array($decrease . $timelang['second'], $result);}
if ($decrease <= 3600) {
return array(ceil($decrease / 60) . $timelang['minute'], $result);
} else {
return array(ceil($decrease / 3600) . $timelang['hour'], $result);
}
} else {
return array(get_date($time, 'H:i'), $result);
}
} elseif ($thistime == $tdtime - 86400) {
if ($type == 1) {
return array($timelang['yesterday'] . " " . $thistime_without_day, $result);
} else {
return array(get_date($time, 'm-d H:i'), $result);
}
} elseif ($thistime == $tdtime - 172800) {
if ($type == 1) {
return array($timelang['qiantian'] . " " . $thistime_without_day, $result);
} else {
return array(get_date($time, 'm-d H:i'), $result);
}
} elseif ($thisyear == $yeartime) {
if ($type == 1) {
return array(get_date($time, 'm-d'), $result);
} else {
return array(get_date($time, 'm-d H:i'), $result);
}
} else {
if ($type == 1) {
return array(get_date($time, 'Y-m-d'), $result);
} else {
return array(get_date($time, 'Y-m-d H:i'), $result);
}
}
}
//缓存工厂
/**
* 缓存实例化工厂
*
* @param string $datastore 缓存类型
* @return PW_Memcache|PW_DBCache
*/
function getDatastore($datastore = null) {
global $db_datastore;
$datastore || $datastore = $db_datastore;
switch (strtolower($datastore)) {
case 'memcache' :
$_cache = L::loadClass('Memcache', 'utility');
break;
case 'dbcache' :
$_cache = L::loadClass('DBCache', 'utility');
break;
default :
$_cache = L::loadClass('DBCache', 'utility');
break;
}
return $_cache;
}
//广告业务
/**
* 获取广告数据
*
* @global int $timestamp
* @global string $db_advertdb
* @global string $db_mode
* @global array $_time
* @param string $advKey 广告key
* @param int $fid 版块id
* @param int $lou 楼号
* @param string $scr
* @return array
*/
function pwAdvert($advKey, $fid = 0, $lou = -1, $scr = 0) {
global $timestamp, $db_advertdb, $db_mode, $_time;
if (empty($db_advertdb[$advKey])) return false;
$hours = $_time['hours'] + 1;
$fid || $fid = $GLOBALS['fid'];
$scr || $scr = $GLOBALS['SCR'];
$scr = strtolower($scr);
$lou = (int) $lou;
$tmpAdvert = $db_advertdb[$advKey];
if ($db_advertdb['config'][$advKey] == 'rand') {
shuffle($tmpAdvert);
}
$arrAdvert = array();
$advert = '';
foreach ($tmpAdvert as $key => $value) {
if ($value['stime'] > $timestamp || $value['etime'] < $timestamp || ($value['dtime'] && strpos(",{$value['dtime']},", ",{$hours},") === false) || ($value['mode'] && strpos($value['mode'], $db_mode) === false) || ($value['page'] && (strpos($value['page'], ",$scr,") === false || ($scr == 'read' && $value['page'] == 'thread'))) || ($value['fid'] && $scr != 'index' && strpos(",{$value['fid']},", ",$fid,") === false) || ($value['lou'] && strpos(",{$value['lou']},", ",$lou,") === false)) {
continue;
}
if ((!$value['ddate'] && !$value['dweek']) || ($value['ddate'] && strpos(",{$value['ddate']},", ",{$_time['day']},") !== false) || ($value['dweek'] && strpos(",{$value['dweek']},", ",{$_time['week']},") !== false)) {
$arrAdvert[] = $value['code'];
$advert .= is_array($value['code']) ? $value['code']['code'] : $value['code'];
if ($db_advertdb['config'][$advKey] != 'all') break;
}
}
return array($advert, $arrAdvert);
}
/**
* 生成下拉选单html
*
* @param string $name 下来菜单名字
* @param string $value 选中值
* @param array $options 下拉选单选项数组
* @param string $attrs 属性设置
* @param string $isempty 是否有空选项
* @return string 返回显示下来菜单的html代码
*/
function formSelect($name, $value = null, $options = array(), $attrs = "", $isEmpty = "") {
$html = '<select name="' . $name . '"';
if ($name == "disabled") {
$html .= ' disabled';
}
$html .= ' ' . $attrs . '>';
if ($isEmpty != '') {
$html .= '<option value="">' . $isEmpty . '</option>';
}
foreach ($options as $k => $v) {
$html .= '<option value="' . $k . '"';
if (null !== $value && $k == $value) {
$html .= ' selected="selected"';
}
$html .= '>' . $v . '</option>';
}
$html .= '</select>';
return $html;
}
/**
* SEO设置项
* @param array $_define 默认seo配置
* @param array $_values 对应 targets 的一组值
* @param array $_targets
* @return multitype:string
*/
function seoSettings($_define = array(), $_values = array(), $_default = array(), $_targets = array()) {
global $db_bbsname, $webPageTitle, $metaDescription, $metaKeywords;
if (empty($_targets)) $_targets = array('{wzmc}', '{bkmc}', '{flmc}', '{tzmc}', '{tmc}', '{wzgy}','{pdmc}');
if (empty($_default)) $_default = array('title' => '{tzmc} | {bkmc} - {wzmc}', 'descp' => '{wzgy} | {wzmc}',
'keywords' => '{flmc} , {tzmc} | {bkmc} - {wzmc}');
if (!empty($_define)) {
$cTitle = $_define['title'];
$cDescription = $_define['metaDescription'];
$cKeywords = $_define['metaKeywords'];
}
if (empty($_values[0])) $_values[0] = $db_bbsname;
/* 过滤参数 */
foreach ($_values as $key => $value) {
$_values[$key] = empty($value) ? '' : trim(strip_tags($value));
}
/*设置默认值*/
empty($cTitle) && $cTitle = $_default['title'];
empty($cDescription) && $cDescription = $_default['descp'];
empty($cKeywords) && $cKeywords = $_default['keywords'];
/* 参数处理 */
$webPageTitle = parseSeoTargets($cTitle, $_values, $_targets);
$metaDescription = parseSeoTargets($cDescription, $_values, $_targets);
$metaKeywords = parseSeoTargets($cKeywords, $_values, $_targets);
return array($webPageTitle, $metaDescription, $metaKeywords);
}
/**
* bbs SEO设置项
*
* @param string $_page 当前页面信息
* @param string $_definedSeo 自定义SEO配置信息
* @param string $_fname 板块名称
* @param string $_types 分类信息
* @param string $_subject 帖子名称
* @param string $_tags 标签
* @param string $_summary 摘要
* @return array
*/
function bbsSeoSettings($_page = 'index', $_definedSeo = array(), $_fname = '', $_types = '', $_subject = '', $_tags = '', $_summary = '') {
global $db_bbsname, $db_seoset;
/* 网站名称,板块名称,分类名称,帖子名称,标签名称,文章概要 */
$_tags = substr($_tags, 0, strpos($_tags, "\t"));
$_types = isset($_types) && is_array($_types) ? $_types['name'] : '';
$_replace = array($db_bbsname, $_fname, $_types, $_subject, $_tags, $_summary);
/*获取SEO配置信息 自定义->后台定义->默认*/
empty($_definedSeo['title']) && $_definedSeo['title'] = $db_seoset['title'][$_page];
empty($_definedSeo['metaDescription']) && $_definedSeo['metaDescription'] = $db_seoset['metaDescription'][$_page];
empty($_definedSeo['metaKeywords']) && $_definedSeo['metaKeywords'] = $db_seoset['metaKeywords'][$_page];
return seoSettings($_definedSeo, $_replace, $_default, $_targets);
}
/**
* seo 目标字符串解析,目标字符串替换
* @param string $content
* @param string $_replace
* @param string $_targets
* @return string
*/
function parseSeoTargets($content, $_replace, $_targets) {
$content = str_replace($_targets, $_replace, $content);
$content = trim(preg_replace(array('((\s*\,\s*)+)', '((\s*\|\s*)+)', '((\s*\t\s*)+)'), array(
',', '|', '', ''), $content), ' -,|');
return $content;
}
/**
* 判断用户是否有前台可视化管理权限
* @return bool
*/
function checkPortalRight() {
global $db_portal_admins,$manager,$winduid,$windid;
return S::inArray($windid,$manager) || ($winduid && in_array($winduid, $db_portal_admins));
}
/**
* 特殊字符替换,如\n 替换为<br/>,[b][/b]替换为<b></b>
* @param string $message
*/
function descriplog($message) {
$message = str_replace(array("\n \n \n", "\n",'[b]','[/b]'),array('<br />','<br />','<b>','</b>'),$message);
if (strpos($message,'[/URL]')!==false || strpos($message,'[/url]')!==false) {
$message = preg_replace("/\[url=([^\[]+?)\](.*?)\[\/url\]/is","<a href=\"\\1\" target=\"_blank\">\\2</a>",$message);
}
return $message;
}
/**
* URL处理 ,对url访问地址进行重写
* @param string $html
* @param flag $flag
*/
function parseHtmlUrlRewrite($html, $flag) {
return $flag ? preg_replace("/\<a(\s*[^\>]+\s*)href\=([\"|\']?)((index|cate|thread|read|faq|rss)\.php\?[^\"\'>\s]+\s?)[\"|\']?/ies", "Htm_cv('\\3','<a\\1href=\"')", $html) : $html;
}
/**
* url处理,去掉转义符”\”,得到URL地址
*
* @param string $url url地址
* @param string $tag 待处理的字符串
* @return string 返回处理后的URL地址
*/
function Htm_cv($url, $tag) {
return stripslashes($tag) . urlRewrite($url) . '"';
}
/**
* URL地址重写,对特殊符号进行替换
* @param unknown_type $url
*/
function urlRewrite($url) {
global $db_htmifopen, $db_dir, $db_ext;
if (!$db_htmifopen) return $url;
$tmppos = strpos($url, '#');
$add = $tmppos !== false ? substr($url, $tmppos) : '';
$turl = str_replace(array('.php?', '=', '&', '&', $add), array($db_dir, '-', '-', '-', ''), $url);
$turl != $url && $turl .= $db_ext;
return $turl . $add;
}
/**
* 类似htmlspecialchars_decode函数,因为htmlspecialchars_decode只在PHP 5.1版本及以上才存在
* @param string $string 待处理字符串
* @param string $decodeTags
*/
function pwHtmlspecialchars_decode ($string,$decodeTags = true) {
$string = str_replace('&','&', $string);
$string = str_replace(array( '"', ''', ' ',' '), array('"', "'", ' ',' '), $string);
$decodeTags && $string = str_replace(array('<', '>','='),array( '<', '>','='),$string);
return $string;
}
/**
* 只解析一部分htmlspecialchars功能
* 替换&,",',= 符号
* @param $string 待处理字符串
* @return string 返回处理后字符串
*/
function pwHtmlspecialchars($string,$decodeTags = false) {
return str_replace(array('&', '"', "'", '='), array('&', '"', ''', '='), $string);
}
/**
* 获取强制索引名称
* @param string 索引名称
* @return array 指定索引对应的数据
*/
function getForceIndex($index) {
$indexdb = array('idx_postdate' => 'idx_postdate', 'idx_digest' => 'idx_digest', 'idx_uid_categoryid_modifiedtime' => 'idx_uid_categoryid_modifiedtime', 'idx_tid' => 'idx_tid' , 'idx_fid_ifcheck_specialsort_lastpost'=>'idx_fid_ifcheck_specialsort_lastpost');
return $indexdb[$index];
}
/**
* 初始化数据库连接
* @return resource
*/
function PwNewDB() {
if (!is_object($GLOBALS['db'])) {
global $db, $database, $dbhost, $dbuser, $dbpw, $dbname, $PW, $charset, $pconnect;
require_once S::escapePath(R_P . "require/db_$database.php");
$db = new DB($dbhost, $dbuser, $dbpw, $dbname, $PW, $charset, $pconnect);
}
}
/**
* 判断是否来自手机客户端
* @return bool 返回true 或false
*/
function checkFromWap() {
static $fromMobile = array('nokia','sony','ericsson','motorola','samsung','java','philips','panasonic','ktouch','alcatel','lenovo','iphone','ipod','android','blackberry','meizu','netfront','symbian','ucweb','windowsce','palmsource','opera mini','opera mobi','cldc','midp','wap','mobile','benq', 'haier');
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
foreach ($fromMobile as $v) {
if (strrpos($userAgent,$v) !== false) return true;
}
return false;
}
/**
* 新建文件夹,修改权限777,文件夹下创建index.html,并修改文件权限为777
* @param string 新建文件夹路径
* @return void
*/
function pwCreateFolder($path) {
if (!is_dir($path)) {
pwCreateFolder(dirname($path));
@mkdir($path);
@chmod($path,0777);
@fclose(@fopen($path.'/index.html','w'));
@chmod($path.'/index.html',0777);
}
}
/**
* 获取默认性别
* @param int $gender 1为man,其他为woman
* @return string 返回性别,man 或 women
*/
function getDefaultGender($gender) {
return ($gender == 1) ? 'man' : 'women';
}
//LOADER
/**
* 自动加载基类
* @author Administrator
*
*/
class PW_BaseLoader {
/**
* 加载类 $className
* @param string $className
* @param string $dir
* @param bool $isGetInstance
* @param string $classPrefix
* @return array 返回类的对象数组
*/
function _loadClass($className, $dir = '', $isGetInstance = true, $classPrefix = 'PW_') {
static $classes = array();
$dir = PW_BaseLoader::_formatDir($dir);
$classToken = $isGetInstance ? $className : $dir . $className; //避免重名
if (isset($classes[$classToken])) return $classes[$classToken];
$classes[$classToken] = true; //默认值
$fileDir = R_P . $dir . strtolower($className) . '.class.php';
if (!$isGetInstance) return (@require_once S::escapePath($fileDir)); //未实例化的直接返回
$class = $classPrefix . $className;
if (!class_exists($class)) {
# pack class start
if($GLOBALS['db_classfile_compress']){
$_directory = explode('/',$dir);
if( isset($_directory[1]) && in_array( $_directory[1], array('framework','gather','forum','job','rate','site','user','utility') ) ){
$fileDir = pwPack::classPath($fileDir,$class);
}
}
# pack class end
if (file_exists($fileDir)) require_once S::escapePath($fileDir);
if (!class_exists($class)) { //再次验证是否存在class
$GLOBALS['className'] = $class;
Showmsg('load_class_error');
}
}
$classes[$classToken] = &new $class(); //实例化
return $classes[$classToken];
}
/**
* 导入文件basedb.php
*/
function _loadBaseDB() {
if (!class_exists('BaseDB')) require_once (R_P . 'lib/base/basedb.php');
}
/**
* 格式化目录路径
* @param string $dir 待处理目录路径
*/
function _formatDir($dir) {
$dir = trim($dir);
if ($dir) $dir = trim($dir, "\\/") . '/';
return $dir;
}
}
/**
* 加载类(包括通用类和通用配置文件的加载)
*/
class L extends PW_BaseLoader {
/**
* 类文件的加载入口
*
* @param string $className 类的名称
* @param string $dir 目录:末尾不需要'/'
* @param boolean $isGetInstance 是否实例化
* @return mixed
*/
function loadClass($className, $dir = '', $isGetInstance = true) {
return parent::_loadClass($className, 'lib/' . parent::_formatDir($dir), $isGetInstance);
}
/**
* dao文件加载入口
*
* @param string $dbName 数据库名称
* @param string $dir 目录
* @return mixed
*/
function loadDB($dbName, $dir = '') {
parent::_loadBaseDB();
return L::loadClass($dbName . 'DB', parent::_formatDir($dir) . 'db');
}
/**
* 加载配置文件
* @param mixed $var 数据参数
* @param string $file 配置文件名
* @param string $dir 配置文件目录
* @param bool $isStatic
* @return array 返回配置数据数组
*/
function config($var = null, $file = 'config', $dir = 'bbscache', $isStatic = true) {
static $conf = array();
$key = $dir . '_' . $file;
if (!isset($conf[$key])) {
if (file_exists(D_P . "data/$dir/{$file}.php")) {
//* include S::escapePath(D_P . "data/$dir/{$file}.php");
//* $arr = get_defined_vars();
//* unset($arr['dir'], $arr['file'], $arr['var'], $arr['key'], $arr['conf'], $arr['isStatic']);
$arr = pwCache::getData(S::escapePath(D_P . "data/$dir/{$file}.php"), false);
if ($isStatic !== true) {return $var ? $arr[$var] : $arr;}
$conf[$key] = $arr;
} else {
$conf[$key] = array();
}
}
return $var ? $conf[$key][$var] : $conf[$key];
}
/**
* 加载配置文件dbreg.php
* @param mixed $var
*/
function reg($var = null) {
return L::config($var, 'dbreg');
}
/**
* 风格选择
* @param mixed $var 配置参数
* @param mixed $skinco 风格配置
* @param bool $ispath 是否为路径
*/
function style($var = null, $skinco = null, $ispath = false) {
global $skin, $db_styledb, $db_defaultstyle;
$skinco && isset($db_styledb[$skinco]) && $skin = $skinco;
if ($skin && strpos($skin, '..') === false && file_exists(D_P . "data/style/$skin.php") && is_array($db_styledb[$skin]) && $db_styledb[$skin][1] == '1') {
} elseif ($db_defaultstyle && strpos($db_defaultstyle, '..') === false && file_exists(D_P . "data/style/$db_defaultstyle.php")) {
$skin = $db_defaultstyle;
} else {
$skin = 'wind';
}
return !$ispath ? L::config($var, $skin, 'style') : S::escapePath(D_P . 'data/style/' . $skin . '.php');
}
/**
* 加载fid_*.php 配置文件
* @param Int $fid 用于选择不同的配置文件
*/
function forum($fid) {
return L::config('foruminfo', 'fid_' . intval($fid), 'forums', false);
}
}
/**
* 消息类
* @author Administrator
*
*/
class M {
/*
* 发送单人/多人消息
*/
/**
* Enter description here ...
* @param int $userId 用户编号
* @param string $usernames 用户名
* @param array $messageInfo array('create_uid','create_username','title','content','expand') 消息体数组
* @param string $shieldType 屏蔽类型
* @param string $typeName 站内信类型,默认为短消息,可选评论/留言/评价
* @return int 发送成功的messageId
*
*/
function sendMessage($userId, $usernames, $messageInfo, $shieldType = null, $typeName = null) {
if ($shieldType) $usernames = M::_getUnShieldUsers($usernames, $shieldType);
if (!$usernames) return false;
$messageServer = L::loadClass("message", 'message');
$typeName = ($typeName) ? $typeName : 'sms_message';
$typeId = $messageServer->getConst($typeName);
return $messageServer->sendMessage($userId, $usernames, $messageInfo, $typeId);
}
/**
* 发送通知 系统通知/团购通知/活动通知/应用通知
* @param array $usernames 用户名
* @param array $messageInfo 消息内容
* @param array $shieldType 屏蔽类型
* @param string $typeName 站内信类型,默认为短消息,可选评论/留言/评价
* @param int $userId 用户编号
* @return int 发送成功的noticeId
*/
function sendNotice($usernames, $messageInfo, $shieldType = 'notice_website', $typeName = null, $userId = '-1') {
$usernames = M::_getUnShieldUsers($usernames, $shieldType);
if (!$usernames) return false;
$messageServer = L::loadClass("message", 'message');
$typeName = ($typeName) ? $typeName : 'notice_system';
$typeId = $messageServer->getConst($typeName);
return $messageServer->sendNotice($userId, $usernames, $messageInfo, $typeId);
}
/**
* 发送请求 好友请求/群组请求/活动请求/应用请求
* @param int $userId 用户编号
* @param string $usernames 用户名
* @param array $messageInfo 消息体数组
* @param string $shieldType 屏蔽类型
* @param string $typeName 请求类型
* @return int 返回请求成功的请求id号
*/
function sendRequest($userId, $usernames, $messageInfo, $shieldType = 'notice_website', $typeName = null) {
$usernames = M::_getUnShieldUsers($usernames, $shieldType);
if (!$usernames) return false;
$messageServer = L::loadClass("message", 'message');
$typeName = ($typeName) ? $typeName : 'request_friend';
$typeId = $messageServer->getConst($typeName);
return $messageServer->sendRequest($userId, $usernames, $messageInfo, $typeId);
}
/**
* 发送群组消息
* @param int $userId 用户编号
* @param int $groupId 群组编号
* @param array $messageInfo 消息体数组
* @param array $userIds 用户编号数组
* @return int 返回增加成功的消息ID
*/
function sendGroupMessage($userId, $groupId, $messageInfo, $userIds = array()) {
$messageServer = L::loadClass("message", 'message');
return $messageServer->sendGroupMessage($userId, $groupId, $messageInfo, '', $userIds);
}
function ifUnShieldThisType($user, $shieldType) {
$messageServer = L::loadClass("message", 'message');
return $messageServer->getMessageShield($user, $shieldType);
}
/**
* 获取没有屏蔽此类型消息的用户
* @param array $userNames 用户名数组
* @param string $shieldType 屏蔽类型
* @return array 返回没有屏蔽改类型消息的用户数组
*/
function _getUnShieldUsers($userNames, $shieldType) {
if (!$shieldType) return $userNames;
$messageServer = L::loadClass("message", 'message'); /* @var $messageServer PW_Message */
$temp = array();
foreach ($userNames as $user) {
if (!$messageServer->getMessageShieldByUserName($user, $shieldType)) continue;
$temp[] = $user;
}
return $temp;
}
}
/**
* template类构造函数
* @author Administrator
*
*/
class template {
var $bev;
/**
* 构造函数
* @param tmplate $bev
*/
function template($bev = null) {
$this->bev = $bev;
}
/**
* 获得模板路径
* @param string $template 模板名
* @param string $EXT 模板后缀名
* @return string 返回模板路径
*/
function printEot($template, $EXT = 'htm') {
if (($filepath = $this->bev->getpath($template, $EXT)) !== false) {return S::escapePath($filepath);}
exit('Can not find ' . $this->bev->getDefaultDir() . $template . '.' . $EXT . ' file');
}
}
/**
* 错误消息类
* @author Administrator
*
*/
class Error {
/**
* 添加一条错误信息
* @param $errorInfo 错误信息
*/
function addError($errorInfo) {
$pwError = L::loadClass('errors','framework');
$pwError->addError($errorInfo);
}
/**
* 添加一条提醒信息
* @param $logInfo 信息内容
*/
function addLog($errorInfo) {
$pwError = L::loadClass('errors','framework');
$pwError->addLog($errorInfo);
}
/**
* 及时报错
* @param $error 错误信息
*/
function showError($error, $jumpurl = '') {
$pwError = L::loadClass('errors','framework');
$pwError->showError($error,$jumpurl);
}
/**
* 检查是否有错误信息,有的话及时报错
* @param string|null 跳转url地址
*/
function checkError($jumpurl = '') {
$pwError = L::loadClass('errors','framework');
$pwError->checkError($jumpurl);
}
/**
* 记录错误信息
*/
function writeLog() {
$pwError = L::loadClass('errors','framework');
$pwError->writeLog();
}
}
/**
* 结构化查询类库.
* @author Administrator
*
*/
class pwQuery{
/**
* 执行新增操作
* @param string $tableName 数据表名
* @param array $col_names 数据表列名数组
* @return int 返回添加成功的记录id号
*/
function insert($tableName, $col_names){
$GLOBALS['db']->update(pwQuery::insertClause($tableName, $col_names));
$insert_id = $GLOBALS['db']->insert_id();
$insert_id && Perf::gatherQuery ( 'insert', array($tableName), array_merge($col_names,array('insert_id'=>$insert_id)));
return $insert_id;
}
/**
* 执行替换操作
* @param string $tableName 数据表名
* @param array $col_names 数据表列名数组
* @return int 返回受到影响的行数
*/
function replace($tableName, $col_names){
$GLOBALS['db']->update(pwQuery::replaceClause($tableName, $col_names));
return $GLOBALS['db']->affected_rows();
}
/**
* 执行更新操作
* @param string $tableName 数据表名
* @param string $where_statement 查询条件语句,如:fid=:fid and ifcheck=:ifcheck,注意后面部分与字段一致
* @param string $where_conditions 查询条件参数,如array(1,2),与上在的条件语句顺序保持一致
* @param array $col_names
* @param array $expand 扩展条件,可选,说明如下
* $expand = array(
* PW_COLUMN = array('fid','tid'),//需要查询的字段,默认为*,参数为数组
* PW_EXPR = array('count(*) as c','max(tid)'),//特殊的查询,如统计,最大/小值,参数为数组
* PW_ORDERBY = array('postdate'=> PW_ASC,'tid'=>PW_DESC),//排序条件,字段=>升/降形式,参数为数组
* PW_GROUPBY = array('tid'),//分组条件,数组
* PW_LIMIT = array(offset,limit),查询起点数与查询个数
* );
* @return int 返回受影响的行数
*/
function update($tableName, $where_statement = null, $where_conditions = null, $col_names, $expand = null) {
$GLOBALS['db']->update(pwQuery::updateClause($tableName, $where_statement, $where_conditions, $col_names, $expand));
return $GLOBALS['db']->affected_rows();
}
/**
* 执行删除操作
* @param string $tableName 数据表名
* @param string $where_statement 查询条件语句,如:fid=:fid and ifcheck=:ifcheck,注意后面部分与字段一致
* @param string $where_conditions 查询条件参数,如array(1,2),与上在的条件语句顺序保持一致
* @param array $expand 扩展条件,可选,说明如下
* $expand = array(
* PW_COLUMN = array('fid','tid'),//需要查询的字段,默认为*,参数为数组
* PW_EXPR = array('count(*) as c','max(tid)'),//特殊的查询,如统计,最大/小值,参数为数组
* PW_ORDERBY = array('postdate'=> PW_ASC,'tid'=>PW_DESC),//排序条件,字段=>升/降形式,参数为数组
* PW_GROUPBY = array('tid'),//分组条件,数组
* PW_LIMIT = array(offset,limit),查询起点数与查询个数
* );
* @return int 返回受影响的行数
*/
function delete($tableName, $where_statement = null, $where_conditions = null, $expand = null) {
$GLOBALS['db']->update(pwQuery::deleteClause($tableName, $where_statement, $where_conditions, $expand ));
return $GLOBALS['db']->affected_rows();
}
/**
* 构造新增insert语句,仅返回数据新增语句,不执行数据库操作
* @param stirng $tableName 数据表名
* @param array $col_names 字段名称数组
* @return string 返回生成sql语句
*/
function insertClause($tableName, $col_names){
$service = L::loadClass('querybuilder','utility');
return $service->insertClause($tableName, $col_names);
}
/**
* 构造替换replace语句,仅返回数据替换语句,不执行数据库操作
* @param string $tableName 数据表名
* @param array $col_names 字段名称数组
* @return string 返回生成sql语句
*/
function replaceClause($tableName, $col_names){
$service = L::loadClass('querybuilder','utility');
return $service->replaceClause($tableName, $col_names);
}
/**
* 构造更新update语句,仅返回数据更新语句,不执行数据库操作
* @param string $tableName 数据表名
* @param string $where_statement 查询条件语句,如:fid=:fid and ifcheck=:ifcheck,注意后面部分与字段一致
* @param string $where_conditions 查询条件参数,如array(1,2),与上在的条件语句顺序保持一致
* @param array $col_names
* @param array $expand 扩展条件,可选,说明如下
* $expand = array(
* PW_COLUMN = array('fid','tid'),//需要查询的字段,默认为*,参数为数组
* PW_EXPR = array('count(*) as c','max(tid)'),//特殊的查询,如统计,最大/小值,参数为数组
* PW_ORDERBY = array('postdate'=> PW_ASC,'tid'=>PW_DESC),//排序条件,字段=>升/降形式,参数为数组
* PW_GROUPBY = array('tid'),//分组条件,数组
* PW_LIMIT = array(offset,limit),查询起点数与查询个数
* );
* @return string 返回生成sql语句
*/
function updateClause($tableName, $where_statement = null, $where_conditions = null, $col_names, $expand = null) {
$service = L::loadClass('querybuilder','utility');
return $service->updateClause($tableName, $where_statement, $where_conditions, $col_names, $expand);
}
/**
* 构造删除delete语句,仅返回数据删除语句,不执行数据库操作
* @param string $tableName 数据表名
* @param string $where_statement 查询条件语句,如:fid=:fid and ifcheck=:ifcheck,注意后面部分与字段一致
* @param string $where_conditions 查询条件参数,如array(1,2),与上在的条件语句顺序保持一致
* @param array $expand 扩展条件,可选,说明如下
* $expand = array(
* PW_COLUMN = array('fid','tid'),//需要查询的字段,默认为*,参数为数组
* PW_EXPR = array('count(*) as c','max(tid)'),//特殊的查询,如统计,最大/小值,参数为数组
* PW_ORDERBY = array('postdate'=> PW_ASC,'tid'=>PW_DESC),//排序条件,字段=>升/降形式,参数为数组
* PW_GROUPBY = array('tid'),//分组条件,数组
* PW_LIMIT = array(offset,limit),查询起点数与查询个数
* );
* @return string 返回生成sql语句
*/
function deleteClause($tableName, $where_statement = null, $where_conditions = null, $expand = null) {
$service = L::loadClass('querybuilder','utility');
return $service->deleteClause($tableName, $where_statement, $where_conditions, $expand );
}
/**
* 构造查询语句,仅返回数据查询语句,不执行数据库操作
* @param string $tableName 数据表名
* @param string $where_statement 查询条件语句,如:fid=:fid and ifcheck=:ifcheck,注意后面部分与字段一致
* @param string $where_conditions 查询条件参数,如array(1,2),与上在的条件语句顺序保持一致
* @param array $expand 扩展条件,可选,说明如下
* $expand = array(
* PW_COLUMN = array('fid','tid'),//需要查询的字段,默认为*,参数为数组
* PW_EXPR = array('count(*) as c','max(tid)'),//特殊的查询,如统计,最大/小值,参数为数组
* PW_ORDERBY = array('postdate'=> PW_ASC,'tid'=>PW_DESC),//排序条件,字段=>升/降形式,参数为数组
* PW_GROUPBY = array('tid'),//分组条件,数组
* PW_LIMIT = array(offset,limit),查询起点数与查询个数
* );
* @return string 返回生成sql语句
*/
function selectClause($tableName, $where_statement = null, $where_conditions = null, $expand = null) {
$service = L::loadClass('querybuilder','utility');
return $service->selectClause($tableName, $where_statement, $where_conditions, $expand);
}
/**
* 构造通用查询语句,仅返回数据查询语句,不执行数据库操作
* @param string $format 查询语句格式,注意数据表名采用:pw_table的形式,多个表名pw_table1,pw_table2
* @param string $parameters 查询语句变量
* @return string 返回生成sql语句
*/
function buildClause($format, $parameters) {
$service = L::loadClass('querybuilder','utility');
return $service->buildClause($format, $parameters);
}
}
/**
* 全局聚合服务中心
* @author Administrator
*
*/
class Perf {
/**
* 全局缓存聚合
* @param string $cacheName 缓存名称,数据表名称,如pw_threads/pw_members
* @return object 返回该对象的引用
*/
function gatherCache($cacheName){
$gatherCache = L::loadClass ( 'gather', 'gather' );
return $gatherCache->spreadCache ($cacheName);
}
/**
* 全局查询聚合
* @param string $operate 操作字符,如insert/select/update/replace/delete
* @param array $tableNames 数据表列表
* @param array $fields where 条件数组或更新数组
* @param array $expand 扩展数组
*/
function gatherQuery($operate, $tableNames, $fields, $expand = array()){
$gatherQuery = L::loadClass('gather','gather');
return $gatherQuery->spreadQuery($operate, $tableNames, $fields, $expand);
}
/**
* 全局信息聚合
* @param string $gatherName 聚合名称(函数名称)
* @param array $information 聚合信息数组
* @param string $defaultName 聚合文件前缀,默认为general
*/
function gatherInfo($gatherName, $information, $defaultName = 'general'){
$gatherInfo = L::loadClass ( 'gather', 'gather' );
$gatherInfo->spreadInfo($gatherName, $information, $defaultName);
}
/**
* 检查是否开启或安装Memcache
*/
function checkMemcache(){
static $isMemcache = null;
if (! isset ( $isMemcache )) {
$isMemcache = class_exists ( "Memcache" ) && strtolower ( $GLOBALS ['db_datastore'] ) == 'memcache';
}
return $isMemcache;
}
/**
* 加载cacheservic
* @return Ambiguous
*/
function getCacheService(){
return L::loadClass('cacheservice','utility');
}
}
/**
* 全局通用读取缓存路径与写缓存数据服务
* @author Administrator
*/
class pwCache {
/**
* 获取缓存路径函数
* @param string $filePath 文件名称
* @param boolean $isPack 是否可选压缩文件
* @return string 返回缓存文件路径
*/
function getPath($filePath, $isPack = false, $withCache = true) {
if (! $withCache || !$isPack ) {
return $filePath;
}
/**
if( $GLOBALS['db_filecache_to_memcache'] && Perf::checkMemcache() && in_array ( SCR, array ('index', 'read', 'thread' ))){
$_cacheService = perf::gatherCache('pw_filecache');
return $_cacheService->getFileCache($filePath);
}
**/
if ( $GLOBALS['db_cachefile_compress'] && in_array ( SCR, array ('index', 'read', 'thread' ) )) {
return pwPack::cachePath ( $filePath );
}
return $filePath;
}
/**
* 读取文件,同前面的readover();
* @param string $fileName 文件名
* @param string $method 读文件模式
* @return string 返回文件内容
*/
function readover($fileName, $method = 'rb'){
return readover($fileName, $method);
}
/**
* 写文件,同前面的writeover();
* @param string $fileName 文件名
* @param string $data 写入文件的内容
* @param string $method 读写文件模式
* @param bool $ifLock 是否加锁
* @param string $ifCheckPath 是否检查路径
* @param string $ifChmod 是否修改文件权限
* @return Ambigous <boolean, number>
*/
function writeover($fileName, $data, $method = 'rb+', $ifLock = true, $ifCheckPath = true, $ifChmod = true){
return writeover($fileName, $data, $method, $ifLock, $ifCheckPath, $ifChmod);
}
/**
* 从缓存文件中获取数据
* @param string $filePath 文件路径
* @param bool $isRegister 是否注册全局变量
* @param bool $isReadOver 是否读取全部缓存数据
*/
function getData($filePath, $isRegister = true, $isReadOver= false ){
$_service = L::loadClass('cachedistribute','utility');
return $_service->getData($filePath,$isRegister,$isReadOver);
}
/**
* 写缓存通用函数
* @param string $filePath 文件名称
* @param string|array $data 数据
* @param boolean $isBuild 是否需要装组装
* @param string $method 读写模式
* @param boolean $ifLock 是否锁文件
*/
function setData($filePath, $data, $isBuild = false, $method = 'rb+', $ifLock = true) {
$_service = L::loadClass('cachedistribute','utility');
return $_service->setData($filePath, $data, $isBuild , $method, $ifLock);
}
/**
* 删除文件缓存函数
* @param string $filePath 文件名称
*/
function deleteData($filePath) {
$_service = L::loadClass('cachedistribute','utility');
return $_service->deleteData($filePath);
}
}
/**
* 版本文件打包服务
* @author Administrator
*
*/
class pwPack {
/**
* 通用缓存文件获取
* @param string $filePath 缓存文件路径
* @return Ambiguous|Ambigous<string, unknown>
*/
function cachePath($filePath) {
if( !$GLOBALS['db_cachefile_compress'] || !in_array ( SCR, array ('index', 'read', 'thread' ) ) ){
return $filePath;
}
$_packService = pwPack::getPackService ();
return $_packService->loadCachePath ( $filePath );
}
/**
* 通用类库文件获取
* @param string $filePath 文件路径
* @param string $className 类名
* @return Ambiguous|string 返回文件路径
*/
function classPath($filePath, $className) {
if( !$GLOBALS['db_classfile_compress'] || !in_array ( SCR, array ('index', 'read', 'thread' ) ) ){
return $filePath;
}
static $_packClassFile = null;
if (! isset ( $_packClassFile )) {
$_packClassFile = D_P . 'data/package/pack.class.' . SCR . '.php';
if (is_file ( $_packClassFile )) {
(! class_exists ( 'BaseDB' )) && require_once (R_P . 'lib/base/basedb.php');
require_once S::escapePath ( $_packClassFile );
}
}
if ($_packClassFile && class_exists ( $className )) {
return R_P . 'require/returns.php';
}
return $filePath;
}
/**
* 通用类库文件压缩
* @return boolean 压缩成功返回true,否则返回false
*/
function files() {
if( !in_array ( SCR, array ('index', 'read', 'thread' ) ) ){
return false;
}
$_packService = pwPack::getPackService ();
if( $GLOBALS['db_cachefile_compress'] ){
$_packService->packCacheFiles ();
}
return true;
}
/**
* 获取打包服务
* @return Ambigous <NULL, PW_packService>
*/
function getPackService() {
static $packService = null;
if (! isset ( $packService )) {
require_once R_P.'require/packservice.php';
$packService = new PW_packService ();
}
return $packService;
}
}
/**
* 论坛扩展机制
* @author Administrator
*
*/
class pwHook{
/**
* 添加不带返回值的的扩展
* pwHook::runHook('post',array('uid'=>11));
* @param string $hookName hook 名字
* @param array $params 传递参数数组
*/
function runHook($hookName,$params = array()) {
if (!pwHook::checkHook($hookName)) return false;
$pwHook = pwHook::_getHook($hookName);
if ($params) $pwHook->setParams($params);
$pwHook->runHook();
}
/**
* 添加一个带返回值的扩展
* pwHook::runFilter('filteruid',$winduid,array('uid'=>11));
* @param string $hookName hook名字
* @param mixed $result 返回值
* @param array $params 传递参数数组
*/
function runFilter($hookName,$result,$params = array()) {
if (!pwHook::checkHook($hookName)) return $result;
$pwHook = pwHook::_getHook($hookName);
if ($params) $pwHook->setParams($params);
return $pwHook->runFilter($result);
}
/**
* 判断该hook是否开启
* @param string $name 钩子名称
* @return bool
*/
function checkHook($name) {
global $db_hookset;
return isset($db_hookset[$name]) || in_array($name,pwHook::getSystemHooks());
}
/**
* 获得系统钩子
* @return array Array('after_login','after_post','after_reply',);
*/
function getSystemHooks() {
return array(
'after_login',
'after_post',
'after_reply',
);
}
/**
* 获取指定的钩子
* @param string $name 钩子名
* @return Ambigous <>|Ambigous <PW_Hook>
*/
function _getHook($name) {
static $hooks = array();
if (isset($hooks[$name])) return $hooks[$name];
L::loadClass('hook','hook',false);
$hooks[$name] = new PW_Hook($name);
return $hooks[$name];
}
}
?>