【discuzX2】/source/function/function_core.php通用核心函数库文件分析

 $message 错误信息
 * @param  $show 是否显示信息
 * @param  $save 是否存入日志
 * @param  $halt 是否中断访问
 */
function system_error($message, $show = true, $save = true, $halt = true) {
	require_once libfile('class/error');
	discuz_error::system_error($message, $show, $save, $halt);
}

/**
 * 更新 session
 * @global  $_G
 * @staticvar boolean $updated
 * @param boolean $force
 * @return boolean
 */
function updatesession($force = false) {

	global $_G;
	static $updated = false;

	if(!$updated) {
		if($_G['uid']) {
			if($_G['cookie']['ulastactivity']) {
				$ulastactivity = authcode($_G['cookie']['ulastactivity'], 'DECODE');
			} else {
				$ulastactivity = getuserprofile('lastactivity');
				dsetcookie('ulastactivity', authcode($ulastactivity, 'ENCODE'), 31536000);
			}
		}
		$discuz = & discuz_core::instance();
		//note 更新在线时间
		$oltimespan = $_G['setting']['oltimespan'];
		$lastolupdate = $discuz->session->var['lastolupdate'];
		if($_G['uid'] && $oltimespan && TIMESTAMP - ($lastolupdate ? $lastolupdate : $ulastactivity) > $oltimespan * 60) {
			DB::query("UPDATE ".DB::table('common_onlinetime')."
				SET total=total+'$oltimespan', thismonth=thismonth+'$oltimespan', lastupdate='" . TIMESTAMP . "'
				WHERE uid='{$_G['uid']}'");
			if(!DB::affected_rows()) {
				DB::insert('common_onlinetime', array(
					'uid' => $_G['uid'],
					'thismonth' => $oltimespan,
					'total' => $oltimespan,
					'lastupdate' => TIMESTAMP,
				));
			}
			$discuz->session->set('lastolupdate', TIMESTAMP);
		}
		foreach($discuz->session->var as $k => $v) {
			if(isset($_G['member'][$k]) && $k != 'lastactivity') {
				$discuz->session->set($k, $_G['member'][$k]);
			}
		}

		foreach($_G['action'] as $k => $v) {
			$discuz->session->set($k, $v);
		}

		$discuz->session->update();

		$updated = true;

		if($_G['uid'] && TIMESTAMP - $ulastactivity > 21600) {
			if($oltimespan && TIMESTAMP - $ulastactivity > 43200) {
				$total = DB::result_first("SELECT total FROM ".DB::table('common_onlinetime')." WHERE uid='$_G[uid]'");
				DB::update('common_member_count', array('oltime' => round(intval($total) / 60)), "uid='$_G[uid]'", 1);
			}
			dsetcookie('ulastactivity', authcode(TIMESTAMP, 'ENCODE'), 31536000);
			DB::update('common_member_status', array('lastip' => $_G['clientip'], 'lastactivity' => TIMESTAMP, 'lastvisit' => TIMESTAMP), "uid='$_G[uid]'", 1);
		}
	}
	return $updated;
}

/**
 * 获取 microtime float 数值,为了兼容php4
 * @return 
 */
function dmicrotime() {
	return array_sum(explode(' ', microtime()));
}

/**
 * 设置全局 $_G 中的变量
 * @global  $_G
 * @param  $key 键
 * @param  $value 值
 * @param  $group 组(准备废弃,尽量不用)
 * @return true
 *
 * @example
 * setglobal('test', 1); // $_G['test'] = 1;
 * setglobal('config/test/abc') = 2; //$_G['config']['test']['abc'] = 2;
 *
 */
function setglobal($key , $value, $group = null) {
	global $_G;
	$k = explode('/', $group === null ? $key : $group.'/'.$key);
	switch (count($k)) {
		case 1: $_G[$k[0]] = $value; break;
		case 2: $_G[$k[0]][$k[1]] = $value; break;
		case 3: $_G[$k[0]][$k[1]][$k[2]] = $value; break;
		case 4: $_G[$k[0]][$k[1]][$k[2]][$k[3]] = $value; break;
		case 5: $_G[$k[0]][$k[1]][$k[2]][$k[3]][$k[4]] =$value; break;
	}
	return true;
}

/**
 * 获取全局变量 $_G 当中的某个数值
 * @global  $_G
 * @param  $key
 * @param  $group 计划废弃的参数,不建议使用
 * @return 
 *
 * $v = getglobal('test'); // $v = $_G['test']
 * $v = getglobal('test/hello/ok');  // $v = $_G['test']['hello']['ok']
 */
function getglobal($key, $group = null) {
	global $_G;
	$k = explode('/', $group === null ? $key : $group.'/'.$key);
	switch (count($k)) {
		case 1: return isset($_G[$k[0]]) ? $_G[$k[0]] : null; break;
		case 2: return isset($_G[$k[0]][$k[1]]) ? $_G[$k[0]][$k[1]] : null; break;
		case 3: return isset($_G[$k[0]][$k[1]][$k[2]]) ? $_G[$k[0]][$k[1]][$k[2]] : null; break;
		case 4: return isset($_G[$k[0]][$k[1]][$k[2]][$k[3]]) ? $_G[$k[0]][$k[1]][$k[2]][$k[3]] : null; break;
		case 5: return isset($_G[$k[0]][$k[1]][$k[2]][$k[3]][$k[4]]) ? $_G[$k[0]][$k[1]][$k[2]][$k[3]][$k[4]] : null; break;
	}
	return null;
}

/**
 * 取出 get, post, cookie 当中的某个变量
 *
 * @param string $k  key 值
 * @param string $type 类型
 * @return mix
 */
function getgpc($k, $type='GP') {
	$type = strtoupper($type);
	switch($type) {
		case 'G': $var = &$_GET; break;
		case 'P': $var = &$_POST; break;
		case 'C': $var = &$_COOKIE; break;
		default:
			if(isset($_GET[$k])) {
				$var = &$_GET;
			} else {
				$var = &$_POST;
			}
			break;
	}

	return isset($var[$k]) ? $var[$k] : NULL;

}

/**
 * 根据uid 获取用户基本数据
 * @staticvar array $users 存放已经获取的用户的信息,避免重复查库
 * @param  $uid
 * @return 
 */
function getuserbyuid($uid) {
	static $users = array();
	if(empty($users[$uid])) {
		$users[$uid] = DB::fetch_first("SELECT * FROM ".DB::table('common_member')." WHERE uid='$uid'");
	}
	return $users[$uid];
}

/**
* 获取当前用户的扩展资料
* @param $field 字段
*/
function getuserprofile($field) {
	global $_G;
	if(isset($_G['member'][$field])) {
		return $_G['member'][$field];
	}
	static $tablefields = array(
		'count'		=> array('extcredits1','extcredits2','extcredits3','extcredits4','extcredits5','extcredits6','extcredits7','extcredits8','friends','posts','threads','digestposts','doings','blogs','albums','sharings','attachsize','views','oltime','todayattachs','todayattachsize'),
		'status'	=> array('regip','lastip','lastvisit','lastactivity','lastpost','lastsendmail','invisible','buyercredit','sellercredit','favtimes','sharetimes','profileprogress'),
		'field_forum'	=> array('publishfeed','customshow','customstatus','medals','sightml','groupterms','authstr','groups','attentiongroup'),
		'field_home'	=> array('videophoto','spacename','spacedescription','domain','addsize','addfriend','menunum','theme','spacecss','blockposition','recentnote','spacenote','privacy','feedfriend','acceptemail','magicgift','stickblogs'),
		'profile'	=> array('realname','gender','birthyear','birthmonth','birthday','constellation','zodiac','telephone','mobile','idcardtype','idcard','address','zipcode','nationality','birthprovince','birthcity','resideprovince','residecity','residedist','residecommunity','residesuite','graduateschool','company','education','occupation','position','revenue','affectivestatus','lookingfor','bloodtype','height','weight','alipay','icq','qq','yahoo','msn','taobao','site','bio','interest','field1','field2','field3','field4','field5','field6','field7','field8'),
		'verify'	=> array('verify1', 'verify2', 'verify3', 'verify4', 'verify5', 'verify6', 'verify7'),
	);
	$profiletable = '';
	foreach($tablefields as $table => $fields) {
		if(in_array($field, $fields)) {
			$profiletable = $table;
			break;
		}
	}
	if($profiletable) {
		$data = array();
		if($_G['uid']) {
			$data = DB::fetch_first("SELECT ".implode(', ', $tablefields[$profiletable])." FROM ".DB::table('common_member_'.$profiletable)." WHERE uid='$_G[uid]'");
		}
		if(!$data) {
			foreach($tablefields[$profiletable] as $k) {
				$data[$k] = '';
			}
		}
		$_G['member'] = array_merge(is_array($_G['member']) ? $_G['member'] : array(), $data);
		return $_G['member'][$field];
	}
}

/**
 * 对字符串或者输入进行 addslashes 操作
 * @param  $string
 * @param  $force
 * @return 
 */
function daddslashes($string, $force = 1) {
	if(is_array($string)) {
		$keys = array_keys($string);
		foreach($keys as $key) {
			$val = $string[$key];
			unset($string[$key]);
			$string[addslashes($key)] = daddslashes($val, $force);
		}
	} else {
		$string = addslashes($string);
	}
	return $string;
}

/**
 * 对字符串进行加密和解密
 * @param  $string
 * @param  $operation  DECODE 解密 | ENCODE  加密
 * @param  $key 当为空的时候,取全局密钥
 * @param  $expiry 有效期,单位秒
 * @return 
 */
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
	$ckey_length = 4;
	$key = md5($key != '' ? $key : getglobal('authkey'));
	$keya = md5(substr($key, 0, 16));
	$keyb = md5(substr($key, 16, 16));
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);

	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);

	$result = '';
	$box = range(0, 255);

	$rndkey = array();
	for($i = 0; $i <= 255; $i++) {
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}

	for($j = $i = 0; $i < 256; $i++) {
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}

	for($a = $j = $i = 0; $i < $string_length; $i++) {
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}

	if($operation == 'DECODE') {
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
			return substr($result, 26);
		} else {
			return '';
		}
	} else {
		return $keyc.str_replace('=', '', base64_encode($result));
	}

}

function fsocketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) {
	$fp = '';
	if(function_exists('fsockopen')) {
		$fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout);
	} elseif(function_exists('pfsockopen')) {
		$fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout);
	} elseif(function_exists('stream_socket_client')) {
		//note php5支持
		$fp = @stream_socket_client($hostname.':'.$port, $errno, $errstr, $timeout);
	}
	return $fp;
}

/**
 * 远程文件文件请求兼容函数
 */
function dfsockopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) {
	require_once libfile('function/filesock');
	return _dfsockopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block);
}

/**
* HTML转义字符
* @param $string - 字符串
* @return 返回转义好的字符串
*/
function dhtmlspecialchars($string) {
	if(is_array($string)) {
		foreach($string as $key => $val) {
			$string[$key] = dhtmlspecialchars($val);
		}
	} else {
		$string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
		if(strpos($string, '&#') !== false) {
			$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
		}
	}
	return $string;
}

/**
 * 退出程序 同 exit 的区别, 对输出数据会进行 重新加工和处理
 * 通常情况下,我们建议使用本函数终止程序, 除非有特别需求
 * @param  $message
 */
function dexit($message = '') {
	echo $message;
	output();
	exit();
}

/**
 * 同 php header函数, 针对 location 跳转做了特殊处理
 * @param  $string
 * @param  $replace
 * @param  $http_response_code
 */
function dheader($string, $replace = true, $http_response_code = 0) {
	//noteX 手机header跳转的统一修改(IN_MOBILE)
	$islocation = substr(strtolower(trim($string)), 0, 8) == 'location';
	if(defined('IN_MOBILE') && strpos($string, 'mobile') === false && $islocation) {
		if (strpos($string, '?') === false) {
			$string = $string.'?mobile=yes';
		} else {
			if(strpos($string, '#') === false) {
				$string = $string.'&mobile=yes';
			} else {
				$str_arr = explode('#', $string);
				$str_arr[0] = $str_arr[0].'&mobile=yes';
				$string = implode('#', $str_arr);
			}
		}
	}
	$string = str_replace(array("\r", "\n"), array('', ''), $string);
	if(empty($http_response_code) || PHP_VERSION < '4.3' ) {
		@header($string, $replace);
	} else {
		@header($string, $replace, $http_response_code);
	}
	if($islocation) {
		exit();
	}
}

/**
* 设置cookie
* @param $var - 变量名
* @param $value - 变量值
* @param $life - 生命期
* @param $prefix - 前缀
*/
function dsetcookie($var, $value = '', $life = 0, $prefix = 1, $httponly = false) {

	global $_G;

	$config = $_G['config']['cookie'];

	$_G['cookie'][$var] = $value;
	$var = ($prefix ? $config['cookiepre'] : '').$var;
	$_COOKIE[$var] = $value;

	if($value == '' || $life < 0) {
		$value = '';
		$life = -1;
	}

	/*手机浏览器设置cookie,强制取消HttpOnly(IN_MOBILE)*/
	if(defined('IN_MOBILE')) {
		$httponly = false;
	}

	$life = $life > 0 ? getglobal('timestamp') + $life : ($life < 0 ? getglobal('timestamp') - 31536000 : 0);
	$path = $httponly && PHP_VERSION < '5.2.0' ? $config['cookiepath'].'; HttpOnly' : $config['cookiepath'];

	$secure = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
	if(PHP_VERSION < '5.2.0') {
		setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure);
	} else {
		setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure, $httponly);
	}
}

/**
 * 获取cookie
 */
function getcookie($key) {
	global $_G;
	return isset($_G['cookie'][$key]) ? $_G['cookie'][$key] : '';
}

/**
 * 获取文件扩展名
 */
function fileext($filename) {
	return addslashes(strtolower(substr(strrchr($filename, '.'), 1, 10)));
}

//note 规则待调整
function formhash($specialadd = '') {
	global $_G;
	$hashadd = defined('IN_ADMINCP') ? 'Only For Discuz! Admin Control Panel' : '';
	return substr(md5(substr($_G['timestamp'], 0, -7).$_G['username'].$_G['uid'].$_G['authkey'].$hashadd.$specialadd), 8, 8);
}

