common.php函数详解

 

<?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}>&#x4E0A;&#x4E00;&#x9875;</a>";

        $page < $numofpage && $nextArrow = "<a class=\"pages_next\" href=\"{$url}page={$next}$mao\"{$ajaxurl}>&#x4E0B;&#x4E00;&#x9875;</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\">&#x5230;&#x7B2C;</div><input type=\"text\" size=\"3\" onkeydown=\"javascript: if(event.keyCode==13){var value = parseInt(this.value); $jsString}\"><div class=\"fl\">&#x9875;</div><button onclick=\"javascript:var value = parseInt(this.previousSibling.previousSibling.value); $jsString\">&#x786E;&#x8BA4;</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?', '=', '&amp;', '&', $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('&amp;','&', $string);

    $string =  str_replace(array( '&quot;', '&#039;', '&nbsp;','&#160;'), array('"', "'", ' ',' '), $string);

    $decodeTags && $string = str_replace(array('&lt;', '&gt;','&#61;'),array( '<', '>','='),$string);

    return $string;

}

 

/**

 * 只解析一部分htmlspecialchars功能

 * 替换&,",',= 符号

 * @param $string 待处理字符串

 * @return string 返回处理后字符串

 */

function pwHtmlspecialchars($string,$decodeTags = false) {

    return str_replace(array('&', '"', "'", '='), array('&amp;', '&quot;', '&#039;', '&#61;'), $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  1man,其他为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];

    }

}

 

?>