function checkrobot($useragent = '') {
	static $kw_spiders = array('bot', 'crawl', 'spider' ,'slurp', 'sohu-search', 'lycos', 'robozilla');
	static $kw_browsers = array('msie', 'netscape', 'opera', 'konqueror', 'mozilla');

	$useragent = strtolower(empty($useragent) ? $_SERVER['HTTP_USER_AGENT'] : $useragent);
	if(strpos($useragent, 'http://') === false && dstrpos($useragent, $kw_browsers)) return false;
	if(dstrpos($useragent, $kw_spiders)) return true;
	return false;
}
/**
* 检查是否是以手机浏览器进入(IN_MOBILE)
*/
function checkmobile() {
	global $_G;
	$mobile = array();
	static $mobilebrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
				'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
				'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
				'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
				'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
				'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
				'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
	$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
	//note 获取手机浏览器
	if(($v = dstrpos($useragent, $mobilebrowser_list, true))) {
		$_G['mobile'] = $v;
		return true;
	}
	$brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');
	if(dstrpos($useragent, $brower)) return false;

	$_G['mobile'] = 'unknown';
	if($_GET['mobile'] === 'yes') {
		return true;
	} else {
		return false;
	}
}

/**
 * 字符串方式实现 preg_match("/(s1|s2|s3)/", $string, $match)
 * @param string $string 源字符串
 * @param array $arr 要查找的字符串 如array('s1', 's2', 's3')
 * @param bool $returnvalue 是否返回找到的值
 * @return bool
 */
function dstrpos($string, &$arr, $returnvalue = false) {
	if(empty($string)) return false;
	foreach((array)$arr as $v) {
		if(strpos($string, $v) !== false) {
			$return = $returnvalue ? $v : true;
			return $return;
		}
	}
	return false;
}

/**
* 检查邮箱是否有效
* @param $email 要检查的邮箱
* @param 返回结果
*/
function isemail($email) {
	return strlen($email) > 6 && preg_match("/^([A-Za-z0-9\-_.+]+)@([A-Za-z0-9\-]+[.][A-Za-z0-9\-.]+)$/", $email);
}

/**
* 问题答案加密
* @param $questionid - 问题
* @param $answer - 答案
* @return 返回加密的字串
*/
function quescrypt($questionid, $answer) {
	return $questionid > 0 && $answer != '' ? substr(md5($answer.md5($questionid)), 16, 8) : '';
}

/**
* 产生随机码
* @param $length - 要多长
* @param $numberic - 数字还是字符串
* @return 返回字符串
*/
function random($length, $numeric = 0) {
	$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
	$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
	$hash = '';
	$max = strlen($seed) - 1;
	for($i = 0; $i < $length; $i++) {
		$hash .= $seed{mt_rand(0, $max)};
	}
	return $hash;
}

/**
 * 判断一个字符串是否在另一个字符串中存在
 *
 * @param string 原始字串 $string
 * @param string 查找 $find
 * @return boolean
 */
function strexists($string, $find) {
	return !(strpos($string, $find) === FALSE);
}

/**
 * 获取头像
 *
 * @param int $uid 需要获取的用户UID值
 * @param string $size 获取尺寸 'small', 'middle', 'big'
 * @param boolean $returnsrc 是否直接返回图片src
 * @param boolean $real 是否返回真实图片
 * @param boolean $static 是否返回真实路径
 * @param string $ucenterurl 强制uc路径
 */
function avatar($uid, $size = 'middle', $returnsrc = FALSE, $real = FALSE, $static = FALSE, $ucenterurl = '') {
	global $_G;
	static $staticavatar;
	if($staticavatar === null) {
		$staticavatar = $_G['setting']['avatarmethod'];
	}

	$ucenterurl = empty($ucenterurl) ? $_G['setting']['ucenterurl'] : $ucenterurl;
	$size = in_array($size, array('big', 'middle', 'small')) ? $size : 'middle';
	$uid = abs(intval($uid));
	if(!$staticavatar && !$static) {
		return $returnsrc ? $ucenterurl.'/avatar.php?uid='.$uid.'&size='.$size : '';
	} else {
		$uid = sprintf("%09d", $uid);
		$dir1 = substr($uid, 0, 3);
		$dir2 = substr($uid, 3, 2);
		$dir3 = substr($uid, 5, 2);
		$file = $ucenterurl.'/data/avatar/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($uid, -2).($real ? '_real' : '').'_avatar_'.$size.'.jpg';
		return $returnsrc ? $file : '';
	}
}

/**
* 加载语言
* 语言文件统一为 $lang = array();
* @param $file - 语言文件,可包含路径如 forum/xxx home/xxx
* @param $langvar - 语言文字索引
* @param $vars - 变量替换数组
* @return 语言文字
*/
function lang($file, $langvar = null, $vars = array(), $default = null) {
	global $_G;
	list($path, $file) = explode('/', $file);
	if(!$file) {
		$file = $path;
		$path = '';
	}

	if($path != 'plugin') {
		$key = $path == '' ? $file : $path.'_'.$file;
		if(!isset($_G['lang'][$key])) {
			include DISCUZ_ROOT.'./source/language/'.($path == '' ? '' : $path.'/').'lang_'.$file.'.php';
			$_G['lang'][$key] = $lang;
		}
		//noteX 合并手机语言包(IN_MOBILE)
		if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) {
			include DISCUZ_ROOT.'./source/language/mobile/lang_template.php';
			$_G['lang'][$key] = array_merge($_G['lang'][$key], $lang);
		}
		$returnvalue = &$_G['lang'];
	} else {
		if(empty($_G['config']['plugindeveloper'])) {
			loadcache('pluginlanguage_script');
		} elseif(!isset($_G['cache']['pluginlanguage_script'][$file]) && preg_match("/^[a-z]+[a-z0-9_]*$/i", $file)) {
			if(@include(DISCUZ_ROOT.'./data/plugindata/'.$file.'.lang.php')) {
				$_G['cache']['pluginlanguage_script'][$file] = $scriptlang[$file];
			} else {
				loadcache('pluginlanguage_script');
			}
		}
		$returnvalue = & $_G['cache']['pluginlanguage_script'];
		$key = &$file;
	}
	$return = $langvar !== null ? (isset($returnvalue[$key][$langvar]) ? $returnvalue[$key][$langvar] : null) : $returnvalue[$key];
	$return = $return === null ? ($default !== null ? $default : $langvar) : $return;
	$searchs = $replaces = array();
	if($vars && is_array($vars)) {
		foreach($vars as $k => $v) {
			$searchs[] = '{'.$k.'}';
			$replaces[] = $v;
		}
	}
	if(is_string($return) && strpos($return, '{_G/') !== false) {
		preg_match_all('/\{_G\/(.+?)\}/', $return, $gvar);
		foreach($gvar[0] as $k => $v) {
			$searchs[] = $v;
			$replaces[] = getglobal($gvar[1][$k]);
		}
	}
	$return = str_replace($searchs, $replaces, $return);
	return $return;
}

/**
* 检查模板源文件是否更新
* 当编译文件不存时强制重新编译
* 当 tplrefresh = 1 时检查文件
* 当 tplrefresh > 1 时,则根据 tplrefresh 取余,无余时则检查更新
*
*/
function checktplrefresh($maintpl, $subtpl, $timecompare, $templateid, $cachefile, $tpldir, $file) {
	static $tplrefresh, $timestamp, $targettplname;
	if($tplrefresh === null) {
		$tplrefresh = getglobal('config/output/tplrefresh');
		$timestamp = getglobal('timestamp');
	}

	if(empty($timecompare) || $tplrefresh == 1 || ($tplrefresh > 1 && !($timestamp % $tplrefresh))) {
		if(empty($timecompare) || @filemtime(DISCUZ_ROOT.$subtpl) > $timecompare) {
			require_once DISCUZ_ROOT.'/source/class/class_template.php';
			$template = new template();
			$template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);
			//更新页面和模块的关联
			if($targettplname === null) {
				$targettplname = getglobal('style/tplfile');
				if(!empty($targettplname)) {
					$targettplname = strtr($targettplname, ':', '_');
					update_template_block($targettplname, $template->blocks);
				}
				$targettplname = true;
			}
			return TRUE;
		}
	}
	return FALSE;
}

/**
* 解析模板
* @return 返回域名
 * 1、模板文件
 * 2、模板类型,如:diy模板和普通模板,diy模板位于data/diy,普通模板位于 template/default/下
 * 3、生成的tpl模板文件的存放位置
 * 4、是否返回模板文件的路径,0-返回编译后的php文件
 * 5、原始的模板文件
*/
function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') {
	global $_G;//超级全局变量:$_G

	static $_init_style = false;//初始化样式标志为false
	if($_init_style === false) {
		$discuz = & discuz_core::instance();//实例化一个discuz_core对象
		$discuz->_init_style();//调用discuz_core对象的_init_style()函数进行样式的初始化
		$_init_style = true;//样式初始化完成标志设置为true
	}
	$oldfile = $file; //原模板,如:"diy:forum/discuz:0"
	if(strpos($file, ':') !== false) {
		$clonefile = '';
                /*
                 * $templateid:diy
                 * $file:forum/discuz
                 * $clonefile:0
                 */
		list($templateid, $file, $clonefile) = explode(':', $file);//将文件以":"分割,如:"diy:forum/discuz:0"
		$oldfile = $file;//结果:forum/discuz
		$file = empty($clonefile) || STYLEID != $_G['cache']['style_default']['styleid'] ? $file : $file.'_'.$clonefile;//默认样式id为1:$_G['cache']['style_default']['styleid'];STYLEID:默认值为1      
		if($templateid == 'diy' && STYLEID == $_G['cache']['style_default']['styleid']) {//默认执行
			$_G['style']['prefile'] = ''; //非预览环境标记预览文件是否存在
			$diypath = DISCUZ_ROOT.'./data/diy/'; //DIY模板文件目录
			$preend = '_diy_preview'; //预览文件后缀
			$_G['gp_preview'] = !empty($_G['gp_preview']) ? $_G['gp_preview'] : ''; //是否预览
			$curtplname = $oldfile;//当前模板名,如:"forum/discuz"
			$basescript = $_G['mod'] == 'viewthread' && !empty($_G['thread']) ? 'forum' : $_G['basescript']; //帖子查看页归到froum中,默认值:forum
			if(isset($_G['cache']['diytemplatename'.$basescript])) {
				$diytemplatename = &$_G['cache']['diytemplatename'.$basescript];//当前应用的DIY文件缓存
			} else {
				$diytemplatename = &$_G['cache']['diytemplatename'];//所有DIY文件缓存
                                //echo $_G['cache']['diytemplatename'];//无任何输出,不知道什么意思
                                //echo "bbbb";//执行else代码段
			}
                        
			$tplsavemod = 0; //公共DIY页面标记
			//独立DIY页面 || 分区或版块没有指定模板 && 公共DIY页面
			if(isset($diytemplatename[$file]) && file_exists($diypath.$file.'.htm') && ($tplsavemod = 1) || empty($_G['forum']['styleid']) && ($file = $primaltpl ? $primaltpl : $oldfile) && isset($diytemplatename[$file]) && file_exists($diypath.$file.'.htm')) {
				$tpldir = 'data/diy'; //文件目录
				!$gettplfile && $_G['style']['tplsavemod'] = $tplsavemod; //独立DIY页面标记:1,公共DIY页面标记:0
				$curtplname = $file; //当前模板名
				if($_G['gp_diy'] == 'yes' || $_G['gp_preview'] == 'yes') { //DIY模式或预览模式下做以下判断
					$flag = file_exists($diypath.$file.$preend.'.htm'); //预览文件是否存在
					if($_G['gp_preview'] == 'yes') { //预览环境
						$file .= $flag ? $preend : ''; //使用预览模板文件
					} else {
						$_G['style']['prefile'] = $flag ? 1 : ''; //非预览环境标记预览文件是否存在
					}
				}
			} else {
				$file = $primaltpl ? $primaltpl : $oldfile; //无DIY页面则使用原模板
			}
			//根据模板自动刷新开关$tplrefresh 更新DIY模板
			$tplrefresh = $_G['config']['output']['tplrefresh'];
			//在有DIY生成模板文件时 && 自动刷新开启 && DIY生成模板文件修改时间 < 原模板修改修改
			if($tpldir == 'data/diy' && ($tplrefresh ==1 || ($tplrefresh > 1 && !($_G['timestamp'] % $tplrefresh))) && filemtime($diypath.$file.'.htm') < filemtime(DISCUZ_ROOT.TPLDIR.'/'.($primaltpl ? $primaltpl : $oldfile).'.htm')) {
				//原模板更改则更新DIY模板,如果更新失败则删除DIY模板
				if (!updatediytemplate($file)) {
					unlink($diypath.$file.'.htm');
					$tpldir = '';
				}
			}

			//保存当前模板名
			if (!$gettplfile && empty($_G['style']['tplfile'])) {
				$_G['style']['tplfile'] = empty($clonefile) ? $curtplname : $oldfile.':'.$clonefile;
			}

			//是否显示继续DIY
			$_G['style']['prefile'] = !empty($_G['gp_preview']) && $_G['gp_preview'] == 'yes' ? '' : $_G['style']['prefile'];

		} else {
			$tpldir = './source/plugin/'.$templateid.'/template';
		}
	}

	$file .= !empty($_G['inajax']) && ($file == 'common/header' || $file == 'common/footer') ? '_ajax' : '';
	$tpldir = $tpldir ? $tpldir : (defined('TPLDIR') ? TPLDIR : '');
	$templateid = $templateid ? $templateid : (defined('TEMPLATEID') ? TEMPLATEID : '');
	$filebak = $file;

	//noteX 将页面模板加一层Mobile目录,用以定位手机模板页面(IN_MOBILE)
	if(defined('IN_MOBILE') && !defined('TPL_DEFAULT') && strpos($file, 'mobile/') === false || $_G['forcemobilemessage']) {
		$file = 'mobile/'.$oldfile;
	}

	$tplfile = ($tpldir ? $tpldir.'/' : './template/').$file.'.htm';

	$file == 'common/header' && defined('CURMODULE') && CURMODULE && $file = 'common/header_'.$_G['basescript'].'_'.CURMODULE;

	//noteX 手机模板的判断(IN_MOBILE)
	if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) {
		//首先判断是否是DIY模板,如果是就删除可能存在的forumdisplay_1中的数字
		if(strpos($tpldir, 'plugin')) {
			if(!file_exists(DISCUZ_ROOT.$tpldir.'/'.$file.'.htm')) {
				require_once libfile('class/error');
				discuz_error::template_error('template_notfound', $tpldir.'/'.$file.'.htm');
			} else {
				$mobiletplfile = $tpldir.'/'.$file.'.htm';
			}
		}
		!$mobiletplfile && $mobiletplfile = $file.'.htm';
		if(strpos($tpldir, 'plugin') && file_exists(DISCUZ_ROOT.$mobiletplfile)) {
			$tplfile = $mobiletplfile;
		} elseif(!file_exists(DISCUZ_ROOT.TPLDIR.'/'.$mobiletplfile)) {
			$mobiletplfile = './template/default/'.$mobiletplfile;
			if(!file_exists(DISCUZ_ROOT.$mobiletplfile) && !$_G['forcemobilemessage']) {
				$tplfile = str_replace('mobile/', '', $tplfile);
				$file = str_replace('mobile/', '', $file);
				define('TPL_DEFAULT', true);
			} else {
				$tplfile = $mobiletplfile;
			}
		} else {
			$tplfile = TPLDIR.'/'.$mobiletplfile;
		}
	}

	$cachefile = './data/template/'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';

	if($templateid != 1 && !file_exists(DISCUZ_ROOT.$tplfile)) {
		$tplfile = './template/default/'.$filebak.'.htm';
	}

	if($gettplfile) {
		return $tplfile;
	}
	checktplrefresh($tplfile, $tplfile, @filemtime(DISCUZ_ROOT.$cachefile), $templateid, $cachefile, $tpldir, $file);
	return DISCUZ_ROOT.$cachefile;
}

/**
 * 对某id进行个性化md5
 */
function modauthkey($id) {
	global $_G;
	return md5($_G['username'].$_G['uid'].$_G['authkey'].substr(TIMESTAMP, 0, -7).$id);
}

/**
 * 获得当前应用页面选中的导航id
 */
function getcurrentnav() {
	global $_G;
	if(!empty($_G['mnid'])) {
		return $_G['mnid'];
	}
	$mnid = '';
	$_G['basefilename'] = $_G['basefilename'] == $_G['basescript'] ? $_G['basefilename'] : $_G['basescript'].'.php';
	if(isset($_G['setting']['navmns'][$_G['basefilename']])) {
		foreach($_G['setting']['navmns'][$_G['basefilename']] as $navmn) {
			if($navmn[0] == array_intersect_assoc($navmn[0], $_GET)) {
				$mnid = $navmn[1];
			}
		}
	}
	if(!$mnid && isset($_G['setting']['navdms'])) {
		foreach($_G['setting']['navdms'] as $navdm => $navid) {
			if(strpos(strtolower($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']), $navdm) !== false) {
				$mnid = $navid;
				break;
			}
		}
	}
	if(!$mnid && isset($_G['setting']['navmn'][$_G['basefilename']])) {
		$mnid = $_G['setting']['navmn'][$_G['basefilename']];
	}
	return $mnid;
}

//读取UC库
function loaducenter() {
	require_once DISCUZ_ROOT.'./config/config_ucenter.php';
	require_once DISCUZ_ROOT.'./uc_client/client.php';
}

/**
* 读取缓存
* @param $cachenames - 缓存名称数组或字串
*/
function loadcache($cachenames, $force = false) {
	global $_G;
	static $loadedcache = array();
	$cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
	$caches = array();
	foreach ($cachenames as $k) {
		if(!isset($loadedcache[$k]) || $force) {
			$caches[] = $k;
			$loadedcache[$k] = true;
		}
	}

	if(!empty($caches)) {
		$cachedata = cachedata($caches);
		foreach($cachedata as $cname => $data) {
			if($cname == 'setting') {
				$_G['setting'] = $data;
			} elseif(strpos($cname, 'usergroup_'.$_G['groupid']) !== false) {
				$_G['cache'][$cname] = $_G['group'] = $data;
			} elseif($cname == 'style_default') {
				$_G['cache'][$cname] = $_G['style'] = $data;
			} elseif($cname == 'grouplevels') {
				$_G['grouplevels'] = $data;
			} else {
				$_G['cache'][$cname] = $data;
			}
		}
	}
	return true;
}

/**
 * 通过memcache\mysql\file等几种手段读缓存
 * @param mixed $cachenames 缓存名的数组或字串
 */
function cachedata($cachenames) {
	global $_G;
	static $isfilecache, $allowmem;
	//$discuz = & discuz_core::instance();

	if(!isset($isfilecache)) {
		$isfilecache = getglobal('config/cache/type') == 'file';
		$allowmem = memory('check');
	}

	$data = array();
	$cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
	if($allowmem) {
		$newarray = array();
		foreach ($cachenames as $name) {
			$data[$name] = memory('get', $name);
			if($data[$name] === null) {
				$data[$name] = null;
				$newarray[] = $name;
			}
		}
		if(empty($newarray)) {
			return $data;
		} else {
			$cachenames = $newarray;
		}
	}

	if($isfilecache) {
		$lostcaches = array();
		foreach($cachenames as $cachename) {
			if(!@include_once(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php')) {
				$lostcaches[] = $cachename;
			}
		}
		if(!$lostcaches) {
			return $data;
		}
		$cachenames = $lostcaches;
		unset($lostcaches);
	}
	$query = DB::query("SELECT * FROM ".DB::table('common_syscache')." WHERE cname IN ('".implode("','", $cachenames)."')");
	while($syscache = DB::fetch($query)) {
		$data[$syscache['cname']] = $syscache['ctype'] ? unserialize($syscache['data']) : $syscache['data'];
		$allowmem && (memory('set', $syscache['cname'], $data[$syscache['cname']]));
		if($isfilecache) {
			$cachedata = '$data[\''.$syscache['cname'].'\'] = '.var_export($data[$syscache['cname']], true).";\n\n";
			if($fp = @fopen(DISCUZ_ROOT.'./data/cache/cache_'.$syscache['cname'].'.php', 'wb')) {
				fwrite($fp, "");
				fclose($fp);
			}
		}
	}

	foreach($cachenames as $name) {
		if($data[$name] === null) {
			$data[$name] = null;
			$allowmem && (memory('set', $name, array()));
		}
	}

	return $data;
}

/**
* 格式化时间
* @param $timestamp - 时间戳
* @param $format - dt=日期时间 d=日期 t=时间 u=个性化 其他=自定义
* @param $timeoffset - 时区
* @return string
*/
function dgmdate($timestamp, $format = 'dt', $timeoffset = '9999', $uformat = '') {
	global $_G;
	$format == 'u' && !$_G['setting']['dateconvert'] && $format = 'dt';
	static $dformat, $tformat, $dtformat, $offset, $lang;
	if($dformat === null) {
		$dformat = getglobal('setting/dateformat');
		$tformat = getglobal('setting/timeformat');
		$dtformat = $dformat.' '.$tformat;
		$offset = getglobal('member/timeoffset');
		$lang = lang('core', 'date');
	}
	$timeoffset = $timeoffset == 9999 ? $offset : $timeoffset;
	$timestamp += $timeoffset * 3600;
	$format = empty($format) || $format == 'dt' ? $dtformat : ($format == 'd' ? $dformat : ($format == 't' ? $tformat : $format));
	if($format == 'u') {
		$todaytimestamp = TIMESTAMP - (TIMESTAMP + $timeoffset * 3600) % 86400 + $timeoffset * 3600;
		$s = gmdate(!$uformat ? str_replace(":i", ":i:s", $dtformat) : $uformat, $timestamp);
		$time = TIMESTAMP + $timeoffset * 3600 - $timestamp;
		if($timestamp >= $todaytimestamp) {
			if($time > 3600) {
				return ''.intval($time / 3600).' '.$lang['hour'].$lang['before'].'';
			} elseif($time > 1800) {
				return ''.$lang['half'].$lang['hour'].$lang['before'].'';
			} elseif($time > 60) {
				return ''.intval($time / 60).' '.$lang['min'].$lang['before'].'';
			} elseif($time > 0) {
				return ''.$time.' '.$lang['sec'].$lang['before'].'';
			} elseif($time == 0) {
				return ''.$lang['now'].'';
			} else {
				return $s;
			}
		} elseif(($days = intval(($todaytimestamp - $timestamp) / 86400)) >= 0 && $days < 7) {
			if($days == 0) {
				return ''.$lang['yday'].' '.gmdate($tformat, $timestamp).'';
			} elseif($days == 1) {
				return ''.$lang['byday'].' '.gmdate($tformat, $timestamp).'';
			} else {
				return ''.($days + 1).' '.$lang['day'].$lang['before'].'';
			}
		} else {
			return $s;
		}
	} else {
		return gmdate($format, $timestamp);
	}
}

/**
	得到时间戳
*/
function dmktime($date) {
	if(strpos($date, '-')) {
		$time = explode('-', $date);
		return mktime(0, 0, 0, $time[1], $time[2], $time[0]);
	}
	return 0;
}

/**
* 更新缓存
* @param $cachename - 缓存名称
* @param $data - 缓存数据
*/
function save_syscache($cachename, $data) {
	static $isfilecache, $allowmem;
	if(!isset($isfilecache)) {
		$isfilecache = getglobal('config/cache/type') == 'file';
		$allowmem = memory('check');
	}

	if(is_array($data)) {
		$ctype = 1;
		$data = addslashes(serialize($data));
	} else {
		$ctype = 0;
	}

	DB::query("REPLACE INTO ".DB::table('common_syscache')." (cname, ctype, dateline, data) VALUES ('$cachename', '$ctype', '".TIMESTAMP."', '$data')");

	$allowmem && memory('rm', $cachename);
	$isfilecache && @unlink(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php');
}

/**
* Portal模块
* @param $parameter - 参数集合
*/
function block_get($parameter) {
	global $_G;
	static $allowmem;
	if($allowmem === null) {
		include_once libfile('function/block');
		$allowmem = getglobal('setting/memory/diyblock/enable') && memory('check');
	}
	if(!$allowmem) {
		block_get_batch($parameter);
		return true;
	}
	$blockids = explode(',', $parameter);
	$lostbids = array();
	foreach ($blockids as $bid) {
		$bid = intval($bid);
		if($bid) {
			$_G['block'][$bid] = memory('get', 'blockcache_'.$bid);
			if($_G['block'][$bid] === null) {
				$lostbids[] = $bid;
			} else {
				$styleid = $_G['block'][$bid]['styleid'];
				if($styleid && !isset($_G['blockstyle_'.$styleid])) {
					$_G['blockstyle_'.$styleid] = memory('get', 'blockstylecache_'.$styleid);
				}
			}
		}
	}

	if($lostbids) {
		block_get_batch(implode(',', $lostbids));
		foreach ($lostbids as $bid) {
			if(isset($_G['block'][$bid])) {
				memory('set', 'blockcache_'.$bid, $_G['block'][$bid], getglobal('setting/memory/diyblock/ttl'));
				$styleid = $_G['block'][$bid]['styleid'];
				if($styleid && $_G['blockstyle_'.$styleid]) {
					memory('set', 'blockstylecache_'.$styleid, $_G['blockstyle_'.$styleid], getglobal('setting/memory/diyblock/ttl'));
				}
			}
		}
	}
}

/**
* Portal 模块显示
*
* @param $parameter - 参数集合
*/
function block_display($bid) {
	include_once libfile('function/block');
	block_display_batch($bid);
}

//连接字符
function dimplode($array) {
	if(!empty($array)) {
		return "'".implode("','", is_array($array) ? $array : array($array))."'";
	} else {
		return 0;
	}
}

/**
* 返回库文件的全路径
*
* @param string $libname 库文件分类及名称
* @param string $folder 模块目录'module','include','class'
* @return string
*
* @example require DISCUZ_ROOT.'./source/function/function_cache.php'
* @example 我们可以利用此函数简写为:require libfile('function/cache');
*
*/
function libfile($libname, $folder = '') {
	$libpath = DISCUZ_ROOT.'/source/'.$folder;
	if(strstr($libname, '/')) {
		list($pre, $name) = explode('/', $libname);
		return realpath("{$libpath}/{$pre}/{$pre}_{$name}.php");
	} else {
		return realpath("{$libpath}/{$libname}.php");
	}
}

/**
 * 针对uft-8进行特殊处理的strlen
 * @param string $str
 * @return int
 */
function dstrlen($str) {
	if(strtolower(CHARSET) != 'utf-8') {
		return strlen($str);
	}
	$count = 0;
	for($i = 0; $i < strlen($str); $i++){
		$value = ord($str[$i]);
		if($value > 127) {
			$count++;
			if($value >= 192 && $value <= 223) $i++;
			elseif($value >= 224 && $value <= 239) $i = $i + 2;
			elseif($value >= 240 && $value <= 247) $i = $i + 3;
	    	}
    		$count++;
	}
	return $count;
}

/**
* 根据中文裁减字符串
* @param $string - 字符串
* @param $length - 长度
* @param $doc - 缩略后缀
* @return 返回带省略号被裁减好的字符串
*/
function cutstr($string, $length, $dot = ' ...') {
	if(strlen($string) <= $length) {
		return $string;
	}

	$pre = chr(1);
	$end = chr(1);
	//保护特殊字符串
	$string = str_replace(array('&', '"', '<', '>'), array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), $string);

	$strcut = '';
	if(strtolower(CHARSET) == 'utf-8') {

		$n = $tn = $noc = 0;
		while($n < strlen($string)) {

			$t = ord($string[$n]);
			if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
				$tn = 1; $n++; $noc++;
			} elseif(194 <= $t && $t <= 223) {
				$tn = 2; $n += 2; $noc += 2;
			} elseif(224 <= $t && $t <= 239) {
				$tn = 3; $n += 3; $noc += 2;
			} elseif(240 <= $t && $t <= 247) {
				$tn = 4; $n += 4; $noc += 2;
			} elseif(248 <= $t && $t <= 251) {
				$tn = 5; $n += 5; $noc += 2;
			} elseif($t == 252 || $t == 253) {
				$tn = 6; $n += 6; $noc += 2;
			} else {
				$n++;
			}

			if($noc >= $length) {
				break;
			}

		}
		if($noc > $length) {
			$n -= $tn;
		}

		$strcut = substr($string, 0, $n);

	} else {
		for($i = 0; $i < $length; $i++) {
			$strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
		}
	}

	//还原特殊字符串
	$strcut = str_replace(array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), array('&', '"', '<', '>'), $strcut);

	//修复出现特殊字符串截段的问题
	$pos = strrpos($strcut, chr(1));
	if($pos !== false) {
		$strcut = substr($strcut,0,$pos);
	}
	return $strcut.$dot;
}

//去掉slassh
function dstripslashes($string) {
	if(empty($string)) return $string;
	if(is_array($string)) {
		foreach($string as $key => $val) {
			$string[$key] = dstripslashes($val);
		}
	} else {
		$string = stripslashes($string);
	}
	return $string;
}

/**
* 论坛 aid url 生成
*/
function aidencode($aid, $type = 0, $tid = 0) {
	global $_G;
	$s = !$type ? $aid.'|'.substr(md5($aid.md5($_G['config']['security']['authkey']).TIMESTAMP.$_G['uid']), 0, 8).'|'.TIMESTAMP.'|'.$_G['uid'].'|'.$tid : $aid.'|'.md5($aid.md5($_G['config']['security']['authkey']).TIMESTAMP).'|'.TIMESTAMP;
	return rawurlencode(base64_encode($s));
}

/**
 * 返回论坛缩放附件图片的地址 url
 */
function getforumimg($aid, $nocache = 0, $w = 140, $h = 140, $type = '') {
	global $_G;
	$key = md5($aid.'|'.$w.'|'.$h);
	return 'forum.php?mod=image&aid='.$aid.'&size='.$w.'x'.$h.'&key='.rawurlencode($key).($nocache ? '&nocache=yes' : '').($type ? '&type='.$type : '');
}

/**
 * 获取rewrite字符串
 * @param string $type 需要获取的rewite
 * @param boolean $returntype true:直接返回href, false:返回a标签
 * @param string $host 可选网站域名
 * @return string
 */
function rewriteoutput($type, $returntype, $host) {
	global $_G;
	$fextra = '';
	if($type == 'forum_forumdisplay') {
		list(,,, $fid, $page, $extra) = func_get_args();
		$r = array(
			'{fid}' => empty($_G['setting']['forumkeys'][$fid]) ? $fid : $_G['setting']['forumkeys'][$fid],
			'{page}' => $page ? $page : 1,
		);
	} elseif($type == 'forum_viewthread') {
		list(,,, $tid, $page, $prevpage, $extra) = func_get_args();
		$r = array(
			'{tid}' => $tid,
			'{page}' => $page ? $page : 1,
			'{prevpage}' => $prevpage && !IS_ROBOT ? $prevpage : 1,
		);
	} elseif($type == 'home_space') {
		list(,,, $uid, $username, $extra) = func_get_args();
		$_G['setting']['rewritecompatible'] && $username = rawurlencode($username);
		$r = array(
			'{user}' => $uid ? 'uid' : 'username',
			'{value}' => $uid ? $uid : $username,
		);
	} elseif($type == 'home_blog') {
		list(,,, $uid, $blogid, $extra) = func_get_args();
		$r = array(
			'{uid}' => $uid,
			'{blogid}' => $blogid,
		);
	} elseif($type == 'group_group') {
		list(,,, $fid, $page, $extra) = func_get_args();
		$r = array(
			'{fid}' => $fid,
			'{page}' => $page ? $page : 1,
		);
	} elseif($type == 'portal_topic') {
		list(,,, $name, $extra) = func_get_args();
		$r = array(
			'{name}' => $name,
		);
	} elseif($type == 'portal_article') {
		list(,,, $id, $page, $extra) = func_get_args();
		$r = array(
			'{id}' => $id,
			'{page}' => $page ? $page : 1,
		);
	} elseif($type == 'forum_archiver') {
		list(,, $action, $value, $page, $extra) = func_get_args();
		$host = '';
		$r = array(
			'{action}' => $action,
			'{value}' => $value,
		);
		if($page) {
			$fextra = '?page='.$page;
		}
	}
	$href = str_replace(array_keys($r), $r, $_G['setting']['rewriterule'][$type]).$fextra;
	if(!$returntype) {
		return '';
	} else {
		return $host.$href;
	}
}

/**
* 手机模式下替换所有链接为mobile=yes形式
* @param $file - 正则匹配到的文件字符串
* @param $file - 要被替换的字符串
* @$replace 替换后字符串
*/
function mobilereplace($file, $replace) {
	global $_G;
	if(strpos($replace, 'mobile=') === false) {
		if(strpos($replace, '?') === false) {
			$replace = 'href="'.$file.$replace.'?mobile=yes"';
		} else {
			$replace = 'href="'.$file.$replace.'&mobile=yes"';
		}
		return $replace;
	} else {
		return 'href="'.$file.$replace.'"';
	}
}

/**
* 手机的output函数
*/
function mobileoutput() {
	global $_G;
	if(!defined('TPL_DEFAULT')) {
		$content = ob_get_contents();
		ob_end_clean();
		$content = preg_replace("/href=\"(\w+\.php)(.*?)\"/e", "mobilereplace('\\1', '\\2')", $content);

		ob_start();
		$content = ''.$content;
		if('utf-8' != CHARSET) {
			@header('Content-Type: text/html; charset=utf-8');
			$content = diconv($content, CHARSET, 'utf-8');
		}
		echo $content;
		exit();

	} elseif (defined('TPL_DEFAULT') && !$_G['cookie']['dismobilemessage'] && $_G['mobile']) {
		//noteX 当检测到手机浏览器,但又没有某个页面的模板时,需要进行此操作
		ob_end_clean();
		ob_start();
		$_G['forcemobilemessage'] = true;
		$query_sting_tmp = str_replace(array('&mobile=yes', 'mobile=yes'), array(''), $_SERVER['QUERY_STRING']);
		$_G['setting']['mobile']['pageurl'] = $_G['siteurl'].substr($_G['PHP_SELF'], 1).($query_sting_tmp ? '?'.$query_sting_tmp.'&mobile=no' : '?mobile=no' );
		unset($query_sting_tmp);
		dsetcookie('dismobilemessage', '1', 3600);
		showmessage('not_in_mobile');
		exit;
	}
}

/**
* 系统输出
* @return 返回内容
*/
function output() {

	global $_G;

	//===================================
	//判断写入页面缓存
	//===================================
	//writepagecache();

	if(defined('DISCUZ_OUTPUTED')) {
		return;
	} else {
		define('DISCUZ_OUTPUTED', 1);
	}

	// 更新模块
	if(!empty($_G['blockupdate'])) {
		block_updatecache($_G['blockupdate']['bid']);
	}

	//noteX 手机模式下重新制作页面输出(IN_MOBILE)
	if(defined('IN_MOBILE')) {
		mobileoutput();
	}
	include_once libfile('function/cloud');
	show();
	$havedomain = implode('', $_G['setting']['domain']['app']);
	if($_G['setting']['rewritestatus'] || !empty($havedomain)) {
		$content = ob_get_contents();
		$content = output_replace($content);


		ob_end_clean();
		$_G['gzipcompress'] ? ob_start('ob_gzhandler') : ob_start();//note X:待调整

		echo $content;
	}
	if($_G['setting']['ftp']['connid']) {
		@ftp_close($_G['setting']['ftp']['connid']);
	}
	$_G['setting']['ftp'] = array();

	//debug Module:HTML_CACHE 如果定义了缓存常量,则此处将缓冲区的内容写入文件。如果为 index 缓存,则直接写入 data/index.cache ,如果为 viewthread 缓存,则根据md5(tid,等参数)取前三位为目录加上$tid_$page,做文件名。
	//debug $threadcacheinfo, $indexcachefile 为全局变量
	if(defined('CACHE_FILE') && CACHE_FILE && !defined('CACHE_FORBIDDEN') && !defined('IN_MOBILE')) {
		if(diskfreespace(DISCUZ_ROOT.'./'.$_G['setting']['cachethreaddir']) > 1000000) {
			if($fp = @fopen(CACHE_FILE, 'w')) {
				flock($fp, LOCK_EX);
				fwrite($fp, empty($content) ? ob_get_contents() : $content);
			}
			@fclose($fp);
			chmod(CACHE_FILE, 0777);
		}
	}

	if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG && @include(libfile('function/debug'))) {
		function_exists('debugmessage') && debugmessage();
	}
}

function output_replace($content) {
	global $_G;
	if(defined('IN_MODCP') || defined('IN_ADMINCP')) return $content;
	if(!empty($_G['setting']['output']['str']['search'])) {
		if(empty($_G['setting']['domain']['app']['default'])) {
			$_G['setting']['output']['str']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['str']['replace']);
		}
		$content = str_replace($_G['setting']['output']['str']['search'], $_G['setting']['output']['str']['replace'], $content);
	}
	if(!empty($_G['setting']['output']['preg']['search'])) {
		if(empty($_G['setting']['domain']['app']['default'])) {
			$_G['setting']['output']['preg']['search'] = str_replace('\{CURHOST\}', preg_quote($_G['siteurl'], '/'), $_G['setting']['output']['preg']['search']);
			$_G['setting']['output']['preg']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['preg']['replace']);
		}

		$content = preg_replace($_G['setting']['output']['preg']['search'], $_G['setting']['output']['preg']['replace'], $content);
	}

	return $content;
}

/**
 * ajax footer使用输出页面内容
 */
function output_ajax() {
	global $_G;
	$s = ob_get_contents();
	ob_end_clean();
	$s = preg_replace("/([\\x01-\\x08\\x0b-\\x0c\\x0e-\\x1f])+/", ' ', $s);
	$s = str_replace(array(chr(0), ']]>'), array(' ', ']]>'), $s);
	if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG && @include(libfile('function/debug'))) {
		function_exists('debugmessage') && $s .= debugmessage(1);
	}
	$havedomain = implode('', $_G['setting']['domain']['app']);
	if($_G['setting']['rewritestatus'] || !empty($havedomain)) {
        $s = output_replace($s);
	}
	return $s;
}

/**
 * 运行钩子
 */
function runhooks() {
	if(!defined('HOOKTYPE')) {
		define('HOOKTYPE', !defined('IN_MOBILE') ? 'hookscript' : 'hookscriptmobile');
	}
	if(defined('CURMODULE')) {
		global $_G;
		if($_G['setting']['plugins'][HOOKTYPE.'_common']) {
			hookscript('common', 'global', 'funcs', array(), 'common');
		}
		hookscript(CURMODULE, $_G['basescript']);
	}
}

/**
 * 执行插件脚本
 */
function hookscript($script, $hscript, $type = 'funcs', $param = array(), $func = '') {
	global $_G;
	static $pluginclasses;
	if($hscript == 'home') {
		if($script != 'spacecp') {
			$script = 'space_'.(!empty($_G['gp_do']) ? $_G['gp_do'] : (!empty($_GET['do']) ? $_GET['do'] : ''));
		} else {
			$script .= !empty($_G['gp_ac']) ? '_'.$_G['gp_ac'] : (!empty($_GET['ac']) ? '_'.$_GET['ac'] : '');
		}
	}
	if(!isset($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {
		return;
	}
	if(!isset($_G['cache']['plugin'])) {
		loadcache('plugin');
	}
	foreach((array)$_G['setting'][HOOKTYPE][$hscript][$script]['module'] as $identifier => $include) {
		$hooksadminid[$identifier] = !$_G['setting'][HOOKTYPE][$hscript][$script]['adminid'][$identifier] || ($_G['setting'][HOOKTYPE][$hscript][$script]['adminid'][$identifier] && $_G['adminid'] > 0 && $_G['setting']['hookscript'][$hscript][$script]['adminid'][$identifier] >= $_G['adminid']);
		if($hooksadminid[$identifier]) {
			@include_once DISCUZ_ROOT.'./source/plugin/'.$include.'.class.php';
		}
	}
	if(@is_array($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {
		$_G['inhookscript'] = true;
		$funcs = !$func ? $_G['setting'][HOOKTYPE][$hscript][$script][$type] : array($func => $_G['setting'][HOOKTYPE][$hscript][$script][$type][$func]);
		foreach($funcs as $hookkey => $hookfuncs) {
			foreach($hookfuncs as $hookfunc) {
				if($hooksadminid[$hookfunc[0]]) {
					$classkey = (HOOKTYPE != 'hookscriptmobile' ? '' : 'mobile').'plugin_'.($hookfunc[0].($hscript != 'global' ? '_'.$hscript : ''));
					if(!class_exists($classkey)) {
						continue;
					}
					if(!isset($pluginclasses[$classkey])) {
						$pluginclasses[$classkey] = new $classkey;
					}
					if(!method_exists($pluginclasses[$classkey], $hookfunc[1])) {
						continue;
					}
					$return = $pluginclasses[$classkey]->$hookfunc[1]($param);

					if(is_array($return)) {
						if(!isset($_G['setting']['pluginhooks'][$hookkey]) || is_array($_G['setting']['pluginhooks'][$hookkey])) {
							foreach($return as $k => $v) {
								$_G['setting']['pluginhooks'][$hookkey][$k] .= $v;
							}
						}
					} else {
						if(!is_array($_G['setting']['pluginhooks'][$hookkey])) {
							$_G['setting']['pluginhooks'][$hookkey] .= $return;
						} else {
							foreach($_G['setting']['pluginhooks'][$hookkey] as $k => $v) {
								$_G['setting']['pluginhooks'][$hookkey][$k] .= $return;
							}
						}
					}
				}
			}
		}
	}
	$_G['inhookscript'] = false;
}

function hookscriptoutput($tplfile) {
	global $_G;
	if(!empty($_G['hookscriptoutput'])) {
		return;
	}
	//note mobiledata
	if(!empty($_G['gp_mobiledata'])) {
		require_once libfile('class/mobiledata');
		$mobiledata = new mobiledata();
		if($mobiledata->validator()) {
			$mobiledata->outputvariables();
		}
	}
	hookscript('global', 'global');
	if(defined('CURMODULE')) {
		$param = array('template' => $tplfile, 'message' => $_G['hookscriptmessage'], 'values' => $_G['hookscriptvalues']);
		hookscript(CURMODULE, $_G['basescript'], 'outputfuncs', $param);
	}
	$_G['hookscriptoutput'] = true;
}

/**
 * 获取插件模块
 */
function pluginmodule($pluginid, $type) {
	global $_G;
	if(!isset($_G['cache']['plugin'])) {
		loadcache('plugin');
	}
	list($identifier, $module) = explode(':', $pluginid);
	if(!is_array($_G['setting']['plugins'][$type]) || !array_key_exists($pluginid, $_G['setting']['plugins'][$type])) {
		showmessage('plugin_nonexistence');
	}
	if(!empty($_G['setting']['plugins'][$type][$pluginid]['url'])) {
		dheader('location: '.$_G['setting']['plugins'][$type][$pluginid]['url']);
	}
	$directory = $_G['setting']['plugins'][$type][$pluginid]['directory'];
	if(empty($identifier) || !preg_match("/^[a-z]+[a-z0-9_]*\/$/i", $directory) || !preg_match("/^[a-z0-9_\-]+$/i", $module)) {
		showmessage('undefined_action');
	}
	if(@!file_exists(DISCUZ_ROOT.($modfile = './source/plugin/'.$directory.$module.'.inc.php'))) {
		showmessage('plugin_module_nonexistence', '', array('mod' => $modfile));
	}
	return DISCUZ_ROOT.$modfile;
}
/**
 * 执行积分规则
 * @param String $action:  规则action名称
 * @param Integer $uid: 操作用户
 * @param array $extrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1')
 * @param String $needle: 防重字符串
 * @param Integer $coef: 积分放大倍数
 * @param Integer $update: 是否执行更新操作
 * @param Integer $fid: 版块ID
 * @return 返回积分策略
 */
function updatecreditbyaction($action, $uid = 0, $extrasql = array(), $needle = '', $coef = 1, $update = 1, $fid = 0) {

	include_once libfile('class/credit');
	$credit = & credit::instance();
	if($extrasql) {
		$credit->extrasql = $extrasql;
	}
	return $credit->execrule($action, $uid, $needle, $coef, $update, $fid);
}

/**
* 检查积分下限
* @param string $action: 策略动作Action或者需要检测的操作积分值使如extcredits1积分进行减1操作检测array('extcredits1' => -1)
* @param Integer $uid: 用户UID
* @param Integer $coef: 积分放大倍数/负数为减分操作
* @param Integer $returnonly: 只要返回结果,不用中断程序运行
*/
function checklowerlimit($action, $uid = 0, $coef = 1, $fid = 0, $returnonly = 0) {
	require_once libfile('function/credit');
	return _checklowerlimit($action, $uid, $coef, $fid, $returnonly);
}

/**
 * 批量执行某一条策略规则
 * @param String $action:  规则action名称
 * @param Integer $uids: 操作用户可以为单个uid或uid数组
 * @param array $extrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1')
 * @param Integer $coef: 积分放大倍数,当为负数时为反转操作
 * @param Integer $fid: 版块ID
 */
function batchupdatecredit($action, $uids = 0, $extrasql = array(), $coef = 1, $fid = 0) {

	include_once libfile('class/credit');
	$credit = & credit::instance();
	if($extrasql) {
		$credit->extrasql = $extrasql;
	}
	return $credit->updatecreditbyrule($action, $uids, $coef, $fid);
}

/**
 * 添加积分
 * @param Integer $uids: 用户uid或者uid数组
 * @param String $dataarr: member count相关操作数组,例: array('threads' => 1, 'doings' => -1)
 * @param Boolean $checkgroup: 是否检查用户组 true or false
 * @param String $operation: 操作类型
 * @param Integer $relatedid:
 * @param String $ruletxt: 积分规则文本
 */

function updatemembercount($uids, $dataarr = array(), $checkgroup = true, $operation = '', $relatedid = 0, $ruletxt = '') {
	if(!empty($uids) && (is_array($dataarr) && $dataarr)) {
		require_once libfile('function/credit');
		return _updatemembercount($uids, $dataarr, $checkgroup, $operation, $relatedid, $ruletxt);
	}
	return true;
}

/**
 * 校验用户组
 * @param $uid
 */
function checkusergroup($uid = 0) {
	require_once libfile('class/credit');
	$credit = & credit::instance();
	$credit->checkusergroup($uid);
}

function checkformulasyntax($formula, $operators, $tokens) {
	$var = implode('|', $tokens);
	$operator = implode('', $operators);

	$operator = str_replace(
		array('+', '-', '*', '/', '(', ')', '{', '}', '\''),
		array('\+', '\-', '\*', '\/', '\(', '\)', '\{', '\}', '\\\''),
		$operator
	);

	if(!empty($formula)) {
		if(!preg_match("/^([$operator\.\d\(\)]|(($var)([$operator\(\)]|$)+))+$/", $formula) || !is_null(eval(preg_replace("/($var)/", "\$\\1", $formula).';'))){
			return false;
		}
	}
	return true;
}

//检验积分公式语法
function checkformulacredits($formula) {
	return checkformulasyntax(
		$formula,
		array('+', '-', '*', '/', ' '),
		array('extcredits[1-8]', 'digestposts', 'posts', 'threads', 'oltime', 'friends', 'doings', 'polls', 'blogs', 'albums', 'sharings')
	);
}

//临时调试通用
function debug($var = null, $vardump = false) {
	echo '
';
	if($var === null) {
		print_r($GLOBALS);
	} else {
		if($vardump) {
			var_dump($var);
		} else {
			print_r($var);
		}
	}
	exit();
}

/**
* 调试信息
*/
function debuginfo() {
	global $_G;
	if(getglobal('setting/debug')) {
		$db = & DB::object();
		$_G['debuginfo'] = array(
		    'time' => number_format((dmicrotime() - $_G['starttime']), 6),
		    'queries' => $db->querynum,
		    'memory' => ucwords($_G['memory'])
		    );
		if($db->slaveid) {
			$_G['debuginfo']['queries'] = 'Total '.$db->querynum.', Slave '.$db->slavequery;
		}
		return TRUE;
	} else {
		return FALSE;
	}
}

/**
 * 随机取出一个站长推荐的条目
 * @param $module 当前模块
 * @return array
*/
function getfocus_rand($module) {
	global $_G;

	if(empty($_G['setting']['focus']) || !array_key_exists($module, $_G['setting']['focus'])) {
		return null;
	}
	do {
		$focusid = $_G['setting']['focus'][$module][array_rand($_G['setting']['focus'][$module])];
		if(!empty($_G['cookie']['nofocus_'.$focusid])) {
			unset($_G['setting']['focus'][$module][$focusid]);
			$continue = 1;
		} else {
			$continue = 0;
		}
	} while(!empty($_G['setting']['focus'][$module]) && $continue);
	if(!$_G['setting']['focus'][$module]) {
		return null;
	}
	loadcache('focus');
	if(empty($_G['cache']['focus']['data']) || !is_array($_G['cache']['focus']['data'])) {
		return null;
	}
	return $focusid;
}

/**
 * 检查验证码正确性
 * @param $value 验证码变量值
 */
function check_seccode($value, $idhash) {
	global $_G;
	if(!$_G['setting']['seccodestatus']) {
		return true;
	}
	if(!isset($_G['cookie']['seccode'.$idhash])) {
		return false;
	}
	list($checkvalue, $checktime, $checkidhash, $checkformhash) = explode("\t", authcode($_G['cookie']['seccode'.$idhash], 'DECODE', $_G['config']['security']['authkey']));
	return $checkvalue == strtoupper($value) && TIMESTAMP - 180 > $checktime && $checkidhash == $idhash && FORMHASH == $checkformhash;
}

/**
 * 检查验证问答正确性
 * @param $value 验证问答变量值
 */
function check_secqaa($value, $idhash) {
	global $_G;
	if(!$_G['setting']['secqaa']) {
		return true;
	}
	if(!isset($_G['cookie']['secqaa'.$idhash])) {
		return false;
	}
	loadcache('secqaa');
	list($checkvalue, $checktime, $checkidhash, $checkformhash) = explode("\t", authcode($_G['cookie']['secqaa'.$idhash], 'DECODE', $_G['config']['security']['authkey']));
	return $checkvalue == md5($value) && TIMESTAMP - 180 > $checktime && $checkidhash == $idhash && FORMHASH == $checkformhash;
}

/**
 * 获取广告
 */
function adshow($parameter) {
	global $_G;
	if($_G['inajax']) {
		return;
	}
	$params = explode('/', $parameter);
	$customid = 0;
	$customc = explode('_', $params[0]);
	if($customc[0] == 'custom') {
		$params[0] = $customc[0];
		$customid = $customc[1];
	}
	$adcontent = null;
	if(empty($_G['setting']['advtype']) || !in_array($params[0], $_G['setting']['advtype'])) {
		$adcontent = '';
	}
	if($adcontent === null) {
		loadcache('advs');
		$adids = array();
		$evalcode = &$_G['cache']['advs']['evalcode'][$params[0]];
		$parameters = &$_G['cache']['advs']['parameters'][$params[0]];
		$codes = &$_G['cache']['advs']['code'][$_G['basescript']][$params[0]];
		if(!empty($codes)) {
			foreach($codes as $adid => $code) {
				$parameter = &$parameters[$adid];
				$checked = true;
				@eval($evalcode['check']);
				if($checked) {
					$adids[] = $adid;
				}
			}
			if(!empty($adids)) {
				$adcode = $extra = '';
				@eval($evalcode['create']);
				if(empty($notag)) {
					$adcontent = ''.$adcode.'
'; } else { $adcontent = $adcode; } } } } $adfunc = 'ad_'.$params[0]; $_G['setting']['pluginhooks'][$adfunc] = null; hookscript('ad', 'global', 'funcs', array('params' => $params, 'content' => $adcontent), $adfunc); hookscript('ad', $_G['basescript'], 'funcs', array('params' => $params, 'content' => $adcontent), $adfunc); return $_G['setting']['pluginhooks'][$adfunc] === null ? $adcontent : $_G['setting']['pluginhooks'][$adfunc]; } /** * 显示提示信息 * @param $message - 提示信息,可中文也可以是 lang_message.php 中的数组 key 值 * @param $url_forward - 提示后跳转的 url * @param $values - 提示信息中可替换的变量值 array(key => value ...) 形式 * @param $extraparam - 扩展参数 array(key => value ...) 形式 * 跳转控制 header header跳转 location location JS 跳转,限于 msgtype = 2、3 timeout 定时跳转 refreshtime 自定义跳转时间 closetime 自定义关闭时间,限于 msgtype = 2,值为 true 时为默认 locationtime 自定义跳转时间,限于 msgtype = 2,值为 true 时为默认 内容控制 alert alert 图标样式 right/info/error return 显示请返回 redirectmsg 下载时用的提示信息,当跳转时显示的信息样式 0:如果您的浏览器没有自动跳转,请点击此链接 1:如果 n 秒后下载仍未开始,请点击此链接 msgtype 信息样式 1:非 Ajax 2:Ajax 弹出框 3:Ajax 只显示信息文本 showmsg 显示信息文本 showdialog 关闭原弹出框显示 showDialog 信息,限于 msgtype = 2 login 未登录时显示登录链接 extrajs 扩展 js striptags 过滤 HTML 标记 Ajax 控制 handle 执行 js 回调函数 showid 控制显示的对象 ID */ function showmessage($message, $url_forward = '', $values = array(), $extraparam = array(), $custom = 0) { require_once libfile('function/message'); return dshowmessage($message, $url_forward, $values, $extraparam, $custom); } /** * 检查是否正确提交了表单 * @param $var 需要检查的变量 * @param $allowget 是否允许GET方式 * @param $seccodecheck 验证码检测是否开启 * @return 返回是否正确提交了表单 */ function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) { if(!getgpc($var)) { return FALSE; } else { global $_G; //note mobiledata if(!empty($_G['gp_mobiledata'])) { require_once libfile('class/mobiledata'); $mobiledata = new mobiledata(); if($mobiledata->validator()) { return TRUE; } } if($allowget || ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_G['gp_formhash']) && $_G['gp_formhash'] == formhash() && empty($_SERVER['HTTP_X_FLASH_VERSION']) && (empty($_SERVER['HTTP_REFERER']) || preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])))) { if(checkperm('seccode')) { if($secqaacheck && !check_secqaa($_G['gp_secanswer'], $_G['gp_sechash'])) { showmessage('submit_secqaa_invalid'); } if($seccodecheck && !check_seccode($_G['gp_seccodeverify'], $_G['gp_sechash'])) { showmessage('submit_seccode_invalid'); } } return TRUE; } else { showmessage('submit_invalid'); } } } /** * 分页 * @param $num - 总数 * @param $perpage - 每页数 * @param $curpage - 当前页 * @param $mpurl - 跳转的路径 * @param $maxpages - 允许显示的最大页数 * @param $page - 最多显示多少页码 * @param $autogoto - 最后一页,自动跳转 * @param $simple - 是否简洁模式(简洁模式不显示上一页、下一页和页码跳转) * @return 返回分页代码 */ function multi($num, $perpage, $curpage, $mpurl, $maxpages = 0, $page = 10, $autogoto = FALSE, $simple = FALSE) { global $_G; //debug 加入 ajaxtarget 属性 $ajaxtarget = !empty($_G['gp_ajaxtarget']) ? " ajaxtarget=\"".htmlspecialchars($_G['gp_ajaxtarget'])."\" " : ''; //note 处理#描点 $a_name = ''; if(strpos($mpurl, '#') !== FALSE) { $a_strs = explode('#', $mpurl); $mpurl = $a_strs[0]; $a_name = '#'.$a_strs[1]; } if(defined('IN_ADMINCP')) { $shownum = $showkbd = TRUE; $lang['prev'] = '‹‹'; $lang['next'] = '››'; } else { $shownum = $showkbd = FALSE; //noteX 手机模式下使用语言包的上下翻页(IN_MOBILE) if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) { $lang['prev'] = lang('core', 'prevpage'); $lang['next'] = lang('core', 'nextpage'); } else { $lang['prev'] = '  '; $lang['next'] = lang('core', 'nextpage'); } } //noteX 手机模式下使用较小的页数和小点(IN_MOBILE) if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) { $dot = '..'; $page = intval($page) < 10 && intval($page) > 0 ? $page : 4 ; } else { $dot = '...'; } $multipage = ''; $mpurl .= strpos($mpurl, '?') !== FALSE ? '&' : '?'; $realpages = 1; $_G['page_next'] = 0; $page -= strlen($curpage) - 1; if($page <= 0) { $page = 1; } if($num > $perpage) { $offset = floor($page * 0.5); $realpages = @ceil($num / $perpage); $pages = $maxpages && $maxpages < $realpages ? $maxpages : $realpages; if($page > $pages) { $from = 1; $to = $pages; } else { $from = $curpage - $offset; $to = $from + $page - 1; if($from < 1) { $to = $curpage + 1 - $from; $from = 1; if($to - $from < $page) { $to = $page; } } elseif($to > $pages) { $from = $pages - $page + 1; $to = $pages; } } $_G['page_next'] = $to; //noteX 替换小点为$dot变量(IN_MOBILE) $multipage = ($curpage - $offset > 1 && $pages > $page ? '1 '.$dot.'' : ''). ($curpage > 1 && !$simple ? '' : ''); for($i = $from; $i <= $to; $i++) { $multipage .= $i == $curpage ? ''.$i.'' : ''.$i.''; } //noteX 替换小点为$dot变量(IN_MOBILE) $multipage .= ($to < $pages ? ''.$dot.' '.$realpages.'' : ''). ($curpage < $pages && !$simple ? ''.$lang['next'].'' : ''). ($showkbd && !$simple && $pages > $page && !$ajaxtarget ? '' : ''); $multipage = $multipage ? '
'.($shownum && !$simple ? ' '.$num.' ' : '').$multipage.'
' : ''; } $maxpage = $realpages; return $multipage; } /** * 只有上一页下一页的分页(无需知道数据总数) * @param $num - 本次所取数据条数 * @param $perpage - 每页数 * @param $curpage - 当前页 * @param $mpurl - 跳转的路径 * @return 返回分页代码 */ function simplepage($num, $perpage, $curpage, $mpurl) { $return = ''; $lang['next'] = lang('core', 'nextpage'); $lang['prev'] = lang('core', 'prevpage'); $next = $num == $perpage ? ''.$lang['next'].'' : ''; $prev = $curpage > 1 ? ''.$lang['prev'].'' : ''; if($next || $prev) { $return = '
'.$prev.$next.'
'; } return $return; } /** * 词语过滤 * @param $message - 词语过滤文本 * @return 成功返回原始文本,否则提示错误或被替换 */ function censor($message, $modword = NULL, $return = FALSE) { global $_G; require_once libfile('class/censor'); $censor = discuz_censor::instance(); $censor->check($message, $modword); if($censor->modbanned() && !$_G['group']['ignorecensor']) { $wordbanned = implode(', ', $censor->words_found); if($return) { return array('message' => lang('message', 'word_banned', array('wordbanned' => $wordbanned))); } if(!defined('IN_ADMINCP')) { showmessage('word_banned', '', array('wordbanned' => $wordbanned)); } else { cpmsg(lang('message', 'word_banned'), '', 'error', array('wordbanned' => $wordbanned)); } } if($_G['group']['allowposturl'] == 0 || $_G['group']['allowposturl'] == 2) { $urllist = get_url_list($message); if(is_array($urllist[1])) foreach($urllist[1] as $key => $val) { if(!$val = trim($val)) continue; if(!iswhitelist($val)) { if($_G['group']['allowposturl'] == 0) { showmessage('post_url_nopermission'); } elseif($_G['group']['allowposturl'] == 2) { $message = str_replace('[url]'.$urllist[0][$key].'[/url]', $urllist[0][$key], $message); $message = preg_replace( array( "@\[url=.*?".preg_quote($urllist[0][$key],'@').".*?\](.*?)\[/url\]@is", "@href=('|\")".preg_quote($urllist[0][$key],'@')."\\1@is", "@\[url\](.*?".preg_quote($urllist[0][$key],'@').".*?)\[/url\]@is", ), array( '\\1', '', '\\1', ), $message); } } } } return $message; } /** 词语过滤,检测是否含有需要审核的词 */ function censormod($message) { global $_G; if($_G['group']['ignorecensor']) { return false; } $modposturl = false; if($_G['group']['allowposturl'] == 1) { $urllist = get_url_list($message); if(is_array($urllist[1])) foreach($urllist[1] as $key => $val) { if(!$val = trim($val)) continue; if(!iswhitelist($val)) { $modposturl = true; } } } if($modposturl) { return true; } require_once libfile('class/censor'); $censor = discuz_censor::instance(); $censor->check($message); return $censor->modmoderated(); } //获取用户附属表信息,累加到第一个变量$values function space_merge(&$values, $tablename) { global $_G; $uid = empty($values['uid'])?$_G['uid']:$values['uid'];//默认当前用户 $var = "member_{$uid}_{$tablename}"; if($uid) { if(!isset($_G[$var])) { $query = DB::query("SELECT * FROM ".DB::table('common_member_'.$tablename)." WHERE uid='$uid'"); if($_G[$var] = DB::fetch($query)) { if($tablename == 'field_home') { //隐私设置 $_G['setting']['privacy'] = empty($_G['setting']['privacy']) ? array() : (is_array($_G['setting']['privacy']) ? $_G['setting']['privacy'] : unserialize($_G['setting']['privacy'])); $_G[$var]['privacy'] = empty($_G[$var]['privacy'])? array() : is_array($_G[$var]['privacy']) ? $_G[$var]['privacy'] : unserialize($_G[$var]['privacy']); foreach (array('feed','view','profile') as $pkey) { if(empty($_G[$var]['privacy'][$pkey]) && !isset($_G[$var]['privacy'][$pkey])) { $_G[$var]['privacy'][$pkey] = isset($_G['setting']['privacy'][$pkey]) ? $_G['setting']['privacy'][$pkey] : array();//取站点默认设置 } } //邮件提醒 $_G[$var]['acceptemail'] = empty($_G[$var]['acceptemail'])? array() : unserialize($_G[$var]['acceptemail']); if(empty($_G[$var]['acceptemail'])) { $_G[$var]['acceptemail'] = empty($_G['setting']['acceptemail'])?array():unserialize($_G['setting']['acceptemail']); } } } else { //插入默认数据 DB::insert('common_member_'.$tablename, array('uid'=>$uid)); $_G[$var] = array(); } } $values = array_merge($values, $_G[$var]); } } /* * 运行log记录 */ function runlog($file, $message, $halt=0) { global $_G; $nowurl = $_SERVER['REQUEST_URI']?$_SERVER['REQUEST_URI']:($_SERVER['PHP_SELF']?$_SERVER['PHP_SELF']:$_SERVER['SCRIPT_NAME']); $log = dgmdate($_G['timestamp'], 'Y-m-d H:i:s')."\t".$_G['clientip']."\t$_G[uid]\t{$nowurl}\t".str_replace(array("\r", "\n"), array(' ', ' '), trim($message))."\n"; writelog($file, $log); if($halt) { exit(); } } /* * 处理搜索关键字 */ function stripsearchkey($string) { $string = trim($string); $string = str_replace('*', '%', addcslashes($string, '%_')); $string = str_replace('_', '\_', $string); return $string; } /* * 递归创建目录 */ function dmkdir($dir, $mode = 0777, $makeindex = TRUE){ if(!is_dir($dir)) { dmkdir(dirname($dir), $mode, $makeindex); @mkdir($dir, $mode); if(!empty($makeindex)) { @touch($dir.'/index.html'); @chmod($dir.'/index.html', 0777); } } return true; } /** * 刷新重定向 */ function dreferer($default = '') { global $_G; $default = empty($default) ? $GLOBALS['_t_curapp'] : ''; $_G['referer'] = !empty($_G['gp_referer']) ? $_G['gp_referer'] : $_SERVER['HTTP_REFERER']; $_G['referer'] = substr($_G['referer'], -1) == '?' ? substr($_G['referer'], 0, -1) : $_G['referer']; if(strpos($_G['referer'], 'member.php?mod=logging')) { $_G['referer'] = $default; } $_G['referer'] = htmlspecialchars($_G['referer'], ENT_QUOTES); $_G['referer'] = str_replace('&', '&', $_G['referer']); $reurl = parse_url($_G['referer']); //判断host是否相同,不同时做进步的校验 if(!empty($reurl['host']) && !in_array($reurl['host'], array($_SERVER['HTTP_HOST'], 'www.'.$_SERVER['HTTP_HOST'])) && !in_array($_SERVER['HTTP_HOST'], array($reurl['host'], 'www.'.$reurl['host']))) { //校验是否在应用域名或版块域名配置中 if(!in_array($reurl['host'], $_G['setting']['domain']['app']) && !isset($_G['setting']['domain']['list'][$reurl['host']])) { $domainroot = substr($reurl['host'], strpos($reurl['host'], '.')+1); //是否为子域名,如果不为子域名则跳到index.php if(empty($_G['setting']['domain']['root']) || (is_array($_G['setting']['domain']['root']) && !in_array($domainroot, $_G['setting']['domain']['root']))) { $_G['referer'] = $_G['setting']['domain']['defaultindex'] ? $_G['setting']['domain']['defaultindex'] : 'index.php'; } } } elseif(empty($reurl['host'])) { $_G['referer'] = $_G['siteurl'].'./'.$_G['referer']; } return strip_tags($_G['referer']); } /** * 远程FTP使用 */ function ftpcmd($cmd, $arg1 = '') { static $ftp; $ftpon = getglobal('setting/ftp/on'); if(!$ftpon) { return $cmd == 'error' ? -101 : 0; } elseif($ftp == null) { require_once libfile('class/ftp'); $ftp = & discuz_ftp::instance(); } if(!$ftp->enabled) { return $ftp->error(); } elseif($ftp->enabled && !$ftp->connectid) { $ftp->connect(); } switch ($cmd) { case 'upload' : return $ftp->upload(getglobal('setting/attachdir').'/'.$arg1, $arg1); break; case 'delete' : return $ftp->ftp_delete($arg1); break; case 'close' : return $ftp->ftp_close(); break; case 'error' : return $ftp->error(); break; case 'object' : return $ftp; break; default : return false; } } /** * 编码转换 * @param $str 要转码的字符 * @param $in_charset 输入字符集 * @param $out_charset 输出字符集(默认当前) * @param $ForceTable 强制使用码表(默认不强制) * */ function diconv($str, $in_charset, $out_charset = CHARSET, $ForceTable = FALSE) { global $_G; $in_charset = strtoupper($in_charset); $out_charset = strtoupper($out_charset); if(empty($str) || $in_charset == $out_charset) { return $str; } $out = ''; if(!$ForceTable) { if(function_exists('iconv')) { $out = iconv($in_charset, $out_charset.'//IGNORE', $str); } elseif(function_exists('mb_convert_encoding')) { $out = mb_convert_encoding($str, $out_charset, $in_charset); } } if($out == '') { require_once libfile('class/chinese'); $chinese = new Chinese($in_charset, $out_charset, true); $out = $chinese->Convert($str); } return $out; } /** * 重建数组 * @param $array 需要反转的数组 * @return array 原数组与的反转后的数组 */ function renum($array) { $newnums = $nums = array(); foreach ($array as $id => $num) { $newnums[$num][] = $id; $nums[$num] = $num; } return array($nums, $newnums); } /** * 获取当前脚本在线人数 * @param $fid 分类 ID,版块、群组 的 id, * @param $tid 内容 ID,帖子 的 id */ function getonlinenum($fid = 0, $tid = 0) { if($fid) { $sql = " AND fid='$fid'"; } if($tid) { $sql = " AND tid='$tid'"; } return DB::result_first('SELECT count(*) FROM '.DB::table("common_session")." WHERE 1 $sql"); } /** * 字节格式化单位 * @param $filesize - 大小(字节) * @return 返回格式化后的文本 */ function sizecount($size) { if($size >= 1073741824) { $size = round($size / 1073741824 * 100) / 100 . ' GB'; } elseif($size >= 1048576) { $size = round($size / 1048576 * 100) / 100 . ' MB'; } elseif($size >= 1024) { $size = round($size / 1024 * 100) / 100 . ' KB'; } else { $size = $size . ' Bytes'; } return $size; } function swapclass($class1, $class2 = '') { static $swapc = null; $swapc = isset($swapc) && $swapc != $class1 ? $class1 : $class2; return $swapc; } /** * 写入运行日志 */ function writelog($file, $log) { global $_G; $yearmonth = dgmdate(TIMESTAMP, 'Ym', $_G['setting']['timeoffset']); $logdir = DISCUZ_ROOT.'./data/log/'; $logfile = $logdir.$yearmonth.'_'.$file.'.php'; if(@filesize($logfile) > 2048000) { $dir = opendir($logdir); $length = strlen($file); $maxid = $id = 0; while($entry = readdir($dir)) { if(strpos($entry, $yearmonth.'_'.$file) !== false) { $id = intval(substr($entry, $length + 8, -4)); $id > $maxid && $maxid = $id; } } closedir($dir); $logfilebak = $logdir.$yearmonth.'_'.$file.'_'.($maxid + 1).'.php'; @rename($logfile, $logfilebak); } if($fp = @fopen($logfile, 'a')) { @flock($fp, 2); $log = is_array($log) ? $log : array($log); foreach($log as $tmp) { fwrite($fp, "\t".str_replace(array(''), '', $tmp)."\n"); } fclose($fp); } } /** * 调色板 * @param $colorid * @param $id * @param $background * @return */ function getcolorpalette($colorid, $id, $background, $fun = '') { return ""; } /** * 取得某标志位的数值 (0|1) * * @param 数值 $status * @param 位置 $position * @return 0 | 1 */ function getstatus($status, $position) { $t = $status & pow(2, $position - 1) ? 1 : 0; return $t; } /** * 设置某一bit位的数值 0 or 1 * * @param int $position 1-16 * @param int $value 0|1 * @param 原始数值 $baseon 0x0000-0xffff * @return int */ function setstatus($position, $value, $baseon = null) { $t = pow(2, $position - 1); if($value) { $t = $baseon | $t; } elseif ($baseon !== null) { $t = $baseon & ~$t; } else { $t = ~$t; } return $t & 0xFFFF; } /** * 通知 * @param Integer $touid: 通知给谁 * @param String $type: 通知类型 * @param String $note: 语言key * @param Array $notevars: 语言变量对应的值 * @param Integer $system: 是否为系统通知 0:非系统通知; 1:系统通知 */ function notification_add($touid, $type, $note, $notevars = array(), $system = 0) { global $_G; $tospace = array('uid'=>$touid); space_merge($tospace, 'field_home'); $filter = empty($tospace['privacy']['filter_note'])?array():array_keys($tospace['privacy']['filter_note']); //检查用户屏蔽 if($filter && (in_array($type.'|0', $filter) || in_array($type.'|'.$_G['uid'], $filter))) { return false; } //获取note的语言 $notevars['actor'] = "".$_G['member']['username'].""; //非漫游通知 if(!is_numeric($type)) { $vars = explode(':', $note); if(count($vars) == 2) { $notestring = lang('plugin/'.$vars[0], $vars[1], $notevars); } else { $notestring = lang('notification', $note, $notevars); } $frommyapp = false; } else { $frommyapp = true; $notestring = $note; } //note去重 $oldnote = array(); if($notevars['from_id'] && $notevars['from_idtype']) { $oldnote = DB::fetch_first("SELECT * FROM ".DB::table('home_notification')." WHERE from_id='$notevars[from_id]' AND from_idtype='$notevars[from_idtype]' AND uid='$touid'"); } if(empty($oldnote['from_num'])) $oldnote['from_num'] = 0; $notevars['from_num'] = $notevars['from_num'] ? $notevars['from_num'] : 1; $setarr = array( 'uid' => $touid, 'type' => $type, 'new' => 1, 'authorid' => $_G['uid'], 'author' => $_G['username'], 'note' => addslashes($notestring), 'dateline' => $_G['timestamp'], 'from_id' => $notevars['from_id'], 'from_idtype' => $notevars['from_idtype'], 'from_num' => ($oldnote['from_num']+$notevars['from_num']) ); if($system) { $setarr['authorid'] = 0; $setarr['author'] = ''; } if($oldnote['id']) { DB::update('home_notification', $setarr, array('id'=>$oldnote['id'])); } else { $oldnote['new'] = 0; DB::insert('home_notification', $setarr); } //更新用户通知 if(empty($oldnote['new'])) { DB::query("UPDATE ".DB::table('common_member')." SET newprompt=newprompt+1 WHERE uid='$touid'"); //给用户发送邮件通知 require_once libfile('function/mail'); $mail_subject = lang('notification', 'mail_to_user'); sendmail_touser($touid, $mail_subject, $notestring, $frommyapp ? 'myapp' : $type); } //更新我的好友关系热度 if(!$system && $_G['uid'] && $touid != $_G['uid']) { DB::query("UPDATE ".DB::table('home_friend')." SET num=num+1 WHERE uid='$_G[uid]' AND fuid='$touid'"); } } /** * 发送管理通知 * @param $type - 通知类型 */ function manage_addnotify($type, $from_num = 0, $langvar = array()) { global $_G; $notifyusers = unserialize($_G['setting']['notifyusers']); $notifytypes = explode(',', $_G['setting']['adminnotifytypes']); $notifytypes = array_flip($notifytypes); $notearr = array('from_id' => 1,'from_idtype' => $type, 'from_num' => $from_num); if($langvar) { $langkey = $langvar['langkey']; $notearr = array_merge($notearr, $langvar); } else { $langkey = 'manage_'.$type; } foreach($notifyusers as $uid => $user) { if($user['types'][$notifytypes[$type]]) { notification_add($uid, $type, $langkey, $notearr, 1); } } } /** * 发送短消息(兼容提醒) * @param $toid - 接收方id * @param $subject - 标题 * @param $message - 内容 * @param $fromid - 发送方id */ function sendpm($toid, $subject, $message, $fromid = '', $replypmid = 0, $isusername = 0, $type = 0) { global $_G; if($fromid === '') { $fromid = $_G['uid']; } loaducenter(); return uc_pm_send($fromid, $toid, $subject, $message, 1, $replypmid, $isusername, $type); } //获得用户组图标 function g_icon($groupid, $return = 0) { global $_G; if(empty($_G['cache']['usergroups'][$groupid]['icon'])) { $s = ''; } else { if(substr($_G['cache']['usergroups'][$groupid]['icon'], 0, 5) == 'http:') { $s = ''; } else { $s = ''; } } if($return) { return $s; } else { echo $s; } } //从数据库中更新DIY模板文件 function updatediytemplate($targettplname = '') { global $_G; $r = false; $where = empty($targettplname) ? '' : " WHERE targettplname='$targettplname'"; $query = DB::query("SELECT * FROM ".DB::table('common_diy_data')."$where"); require_once libfile('function/portalcp'); while($value = DB::fetch($query)) { $r = save_diy_data($value['primaltplname'], $value['targettplname'], unserialize($value['diycontent'])); } return $r; } //获得用户唯一串 function space_key($uid, $appid=0) { global $_G; $siteuniqueid = DB::result_first("SELECT svalue FROM ".DB::table('common_setting')." WHERE skey='siteuniqueid'"); return substr(md5($siteuniqueid.'|'.$uid.(empty($appid)?'':'|'.$appid)), 8, 16); } //note post分表相关函数 /** * * 通过tid得到相应的单一post表名或post表集合 * @param $tids: 允许传进单个tid,也可以是tid集合 * @param $primary: 是否只查主题表 0:遍历所有表;1:只查主表 * @return 当传进来的是单一的tid将直接返回表名,否则返回表集合的二维数组例:array('forum_post' => array(tids),'forum_post_1' => array(tids)) * @TODO tid传进来的是字符串的,返回单个表名,传进来的是数组的,不管是不是一个数组,返回的还是数组,保证进出值对应 */ function getposttablebytid($tids, $primary = 0) { global $_G; $isstring = false; if(!is_array($tids)) { $tids = array(intval($tids)); $isstring = true; } //note 过滤重复的tid $tids = array_unique($tids); //note 反转数组、便于下面的踢除操作 $tids = array_flip($tids); if(!$primary) { loadcache('threadtableids'); $threadtableids = !empty($_G['cache']['threadtableids']) ? $_G['cache']['threadtableids'] : array(); if(!in_array(0, $threadtableids)) { $threadtableids = array_merge(array(0), $threadtableids); } } else { $threadtableids = array(0); } $tables = array(); $posttable = ''; $singletable = count($tids) > 1 ? false : true; //note 遍历存档表 foreach($threadtableids as $tableid) { $threadtable = $tableid ? "forum_thread_$tableid" : 'forum_thread'; $query = DB::query("SELECT tid, posttableid FROM ".DB::table($threadtable)." WHERE tid IN(".dimplode(array_keys($tids)).")"); while ($value = DB::fetch($query)) { $posttable = 'forum_post'.($value['posttableid'] ? "_$value[posttableid]" : ''); $tables[$posttable][$value['tid']] = $value['tid']; unset($tids[$value['tid']]); } if(!count($tids)) { break; } } if(empty($posttable)) { $posttable = 'forum_post'; $tables[$posttable] = array_flip($tids); } return $isstring ? $posttable : $tables; } /** * 获取论坛帖子表名 * @param $tableid: 分表ID,默认为:fourm_post表 * @param $prefix: 是否默认带有表前缀 * @return forum_post or forum_post_* */ function getposttable($tableid = 0, $prefix = false) { global $_G; $tableid = intval($tableid); if($tableid) { //TODO 可以考虑在此加入验证表名 loadcache('posttableids'); $tableid = $_G['cache']['posttableids'] && in_array($tableid, $_G['cache']['posttableids']) ? $tableid : 0; $tablename = 'forum_post'.($tableid ? "_$tableid" : ''); } else { $tablename = 'forum_post'; } if($prefix) { $tablename = DB::table($tablename); } return $tablename; } /** * 内存读写接口函数 * * @param 命令 $cmd (set|get|rm|check) * @param 键值 $key * @param 数据 $value * @param 有效期 $ttl * @return mix * * @example set : 写入内存 $ret = memory('set', 'test', 'ok') * @example get : 读取内存 $data = memory('get', 'test') * @example rm : 删除内存 $ret = memory('rm', 'test') * @example check : 检查内存功能是否可用 $allow = memory('check') */ function memory($cmd, $key='', $value='', $ttl = 0) { $discuz = & discuz_core::instance(); if($cmd == 'check') { return $discuz->mem->enable ? $discuz->mem->type : ''; } elseif($discuz->mem->enable && in_array($cmd, array('set', 'get', 'rm'))) { switch ($cmd) { case 'set': return $discuz->mem->set($key, $value, $ttl); break; case 'get': return $discuz->mem->get($key); break; case 'rm': return $discuz->mem->rm($key); break; } } return null; } /** * ip允许访问 * @param $ip 要检查的ip地址 * @param - $accesslist 允许访问的ip地址 * @param 返回结果 */ function ipaccess($ip, $accesslist) { return preg_match("/^(".str_replace(array("\r\n", ' '), array('|', ''), preg_quote($accesslist, '/')).")/", $ip); } /** * ip限制访问 * @param $ip 要检查的ip地址 * @param - $accesslist 允许访问的ip地址 * @param 返回结果 */ function ipbanned($onlineip) { global $_G; if($_G['setting']['ipaccess'] && !ipaccess($onlineip, $_G['setting']['ipaccess'])) { return TRUE; } loadcache('ipbanned'); if(empty($_G['cache']['ipbanned'])) { return FALSE; } else { if($_G['cache']['ipbanned']['expiration'] < TIMESTAMP) { require_once libfile('function/cache'); updatecache('ipbanned'); } return preg_match("/^(".$_G['cache']['ipbanned']['regexp'].")$/", $onlineip); } } //获得统计数 function getcount($tablename, $condition) { if(empty($condition)) { $where = '1'; } elseif(is_array($condition)) { $where = DB::implode_field_value($condition, ' AND '); } else { $where = $condition; } $ret = intval(DB::result_first("SELECT COUNT(*) AS num FROM ".DB::table($tablename)." WHERE $where")); return $ret; } /** * 系统级消息 */ function sysmessage($message) { require libfile('function/sysmessage'); show_system_message($message); } /** * 论坛权限 * @param $permstr - 权限信息 * @param $groupid - 只判断用户组 * @return 0 无权限 > 0 有权限 */ function forumperm($permstr, $groupid = 0) { global $_G; $groupidarray = array($_G['groupid']); if($groupid) { return preg_match("/(^|\t)(".$groupid.")(\t|$)/", $permstr); } foreach(explode("\t", $_G['member']['extgroupids']) as $extgroupid) { if($extgroupid = intval(trim($extgroupid))) { $groupidarray[] = $extgroupid; } } if($_G['setting']['verify']['enabled']) { getuserprofile('verify1'); foreach($_G['setting']['verify'] as $vid => $verify) { if($verify['available'] && $_G['member']['verify'.$vid] == 1) { $groupidarray[] = 'v'.$vid; } } } return preg_match("/(^|\t)(".implode('|', $groupidarray).")(\t|$)/", $permstr); } /** * PHP 兼容性函数 */ if(!function_exists('file_put_contents')) { if(!defined('FILE_APPEND')) define('FILE_APPEND', 8); function file_put_contents($filename, $data, $flag = 0) { $return = false; if($fp = @fopen($filename, $flag != FILE_APPEND ? 'w' : 'a')) { if($flag == LOCK_EX) @flock($fp, LOCK_EX); $return = fwrite($fp, is_array($data) ? implode('', $data) : $data); fclose($fp); } return $return; } } //检查权限 function checkperm($perm) { global $_G; return (empty($_G['group'][$perm])?'':$_G['group'][$perm]); } /** * 时间段设置检测 * @param $periods - 那种时间段 $settings[$periods] $settings['postbanperiods'] $settings['postmodperiods'] * @param $showmessage - 是否提示信息 * @return 返回检查结果 */ function periodscheck($periods, $showmessage = 1) { global $_G; if(!$_G['group']['disableperiodctrl'] && $_G['setting'][$periods]) { $now = dgmdate(TIMESTAMP, 'G.i', $_G['setting']['timeoffset']); foreach(explode("\r\n", str_replace(':', '.', $_G['setting'][$periods])) as $period) { list($periodbegin, $periodend) = explode('-', $period); if(($periodbegin > $periodend && ($now >= $periodbegin || $now < $periodend)) || ($periodbegin < $periodend && $now >= $periodbegin && $now < $periodend)) { $banperiods = str_replace("\r\n", ', ', $_G['setting'][$periods]); if($showmessage) { showmessage('period_nopermission', NULL, array('banperiods' => $banperiods), array('login' => 1)); } else { return TRUE; } } } } return FALSE; } //新用户发言 function cknewuser($return=0) { global $_G; $result = true; if(!$_G['uid']) return true; //不受防灌水限制 if(checkperm('disablepostctrl')) { return $result; } $ckuser = $_G['member']; //见习时间 if($_G['setting']['newbiespan'] && $_G['timestamp']-$ckuser['regdate']<$_G['setting']['newbiespan']*60) { if(empty($return)) showmessage('no_privilege_newbiespan', '', array('newbiespan' => $_G['setting']['newbiespan']), array('return' => true)); $result = false; } //需要上传头像 if($_G['setting']['need_avatar'] && empty($ckuser['avatarstatus'])) { if(empty($return)) showmessage('no_privilege_avatar', '', array(), array('return' => true)); $result = false; } //强制新用户激活邮箱 if($_G['setting']['need_email'] && empty($ckuser['emailstatus'])) { if(empty($return)) showmessage('no_privilege_email', '', array(), array('return' => true)); $result = false; } //强制新用户好友个数 if($_G['setting']['need_friendnum']) { space_merge($ckuser, 'count'); if($ckuser['friends'] < $_G['setting']['need_friendnum']) { if(empty($return)) showmessage('no_privilege_friendnum', '', array('friendnum' => $_G['setting']['need_friendnum']), array('return' => true)); $result = false; } } return $result; } function manyoulog($logtype, $uids, $action, $fid = '') { global $_G; if($_G['setting']['my_app_status'] && $logtype == 'user') { $action = daddslashes($action); $values = array(); $uids = is_array($uids) ? $uids : array($uids); foreach($uids as $uid) { $uid = intval($uid); $values[$uid] = "('$uid', '$action', '".TIMESTAMP."')"; } if($values) { DB::query("REPLACE INTO ".DB::table('common_member_log')." (`uid`, `action`, `dateline`) VALUES ".implode(',', $values)); } } } /** * 用户操作日志 * @param int $uid 用户ID * @param string $action 操作类型 tid=thread pid=post blogid=blog picid=picture doid=doing sid=share aid=article uid_cid/blogid_cid/sid_cid/picid_cid/aid_cid/topicid_cid=comment * @return bool */ function useractionlog($uid, $action) { $uid = intval($uid); if(empty($uid) || empty($action)) { return false; } $action = getuseraction($action); $timestamp = TIMESTAMP; DB::query("INSERT INTO ".DB::table('common_member_action_log')." (`uid`, `action`, `dateline`) VALUES ('$uid', '$action', '$timestamp')"); return true; } /** * 得到用户操作的代码或代表字符,参数为数字返回字符串,参数为字符串返回数字 * @param string/int $var * @return int/string 注意:如果失败返回false,请使用===判断,因为代码0代表tid */ function getuseraction($var) { $value = false; //操作代码 $ops = array('tid', 'pid', 'blogid', 'picid', 'doid', 'sid', 'aid', 'uid_cid', 'blogid_cid', 'sid_cid', 'picid_cid', 'aid_cid', 'topicid_cid'); if(is_numeric($var)) { $value = isset($ops[$var]) ? $ops[$var] : false; } else { $value = array_search($var, $ops); } return $value; } /** * 获取我的中心中展示的应用 */ function getuserapp($panel = 0) { require_once libfile('function/manyou'); manyou_getuserapp($panel); return true; } /** * 获取manyou应用本地图标路径 * @param $appid */ function getmyappiconpath($appid, $iconstatus=0) { if($iconstatus > 0) { return getglobal('setting/attachurl').'./'.'myapp/icon/'.$appid.'.jpg'; } return 'http://appicon.manyou.com/icons/'.$appid; } //获取超时时间 function getexpiration() { global $_G; $date = getdate($_G['timestamp']); return mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']) + 86400; } function return_bytes($val) { $val = trim($val); $last = strtolower($val{strlen($val)-1}); switch($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $val; } /** * 获取文字内的url列表 * * @param $message 文字 * @return url列表 * */ function get_url_list($message) { $return = array(); (strpos($message, '[/img]') || strpos($message, '[/flash]')) && $message = preg_replace("/\[img[^\]]*\]\s*([^\[\<\r\n]+?)\s*\[\/img\]|\[flash[^\]]*\]\s*([^\[\<\r\n]+?)\s*\[\/flash\]/is", '', $message); if(preg_match_all("/((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|thunder|qqdl|synacast){1}:\/\/|www\.)[^\[\]\"']+/i", $message, $urllist)) { foreach($urllist[0] as $key => $val) { $val = trim($val); $return[0][$key] = $val; if(!preg_match('/^http:\/\//is', $val)) $val = 'http://'.$val; $tmp = parse_url($val); $return[1][$key] = $tmp['host']; if($tmp['port']){ $return[1][$key] .= ":$tmp[port]"; } } } return $return; } function iswhitelist($host) { global $_G; static $iswhitelist = array(); if(isset($iswhitelist[$host])) { return $iswhitelist[$host]; } $hostlen = strlen($host); $iswhitelist[$host] = false; if(is_array($_G['cache']['domainwhitelist'])) foreach($_G['cache']['domainwhitelist'] as $val) { $domainlen = strlen($val); if($domainlen > $hostlen) { continue; } if(substr($host, -$domainlen) == $val) { $iswhitelist[$host] = true; break; } } if($iswhitelist[$host] == false) { $iswhitelist[$host] = $host == $_SERVER['HTTP_HOST']; } return $iswhitelist[$host]; } /** * 更新页面和模块的关系 * @param string $targettplname 页面名称 * @param array $blocks 模块IDS */ function update_template_block($targettplname, $blocks) { //更新模板中包含的模块(bid) if(!empty($targettplname)) { if(empty($blocks)) { DB::delete('common_template_block', array('targettplname'=>$targettplname)); } else { //原所有BIDS $oldbids = array(); $query = DB::query('SELECT bid FROM '.DB::table('common_template_block')." WHERE targettplname='$targettplname'"); while($value = DB::fetch($query)) { $oldbids[] = $value['bid']; } //新增加的BIDS $newaddbids = array_diff($blocks, $oldbids); //清空原关联关系 DB::delete('common_template_block', array('targettplname'=>$targettplname)); //唯一性处理 $blocks = array_unique($blocks); //保存新的关联关系 $values = array(); foreach ($blocks as $bid) { $values[] = "('$targettplname','$bid')"; } if (!empty($values)) { DB::query("INSERT INTO ".DB::table('common_template_block')." (targettplname,bid) VALUES ".implode(',', $values)); } //更新模块的权限 if(!empty($newaddbids)) { require_once libfile('class/blockpermission'); $tplpermission = & template_permission::instance(); $tplpermission->add_blocks($targettplname, $newaddbids); } } } } if(!function_exists('http_build_query')) { function http_build_query($data, $numeric_prefix='', $arg_separator='', $prefix='') { $render = array(); if (empty($arg_separator)) { $arg_separator = ini_get('arg_separator.output'); empty($arg_separator) && $arg_separator = '&'; } foreach ((array) $data as $key => $val) { if (is_array($val) || is_object($val)) { $_key = empty($prefix) ? "{$key}[%s]" : sprintf($prefix, $key) . "[%s]"; $_render = http_build_query($val, '', $arg_separator, $_key); if (!empty($_render)) { $render[] = $_render; } } else { if (is_numeric($key) && empty($prefix)) { $render[] = urlencode("{$numeric_prefix}{$key}") . "=" . urlencode($val); } else { if (!empty($prefix)) { $_key = sprintf($prefix, $key); $render[] = urlencode($_key) . "=" . urlencode($val); } else { $render[] = urlencode($key) . "=" . urlencode($val); } } } } $render = implode($arg_separator, $render); if (empty($render)) { $render = ''; } return $render; } } /** * 获取批定类型的关联连接 * * @param string $extent 内容所需关联链接范围 article, forum, group, blog * @return string 有效的关联链接 */ function getrelatedlink($extent) { global $_G; loadcache('relatedlink'); $allextent = array('article' => 0, 'forum' => 1, 'group' => 2, 'blog' => 3); $links = array(); if($_G['cache']['relatedlink'] && isset($allextent[$extent])) { foreach($_G['cache']['relatedlink'] as $link) { $link['extent'] = sprintf('%04b', $link['extent']); if($link['extent'][$allextent[$extent]] && $link['name'] && $link['url']) { $links[] = daddslashes($link); } } } return $links; } /** * 通过 AID 获取附件表名 * @param $aid */ function getattachtablebyaid($aid) { $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE aid='$aid'"); return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused'); } /** * 返回指定 TID 所对应的附件表编号 * @param $tid */ function getattachtableid($tid) { $tid = (string)$tid; return intval($tid{strlen($tid)-1}); } /** * 通过 TID 获取附件表名 * @param $tid */ function getattachtablebytid($tid) { return 'forum_attachment_'.getattachtableid($tid); } /** * 通过 PID 获取附件表名 * @param $pid */ function getattachtablebypid($pid) { $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE pid='$pid' LIMIT 1"); return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused'); } /** * 添加一个新的附件索引记录,并返回新附件 ID * @param $uid */ function getattachnewaid($uid = 0) { global $_G; $uid = !$uid ? $_G['uid'] : $uid; return DB::insert('forum_attachment', array('tid' => 0, 'pid' => 0, 'uid' => $uid, 'tableid' => 127), true); } /** * 获取 SEO设置 * @param string $page 调用哪个页面的 * @param array $data 可替换数据 * @return array('seotitle', 'seodescription', 'seokeywords') */ function get_seosetting($page, $data = array(), $defset = array()) { global $_G; $searchs = array('{bbname}'); $replaces = array($_G['setting']['bbname']); $seotitle = $seodescription = $seokeywords = ''; $titletext = $defset['seotitle'] ? $defset['seotitle'] : $_G['setting']['seotitle'][$page]; $descriptiontext = $defset['seodescription'] ? $defset['seodescription'] : $_G['setting']['seodescription'][$page]; $keywordstext = $defset['seokeywords'] ? $defset['seokeywords'] : $_G['setting']['seokeywords'][$page]; preg_match_all("/\{([a-z0-9_-]+?)\}/", $titletext.$descriptiontext.$keywordstext, $pageparams); if($pageparams) { foreach($pageparams[1] as $var) { $searchs[] = '{'.$var.'}'; //处理分页,分页数大于1时显示 if($var == 'page') { $data['page'] = $data['page'] > 1 ? lang('core', 'page', array('page' => $data['page'])) : ''; } $replaces[] = $data[$var] ? strip_tags($data[$var]) : ''; } if($titletext) { $seotitle = strreplace_strip_split($searchs, $replaces, $titletext); } if($descriptiontext && (CURSCRIPT == 'forum' || IS_ROBOT || $_G['adminid'] == 1)) { $seodescription = strreplace_strip_split($searchs, $replaces, $descriptiontext); } if($keywordstext && (CURSCRIPT == 'forum' || IS_ROBOT || $_G['adminid'] == 1)) { $seokeywords = strreplace_strip_split($searchs, $replaces, $keywordstext); } } return array($seotitle, $seodescription, $seokeywords); } /** * 需处理连续分隔符的str_replace() * @param array $searchs 被替换的数组 * @param array $replaces 用于替换的数组 * @param string $str 目标字符串 */ function strreplace_strip_split($searchs, $replaces, $str) { $searchspace = array('((\s*\-\s*)+)', '((\s*\,\s*)+)', '((\s*\|\s*)+)', '((\s*\t\s*)+)', '((\s*_\s*)+)'); $replacespace = array('-', ',', '|', ' ', '_'); return trim(preg_replace($searchspace, $replacespace, str_replace($searchs, $replaces, $str)), ' ,-|_'); } /** * 返回带第几页的title * @global $_G * @param string $navtitle 源标题 * @param int $page 页码 * @return string */ function get_title_page($navtitle, $page){ if($page > 1) { $navtitle .= ' - '.lang('core', 'page', array('page' => $page)); } return $navtitle; } /** * * 生成缩略图文件名 * @param String $fileStr: 原文件名,允许附带路径 * @param String $extend: 新文件名后缀 * @param Boolean $holdOldExt: 是否保留原扩展名 * @return 返加新的后缀文件名 */ function getimgthumbname($fileStr, $extend='.thumb.jpg', $holdOldExt=true) { if(empty($fileStr)) { return ''; } //去掉原扩展名 if(!$holdOldExt) { $fileStr = substr($fileStr, 0, strrpos($fileStr, '.')); } $extend = strstr($extend, '.') ? $extend : '.'.$extend; return $fileStr.$extend; } /** * 更新数据的审核状态 * @param $idtype 数据类型 tid=thread pid=post blogid=blog picid=picture doid=doing sid=share aid=article uid_cid/blogid_cid/sid_cid/picid_cid/aid_cid/topicid_cid=comment * @param $ids ID 数组、ID 值 * @param $status 状态 0=加入审核(默认) 1=忽略审核 2=审核通过 */ function updatemoderate($idtype, $ids, $status = 0) { global $_G; $ids = is_array($ids) ? $ids : array($ids); if(!$ids) { return; } if(!$status) { foreach($ids as $id) { DB::insert('common_moderate', array('id' => $id, 'idtype' => $idtype, 'status' => 0, 'dateline' => $_G['timestamp']), false, true); } } elseif($status == 1) { DB::update('common_moderate', array('status' => 1), "id IN (".dimplode($ids).") AND idtype='$idtype'"); } elseif($status == 2) { DB::delete('common_moderate', "id IN (".dimplode($ids).") AND idtype='$idtype'"); } } /** * 显示漫游应用公告 */ function userappprompt() { global $_G; if($_G['setting']['my_app_status'] && $_G['setting']['my_openappprompt'] && empty($_G['cookie']['userappprompt'])) { $sid = $_G['setting']['my_siteid']; $ts = $_G['timestamp']; $key = md5($sid.$ts.$_G['setting']['my_sitekey']); $uchId = $_G['uid'] ? $_G['uid'] : 0; echo ''; } } function makeSearchSignUrl() { global $_G; $url = ''; $params = array(); $my_search_data = unserialize($_G['setting']['my_search_data']); $my_siteid = $_G['setting']['my_siteid']; $my_sitekey= $_G['setting']['my_sitekey']; require_once libfile('function/cloud'); if($my_search_data['status'] && getcloudappstatus('search') && $my_siteid) { $my_extgroupids = array(); $_extgroupids = explode("\t", $_G['member']['extgroupids']); foreach($_extgroupids as $v) { if ($v) { $my_extgroupids[] = $v; } } $my_extgroupids_str = implode(',', $my_extgroupids); $params = array('sId' => $my_siteid, 'ts' => time(), 'cuId' => $_G['uid'], 'cuName' => $_G['username'], 'gId' => intval($_G['groupid']), 'agId' => intval($_G['adminid']), 'egIds' => $my_extgroupids_str, // 'fIds' => $params['fIds'], 'fmSign' => '', ); $groupIds = array($params['gId']); if ($params['agId']) { $groupIds[] = $params['agId']; } if ($my_extgroupids) { $groupIds = array_merge($groupIds, $my_extgroupids); } $groupIds = array_unique($groupIds); foreach($groupIds as $v) { $key = 'ugSign' . $v; $params[$key] = ''; } $params['sign'] = md5(implode('|', $params) . '|' . $my_sitekey); $params['charset'] = $_G['charset']; $mySearchData = unserialize($_G['setting']['my_search_data']); if ($mySearchData['domain']) { $domain = $mySearchData['domain']; } else { $domain = 'search.discuz.qq.com'; } $url = 'http://' . $domain . '/f/discuz'; } return !empty($url) ? array($url, $params) : array(); } ?>

你可能感兴趣的:(【discuzx2,x3深入研究】)