找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2967|回复: 0

[分享] Discuz开发之function_core常用函数解析

[复制链接]
发表于 2017-11-15 10:54:09 | 显示全部楼层 |阅读模式 来自 河南省新乡市
Discuz function_core 常用函数解析,有需要的朋友可以参考下。
Discuz!常用函数解析
  1. <?php  
  2.   
  3. /**
  4. *      [Discuz!] (C)2001-2099 Comsenz Inc.
  5. *      This is NOT a freeware, use is subject to license terms
  6. *
  7. *      $Id: function_core.php 34523 2014-05-15 04:22:29Z nemohou $
  8. */  
  9.   
  10. if(!defined('IN_DISCUZ')) {  
  11.         exit('Access Denied');  
  12. }  
  13.   
  14. define('DISCUZ_CORE_FUNCTION', true);  
  15.   
  16. /**
  17. * like url encode, but can encode full url, not only the parms
  18. * this function to encode URLs according to RFC 3986(exclude char ',(,) )
  19. * @param type $url
  20. * @return type
  21. */  
  22. function durlencode($url) {  
  23.         static $fix = array('%21', '%2A','%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');  
  24.         static $replacements = array('!', '*', ';', ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]");  
  25.         return str_replace($fix, $replacements, urlencode($url));  
  26. }  
  27.   
  28. /**
  29. * 系统错误处理
  30. * @param <type> $message 错误信息a
  31. * @param <type> $show 是否显示信息
  32. * @param <type> $save 是否存入日志
  33. * @param <type> $halt 是否中断访问
  34. */  
  35. function system_error($message, $show = true, $save = true, $halt = true) {  
  36.         discuz_error::system_error($message, $show, $save, $halt);  
  37. }  
  38.   
  39. /**
  40. * 更新 session
  41. * @global <type> $_G
  42. * @staticvar boolean $updated
  43. * @return boolean
  44. */  
  45. function updatesession() {  
  46.         return C::app()->session->updatesession();  
  47. }  
  48.   
  49. /**
  50. * 设置全局 $_G 中的变量
  51. * @global <array> $_G
  52. * @param <string> $key 键
  53. * @param <string> $value 值
  54. * @return true
  55. *
  56. * @example
  57. * setglobal('test', 1); // $_G['test'] = 1;
  58. * setglobal('config/test/abc') = 2; //$_G['config']['test']['abc'] = 2;
  59. *
  60. */  
  61. function setglobal($key , $value, $group = null) {  
  62.         global $_G;  
  63.         $key = explode('/', $group === null ? $key : $group.'/'.$key);  
  64.         $p = &$_G;  
  65.         foreach ($key as $k) {  
  66.                 if(!isset($p[$k]) || !is_array($p[$k])) {  
  67.                         $p[$k] = array();  
  68.                 }  
  69.                 $p = &$p[$k];  
  70.         }  
  71.         $p = $value;  
  72.         return true;  
  73. }  
  74.   
  75. /**
  76. * 获取全局变量 $_G 当中的某个数值
  77. * @example
  78. * $v = getglobal('test'); // $v = $_G['test']
  79. * $v = getglobal('test/hello/ok');  // $v = $_G['test']['hello']['ok']
  80. *
  81. * @global  $_G
  82. * @param string $key
  83. *
  84. * @return type
  85. */  
  86. function getglobal($key, $group = null) {  
  87.         global $_G;  
  88.         $key = explode('/', $group === null ? $key : $group.'/'.$key);  
  89.         $v = &$_G;  
  90.         foreach ($key as $k) {  
  91.                 if (!isset($v[$k])) {  
  92.                         return null;  
  93.                 }  
  94.                 $v = &$v[$k];  
  95.         }  
  96.         return $v;  
  97. }  
  98.   
  99. /**
  100. * 取出 get, post, cookie 当中的某个变量
  101. *
  102. * @param string $k  key 值
  103. * @param string $type 类型
  104. * @return mix
  105. */  
  106. function getgpc($k, $type='GP') {  
  107.         $type = strtoupper($type);  
  108.         switch($type) {  
  109.                 case 'G': $var = &$_GET; break;  
  110.                 case 'P': $var = &$_POST; break;  
  111.                 case 'C': $var = &$_COOKIE; break;  
  112.                 default:  
  113.                         if(isset($_GET[$k])) {  
  114.                                 $var = &$_GET;  
  115.                         } else {  
  116.                                 $var = &$_POST;  
  117.                         }  
  118.                         break;  
  119.         }  
  120.   
  121.         return isset($var[$k]) ? $var[$k] : NULL;  
  122.   
  123. }  
  124.   
  125. /**
  126. * 根据uid 获取用户基本数据
  127. * @staticvar array $users 存放已经获取的用户的信息,避免重复查库
  128. * @param <int> $uid
  129. * @param int $fetch_archive 0:只查询主表,1:查询主表和存档表,2只查询存档表
  130. * @return <array>
  131. */  
  132. function getuserbyuid($uid, $fetch_archive = 0) {  
  133.         static $users = array();  
  134.         if(empty($users[$uid])) {  
  135.                 $users[$uid] = C::t('common_member'.($fetch_archive === 2 ? '_archive' : ''))->fetch($uid);  
  136.                 if($fetch_archive === 1 && empty($users[$uid])) {  
  137.                         $users[$uid] = C::t('common_member_archive')->fetch($uid);  
  138.                 }  
  139.         }  
  140.         if(!isset($users[$uid]['self']) && $uid == getglobal('uid') && getglobal('uid')) {  
  141.                 $users[$uid]['self'] = 1;  
  142.         }  
  143.         return $users[$uid];  
  144. }  
  145.   
  146. /**
  147. * 获取当前用户的扩展资料
  148. * @param $field 字段
  149. */  
  150. function getuserprofile($field) {  
  151.         global $_G;  
  152.         if(isset($_G['member'][$field])) {  
  153.                 return $_G['member'][$field];  
  154.         }  
  155.         static $tablefields = array(  
  156.                 'count'                => array('extcredits1','extcredits2','extcredits3','extcredits4','extcredits5','extcredits6','extcredits7','extcredits8','friends','posts','threads','digestposts','doings','blogs','albums','sharings','attachsize','views','oltime','todayattachs','todayattachsize', 'follower', 'following', 'newfollower', 'blacklist'),  
  157.                 'status'        => array('regip','lastip','lastvisit','lastactivity','lastpost','lastsendmail','invisible','buyercredit','sellercredit','favtimes','sharetimes','profileprogress'),  
  158.                 'field_forum'        => array('publishfeed','customshow','customstatus','medals','sightml','groupterms','authstr','groups','attentiongroup'),  
  159.                 'field_home'        => array('videophoto','spacename','spacedescription','domain','addsize','addfriend','menunum','theme','spacecss','blockposition','recentnote','spacenote','privacy','feedfriend','acceptemail','magicgift','stickblogs'),  
  160.                 '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'),  
  161.                 'verify'        => array('verify1', 'verify2', 'verify3', 'verify4', 'verify5', 'verify6', 'verify7'),  
  162.         );  
  163.         $profiletable = '';  
  164.         foreach($tablefields as $table => $fields) {  
  165.                 if(in_array($field, $fields)) {  
  166.                         $profiletable = $table;  
  167.                         break;  
  168.                 }  
  169.         }  
  170.         if($profiletable) {  
  171.                 /*$data = array();
  172.                 if($_G['uid']) {
  173.                         //$data = DB::fetch_first("SELECT ".implode(', ', $tablefields[$profiletable])." FROM ".DB::table('common_member_'.$profiletable)." WHERE uid='$_G[uid]'");
  174.                         $data = C::t('common_member_'.$profiletable)->fetch($_G['uid']);
  175.                 }
  176.                 if(!$data) {
  177.                         foreach($tablefields[$profiletable] as $k) {
  178.                                 $data[$k] = '';
  179.                         }
  180.                 }
  181.                 $_G['member'] = array_merge(is_array($_G['member']) ? $_G['member'] : array(), $data);*/  
  182.   
  183.                 if(is_array($_G['member']) && $_G['member']['uid']) {  
  184.                         space_merge($_G['member'], $profiletable);  
  185.                 } else {  
  186.                         foreach($tablefields[$profiletable] as $k) {  
  187.                                 $_G['member'][$k] = '';  
  188.                         }  
  189.                 }  
  190.                 return $_G['member'][$field];  
  191.         }  
  192.         return null;  
  193. }  
  194.   
  195. /**
  196. * 对字符串或者输入进行 addslashes 操作
  197. * @param <mix> $string
  198. * @param <int> $force
  199. * @return <mix>
  200. */  
  201. function daddslashes($string, $force = 1) {  
  202.         if(is_array($string)) {  
  203.                 $keys = array_keys($string);  
  204.                 foreach($keys as $key) {  
  205.                         $val = $string[$key];  
  206.                         unset($string[$key]);  
  207.                         $string[addslashes($key)] = daddslashes($val, $force);  
  208.                 }  
  209.         } else {  
  210.                 $string = addslashes($string);  
  211.         }  
  212.         return $string;  
  213. }  
  214.   
  215. /**
  216. * 对字符串进行加密和解密
  217. * @param <string> $string
  218. * @param <string> $operation  DECODE 解密 | ENCODE  加密
  219. * @param <string> $key 当为空的时候,取全局密钥
  220. * @param <int> $expiry 有效期,单位秒
  221. * @return <string>
  222. */  
  223. function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {  
  224.         $ckey_length = 4;  
  225.         $key = md5($key != '' ? $key : getglobal('authkey'));  
  226.         $keya = md5(substr($key, 0, 16));  
  227.         $keyb = md5(substr($key, 16, 16));  
  228.         $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';  
  229.   
  230.         $cryptkey = $keya.md5($keya.$keyc);  
  231.         $key_length = strlen($cryptkey);  
  232.   
  233.         $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;  
  234.         $string_length = strlen($string);  
  235.   
  236.         $result = '';  
  237.         $box = range(0, 255);  
  238.   
  239.         $rndkey = array();  
  240.         for($i = 0; $i <= 255; $i++) {  
  241.                 $rndkey[$i] = ord($cryptkey[$i % $key_length]);  
  242.         }  
  243.   
  244.         for($j = $i = 0; $i < 256; $i++) {  
  245.                 $j = ($j + $box[$i] + $rndkey[$i]) % 256;  
  246.                 $tmp = $box[$i];  
  247.                 $box[$i] = $box[$j];  
  248.                 $box[$j] = $tmp;  
  249.         }  
  250.   
  251.         for($a = $j = $i = 0; $i < $string_length; $i++) {  
  252.                 $a = ($a + 1) % 256;  
  253.                 $j = ($j + $box[$a]) % 256;  
  254.                 $tmp = $box[$a];  
  255.                 $box[$a] = $box[$j];  
  256.                 $box[$j] = $tmp;  
  257.                 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));  
  258.         }  
  259.   
  260.         if($operation == 'DECODE') {  
  261.                 if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {  
  262.                         return substr($result, 26);  
  263.                 } else {  
  264.                         return '';  
  265.                 }  
  266.         } else {  
  267.                 return $keyc.str_replace('=', '', base64_encode($result));  
  268.         }  
  269.   
  270. }  
  271.   
  272. function fsocketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) {  
  273.         $fp = '';  
  274.         if(function_exists('fsockopen')) {  
  275.                 $fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout);  
  276.         } elseif(function_exists('pfsockopen')) {  
  277.                 $fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout);  
  278.         } elseif(function_exists('stream_socket_client')) {  
  279.                 //note php5支持  
  280.                 $fp = @stream_socket_client($hostname.':'.$port, $errno, $errstr, $timeout);  
  281.         }  
  282.         return $fp;  
  283. }  
  284.   
  285. /**
  286. * 远程文件文件请求兼容函数
  287. */  
  288. function dfsockopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE', $allowcurl = TRUE, $position = 0, $files = array()) {  
  289.         require_once libfile('function/filesock');  
  290.         return _dfsockopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block, $encodetype, $allowcurl, $position, $files);  
  291. }  
  292.   
  293. /**
  294. * HTML转义字符
  295. * @param $string - 字符串
  296. * @param $flags 参见手册 htmlspecialchars
  297. * @return 返回转义好的字符串
  298. */  
  299. function dhtmlspecialchars($string, $flags = null) {  
  300.         if(is_array($string)) {  
  301.                 foreach($string as $key => $val) {  
  302.                         $string[$key] = dhtmlspecialchars($val, $flags);  
  303.                 }  
  304.         } else {  
  305.                 if($flags === null) {  
  306.                         $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);  
  307.                         if(strpos($string, '&#') !== false) {  
  308.                                 $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);  
  309.                         }  
  310.                 } else {  
  311.                         if(PHP_VERSION < '5.4.0') {  
  312.                                 $string = htmlspecialchars($string, $flags);  
  313.                         } else {  
  314.                                 if(strtolower(CHARSET) == 'utf-8') {  
  315.                                         $charset = 'UTF-8';  
  316.                                 } else {  
  317.                                         $charset = 'ISO-8859-1';  
  318.                                 }  
  319.                                 $string = htmlspecialchars($string, $flags, $charset);  
  320.                         }  
  321.                 }  
  322.         }  
  323.         return $string;  
  324. }  
  325.   
  326. /**
  327. * 退出程序 同 exit 的区别, 对输出数据会进行 重新加工和处理
  328. * 通常情况下,我们建议使用本函数终止程序, 除非有特别需求
  329. * @param <type> $message
  330. */  
  331. function dexit($message = '') {  
  332.         echo $message;  
  333.         output();  
  334.         exit();  
  335. }  
  336.   
  337. /**
  338. * 同 php header函数, 针对 location 跳转做了特殊处理
  339. * @param <type> $string
  340. * @param <type> $replace
  341. * @param <type> $http_response_code
  342. */  
  343. function dheader($string, $replace = true, $http_response_code = 0) {  
  344.         //noteX 手机header跳转的统一修改(IN_MOBILE)  
  345.         $islocation = substr(strtolower(trim($string)), 0, 8) == 'location';  
  346.         if(defined('IN_MOBILE') && strpos($string, 'mobile') === false && $islocation) {  
  347.                 if (strpos($string, '?') === false) {  
  348.                         $string = $string.'?mobile='.IN_MOBILE;  
  349.                 } else {  
  350.                         if(strpos($string, '#') === false) {  
  351.                                 $string = $string.'&mobile='.IN_MOBILE;  
  352.                         } else {  
  353.                                 $str_arr = explode('#', $string);  
  354.                                 $str_arr[0] = $str_arr[0].'&mobile='.IN_MOBILE;  
  355.                                 $string = implode('#', $str_arr);  
  356.                         }  
  357.                 }  
  358.         }  
  359.         $string = str_replace(array("\r", "\n"), array('', ''), $string);  
  360.         if(empty($http_response_code) || PHP_VERSION < '4.3' ) {  
  361.                 @header($string, $replace);  
  362.         } else {  
  363.                 @header($string, $replace, $http_response_code);  
  364.         }  
  365.         if($islocation) {  
  366.                 exit();  
  367.         }  
  368. }  
  369.   
  370. /**
  371. * 设置cookie
  372. * @param $var - 变量名
  373. * @param $value - 变量值
  374. * @param $life - 生命期
  375. * @param $prefix - 前缀
  376. */  
  377. function dsetcookie($var, $value = '', $life = 0, $prefix = 1, $httponly = false) {  
  378.   
  379.         global $_G;  
  380.   
  381.         $config = $_G['config']['cookie'];  
  382.   
  383.         $_G['cookie'][$var] = $value;  
  384.         $var = ($prefix ? $config['cookiepre'] : '').$var;  
  385.         $_COOKIE[$var] = $value;  
  386.   
  387.         if($value == '' || $life < 0) {  
  388.                 $value = '';  
  389.                 $life = -1;  
  390.         }  
  391.   
  392.         /*手机浏览器设置cookie,强制取消HttpOnly(IN_MOBILE)*/  
  393.         if(defined('IN_MOBILE')) {  
  394.                 $httponly = false;  
  395.         }  
  396.   
  397.         $life = $life > 0 ? getglobal('timestamp') + $life : ($life < 0 ? getglobal('timestamp') - 31536000 : 0);  
  398.         $path = $httponly && PHP_VERSION < '5.2.0' ? $config['cookiepath'].'; HttpOnly' : $config['cookiepath'];  
  399.   
  400.         $secure = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;  
  401.         if(PHP_VERSION < '5.2.0') {  
  402.                 setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure);  
  403.         } else {  
  404.                 setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure, $httponly);  
  405.         }  
  406. }  
  407.   
  408. /**
  409. * 获取cookie
  410. */  
  411. function getcookie($key) {  
  412.         global $_G;  
  413.         return isset($_G['cookie'][$key]) ? $_G['cookie'][$key] : '';  
  414. }  
  415.   
  416. /**
  417. * 获取文件扩展名
  418. */  
  419. function fileext($filename) {  
  420.         return addslashes(strtolower(substr(strrchr($filename, '.'), 1, 10)));  
  421. }  
  422.   
  423. //note 规则待调整  
  424. function formhash($specialadd = '') {  
  425.         global $_G;  
  426.         $hashadd = defined('IN_ADMINCP') ? 'Only For Discuz! Admin Control Panel' : '';  
  427.         return substr(md5(substr($_G['timestamp'], 0, -7).$_G['username'].$_G['uid'].$_G['authkey'].$hashadd.$specialadd), 8, 8);  
  428. }  
  429.   
  430. function checkrobot($useragent = '') {  
  431.         static $kw_spiders = array('bot', 'crawl', 'spider' ,'slurp', 'sohu-search', 'lycos', 'robozilla');  
  432.         static $kw_browsers = array('msie', 'netscape', 'opera', 'konqueror', 'mozilla');  
  433.   
  434.         $useragent = strtolower(empty($useragent) ? $_SERVER['HTTP_USER_AGENT'] : $useragent);  
  435.         if(strpos($useragent, 'http://') === false && dstrpos($useragent, $kw_browsers)) return false;  
  436.         if(dstrpos($useragent, $kw_spiders)) return true;  
  437.         return false;  
  438. }  
  439. /**
  440. * 检查是否是以手机浏览器进入(IN_MOBILE)
  441. */  
  442. function checkmobile() {  
  443.         global $_G;  
  444.         $mobile = array();  
  445.         static $touchbrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',  
  446.                                 'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',  
  447.                                 'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',  
  448.                                 'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',  
  449.                                 'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',  
  450.                                 'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',  
  451.                                 'benq', 'haier', '^lct', '320x320', '240x320', '176x220', 'windows phone');  
  452.         static $wmlbrowser_list = array('cect', 'compal', 'ctl', 'lg', 'nec', 'tcl', 'alcatel', 'ericsson', 'bird', 'daxian', 'dbtel', 'eastcom',  
  453.                         'pantech', 'dopod', 'philips', 'haier', 'konka', 'kejian', 'lenovo', 'benq', 'mot', 'soutec', 'nokia', 'sagem', 'sgh',  
  454.                         'sed', 'capitel', 'panasonic', 'sonyericsson', 'sharp', 'amoi', 'panda', 'zte');  
  455.   
  456.         static $pad_list = array('ipad');//note 包含ipad,WebOS HP Touchpad,Samsung Galaxy Pad  
  457.   
  458.         $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);  
  459.   
  460.         //note 判断是否为pad浏览器  
  461.         if(dstrpos($useragent, $pad_list)) {  
  462.                 return false;  
  463.         }  
  464.         if(($v = dstrpos($useragent, $touchbrowser_list, true))){  
  465.                 $_G['mobile'] = $v;  
  466.                 return '2'; //默认触屏版  
  467.         }  
  468.         //note wml版手机浏览器 //isset($_SERVER[HTTP_X_WAP_PROFILE]) or isset($_SERVER[HTTP_PROFILE]) 这两个属性暂不使用  
  469.         if(($v = dstrpos($useragent, $wmlbrowser_list))) {  
  470.                 $_G['mobile'] = $v;  
  471.                 return '3'; //wml版  
  472.         }  
  473.         $brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');  
  474.         if(dstrpos($useragent, $brower)) return false;  
  475.   
  476.         $_G['mobile'] = 'unknown';  
  477.         if(isset($_G['mobiletpl'][$_GET['mobile']])) {  
  478.                 return true;  
  479.         } else {  
  480.                 return false;  
  481.         }  
  482. }  
  483.   
  484. /**
  485. * 字符串方式实现 preg_match("/(s1|s2|s3)/", $string, $match)
  486. * @param string $string 源字符串
  487. * @param array $arr 要查找的字符串 如array('s1', 's2', 's3')
  488. * @param bool $returnvalue 是否返回找到的值
  489. * @return bool
  490. */  
  491. function dstrpos($string, $arr, $returnvalue = false) {  
  492.         if(empty($string)) return false;  
  493.         foreach((array)$arr as $v) {  
  494.                 if(strpos($string, $v) !== false) {  
  495.                         $return = $returnvalue ? $v : true;  
  496.                         return $return;  
  497.                 }  
  498.         }  
  499.         return false;  
  500. }  
  501.   
  502. /**
  503. * 检查邮箱是否有效
  504. * @param $email 要检查的邮箱
  505. * @param 返回结果
  506. */  
  507. function isemail($email) {  
  508.         return strlen($email) > 6 && strlen($email) <= 32 && preg_match("/^([A-Za-z0-9\-_.+]+)@([A-Za-z0-9\-]+[.][A-Za-z0-9\-.]+)$/", $email);  
  509. }  
  510.   
  511. /**
  512. * 问题答案加密
  513. * @param $questionid - 问题
  514. * @param $answer - 答案
  515. * @return 返回加密的字串
  516. */  
  517. function quescrypt($questionid, $answer) {  
  518.         return $questionid > 0 && $answer != '' ? substr(md5($answer.md5($questionid)), 16, 8) : '';  
  519. }  
  520.   
  521. /**
  522. * 产生随机码
  523. * @param $length - 要多长
  524. * @param $numberic - 数字还是字符串
  525. * @return 返回字符串
  526. */  
  527. function random($length, $numeric = 0) {  
  528.         $seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);  
  529.         $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));  
  530.         if($numeric) {  
  531.                 $hash = '';  
  532.         } else {  
  533.                 $hash = chr(rand(1, 26) + rand(0, 1) * 32 + 64);  
  534.                 $length--;  
  535.         }  
  536.         $max = strlen($seed) - 1;  
  537.         for($i = 0; $i < $length; $i++) {  
  538.                 $hash .= $seed{mt_rand(0, $max)};  
  539.         }  
  540.         return $hash;  
  541. }  
  542.   
  543. /**
  544. * 判断一个字符串是否在另一个字符串中存在
  545. *
  546. * @param string 原始字串 $string
  547. * @param string 查找 $find
  548. * @return boolean
  549. */  
  550. function strexists($string, $find) {  
  551.         return !(strpos($string, $find) === FALSE);  
  552. }  
  553.   
  554. /**
  555. * 获取头像
  556. *
  557. * @param int $uid 需要获取的用户UID值
  558. * @param string $size 获取尺寸 'small', 'middle', 'big'
  559. * @param boolean $returnsrc 是否直接返回图片src
  560. * @param boolean $real 是否返回真实图片
  561. * @param boolean $static 是否返回真实路径
  562. * @param string $ucenterurl 强制uc路径
  563. */  
  564. function avatar($uid, $size = 'middle', $returnsrc = FALSE, $real = FALSE, $static = FALSE, $ucenterurl = '') {  
  565.         global $_G;  
  566.         if($_G['setting']['plugins']['func'][HOOKTYPE]['avatar']) {  
  567.                 $_G['hookavatar'] = '';  
  568.                 $param = func_get_args();  
  569.                 hookscript('avatar', 'global', 'funcs', array('param' => $param), 'avatar');  
  570.                 if($_G['hookavatar']) {  
  571.                         return $_G['hookavatar'];  
  572.                 }  
  573.         }  
  574.         static $staticavatar;  
  575.         if($staticavatar === null) {  
  576.                 $staticavatar = $_G['setting']['avatarmethod'];  
  577.         }  
  578.   
  579.         $ucenterurl = empty($ucenterurl) ? $_G['setting']['ucenterurl'] : $ucenterurl;  
  580.         $size = in_array($size, array('big', 'middle', 'small')) ? $size : 'middle';  
  581.         $uid = abs(intval($uid));  
  582.         if(!$staticavatar && !$static) {  
  583.                 return $returnsrc ? $ucenterurl.'/avatar.php?uid='.$uid.'&size='.$size.($real ? '&type=real' : '') : '<img src="'.$ucenterurl.'/avatar.php?uid='.$uid.'&size='.$size.($real ? '&type=real' : '').'" />';  
  584.         } else {  
  585.                 $uid = sprintf("%09d", $uid);  
  586.                 $dir1 = substr($uid, 0, 3);  
  587.                 $dir2 = substr($uid, 3, 2);  
  588.                 $dir3 = substr($uid, 5, 2);  
  589.                 $file = $ucenterurl.'/data/avatar/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($uid, -2).($real ? '_real' : '').'_avatar_'.$size.'.jpg';  
  590.                 return $returnsrc ? $file : '<img src="'.$file.'" onerror="this.onerror=null;this.src=\''.$ucenterurl.'/images/noavatar_'.$size.'.gif\'" />';  
  591.         }  
  592. }  
  593.   
  594. /**
  595. * 加载语言
  596. * 语言文件统一为 $lang = array();
  597. * @param $file - 语言文件,可包含路径如 forum/xxx home/xxx
  598. * @param $langvar - 语言文字索引
  599. * @param $vars - 变量替换数组
  600. * @return 语言文字
  601. */  
  602. function lang($file, $langvar = null, $vars = array(), $default = null) {  
  603.         global $_G;  
  604.         $fileinput = $file;  
  605.         list($path, $file) = explode('/', $file);  
  606.         if(!$file) {  
  607.                 $file = $path;  
  608.                 $path = '';  
  609.         }  
  610.         if(strpos($file, ':') !== false) {  
  611.                 $path = 'plugin';  
  612.                 list($file) = explode(':', $file);  
  613.         }  
  614.   
  615.         if($path != 'plugin') {  
  616.                 $key = $path == '' ? $file : $path.'_'.$file;  
  617.                 if(!isset($_G['lang'][$key])) {  
  618.                         //#start  
  619.                         $_akey = '#file#source/language/'.($path == '' ? '' : $path.'/').'lang_'.$file.'.php';  
  620.                         C::analysisStart($_akey);  
  621.                         //#end  
  622.                         include DISCUZ_ROOT.'./source/language/'.($path == '' ? '' : $path.'/').'lang_'.$file.'.php';  
  623.                         //#start  
  624.                         C::analysisStop($_akey);  
  625.                         //#end  
  626.                         $_G['lang'][$key] = $lang;  
  627.                 }  
  628.                 //noteX 合并手机语言包(IN_MOBILE)  
  629.                 if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) {  
  630.                         //#start  
  631.                         $_akey = '#file#source/language/mobile/lang_template.php';  
  632.                         C::analysisStart($_akey);  
  633.                         //#end  
  634.                         include DISCUZ_ROOT.'./source/language/mobile/lang_template.php';  
  635.                         //#start  
  636.                         C::analysisStop($_akey);  
  637.                         //#end  
  638.                         $_G['lang'][$key] = array_merge($_G['lang'][$key], $lang);  
  639.                 }  
  640.                 if($file != 'error' && !isset($_G['cache']['pluginlanguage_system'])) {  
  641.                         loadcache('pluginlanguage_system');  
  642.                 }  
  643.                 if(!isset($_G['hooklang'][$fileinput])) {  
  644.                         if(isset($_G['cache']['pluginlanguage_system'][$fileinput]) && is_array($_G['cache']['pluginlanguage_system'][$fileinput])) {  
  645.                                 $_G['lang'][$key] = array_merge($_G['lang'][$key], $_G['cache']['pluginlanguage_system'][$fileinput]);  
  646.                         }  
  647.                         $_G['hooklang'][$fileinput] = true;  
  648.                 }  
  649.                 $returnvalue = &$_G['lang'];  
  650.         } else {  
  651.                 if(empty($_G['config']['plugindeveloper'])) {  
  652.                         loadcache('pluginlanguage_script');  
  653.                 } elseif(!isset($_G['cache']['pluginlanguage_script'][$file]) && preg_match("/^[a-z]+[a-z0-9_]*$/i", $file)) {  
  654.                         if(@include(DISCUZ_ROOT.'./data/plugindata/'.$file.'.lang.php')) {  
  655.                                 $_G['cache']['pluginlanguage_script'][$file] = $scriptlang[$file];  
  656.                         } else {  
  657.                                 loadcache('pluginlanguage_script');  
  658.                         }  
  659.                 }  
  660.                 $returnvalue = & $_G['cache']['pluginlanguage_script'];  
  661.                 $key = &$file;  
  662.         }  
  663.         $return = $langvar !== null ? (isset($returnvalue[$key][$langvar]) ? $returnvalue[$key][$langvar] : null) : $returnvalue[$key];  
  664.         $return = $return === null ? ($default !== null ? $default : $langvar) : $return;  
  665.         $searchs = $replaces = array();  
  666.         if($vars && is_array($vars)) {  
  667.                 foreach($vars as $k => $v) {  
  668.                         $searchs[] = '{'.$k.'}';  
  669.                         $replaces[] = $v;  
  670.                 }  
  671.         }  
  672.         if(is_string($return) && strpos($return, '{_G/') !== false) {  
  673.                 preg_match_all('/\{_G\/(.+?)\}/', $return, $gvar);  
  674.                 foreach($gvar[0] as $k => $v) {  
  675.                         $searchs[] = $v;  
  676.                         $replaces[] = getglobal($gvar[1][$k]);  
  677.                 }  
  678.         }  
  679.         $return = str_replace($searchs, $replaces, $return);  
  680.         return $return;  
  681. }  
  682.   
  683. /**
  684. * 检查模板源文件是否更新
  685. * 当编译文件不存时强制重新编译
  686. * 当 tplrefresh = 1 时检查文件
  687. * 当 tplrefresh > 1 时,则根据 tplrefresh 取余,无余时则检查更新
  688. *
  689. */  
  690. function checktplrefresh($maintpl, $subtpl, $timecompare, $templateid, $cachefile, $tpldir, $file) {  
  691.         static $tplrefresh, $timestamp, $targettplname;  
  692.         if($tplrefresh === null) {  
  693.                 $tplrefresh = getglobal('config/output/tplrefresh');  
  694.                 $timestamp = getglobal('timestamp');  
  695.         }  
  696.   
  697.         if(empty($timecompare) || $tplrefresh == 1 || ($tplrefresh > 1 && !($timestamp % $tplrefresh))) {  
  698.                 if(empty($timecompare) || @filemtime(DISCUZ_ROOT.$subtpl) > $timecompare) {  
  699.                         require_once DISCUZ_ROOT.'/source/class/class_template.php';  
  700.                         $template = new template();  
  701.                         $template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);  
  702.                         //更新页面和模块的关联  
  703.                         if($targettplname === null) {  
  704.                                 $targettplname = getglobal('style/tplfile');  
  705.                                 if(!empty($targettplname)) {  
  706.                                         include_once libfile('function/block');  
  707.                                         $targettplname = strtr($targettplname, ':', '_');  
  708.                                         update_template_block($targettplname, getglobal('style/tpldirectory'), $template->blocks);  
  709.                                 }  
  710.                                 $targettplname = true;  
  711.                         }  
  712.                         return TRUE;  
  713.                 }  
  714.         }  
  715.         return FALSE;  
  716. }  
  717.   
  718. /**
  719. * 解析模板
  720. * @return 返回域名
  721. */  
  722. function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') {  
  723.         global $_G;  
  724.   
  725.         static $_init_style = false;  
  726.         if($_init_style === false) {  
  727.                 C::app()->_init_style();  
  728.                 $_init_style = true;  
  729.         }  
  730.         $oldfile = $file; //原模板  
  731.         if(strpos($file, ':') !== false) {  
  732.                 $clonefile = '';  
  733.                 list($templateid, $file, $clonefile) = explode(':', $file);  
  734.                 $oldfile = $file;  
  735.                 $file = empty($clonefile) ? $file : $file.'_'.$clonefile;  
  736.                 if($templateid == 'diy') {  
  737.                         $indiy = false; //是否存在DIY  
  738.                         $_G['style']['tpldirectory'] = $tpldir ? $tpldir : (defined('TPLDIR') ? TPLDIR : ''); //模板文件所在的目录,DIY保存时使用  
  739.                         $_G['style']['prefile'] = ''; //非预览环境标记预览文件是否存在  
  740.                         $diypath = DISCUZ_ROOT.'./data/diy/'.$_G['style']['tpldirectory'].'/'; //DIY模板文件目录  
  741.                         $preend = '_diy_preview'; //预览文件后缀  
  742.                         $_GET['preview'] = !empty($_GET['preview']) ? $_GET['preview'] : ''; //是否预览  
  743.                         $curtplname = $oldfile;//当前模板名  
  744.                         $basescript = $_G['mod'] == 'viewthread' && !empty($_G['thread']) ? 'forum' : $_G['basescript']; //帖子查看页归到froum中  
  745.                         if(isset($_G['cache']['diytemplatename'.$basescript])) {  
  746.                                 $diytemplatename = &$_G['cache']['diytemplatename'.$basescript];//当前应用的DIY文件缓存  
  747.                         } else {  
  748.                                 if(!isset($_G['cache']['diytemplatename'])) {  
  749.                                         loadcache('diytemplatename');  
  750.                                 }  
  751.                                 $diytemplatename = &$_G['cache']['diytemplatename'];//所有DIY文件缓存  
  752.                         }  
  753.                         $tplsavemod = 0; //公共DIY页面标记  
  754.                         //独立DIY页面 || 分区或版块没有指定模板 && 公共DIY页面  
  755.                         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')) {  
  756.                                 $tpldir = 'data/diy/'.$_G['style']['tpldirectory'].'/'; //文件目录  
  757.                                 !$gettplfile && $_G['style']['tplsavemod'] = $tplsavemod; //独立DIY页面标记:1,公共DIY页面标记:0  
  758.                                 $curtplname = $file; //当前模板名  
  759.                                 if(isset($_GET['diy']) && $_GET['diy'] == 'yes' || isset($_GET['diy']) && $_GET['preview'] == 'yes') { //DIY模式或预览模式下做以下判断  
  760.                                         $flag = file_exists($diypath.$file.$preend.'.htm'); //预览文件是否存在  
  761.                                         if($_GET['preview'] == 'yes') { //预览环境  
  762.                                                 $file .= $flag ? $preend : ''; //使用预览模板文件  
  763.                                         } else {  
  764.                                                 $_G['style']['prefile'] = $flag ? 1 : ''; //非预览环境标记预览文件是否存在  
  765.                                         }  
  766.                                 }  
  767.                                 $indiy = true;  
  768.                         } else {  
  769.                                 $file = $primaltpl ? $primaltpl : $oldfile; //无DIY页面则使用原模板  
  770.                         }  
  771.                         //根据模板自动刷新开关$tplrefresh 更新DIY模板  
  772.                         $tplrefresh = $_G['config']['output']['tplrefresh'];  
  773.                         //在有DIY生成模板文件时 && 自动刷新开启 && DIY生成模板文件修改时间 < 原模板修改修改  
  774.                         if($indiy && ($tplrefresh ==1 || ($tplrefresh > 1 && !($_G['timestamp'] % $tplrefresh))) && filemtime($diypath.$file.'.htm') < filemtime(DISCUZ_ROOT.$_G['style']['tpldirectory'].'/'.($primaltpl ? $primaltpl : $oldfile).'.htm')) {  
  775.                                 //原模板更改则更新DIY模板,如果更新失败则删除DIY模板  
  776.                                 if (!updatediytemplate($file, $_G['style']['tpldirectory'])) {  
  777.                                         unlink($diypath.$file.'.htm');  
  778.                                         $tpldir = '';  
  779.                                 }  
  780.                         }  
  781.   
  782.                         //保存当前模板名  
  783.                         if (!$gettplfile && empty($_G['style']['tplfile'])) {  
  784.                                 $_G['style']['tplfile'] = empty($clonefile) ? $curtplname : $oldfile.':'.$clonefile;  
  785.                         }  
  786.   
  787.                         //是否显示继续DIY  
  788.                         $_G['style']['prefile'] = !empty($_GET['preview']) && $_GET['preview'] == 'yes' ? '' : $_G['style']['prefile'];  
  789.   
  790.                 } else {  
  791.                         $tpldir = './source/plugin/'.$templateid.'/template';  
  792.                 }  
  793.         }  
  794.   
  795.         $file .= !empty($_G['inajax']) && ($file == 'common/header' || $file == 'common/footer') ? '_ajax' : '';  
  796.         $tpldir = $tpldir ? $tpldir : (defined('TPLDIR') ? TPLDIR : '');  
  797.         $templateid = $templateid ? $templateid : (defined('TEMPLATEID') ? TEMPLATEID : '');  
  798.         $filebak = $file;  
  799.   
  800.         //noteX 将页面模板加一层Mobile目录,用以定位手机模板页面(IN_MOBILE)  
  801.         if(defined('IN_MOBILE') && !defined('TPL_DEFAULT') && strpos($file, $_G['mobiletpl'][IN_MOBILE].'/') === false || (isset($_G['forcemobilemessage']) && $_G['forcemobilemessage'])) {  
  802.                 if(IN_MOBILE == 2) {  
  803.                         $oldfile .= !empty($_G['inajax']) && ($oldfile == 'common/header' || $oldfile == 'common/footer') ? '_ajax' : '';  
  804.                 }  
  805.                 $file = $_G['mobiletpl'][IN_MOBILE].'/'.$oldfile;  
  806.         }  
  807.   
  808.         //确保$tpldir有值  
  809.         if(!$tpldir) {  
  810.                 $tpldir = './template/default';  
  811.         }  
  812.         $tplfile = $tpldir.'/'.$file.'.htm';  
  813.   
  814.         $file == 'common/header' && defined('CURMODULE') && CURMODULE && $file = 'common/header_'.$_G['basescript'].'_'.CURMODULE;  
  815.   
  816.         //noteX 手机模板的判断(IN_MOBILE)  
  817.         if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) {  
  818.                 //首先判断是否是DIY模板,如果是就删除可能存在的forumdisplay_1中的数字  
  819.                 if(strpos($tpldir, 'plugin')) {  
  820.                         if(!file_exists(DISCUZ_ROOT.$tpldir.'/'.$file.'.htm') && !file_exists(DISCUZ_ROOT.$tpldir.'/'.$file.'.php')) {  
  821.                                 $url = $_SERVER['REQUEST_URI'].(strexists($_SERVER['REQUEST_URI'], '?') ? '&' : '?').'mobile=no';  
  822.                                 showmessage('mobile_template_no_found', '', array('url' => $url));  
  823.                         } else {  
  824.                                 $mobiletplfile = $tpldir.'/'.$file.'.htm';  
  825.                         }  
  826.                 }  
  827.                 !$mobiletplfile && $mobiletplfile = $file.'.htm';  
  828.                 if(strpos($tpldir, 'plugin') && (file_exists(DISCUZ_ROOT.$mobiletplfile) || file_exists(substr(DISCUZ_ROOT.$mobiletplfile, 0, -4).'.php'))) {  
  829.                         $tplfile = $mobiletplfile;  
  830.                 } elseif(!file_exists(DISCUZ_ROOT.TPLDIR.'/'.$mobiletplfile) && !file_exists(substr(DISCUZ_ROOT.TPLDIR.'/'.$mobiletplfile, 0, -4).'.php')) {  
  831.                         $mobiletplfile = './template/default/'.$mobiletplfile;  
  832.                         if(!file_exists(DISCUZ_ROOT.$mobiletplfile) && !$_G['forcemobilemessage']) {  
  833.                                 $tplfile = str_replace($_G['mobiletpl'][IN_MOBILE].'/', '', $tplfile);  
  834.                                 $file = str_replace($_G['mobiletpl'][IN_MOBILE].'/', '', $file);  
  835.                                 define('TPL_DEFAULT', true);  
  836.                         } else {  
  837.                                 $tplfile = $mobiletplfile;  
  838.                         }  
  839.                 } else {  
  840.                         $tplfile = TPLDIR.'/'.$mobiletplfile;  
  841.                 }  
  842.         }  
  843.   
  844.         $cachefile = './data/template/'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';  
  845.         //非系统模板目录 && $tplfile模板文件不存在 && .php后缀的模板文件不存在 && //当前模板目录+原模板文件不存在  
  846.         if($templateid != 1 && !file_exists(DISCUZ_ROOT.$tplfile) && !file_exists(substr(DISCUZ_ROOT.$tplfile, 0, -4).'.php')  
  847.                         && !file_exists(DISCUZ_ROOT.($tplfile = $tpldir.$filebak.'.htm'))) {  
  848.                 $tplfile = './template/default/'.$filebak.'.htm';  
  849.         }  
  850.   
  851.         if($gettplfile) {  
  852.                 return $tplfile;  
  853.         }  
  854.         checktplrefresh($tplfile, $tplfile, @filemtime(DISCUZ_ROOT.$cachefile), $templateid, $cachefile, $tpldir, $file);  
  855.         return DISCUZ_ROOT.$cachefile;  
  856. }  
  857.   
  858. /**
  859. * 数据签名
  860. * @param string $str 源数据
  861. * @param int $length 返回值的长度,8-32位之间
  862. * @return string
  863. */  
  864. function dsign($str, $length = 16){  
  865.         return substr(md5($str.getglobal('config/security/authkey')), 0, ($length ? max(8, $length) : 16));  
  866. }  
  867.   
  868. /**
  869. * 对某id进行个性化md5
  870. */  
  871. function modauthkey($id) {  
  872.         return md5(getglobal('username').getglobal('uid').getglobal('authkey').substr(TIMESTAMP, 0, -7).$id);  
  873. }  
  874.   
  875. /**
  876. * 获得当前应用页面选中的导航id
  877. */  
  878. function getcurrentnav() {  
  879.         global $_G;  
  880.         if(!empty($_G['mnid'])) {  
  881.                 return $_G['mnid'];  
  882.         }  
  883.         $mnid = '';  
  884.         $_G['basefilename'] = $_G['basefilename'] == $_G['basescript'] ? $_G['basefilename'] : $_G['basescript'].'.php';  
  885.         if(isset($_G['setting']['navmns'][$_G['basefilename']])) {  
  886.                 if($_G['basefilename'] == 'home.php' && $_GET['mod'] == 'space' && (empty($_GET['do']) || in_array($_GET['do'], array('follow', 'view')))) {  
  887.                         $_GET['mod'] = 'follow';  
  888.                 }  
  889.                 foreach($_G['setting']['navmns'][$_G['basefilename']] as $navmn) {  
  890.                         if($navmn[0] == array_intersect_assoc($navmn[0], $_GET) || ($navmn[0]['mod'] == 'space' && $_GET['mod'] == 'spacecp' && ($navmn[0]['do'] == $_GET['ac'] || $navmn[0]['do'] == 'album' && $_GET['ac'] == 'upload'))) {  
  891.                                 $mnid = $navmn[1];  
  892.                         }  
  893.                 }  
  894.   
  895.         }  
  896.         if(!$mnid && isset($_G['setting']['navdms'])) {  
  897.                 foreach($_G['setting']['navdms'] as $navdm => $navid) {  
  898.                         if(strpos(strtolower($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']), $navdm) !== false && strpos(strtolower($_SERVER['HTTP_HOST']), $navdm) === false) {  
  899.                                 $mnid = $navid;  
  900.                                 break;  
  901.                         }  
  902.                 }  
  903.         }  
  904.         if(!$mnid && isset($_G['setting']['navmn'][$_G['basefilename']])) {  
  905.                 $mnid = $_G['setting']['navmn'][$_G['basefilename']];  
  906.         }  
  907.         return $mnid;  
  908. }  
  909.   
  910. //读取UC库  
  911. function loaducenter() {  
  912.         require_once DISCUZ_ROOT.'./config/config_ucenter.php';  
  913.         require_once DISCUZ_ROOT.'./uc_client/client.php';  
  914. }  
  915.   
  916. /**
  917. * 读取缓存
  918. * @param $cachenames - 缓存名称数组或字串
  919. */  
  920. function loadcache($cachenames, $force = false) {  
  921.         global $_G;  
  922.         static $loadedcache = array();  
  923.         $cachenames = is_array($cachenames) ? $cachenames : array($cachenames);  
  924.         $caches = array();  
  925.         foreach ($cachenames as $k) {  
  926.                 if(!isset($loadedcache[$k]) || $force) {  
  927.                         $caches[] = $k;  
  928.                         $loadedcache[$k] = true;  
  929.                 }  
  930.         }  
  931.   
  932.         if(!empty($caches)) {  
  933.                 $cachedata = C::t('common_syscache')->fetch_all($caches);  
  934.                 foreach($cachedata as $cname => $data) {  
  935.                         if($cname == 'setting') {  
  936.                                 $_G['setting'] = $data;  
  937.                         } elseif($cname == 'usergroup_'.$_G['groupid']) {  
  938.                                 $_G['cache'][$cname] = $_G['group'] = $data;  
  939.                         } elseif($cname == 'style_default') {  
  940.                                 $_G['cache'][$cname] = $_G['style'] = $data;  
  941.                         } elseif($cname == 'grouplevels') {  
  942.                                 $_G['grouplevels'] = $data;  
  943.                         } else {  
  944.                                 $_G['cache'][$cname] = $data;  
  945.                         }  
  946.                 }  
  947.         }  
  948.         return true;  
  949. }  
  950.   
  951. /**
  952. * 格式化时间
  953. * @param $timestamp - 时间戳
  954. * @param $format - dt=日期时间 d=日期 t=时间 u=个性化 其他=自定义
  955. * @param $timeoffset - 时区
  956. * @return string
  957. */  
  958. function dgmdate($timestamp, $format = 'dt', $timeoffset = '9999', $uformat = '') {  
  959.         global $_G;  
  960.         $format == 'u' && !$_G['setting']['dateconvert'] && $format = 'dt';  
  961.         static $dformat, $tformat, $dtformat, $offset, $lang;  
  962.         if($dformat === null) {  
  963.                 $dformat = getglobal('setting/dateformat');  
  964.                 $tformat = getglobal('setting/timeformat');  
  965.                 $dtformat = $dformat.' '.$tformat;  
  966.                 $offset = getglobal('member/timeoffset');  
  967.                 $sysoffset = getglobal('setting/timeoffset');  
  968.                 $offset = $offset == 9999 ? ($sysoffset ? $sysoffset : 0) : $offset;  
  969.                 $lang = lang('core', 'date');  
  970.         }  
  971.         $timeoffset = $timeoffset == 9999 ? $offset : $timeoffset;  
  972.         $timestamp += $timeoffset * 3600;  
  973.         $format = empty($format) || $format == 'dt' ? $dtformat : ($format == 'd' ? $dformat : ($format == 't' ? $tformat : $format));  
  974.         if($format == 'u') {  
  975.                 $todaytimestamp = TIMESTAMP - (TIMESTAMP + $timeoffset * 3600) % 86400 + $timeoffset * 3600;  
  976.                 $s = gmdate(!$uformat ? $dtformat : $uformat, $timestamp);  
  977.                 $time = TIMESTAMP + $timeoffset * 3600 - $timestamp;  
  978.                 if($timestamp >= $todaytimestamp) {  
  979.                         if($time > 3600) {  
  980.                                 $return = intval($time / 3600).' '.$lang['hour'].$lang['before'];  
  981.                         } elseif($time > 1800) {  
  982.                                 $return = $lang['half'].$lang['hour'].$lang['before'];  
  983.                         } elseif($time > 60) {  
  984.                                 $return = intval($time / 60).' '.$lang['min'].$lang['before'];  
  985.                         } elseif($time > 0) {  
  986.                                 $return = $time.' '.$lang['sec'].$lang['before'];  
  987.                         } elseif($time == 0) {  
  988.                                 $return = $lang['now'];  
  989.                         } else {  
  990.                                 $return = $s;  
  991.                         }  
  992.                         if($time >=0 && !defined('IN_MOBILE')) {  
  993.                                 $return = '<span title="'.$s.'">'.$return.'</span>';  
  994.                         }  
  995.                 } elseif(($days = intval(($todaytimestamp - $timestamp) / 86400)) >= 0 && $days < 7) {  
  996.                         if($days == 0) {  
  997.                                 $return = $lang['yday'].' '.gmdate($tformat, $timestamp);  
  998.                         } elseif($days == 1) {  
  999.                                 $return = $lang['byday'].' '.gmdate($tformat, $timestamp);  
  1000.                         } else {  
  1001.                                 $return = ($days + 1).' '.$lang['day'].$lang['before'];  
  1002.                         }  
  1003.                         if(!defined('IN_MOBILE')) {  
  1004.                                 $return = '<span title="'.$s.'">'.$return.'</span>';  
  1005.                         }  
  1006.                 } else {  
  1007.                         $return = $s;  
  1008.                 }  
  1009.                 return $return;  
  1010.         } else {  
  1011.                 return gmdate($format, $timestamp);  
  1012.         }  
  1013. }  
  1014.   
  1015. /**
  1016.         得到时间戳
  1017. */  
  1018. function dmktime($date) {  
  1019.         if(strpos($date, '-')) {  
  1020.                 $time = explode('-', $date);  
  1021.                 return mktime(0, 0, 0, $time[1], $time[2], $time[0]);  
  1022.         }  
  1023.         return 0;  
  1024. }  
  1025.   
  1026. /**
  1027. *        个性化数字
  1028. */  
  1029. function dnumber($number) {  
  1030.         return abs($number) > 10000 ? '<span title="'.$number.'">'.intval($number / 10000).lang('core', '10k').'</span>' : $number;  
  1031. }  
  1032.   
  1033. /**
  1034. * 更新缓存
  1035. * @param $cachename - 缓存名称
  1036. * @param $data - 缓存数据
  1037. */  
  1038. function savecache($cachename, $data) {  
  1039.         C::t('common_syscache')->insert($cachename, $data);  
  1040. }  
  1041.   
  1042. /**
  1043. * 更新缓存 savecache的别名
  1044. * @param $cachename - 缓存名称
  1045. * @param $data - 缓存数据
  1046. */  
  1047. function save_syscache($cachename, $data) {  
  1048.         savecache($cachename, $data);  
  1049. }  
  1050.   
  1051. /**
  1052. * Portal模块
  1053. * @param $parameter - 参数集合
  1054. */  
  1055. function block_get($parameter) {  
  1056.         include_once libfile('function/block');  
  1057.         block_get_batch($parameter);  
  1058. }  
  1059.   
  1060. /**
  1061. * Portal 模块显示
  1062. *
  1063. * @param $parameter - 参数集合
  1064. */  
  1065. function block_display($bid) {  
  1066.         include_once libfile('function/block');  
  1067.         block_display_batch($bid);  
  1068. }  
  1069.   
  1070. //连接字符  
  1071. function dimplode($array) {  
  1072.         if(!empty($array)) {  
  1073.                 $array = array_map('addslashes', $array);  
  1074.                 return "'".implode("','", is_array($array) ? $array : array($array))."'";  
  1075.         } else {  
  1076.                 return 0;  
  1077.         }  
  1078. }  
  1079.   
  1080. /**
  1081. * 返回库文件的全路径
  1082. *
  1083. * @param string $libname 库文件分类及名称
  1084. * @param string $folder 模块目录'module','include','class'
  1085. * @return string
  1086. *
  1087. * @example require DISCUZ_ROOT.'./source/function/function_cache.php'
  1088. * @example 我们可以利用此函数简写为:require libfile('function/cache');
  1089. *
  1090. */  
  1091. function libfile($libname, $folder = '') {  
  1092.         $libpath = '/source/'.$folder;  
  1093.         if(strstr($libname, '/')) {  
  1094.                 list($pre, $name) = explode('/', $libname);  
  1095.                 $path = "{$libpath}/{$pre}/{$pre}_{$name}";  
  1096.                 //return realpath("{$libpath}/{$pre}/{$pre}_{$name}.php");  
  1097.         } else {  
  1098.                 $path = "{$libpath}/{$libname}";  
  1099.                 //return realpath("{$libpath}/{$libname}.php");  
  1100.         }  
  1101.         return preg_match('/^[\w\d\/_]+$/i', $path) ? realpath(DISCUZ_ROOT.$path.'.php') : false;  
  1102. }  
  1103.   
  1104. /**
  1105. * 针对uft-8进行特殊处理的strlen
  1106. * @param string $str
  1107. * @return int
  1108. */  
  1109. function dstrlen($str) {  
  1110.         if(strtolower(CHARSET) != 'utf-8') {  
  1111.                 return strlen($str);  
  1112.         }  
  1113.         $count = 0;  
  1114.         for($i = 0; $i < strlen($str); $i++){  
  1115.                 $value = ord($str[$i]);  
  1116.                 if($value > 127) {  
  1117.                         $count++;  
  1118.                         if($value >= 192 && $value <= 223) $i++;  
  1119.                         elseif($value >= 224 && $value <= 239) $i = $i + 2;  
  1120.                         elseif($value >= 240 && $value <= 247) $i = $i + 3;  
  1121.                     }  
  1122.                     $count++;  
  1123.         }  
  1124.         return $count;  
  1125. }  
  1126.   
  1127. /**
  1128. * 根据中文裁减字符串
  1129. * @param $string - 字符串
  1130. * @param $length - 长度
  1131. * @param $doc - 缩略后缀
  1132. * @return 返回带省略号被裁减好的字符串
  1133. */  
  1134. function cutstr($string, $length, $dot = ' ...') {  
  1135.         if(strlen($string) <= $length) {  
  1136.                 return $string;  
  1137.         }  
  1138.   
  1139.         $pre = chr(1);  
  1140.         $end = chr(1);  
  1141.         //保护特殊字符串  
  1142.         $string = str_replace(array('&', '"', '<', '>'), array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), $string);  
  1143.   
  1144.         $strcut = '';  
  1145.         if(strtolower(CHARSET) == 'utf-8') {  
  1146.   
  1147.                 $n = $tn = $noc = 0;  
  1148.                 while($n < strlen($string)) {  
  1149.   
  1150.                         $t = ord($string[$n]);  
  1151.                         if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {  
  1152.                                 $tn = 1; $n++; $noc++;  
  1153.                         } elseif(194 <= $t && $t <= 223) {  
  1154.                                 $tn = 2; $n += 2; $noc += 2;  
  1155.                         } elseif(224 <= $t && $t <= 239) {  
  1156.                                 $tn = 3; $n += 3; $noc += 2;  
  1157.                         } elseif(240 <= $t && $t <= 247) {  
  1158.                                 $tn = 4; $n += 4; $noc += 2;  
  1159.                         } elseif(248 <= $t && $t <= 251) {  
  1160.                                 $tn = 5; $n += 5; $noc += 2;  
  1161.                         } elseif($t == 252 || $t == 253) {  
  1162.                                 $tn = 6; $n += 6; $noc += 2;  
  1163.                         } else {  
  1164.                                 $n++;  
  1165.                         }  
  1166.   
  1167.                         if($noc >= $length) {  
  1168.                                 break;  
  1169.                         }  
  1170.   
  1171.                 }  
  1172.                 if($noc > $length) {  
  1173.                         $n -= $tn;  
  1174.                 }  
  1175.   
  1176.                 $strcut = substr($string, 0, $n);  
  1177.   
  1178.         } else {  
  1179.                 $_length = $length - 1;  
  1180.                 for($i = 0; $i < $length; $i++) {  
  1181.                         //ASCII 码值小于等于127时直接累加字符,大于127时一次取两位累加  
  1182.                         //但当只剩一位时且遇到大于127字符时则舍去此字符,避免大于裁减长度  
  1183.                         if(ord($string[$i]) <= 127) {  
  1184.                                 $strcut .= $string[$i];  
  1185.                         } else if($i < $_length) {  
  1186.                                 $strcut .= $string[$i].$string[++$i];  
  1187.                         }  
  1188.                 }  
  1189.         }  
  1190.   
  1191.         //还原特殊字符串  
  1192.         $strcut = str_replace(array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), array('&', '"', '<', '>'), $strcut);  
  1193.   
  1194.         //修复出现特殊字符串截段的问题  
  1195.         $pos = strrpos($strcut, chr(1));  
  1196.         if($pos !== false) {  
  1197.                 $strcut = substr($strcut,0,$pos);  
  1198.         }  
  1199.         return $strcut.$dot;  
  1200. }  
  1201.   
  1202. //去掉slassh  
  1203. function dstripslashes($string) {  
  1204.         if(empty($string)) return $string;  
  1205.         if(is_array($string)) {  
  1206.                 foreach($string as $key => $val) {  
  1207.                         $string[$key] = dstripslashes($val);  
  1208.                 }  
  1209.         } else {  
  1210.                 $string = stripslashes($string);  
  1211.         }  
  1212.         return $string;  
  1213. }  
  1214.   
  1215. /**
  1216. * 论坛 aid url 生成
  1217. */  
  1218. function aidencode($aid, $type = 0, $tid = 0) {  
  1219.         global $_G;  
  1220.         $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;  
  1221.         return rawurlencode(base64_encode($s));  
  1222. }  
  1223.   
  1224. /**
  1225. * 返回论坛缩放附件图片的地址 url
  1226. */  
  1227. function getforumimg($aid, $nocache = 0, $w = 140, $h = 140, $type = '') {  
  1228.         global $_G;  
  1229.         $key = dsign($aid.'|'.$w.'|'.$h);  
  1230.         return 'forum.php?mod=image&aid='.$aid.'&size='.$w.'x'.$h.'&key='.rawurlencode($key).($nocache ? '&nocache=yes' : '').($type ? '&type='.$type : '');  
  1231. }  
  1232.   
  1233. /**
  1234. * 获取rewrite字符串
  1235. * @param string $type 需要获取的rewite
  1236. * @param boolean $returntype true:直接返回href, false:返回a标签
  1237. * @param string $host 可选网站域名
  1238. * @return string
  1239. */  
  1240. function rewriteoutput($type, $returntype, $host) {  
  1241.         global $_G;  
  1242.         $fextra = '';  
  1243.         if($type == 'forum_forumdisplay') {  
  1244.                 list(,,, $fid, $page, $extra) = func_get_args();  
  1245.                 $r = array(  
  1246.                         '{fid}' => empty($_G['setting']['forumkeys'][$fid]) ? $fid : $_G['setting']['forumkeys'][$fid],  
  1247.                         '{page}' => $page ? $page : 1,  
  1248.                 );  
  1249.         } elseif($type == 'forum_viewthread') {  
  1250.                 list(,,, $tid, $page, $prevpage, $extra) = func_get_args();  
  1251.                 $r = array(  
  1252.                         '{tid}' => $tid,  
  1253.                         '{page}' => $page ? $page : 1,  
  1254.                         '{prevpage}' => $prevpage && !IS_ROBOT ? $prevpage : 1,  
  1255.                 );  
  1256.         } elseif($type == 'home_space') {  
  1257.                 list(,,, $uid, $username, $extra) = func_get_args();  
  1258.                 $_G['setting']['rewritecompatible'] && $username = rawurlencode($username);  
  1259.                 $r = array(  
  1260.                         '{user}' => $uid ? 'uid' : 'username',  
  1261.                         '{value}' => $uid ? $uid : $username,  
  1262.                 );  
  1263.         } elseif($type == 'home_blog') {  
  1264.                 list(,,, $uid, $blogid, $extra) = func_get_args();  
  1265.                 $r = array(  
  1266.                         '{uid}' => $uid,  
  1267.                         '{blogid}' => $blogid,  
  1268.                 );  
  1269.         } elseif($type == 'group_group') {  
  1270.                 list(,,, $fid, $page, $extra) = func_get_args();  
  1271.                 $r = array(  
  1272.                         '{fid}' => $fid,  
  1273.                         '{page}' => $page ? $page : 1,  
  1274.                 );  
  1275.         } elseif($type == 'portal_topic') {  
  1276.                 list(,,, $name, $extra) = func_get_args();  
  1277.                 $r = array(  
  1278.                         '{name}' => $name,  
  1279.                 );  
  1280.         } elseif($type == 'portal_article') {  
  1281.                 list(,,, $id, $page, $extra) = func_get_args();  
  1282.                 $r = array(  
  1283.                         '{id}' => $id,  
  1284.                         '{page}' => $page ? $page : 1,  
  1285.                 );  
  1286.         } elseif($type == 'forum_archiver') {  
  1287.                 list(,, $action, $value, $page, $extra) = func_get_args();  
  1288.                 $host = '';  
  1289.                 $r = array(  
  1290.                         '{action}' => $action,  
  1291.                         '{value}' => $value,  
  1292.                 );  
  1293.                 if($page) {  
  1294.                         $fextra = '?page='.$page;  
  1295.                 }  
  1296.         } elseif($type == 'plugin') {  
  1297.                 list(,, $pluginid, $module,, $param, $extra) = func_get_args();  
  1298.                 $host = '';  
  1299.                 $r = array(  
  1300.                         '{pluginid}' => $pluginid,  
  1301.                         '{module}' => $module,  
  1302.                 );  
  1303.                 if($param) {  
  1304.                         $fextra = '?'.$param;  
  1305.                 }  
  1306.         }  
  1307.         $href = str_replace(array_keys($r), $r, $_G['setting']['rewriterule'][$type]).$fextra;  
  1308.         if(!$returntype) {  
  1309.                 return '<a href="'.$host.$href.'"'.(!empty($extra) ? stripslashes($extra) : '').'>';  
  1310.         } else {  
  1311.                 return $host.$href;  
  1312.         }  
  1313. }  
  1314.   
  1315. /**
  1316. * 手机模式下替换所有链接为mobile=yes形式
  1317. * @param $file - 正则匹配到的文件字符串
  1318. * @param $file - 要被替换的字符串
  1319. * @$replace 替换后字符串
  1320. */  
  1321. function mobilereplace($file, $replace) {  
  1322.         return helper_mobile::mobilereplace($file, $replace);  
  1323. }  
  1324.   
  1325. /**
  1326. * 手机的output函数
  1327. */  
  1328. function mobileoutput() {  
  1329.         helper_mobile::mobileoutput();  
  1330. }  
  1331.   
  1332. /**
  1333. * 系统输出
  1334. * @return 返回内容
  1335. */  
  1336. function output() {  
  1337.   
  1338.         global $_G;  
  1339.   
  1340.         //===================================  
  1341.         //判断写入页面缓存  
  1342.         //===================================  
  1343.         //writepagecache();  
  1344.   
  1345.         if(defined('DISCUZ_OUTPUTED')) {  
  1346.                 return;  
  1347.         } else {  
  1348.                 define('DISCUZ_OUTPUTED', 1);  
  1349.         }  
  1350.   
  1351.         // 更新模块  
  1352.         if(!empty($_G['blockupdate'])) {  
  1353.                 block_updatecache($_G['blockupdate']['bid']);  
  1354.         }  
  1355.   
  1356.         //noteX 手机模式下重新制作页面输出(IN_MOBILE)  
  1357.         if(defined('IN_MOBILE')) {  
  1358.                 mobileoutput();  
  1359.         }  
  1360.         if(!defined('IN_MOBILE') && !defined('IN_ARCHIVER')) {  
  1361.                 $tipsService = Cloud::loadClass('Service_DiscuzTips');  
  1362.                 $tipsService->show();  
  1363.         }  
  1364.         $havedomain = implode('', $_G['setting']['domain']['app']);  
  1365.         if($_G['setting']['rewritestatus'] || !empty($havedomain)) {  
  1366.                 $content = ob_get_contents();  
  1367.                 $content = output_replace($content);  
  1368.   
  1369.   
  1370.                 ob_end_clean();  
  1371.                 $_G['gzipcompress'] ? ob_start('ob_gzhandler') : ob_start();//note X:待调整  
  1372.   
  1373.                 echo $content;  
  1374.         }  
  1375.   
  1376.         //生成静态文件  
  1377.         if(isset($_G['makehtml'])) {  
  1378.                 helper_makehtml::make_html();  
  1379.         }  
  1380.   
  1381.         if($_G['setting']['ftp']['connid']) {  
  1382.                 @ftp_close($_G['setting']['ftp']['connid']);  
  1383.         }  
  1384.         $_G['setting']['ftp'] = array();  
  1385.   
  1386.         //debug Module:HTML_CACHE 如果定义了缓存常量,则此处将缓冲区的内容写入文件。如果为 index 缓存,则直接写入 data/index.cache ,如果为 viewthread 缓存,则根据md5(tid,等参数)取前三位为目录加上$tid_$page,做文件名。  
  1387.         //debug $threadcacheinfo, $indexcachefile 为全局变量  
  1388.         if(defined('CACHE_FILE') && CACHE_FILE && !defined('CACHE_FORBIDDEN') && !defined('IN_MOBILE') && !checkmobile()) {  
  1389.                 if(diskfreespace(DISCUZ_ROOT.'./'.$_G['setting']['cachethreaddir']) > 1000000) {  
  1390.                         if($fp = @fopen(CACHE_FILE, 'w')) {  
  1391.                                 flock($fp, LOCK_EX);  
  1392.                                 fwrite($fp, empty($content) ? ob_get_contents() : $content);  
  1393.                         }  
  1394.                         @fclose($fp);  
  1395.                         chmod(CACHE_FILE, 0777);  
  1396.                 }  
  1397.         }  
  1398.   
  1399.         if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG && @include(libfile('function/debug'))) {  
  1400.                 function_exists('debugmessage') && debugmessage();  
  1401.         }  
  1402. }  
  1403.   
  1404. function output_replace($content) {  
  1405.         global $_G;  
  1406.         if(defined('IN_MODCP') || defined('IN_ADMINCP')) return $content;  
  1407.         if(!empty($_G['setting']['output']['str']['search'])) {  
  1408.                 if(empty($_G['setting']['domain']['app']['default'])) {  
  1409.                         $_G['setting']['output']['str']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['str']['replace']);  
  1410.                 }  
  1411.                 $content = str_replace($_G['setting']['output']['str']['search'], $_G['setting']['output']['str']['replace'], $content);  
  1412.         }  
  1413.         if(!empty($_G['setting']['output']['preg']['search']) && (empty($_G['setting']['rewriteguest']) || empty($_G['uid']))) {  
  1414.                 if(empty($_G['setting']['domain']['app']['default'])) {  
  1415.                         $_G['setting']['output']['preg']['search'] = str_replace('\{CURHOST\}', preg_quote($_G['siteurl'], '/'), $_G['setting']['output']['preg']['search']);  
  1416.                         $_G['setting']['output']['preg']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['preg']['replace']);  
  1417.                 }  
  1418.   
  1419.                 $content = preg_replace($_G['setting']['output']['preg']['search'], $_G['setting']['output']['preg']['replace'], $content);  
  1420.         }  
  1421.   
  1422.         return $content;  
  1423. }  
  1424.   
  1425. /**
  1426. * ajax footer使用输出页面内容
  1427. */  
  1428. function output_ajax() {  
  1429.         global $_G;  
  1430.         $s = ob_get_contents();  
  1431.         ob_end_clean();  
  1432.         $s = preg_replace("/([\\x01-\\x08\\x0b-\\x0c\\x0e-\\x1f])+/", ' ', $s);  
  1433.         $s = str_replace(array(chr(0), ']]>'), array(' ', ']]>'), $s);  
  1434.         if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG && @include(libfile('function/debug'))) {  
  1435.                 function_exists('debugmessage') && $s .= debugmessage(1);  
  1436.         }  
  1437.         $havedomain = implode('', $_G['setting']['domain']['app']);  
  1438.         if($_G['setting']['rewritestatus'] || !empty($havedomain)) {  
  1439.         $s = output_replace($s);  
  1440.         }  
  1441.         return $s;  
  1442. }  
  1443.   
  1444. /**
  1445. * 运行钩子
  1446. */  
  1447. function runhooks($scriptextra = '') {  
  1448.         if(!defined('HOOKTYPE')) {  
  1449.                 define('HOOKTYPE', !defined('IN_MOBILE') ? 'hookscript' : 'hookscriptmobile');  
  1450.         }  
  1451.         if(defined('CURMODULE')) {  
  1452.                 global $_G;  
  1453.                 if($_G['setting']['plugins']['func'][HOOKTYPE]['common']) {  
  1454.                         hookscript('common', 'global', 'funcs', array(), 'common');  
  1455.                 }  
  1456.                 hookscript(CURMODULE, $_G['basescript'], 'funcs', array(), '', $scriptextra);  
  1457.         }  
  1458. }  
  1459.   
  1460. /**
  1461. * 执行插件脚本
  1462. */  
  1463. function hookscript($script, $hscript, $type = 'funcs', $param = array(), $func = '', $scriptextra = '') {  
  1464.         global $_G;  
  1465.         static $pluginclasses;  
  1466.         if($hscript == 'home') {  
  1467.                 if($script == 'space') {  
  1468.                         $scriptextra = !$scriptextra ? $_GET['do'] : $scriptextra;  
  1469.                         $script = 'space'.(!empty($scriptextra) ? '_'.$scriptextra : '');  
  1470.                 } elseif($script == 'spacecp') {  
  1471.                         $scriptextra = !$scriptextra ? $_GET['ac'] : $scriptextra;  
  1472.                         $script .= !empty($scriptextra) ? '_'.$scriptextra : '';  
  1473.                 }  
  1474.         }  
  1475.         if(!isset($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {  
  1476.                 return;  
  1477.         }  
  1478.         if(!isset($_G['cache']['plugin'])) {  
  1479.                 loadcache('plugin');  
  1480.         }  
  1481.         foreach((array)$_G['setting'][HOOKTYPE][$hscript][$script]['module'] as $identifier => $include) {  
  1482.                 if($_G['pluginrunlist'] && !in_array($identifier, $_G['pluginrunlist'])) {  
  1483.                         continue;  
  1484.                 }  
  1485.                 $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']);  
  1486.                 if($hooksadminid[$identifier]) {  
  1487.                         //#start  
  1488.                         $_akey = '#file#source/plugin/'.$include.'.class.php';  
  1489.                         C::analysisStart($_akey);  
  1490.                         //#end;  
  1491.                         @include_once DISCUZ_ROOT.'./source/plugin/'.$include.'.class.php';  
  1492.                         //#start  
  1493.                         C::analysisStop($_akey);  
  1494.                         //#end  
  1495.                 }  
  1496.         }  
  1497.         if(@is_array($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {  
  1498.                 $_G['inhookscript'] = true;  
  1499.                 $funcs = !$func ? $_G['setting'][HOOKTYPE][$hscript][$script][$type] : array($func => $_G['setting'][HOOKTYPE][$hscript][$script][$type][$func]);  
  1500.                 foreach($funcs as $hookkey => $hookfuncs) {  
  1501.                         foreach($hookfuncs as $hookfunc) {  
  1502.                                 if($hooksadminid[$hookfunc[0]]) {  
  1503.                                         $classkey = (HOOKTYPE != 'hookscriptmobile' ? '' : 'mobile').'plugin_'.($hookfunc[0].($hscript != 'global' ? '_'.$hscript : ''));  
  1504.                                         if(!class_exists($classkey, false)) {  
  1505.                                                 continue;  
  1506.                                         }  
  1507.                                         if(!isset($pluginclasses[$classkey])) {  
  1508.                                                 $pluginclasses[$classkey] = new $classkey;  
  1509.                                         }  
  1510.                                         if(!method_exists($pluginclasses[$classkey], $hookfunc[1])) {  
  1511.                                                 continue;  
  1512.                                         }  
  1513.                                         //#start  
  1514.                                         $_akey = '#function#'.$classkey.'::'.$hookfunc[1];  
  1515.                                         C::analysisStart($_akey);  
  1516.                                         //#end  
  1517.                                         $return = $pluginclasses[$classkey]->$hookfunc[1]($param);  
  1518.                                         //#start  
  1519.                                         C::analysisStop($_akey);  
  1520.                                         //#end  
  1521.   
  1522.                                         if(substr($hookkey, -7) == '_extend' && !empty($_G['setting']['pluginhooks'][$hookkey])) {  
  1523.                                                 continue;  
  1524.                                         }  
  1525.   
  1526.                                         if(is_array($return)) {  
  1527.                                                 if(!isset($_G['setting']['pluginhooks'][$hookkey]) || is_array($_G['setting']['pluginhooks'][$hookkey])) {  
  1528.                                                         foreach($return as $k => $v) {  
  1529.                                                                 $_G['setting']['pluginhooks'][$hookkey][$k] .= $v;  
  1530.                                                         }  
  1531.                                                 } else {  
  1532.                                                         foreach($return as $k => $v) {  
  1533.                                                                 $_G['setting']['pluginhooks'][$hookkey][$k] = $v;  
  1534.                                                         }  
  1535.                                                 }  
  1536.                                         } else {  
  1537.                                                 if(!is_array($_G['setting']['pluginhooks'][$hookkey])) {  
  1538.                                                         $_G['setting']['pluginhooks'][$hookkey] .= $return;  
  1539.                                                 } else {  
  1540.                                                         foreach($_G['setting']['pluginhooks'][$hookkey] as $k => $v) {  
  1541.                                                                 $_G['setting']['pluginhooks'][$hookkey][$k] .= $return;  
  1542.                                                         }  
  1543.                                                 }  
  1544.                                         }  
  1545.                                 }  
  1546.                         }  
  1547.                 }  
  1548.         }  
  1549.         $_G['inhookscript'] = false;  
  1550. }  
  1551.   
  1552. function hookscriptoutput($tplfile) {  
  1553.         global $_G;  
  1554.         if(!empty($_G['hookscriptoutput'])) {  
  1555.                 return;  
  1556.         }  
  1557. //        //note mobiledata  
  1558. //        if(!empty($_GET['mobiledata'])) {  
  1559. //                require_once libfile('class/mobiledata');  
  1560. //                $mobiledata = new mobiledata();  
  1561. //                if($mobiledata->validator()) {  
  1562. //                        $mobiledata->outputvariables();  
  1563. //                }  
  1564. //        }  
  1565.         hookscript('global', 'global');  
  1566.         if(defined('CURMODULE')) {  
  1567.                 $param = array('template' => $tplfile, 'message' => $_G['hookscriptmessage'], 'values' => $_G['hookscriptvalues']);  
  1568.                 hookscript(CURMODULE, $_G['basescript'], 'outputfuncs', $param);  
  1569.         }  
  1570.         $_G['hookscriptoutput'] = true;  
  1571. }  
  1572.   
  1573. /**
  1574. * 获取插件模块
  1575. */  
  1576. function pluginmodule($pluginid, $type) {  
  1577.         global $_G;  
  1578.         //note 过滤插件ID  
  1579.         $pluginid = $pluginid ? preg_replace("/[^A-Za-z0-9_:]/", '', $pluginid) : '';  
  1580.         if(!isset($_G['cache']['plugin'])) {  
  1581.                 loadcache('plugin');  
  1582.         }  
  1583.         list($identifier, $module) = explode(':', $pluginid);  
  1584.         if(!is_array($_G['setting']['plugins'][$type]) || !array_key_exists($pluginid, $_G['setting']['plugins'][$type])) {  
  1585.                 showmessage('plugin_nonexistence');  
  1586.         }  
  1587.         if(!empty($_G['setting']['plugins'][$type][$pluginid]['url'])) {  
  1588.                 dheader('location: '.$_G['setting']['plugins'][$type][$pluginid]['url']);  
  1589.         }  
  1590.         $directory = $_G['setting']['plugins'][$type][$pluginid]['directory'];  
  1591.         if(empty($identifier) || !preg_match("/^[a-z]+[a-z0-9_]*\/$/i", $directory) || !preg_match("/^[a-z0-9_\-]+$/i", $module)) {  
  1592.                 showmessage('undefined_action');  
  1593.         }  
  1594.         if(@!file_exists(DISCUZ_ROOT.($modfile = './source/plugin/'.$directory.$module.'.inc.php'))) {  
  1595.                 showmessage('plugin_module_nonexistence', '', array('mod' => $modfile));  
  1596.         }  
  1597.         return DISCUZ_ROOT.$modfile;  
  1598. }  
  1599. /**
  1600. * 执行积分规则
  1601. * @param String $action:  规则action名称
  1602. * @param Integer $uid: 操作用户
  1603. * @param array $extrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1')
  1604. * @param String $needle: 防重字符串
  1605. * @param Integer $coef: 积分放大倍数
  1606. * @param Integer $update: 是否执行更新操作
  1607. * @param Integer $fid: 版块ID
  1608. * @return 返回积分策略
  1609. */  
  1610. function updatecreditbyaction($action, $uid = 0, $extrasql = array(), $needle = '', $coef = 1, $update = 1, $fid = 0) {  
  1611.   
  1612.         //include_once libfile('class/credit');  
  1613.         $credit = credit::instance();  
  1614.         if($extrasql) {  
  1615.                 $credit->extrasql = $extrasql;  
  1616.         }  
  1617.         return $credit->execrule($action, $uid, $needle, $coef, $update, $fid);  
  1618. }  
  1619.   
  1620. /**
  1621. * 检查积分下限
  1622. * @param string $action: 策略动作Action或者需要检测的操作积分值使如extcredits1积分进行减1操作检测array('extcredits1' => -1)
  1623. * @param Integer $uid: 用户UID
  1624. * @param Integer $coef: 积分放大倍数/负数为减分操作
  1625. * @param Integer $returnonly: 只要返回结果,不用中断程序运行
  1626. */  
  1627. function checklowerlimit($action, $uid = 0, $coef = 1, $fid = 0, $returnonly = 0) {  
  1628.         require_once libfile('function/credit');  
  1629.         return _checklowerlimit($action, $uid, $coef, $fid, $returnonly);  
  1630. }  
  1631.   
  1632. /**
  1633. * 批量执行某一条策略规则
  1634. * @param String $action:  规则action名称
  1635. * @param Integer $uids: 操作用户可以为单个uid或uid数组
  1636. * @param array $extrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1')
  1637. * @param Integer $coef: 积分放大倍数,当为负数时为反转操作
  1638. * @param Integer $fid: 版块ID
  1639. */  
  1640. function batchupdatecredit($action, $uids = 0, $extrasql = array(), $coef = 1, $fid = 0) {  
  1641.   
  1642.         $credit = & credit::instance();  
  1643.         if($extrasql) {  
  1644.                 $credit->extrasql = $extrasql;  
  1645.         }  
  1646.         return $credit->updatecreditbyrule($action, $uids, $coef, $fid);  
  1647. }  
  1648.   
  1649. /**
  1650. * 添加积分
  1651. * @param Integer $uids: 用户uid或者uid数组
  1652. * @param String $dataarr: member count相关操作数组,例: array('threads' => 1, 'doings' => -1)
  1653. * @param Boolean $checkgroup: 是否检查用户组 true or false
  1654. * @param String $operation: 操作类型
  1655. * @param Integer $relatedid:
  1656. * @param String $ruletxt: 积分规则文本
  1657. * @param String $customtitle: 自定义积分记录标题
  1658. * @param String $custommemo: 自定义积分记录说明
  1659. */  
  1660.   
  1661. function updatemembercount($uids, $dataarr = array(), $checkgroup = true, $operation = '', $relatedid = 0, $ruletxt = '', $customtitle = '', $custommemo = '') {  
  1662.         if(!empty($uids) && (is_array($dataarr) && $dataarr)) {  
  1663.                 require_once libfile('function/credit');  
  1664.                 return _updatemembercount($uids, $dataarr, $checkgroup, $operation, $relatedid, $ruletxt, $customtitle, $custommemo);  
  1665.         }  
  1666.         return true;  
  1667. }  
  1668.   
  1669. /**
  1670. * 校验用户组
  1671. * @param $uid
  1672. */  
  1673. function checkusergroup($uid = 0) {  
  1674.         $credit = & credit::instance();  
  1675.         $credit->checkusergroup($uid);  
  1676. }  
  1677.   
  1678. function checkformulasyntax($formula, $operators, $tokens) {  
  1679.         $var = implode('|', $tokens);  
  1680.         $operator = implode('', $operators);  
  1681.   
  1682.         $operator = str_replace(  
  1683.                 array('+', '-', '*', '/', '(', ')', '{', '}', '\''),  
  1684.                 array('\+', '\-', '\*', '\/', '\(', '\)', '\{', '\}', '\\\''),  
  1685.                 $operator  
  1686.         );  
  1687.   
  1688.         if(!empty($formula)) {  
  1689.                 if(!preg_match("/^([$operator\.\d]|(($var)([$operator]|$)+))+$/", $formula) || !is_null(eval(preg_replace("/($var)/", "\$\\1", $formula).';'))){  
  1690.                         return false;  
  1691.                 }  
  1692.         }  
  1693.         return true;  
  1694. }  
  1695.   
  1696. //检验积分公式语法  
  1697. function checkformulacredits($formula) {  
  1698.         return checkformulasyntax(  
  1699.                 $formula,  
  1700.                 array('+', '-', '*', '/', ' '),  
  1701.                 array('extcredits[1-8]', 'digestposts', 'posts', 'threads', 'oltime', 'friends', 'doings', 'polls', 'blogs', 'albums', 'sharings')  
  1702.         );  
  1703. }  
  1704.   
  1705. //临时调试通用  
  1706. function debug($var = null, $vardump = false) {  
  1707.         echo '<pre>';  
  1708.         $vardump = empty($var) ? true : $vardump;  
  1709.         if($vardump) {  
  1710.                 var_dump($var);  
  1711.         } else {  
  1712.                 print_r($var);  
  1713.         }  
  1714.         exit();  
  1715. }  
  1716.   
  1717. /**
  1718. * 调试信息
  1719. */  
  1720. function debuginfo() {  
  1721.         global $_G;  
  1722.         if(getglobal('setting/debug')) {  
  1723.                 $db = & DB::object();  
  1724.                 $_G['debuginfo'] = array(  
  1725.                     'time' => number_format((microtime(true) - $_G['starttime']), 6),  
  1726.                     'queries' => $db->querynum,  
  1727.                     'memory' => ucwords(C::memory()->type)  
  1728.                     );  
  1729.                 if($db->slaveid) {  
  1730.                         $_G['debuginfo']['queries'] = 'Total '.$db->querynum.', Slave '.$db->slavequery;  
  1731.                 }  
  1732.                 return TRUE;  
  1733.         } else {  
  1734.                 return FALSE;  
  1735.         }  
  1736. }  
  1737.   
  1738. /**
  1739. * 随机取出一个[url=http://bbs.piaoxian.net/]站长[/url]推荐的条目
  1740. * @param $module 当前模块
  1741. * @return array
  1742. */  
  1743. function getfocus_rand($module) {  
  1744.         global $_G;  
  1745.   
  1746.         if(empty($_G['setting']['focus']) || !array_key_exists($module, $_G['setting']['focus']) || !empty($_G['cookie']['nofocus_'.$module]) || !$_G['setting']['focus'][$module]) {  
  1747.                 return null;  
  1748.         }  
  1749.         loadcache('focus');  
  1750.         if(empty($_G['cache']['focus']['data']) || !is_array($_G['cache']['focus']['data'])) {  
  1751.                 return null;  
  1752.         }  
  1753.         $focusid = $_G['setting']['focus'][$module][array_rand($_G['setting']['focus'][$module])];  
  1754.         return $focusid;  
  1755. }  
  1756.   
  1757. /**
  1758. * 检查验证码正确性
  1759. * @param $value 验证码变量值
  1760. */  
  1761. function check_seccode($value, $idhash, $fromjs = 0, $modid = '') {  
  1762.         return helper_seccheck::check_seccode($value, $idhash, $fromjs, $modid);  
  1763. }  
  1764.   
  1765. /**
  1766. * 检查验证问答正确性
  1767. * @param $value 验证问答变量值
  1768. */  
  1769. function check_secqaa($value, $idhash) {  
  1770.         return helper_seccheck::check_secqaa($value, $idhash);  
  1771. }  
  1772.   
  1773. /**
  1774. * 检查是否需要启用验证码、验证问答
  1775. */  
  1776. function seccheck($rule, $param = array()) {  
  1777.         return helper_seccheck::seccheck($rule, $param);  
  1778. }  
  1779.   
  1780. function make_seccode($seccode = '') {  
  1781.         return helper_seccheck::make_seccode($seccode);  
  1782. }  
  1783.   
  1784. function make_secqaa() {  
  1785.         return helper_seccheck::make_secqaa();  
  1786. }  
  1787.   
  1788. /**
  1789. * 获取广告
  1790. */  
  1791. function adshow($parameter) {  
  1792.         global $_G;  
  1793.         if($_G['inajax'] || $_G['group']['closead']) {  
  1794.                 return;  
  1795.         }  
  1796.         if(isset($_G['config']['plugindeveloper']) && $_G['config']['plugindeveloper'] == 2) {  
  1797.                 return '<hook>[ad '.$parameter.']</hook>';  
  1798.         }  
  1799.         $params = explode('/', $parameter);  
  1800.         $customid = 0;  
  1801.         $customc = explode('_', $params[0]);  
  1802.         if($customc[0] == 'custom') {  
  1803.                 $params[0] = $customc[0];  
  1804.                 $customid = $customc[1];  
  1805.         }  
  1806.         $adcontent = null;  
  1807.         if(empty($_G['setting']['advtype']) || !in_array($params[0], $_G['setting']['advtype'])) {  
  1808.                 $adcontent = '';  
  1809.         }  
  1810.         if($adcontent === null) {  
  1811.                 loadcache('advs');  
  1812.                 $adids = array();  
  1813.                 $evalcode = &$_G['cache']['advs']['evalcode'][$params[0]];  
  1814.                 $parameters = &$_G['cache']['advs']['parameters'][$params[0]];  
  1815.                 $codes = &$_G['cache']['advs']['code'][$_G['basescript']][$params[0]];  
  1816.                 if(!empty($codes)) {  
  1817.                         foreach($codes as $adid => $code) {  
  1818.                                 $parameter = &$parameters[$adid];  
  1819.                                 $checked = true;  
  1820.                                 @eval($evalcode['check']);  
  1821.                                 if($checked) {  
  1822.                                         $adids[] = $adid;  
  1823.                                 }  
  1824.                         }  
  1825.                         if(!empty($adids)) {  
  1826.                                 $adcode = $extra = '';  
  1827.                                 @eval($evalcode['create']);  
  1828.                                 if(empty($notag)) {  
  1829.                                         $adcontent = '<div'.($params[1] != '' ? ' class="'.$params[1].'"' : '').$extra.'>'.$adcode.'</div>';  
  1830.                                 } else {  
  1831.                                         $adcontent = $adcode;  
  1832.                                 }  
  1833.                         }  
  1834.                 }  
  1835.         }  
  1836.         $adfunc = 'ad_'.$params[0];  
  1837.         $_G['setting']['pluginhooks'][$adfunc] = null;  
  1838.         hookscript('ad', 'global', 'funcs', array('params' => $params, 'content' => $adcontent), $adfunc);  
  1839.         if(!$_G['setting']['hookscript']['global']['ad']['funcs'][$adfunc]) {  
  1840.                 hookscript('ad', $_G['basescript'], 'funcs', array('params' => $params, 'content' => $adcontent), $adfunc);  
  1841.         }  
  1842.         return $_G['setting']['pluginhooks'][$adfunc] === null ? $adcontent : $_G['setting']['pluginhooks'][$adfunc];  
  1843. }  
  1844.   
  1845. /**
  1846. * 显示提示信息
  1847. * @param $message - 提示信息,可中文也可以是 lang_message.php 中的数组 key 值
  1848. * @param $url_forward - 提示后跳转的 url
  1849. * @param $values - 提示信息中可替换的变量值 array(key => value ...) 形式
  1850. * @param $extraparam - 扩展参数 array(key => value ...) 形式
  1851. *        跳转控制
  1852.                 header                header跳转
  1853.                 location        location JS 跳转,限于 msgtype = 2、3
  1854.                 timeout                定时跳转
  1855.                 refreshtime        自定义跳转时间
  1856.                 closetime        自定义关闭时间,限于 msgtype = 2,值为 true 时为默认
  1857.                 locationtime        自定义跳转时间,限于 msgtype = 2,值为 true 时为默认
  1858.         内容控制
  1859.                 alert                alert 图标样式 right/info/error
  1860.                 return                显示请返回
  1861.                 redirectmsg        下载时用的提示信息,当跳转时显示的信息样式
  1862.                                          0:如果您的浏览器没有自动跳转,请点击此链接
  1863.                                          1:如果 n 秒后下载仍未开始,请点击此链接
  1864.                 msgtype                信息样式
  1865.                                          1:非 Ajax
  1866.                                          2:Ajax 弹出框
  1867.                                          3:Ajax 只显示信息文本
  1868.                 showmsg                显示信息文本
  1869.                 showdialog        关闭原弹出框显示 showDialog 信息,限于 msgtype = 2
  1870.                 login                未登录时显示登录链接
  1871.                 extrajs                扩展 js
  1872.                 striptags        过滤 HTML 标记
  1873.         Ajax 控制
  1874.                 handle                执行 js 回调函数
  1875.                 showid                控制显示的对象 ID
  1876. */  
  1877. function showmessage($message, $url_forward = '', $values = array(), $extraparam = array(), $custom = 0) {  
  1878.         require_once libfile('function/message');  
  1879.         return dshowmessage($message, $url_forward, $values, $extraparam, $custom);  
  1880. }  
  1881.   
  1882. /**
  1883. * 检查是否正确提交了表单
  1884. * @param $var 需要检查的变量
  1885. * @param $allowget 是否允许GET方式
  1886. * @param $seccodecheck 验证码检测是否开启
  1887. * @return 返回是否正确提交了表单
  1888. */  
  1889. function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) {  
  1890.         if(!getgpc($var)) {  
  1891.                 return FALSE;  
  1892.         } else {  
  1893.                 return helper_form::submitcheck($var, $allowget, $seccodecheck, $secqaacheck);  
  1894.         }  
  1895. }  
  1896.   
  1897. /**
  1898. * 分页
  1899. * @param $num - 总数
  1900. * @param $perpage - 每页数
  1901. * @param $curpage - 当前页
  1902. * @param $mpurl - 跳转的路径
  1903. * @param $maxpages - 允许显示的最大页数
  1904. * @param $page - 最多显示多少页码
  1905. * @param $autogoto - 最后一页,自动跳转
  1906. * @param $simple - 是否简洁模式(简洁模式不显示上一页、下一页和页码跳转)
  1907. * @return 返回分页代码
  1908. */  
  1909. function multi($num, $perpage, $curpage, $mpurl, $maxpages = 0, $page = 10, $autogoto = FALSE, $simple = FALSE, $jsfunc = FALSE) {  
  1910.         return $num > $perpage ? helper_page::multi($num, $perpage, $curpage, $mpurl, $maxpages, $page, $autogoto, $simple, $jsfunc) : '';  
  1911. }  
  1912.   
  1913. /**
  1914. * 只有上一页下一页的分页(无需知道数据总数)
  1915. * @param $num - 本次所取数据条数
  1916. * @param $perpage - 每页数
  1917. * @param $curpage - 当前页
  1918. * @param $mpurl - 跳转的路径
  1919. * @return 返回分页代码
  1920. */  
  1921. function simplepage($num, $perpage, $curpage, $mpurl) {  
  1922.         return helper_page::simplepage($num, $perpage, $curpage, $mpurl);  
  1923. }  
  1924.   
  1925. /**
  1926. * 词语过滤
  1927. * @param $message - 词语过滤文本
  1928. * @return 成功返回原始文本,否则提示错误或被替换
  1929. */  
  1930. function censor($message, $modword = NULL, $return = FALSE) {  
  1931.         return helper_form::censor($message, $modword, $return);  
  1932. }  
  1933.   
  1934. /**
  1935.         词语过滤,检测是否含有需要审核的词
  1936. */  
  1937. function censormod($message) {  
  1938.         return getglobal('group/ignorecensor') || !$message ? false :helper_form::censormod($message);  
  1939. }  
  1940.   
  1941. //获取用户附属表信息,累加到第一个变量$values  
  1942. function space_merge(&$values, $tablename, $isarchive = false) {  
  1943.         global $_G;  
  1944.   
  1945.         $uid = empty($values['uid'])?$_G['uid']:$values['uid'];//默认当前用户  
  1946.         $var = "member_{$uid}_{$tablename}";  
  1947.         if($uid) {  
  1948.                 if(!isset($_G[$var])) {  
  1949.                         //$query = DB::query("SELECT * FROM ".DB::table('common_member_'.$tablename)." WHERE uid='$uid'");  
  1950.                         //if($_G[$var] = DB::fetch($query)) {  
  1951.                         $ext = $isarchive ? '_archive' : '';  
  1952.                         if(($_G[$var] = C::t('common_member_'.$tablename.$ext)->fetch($uid)) !== false) {  
  1953.                                 if($tablename == 'field_home') {  
  1954.                                         //隐私设置  
  1955.                                         $_G['setting']['privacy'] = empty($_G['setting']['privacy']) ? array() : (is_array($_G['setting']['privacy']) ? $_G['setting']['privacy'] : dunserialize($_G['setting']['privacy']));  
  1956.                                         $_G[$var]['privacy'] = empty($_G[$var]['privacy'])? array() : is_array($_G[$var]['privacy']) ? $_G[$var]['privacy'] : dunserialize($_G[$var]['privacy']);  
  1957.                                         foreach (array('feed','view','profile') as $pkey) {  
  1958.                                                 if(empty($_G[$var]['privacy'][$pkey]) && !isset($_G[$var]['privacy'][$pkey])) {  
  1959.                                                         $_G[$var]['privacy'][$pkey] = isset($_G['setting']['privacy'][$pkey]) ? $_G['setting']['privacy'][$pkey] : array();//取站点默认设置  
  1960.                                                 }  
  1961.                                         }  
  1962.                                         //邮件提醒  
  1963.                                         $_G[$var]['acceptemail'] = empty($_G[$var]['acceptemail'])? array() : dunserialize($_G[$var]['acceptemail']);  
  1964.                                         if(empty($_G[$var]['acceptemail'])) {  
  1965.                                                 $_G[$var]['acceptemail'] = empty($_G['setting']['acceptemail'])?array():dunserialize($_G['setting']['acceptemail']);  
  1966.                                         }  
  1967.                                 }  
  1968.                         } else {  
  1969.                                 //插入默认数据  
  1970.                                 //DB::insert('common_member_'.$tablename, array('uid'=>$uid));  
  1971.                                 C::t('common_member_'.$tablename.$ext)->insert(array('uid'=>$uid));  
  1972.                                 $_G[$var] = array();  
  1973.                         }  
  1974.                 }  
  1975.                 $values = array_merge($values, $_G[$var]);  
  1976.         }  
  1977. }  
  1978.   
  1979. /*
  1980. * 运行log记录
  1981. */  
  1982. function runlog($file, $message, $halt=0) {  
  1983.         helper_log::runlog($file, $message, $halt);  
  1984. }  
  1985.   
  1986. /*
  1987. * 处理搜索关键字
  1988. */  
  1989. function stripsearchkey($string) {  
  1990.         $string = trim($string);  
  1991.         $string = str_replace('*', '%', addcslashes($string, '%_'));  
  1992.         //$string = str_replace('_', '\_', $string);  
  1993.         return $string;  
  1994. }  
  1995.   
  1996. /*
  1997. * 递归创建目录
  1998. */  
  1999. function dmkdir($dir, $mode = 0777, $makeindex = TRUE){  
  2000.         if(!is_dir($dir)) {  
  2001.                 dmkdir(dirname($dir), $mode, $makeindex);  
  2002.                 @mkdir($dir, $mode);  
  2003.                 if(!empty($makeindex)) {  
  2004.                         @touch($dir.'/index.html'); @chmod($dir.'/index.html', 0777);  
  2005.                 }  
  2006.         }  
  2007.         return true;  
  2008. }  
  2009.   
  2010. /**
  2011. * 刷新重定向
  2012. */  
  2013. function dreferer($default = '') {  
  2014.         global $_G;  
  2015.   
  2016.         $default = empty($default) && $_ENV['curapp'] ? $_ENV['curapp'].'.php' : '';  
  2017.         $_G['referer'] = !empty($_GET['referer']) ? $_GET['referer'] : $_SERVER['HTTP_REFERER'];  
  2018.         $_G['referer'] = substr($_G['referer'], -1) == '?' ? substr($_G['referer'], 0, -1) : $_G['referer'];  
  2019.   
  2020.         if(strpos($_G['referer'], 'member.php?mod=logging')) {  
  2021.                 $_G['referer'] = $default;  
  2022.         }  
  2023.   
  2024.         $reurl = parse_url($_G['referer']);  
  2025.         /**
  2026.          * 判断host是否相同,不同时做进一步的校验
  2027.          * 当解析到的host与HTTP_HOST,相同的,不管是不是加www均给予放行
  2028.          */  
  2029.         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']))) {  
  2030.                 //校验是否在应用域名或版块域名配置中  
  2031.                 if(!in_array($reurl['host'], $_G['setting']['domain']['app']) && !isset($_G['setting']['domain']['list'][$reurl['host']])) {  
  2032.                         $domainroot = substr($reurl['host'], strpos($reurl['host'], '.')+1);  
  2033.                         //是否为子域名,如果不为子域名则跳到index.php  
  2034.                         if(empty($_G['setting']['domain']['root']) || (is_array($_G['setting']['domain']['root']) && !in_array($domainroot, $_G['setting']['domain']['root']))) {  
  2035.                                 $_G['referer'] = $_G['setting']['domain']['defaultindex'] ? $_G['setting']['domain']['defaultindex'] : 'index.php';  
  2036.                         }  
  2037.                 }  
  2038.         } elseif(empty($reurl['host'])) {  
  2039.                 $_G['referer'] = $_G['siteurl'].'./'.$_G['referer'];  
  2040.         }  
  2041.   
  2042.         $_G['referer'] = durlencode($_G['referer']);  
  2043.         return$_G['referer'];  
  2044. }  
  2045.   
  2046. /**
  2047. * 远程FTP使用
  2048. */  
  2049. function ftpcmd($cmd, $arg1 = '') {  
  2050.         static $ftp;  
  2051.         $ftpon = getglobal('setting/ftp/on');  
  2052.         if(!$ftpon) {  
  2053.                 return $cmd == 'error' ? -101 : 0;  
  2054.         } elseif($ftp == null) {  
  2055.                 $ftp = & discuz_ftp::instance();  
  2056.         }  
  2057.         if(!$ftp->enabled) {  
  2058.                 return $ftp->error();  
  2059.         } elseif($ftp->enabled && !$ftp->connectid) {  
  2060.                 $ftp->connect();  
  2061.         }  
  2062.         switch ($cmd) {  
  2063.                 case 'upload' : return $ftp->upload(getglobal('setting/attachdir').'/'.$arg1, $arg1); break;  
  2064.                 case 'delete' : return $ftp->ftp_delete($arg1); break;  
  2065.                 case 'close'  : return $ftp->ftp_close(); break;  
  2066.                 case 'error'  : return $ftp->error(); break;  
  2067.                 case 'object' : return $ftp; break;  
  2068.                 default       : return false;  
  2069.         }  
  2070.   
  2071. }  
  2072.   
  2073. /**
  2074. * 编码转换
  2075. * @param <string> $str 要转码的字符
  2076. * @param <string> $in_charset 输入字符集
  2077. * @param <string> $out_charset 输出字符集(默认当前)
  2078. * @param <boolean> $ForceTable 强制使用码表(默认不强制)
  2079. *
  2080. */  
  2081. function diconv($str, $in_charset, $out_charset = CHARSET, $ForceTable = FALSE) {  
  2082.         global $_G;  
  2083.   
  2084.         $in_charset = strtoupper($in_charset);  
  2085.         $out_charset = strtoupper($out_charset);  
  2086.   
  2087.         if(empty($str) || $in_charset == $out_charset) {  
  2088.                 return $str;  
  2089.         }  
  2090.   
  2091.         $out = '';  
  2092.   
  2093.         if(!$ForceTable) {  
  2094.                 if(function_exists('iconv')) {  
  2095.                         $out = iconv($in_charset, $out_charset.'//IGNORE', $str);  
  2096.                 } elseif(function_exists('mb_convert_encoding')) {  
  2097.                         $out = mb_convert_encoding($str, $out_charset, $in_charset);  
  2098.                 }  
  2099.         }  
  2100.   
  2101.         if($out == '') {  
  2102.                 $chinese = new Chinese($in_charset, $out_charset, true);  
  2103.                 $out = $chinese->Convert($str);  
  2104.         }  
  2105.   
  2106.         return $out;  
  2107. }  
  2108.   
  2109. function widthauto() {  
  2110.         global $_G;  
  2111.         if($_G['disabledwidthauto']) {  
  2112.                 return 0;  
  2113.         }  
  2114.         if(!empty($_G['widthauto'])) {  
  2115.                 return $_G['widthauto'] > 0 ? 1 : 0;  
  2116.         }  
  2117.         if($_G['setting']['switchwidthauto'] && !empty($_G['cookie']['widthauto'])) {  
  2118.                 return $_G['cookie']['widthauto'] > 0 ? 1 : 0;  
  2119.         } else {  
  2120.                 return $_G['setting']['allowwidthauto'] ? 0 : 1;  
  2121.         }  
  2122. }  
  2123. /**
  2124. * 重建数组
  2125. * @param <string> $array 需要反转的数组
  2126. * @return array 原数组与的反转后的数组
  2127. */  
  2128. function renum($array) {  
  2129.         $newnums = $nums = array();  
  2130.         foreach ($array as $id => $num) {  
  2131.                 $newnums[$num][] = $id;  
  2132.                 $nums[$num] = $num;  
  2133.         }  
  2134.         return array($nums, $newnums);  
  2135. }  
  2136.   
  2137. /**
  2138. * 字节格式化单位
  2139. * @param $filesize - 大小(字节)
  2140. * @return 返回格式化后的文本
  2141. */  
  2142. function sizecount($size) {  
  2143.         if($size >= 1073741824) {  
  2144.                 $size = round($size / 1073741824 * 100) / 100 . ' GB';  
  2145.         } elseif($size >= 1048576) {  
  2146.                 $size = round($size / 1048576 * 100) / 100 . ' MB';  
  2147.         } elseif($size >= 1024) {  
  2148.                 $size = round($size / 1024 * 100) / 100 . ' KB';  
  2149.         } else {  
  2150.                 $size = intval($size) . ' Bytes';  
  2151.         }  
  2152.         return $size;  
  2153. }  
  2154.   
  2155. function swapclass($class1, $class2 = '') {  
  2156.         static $swapc = null;  
  2157.         $swapc = isset($swapc) && $swapc != $class1 ? $class1 : $class2;  
  2158.         return $swapc;  
  2159. }  
  2160.   
  2161. /**
  2162. * 写入运行日志
  2163. */  
  2164. function writelog($file, $log) {  
  2165.         helper_log::writelog($file, $log);  
  2166. }  
  2167.   
  2168. /**
  2169. * 取得某标志位的数值 (0|1)
  2170. *
  2171. * @param 数值 $status
  2172. * @param 位置 $position
  2173. * @return 0 | 1
  2174. */  
  2175. function getstatus($status, $position) {  
  2176.         $t = $status & pow(2, $position - 1) ? 1 : 0;  
  2177.         return $t;  
  2178. }  
  2179.   
  2180. /**
  2181. * 设置某一bit位的数值 0 or 1
  2182. *
  2183. * @param int $position  1-16
  2184. * @param int $value  0|1
  2185. * @param 原始数值 $baseon  0x0000-0xffff
  2186. * @return int
  2187. */  
  2188. function setstatus($position, $value, $baseon = null) {  
  2189.         $t = pow(2, $position - 1);  
  2190.         if($value) {  
  2191.                 $t = $baseon | $t;  
  2192.         } elseif ($baseon !== null) {  
  2193.                 $t = $baseon & ~$t;  
  2194.         } else {  
  2195.                 $t = ~$t;  
  2196.         }  
  2197.         return $t & 0xFFFF;  
  2198. }  
  2199.   
  2200. /**
  2201. * 通知
  2202. * @param Integer $touid: 通知给谁
  2203. * @param String $type: 通知类型
  2204. * @param String $note: 语言key
  2205. * @param Array $notevars: 语言变量对应的值
  2206. * @param Integer $system: 是否为系统通知 0:非系统通知; 1:系统通知
  2207. */  
  2208. function notification_add($touid, $type, $note, $notevars = array(), $system = 0) {  
  2209.         return helper_notification::notification_add($touid, $type, $note, $notevars, $system);  
  2210. }  
  2211.   
  2212. /**
  2213. * 发送管理通知
  2214. * @param $type - 通知类型
  2215. */  
  2216. function manage_addnotify($type, $from_num = 0, $langvar = array()) {  
  2217.         helper_notification::manage_addnotify($type, $from_num, $langvar);  
  2218. }  
  2219.   
  2220. /**
  2221. * 发送短消息(兼容提醒)
  2222. * @param $toid - 接收方id
  2223. * @param $subject - 标题
  2224. * @param $message - 内容
  2225. * @param $fromid - 发送方id
  2226. */  
  2227. function sendpm($toid, $subject, $message, $fromid = '', $replypmid = 0, $isusername = 0, $type = 0) {  
  2228.         return helper_pm::sendpm($toid, $subject, $message, $fromid, $replypmid, $isusername, $type);  
  2229. }  
  2230.   
  2231. //获得用户组图标  
  2232. function g_icon($groupid, $return = 0) {  
  2233.         global $_G;  
  2234.         if(empty($_G['cache']['usergroups'][$groupid]['icon'])) {  
  2235.                 $s =  '';  
  2236.         } else {  
  2237.                 if(substr($_G['cache']['usergroups'][$groupid]['icon'], 0, 5) == 'http:') {  
  2238.                         $s = '<img src="'.$_G['cache']['usergroups'][$groupid]['icon'].'" alt="" class="vm" />';  
  2239.                 } else {  
  2240.                         $s = '<img src="'.$_G['setting']['attachurl'].'common/'.$_G['cache']['usergroups'][$groupid]['icon'].'" alt="" class="vm" />';  
  2241.                 }  
  2242.         }  
  2243.         if($return) {  
  2244.                 return $s;  
  2245.         } else {  
  2246.                 echo $s;  
  2247.         }  
  2248. }  
  2249. //从数据库中更新DIY模板文件  
  2250. function updatediytemplate($targettplname = '', $tpldirectory = '') {  
  2251.         $r = false;  
  2252.         //$where = empty($targettplname) ? '' : " WHERE targettplname='$targettplname'";  
  2253.         //$query = DB::query("SELECT * FROM ".DB::table('common_diy_data')."$where");  
  2254.         $alldata = !empty($targettplname) ? array( C::t('common_diy_data')->fetch($targettplname, $tpldirectory)) : C::t('common_diy_data')->range();  
  2255.         require_once libfile('function/portalcp');  
  2256.         //while($value = DB::fetch($query)) {  
  2257.         foreach($alldata as $value) {  
  2258.                 $r = save_diy_data($value['tpldirectory'], $value['primaltplname'], $value['targettplname'], dunserialize($value['diycontent']));  
  2259.         }  
  2260.         return $r;  
  2261. }  
  2262.   
  2263. //获得用户唯一串  
  2264. function space_key($uid, $appid=0) {  
  2265.         global $_G;  
  2266.         //$siteuniqueid = DB::result_first("SELECT svalue FROM ".DB::table('common_setting')." WHERE skey='siteuniqueid'");  
  2267.         return substr(md5($_G['setting']['siteuniqueid'].'|'.$uid.(empty($appid)?'':'|'.$appid)), 8, 16);  
  2268. }  
  2269.   
  2270.   
  2271. //note post分表相关函数  
  2272. /**
  2273. *
  2274. * 通过tid得到相应的单一post表名或post表集合
  2275. * @param <mix> $tids: 允许传进单个tid,也可以是tid集合
  2276. * @param $primary: 是否只查主题表 0:遍历所有表;1:只查主表
  2277. * @return 当传进来的是单一的tid将直接返回表名,否则返回表集合的二维数组例:array('forum_post' => array(tids),'forum_post_1' => array(tids))
  2278. * @TODO tid传进来的是字符串的,返回单个表名,传进来的是数组的,不管是不是一个数组,返回的还是数组,保证进出值对应
  2279. */  
  2280. function getposttablebytid($tids, $primary = 0) {  
  2281.         return table_forum_post::getposttablebytid($tids, $primary);  
  2282. }  
  2283.   
  2284. /**
  2285. * 获取论坛帖子表名
  2286. * @param <int> $tableid: 分表ID,默认为:fourm_post表
  2287. * @param <boolean> $prefix: 是否默认带有表前缀
  2288. * @return forum_post or forum_post_*
  2289. */  
  2290. function getposttable($tableid = 0, $prefix = false) {  
  2291.         return table_forum_post::getposttable($tableid, $prefix);  
  2292. }  
  2293.   
  2294. /**
  2295. * 内存读写接口函数
  2296. * <code>
  2297. * memory('get', 'keyname') === false;//缓存中没有这个keyname时结果为true
  2298. * </code>
  2299. *  * @param 命令 $cmd (set|get|rm|check|inc|dec)
  2300. * @param 键值 $key
  2301. * @param 数据 $value 当$cmd=get|rm时,$value即为$prefix;当$cmd=inc|dec时,$value为$step,默认为1
  2302. * @param 有效期 $ttl
  2303. * @param 键值的前缀 $prefix
  2304. * @return mix
  2305. *
  2306. * @example set : 写入内存 $ret = memory('set', 'test', 'ok')
  2307. * @example get : 读取内存 $data = memory('get', 'test')
  2308. * @example rm : 删除内存  $ret = memory('rm', 'test')
  2309. * @example check : 检查内存功能是否可用 $allow = memory('check')
  2310. */  
  2311. function memory($cmd, $key='', $value='', $ttl = 0, $prefix = '') {  
  2312.         if($cmd == 'check') {  
  2313.                 return  C::memory()->enable ? C::memory()->type : '';  
  2314.         } elseif(C::memory()->enable && in_array($cmd, array('set', 'get', 'rm', 'inc', 'dec'))) {  
  2315.                 if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {  
  2316.                         if(is_array($key)) {  
  2317.                                 foreach($key as $k) {  
  2318.                                         C::memory()->debug[$cmd][] = ($cmd == 'get' || $cmd == 'rm' ? $value : '').$prefix.$k;  
  2319.                                 }  
  2320.                         } else {  
  2321.                                 C::memory()->debug[$cmd][] = ($cmd == 'get' || $cmd == 'rm' ? $value : '').$prefix.$key;  
  2322.                         }  
  2323.                 }  
  2324.                 switch ($cmd) {  
  2325.                         case 'set': return C::memory()->set($key, $value, $ttl, $prefix); break;  
  2326.                         case 'get': return C::memory()->get($key, $value); break;  
  2327.                         case 'rm': return C::memory()->rm($key, $value); break;  
  2328.                         case 'inc': return C::memory()->inc($key, $value ? $value : 1); break;  
  2329.                         case 'dec': return C::memory()->dec($key, $value ? $value : -1); break;  
  2330.                 }  
  2331.         }  
  2332.         return null;  
  2333. }  
  2334.   
  2335. /**
  2336. * ip允许访问
  2337. * @param $ip 要检查的ip地址
  2338. * @param - $accesslist 允许访问的ip地址
  2339. * @param 返回结果
  2340. */  
  2341. function ipaccess($ip, $accesslist) {  
  2342.         return preg_match("/^(".str_replace(array("\r\n", ' '), array('|', ''), preg_quote($accesslist, '/')).")/", $ip);  
  2343. }  
  2344.   
  2345. /**
  2346. * ip限制访问
  2347. * @param $ip 要检查的ip地址
  2348. * @param - $accesslist 允许访问的ip地址
  2349. * @param 返回结果
  2350. */  
  2351. function ipbanned($onlineip) {  
  2352.         global $_G;  
  2353.   
  2354.         if($_G['setting']['ipaccess'] && !ipaccess($onlineip, $_G['setting']['ipaccess'])) {  
  2355.                 return TRUE;  
  2356.         }  
  2357.   
  2358.         loadcache('ipbanned');  
  2359.         if(empty($_G['cache']['ipbanned'])) {  
  2360.                 return FALSE;  
  2361.         } else {  
  2362.                 if($_G['cache']['ipbanned']['expiration'] < TIMESTAMP) {  
  2363.                         require_once libfile('function/cache');  
  2364.                         updatecache('ipbanned');  
  2365.                 }  
  2366.                 return preg_match("/^(".$_G['cache']['ipbanned']['regexp'].")$/", $onlineip);  
  2367.         }  
  2368. }  
  2369.   
  2370. //获得统计数  
  2371. function getcount($tablename, $condition) {  
  2372.         if(empty($condition)) {  
  2373.                 $where = '1';  
  2374.         } elseif(is_array($condition)) {  
  2375.                 $where = DB::implode_field_value($condition, ' AND ');  
  2376.         } else {  
  2377.                 $where = $condition;  
  2378.         }  
  2379.         $ret = intval(DB::result_first("SELECT COUNT(*) AS num FROM ".DB::table($tablename)." WHERE $where"));  
  2380.         return $ret;  
  2381. }  
  2382.   
  2383. /**
  2384. * 系统级消息
  2385. */  
  2386. function sysmessage($message) {  
  2387.         //require libfile('function/sysmessage');  
  2388.         //show_system_message($message);  
  2389.         helper_sysmessage::show($message);  
  2390. }  
  2391.   
  2392. /**
  2393. * 论坛权限
  2394. * @param $permstr - 权限信息
  2395. * @param $groupid - 只判断用户组
  2396. * @return 0 无权限 > 0 有权限
  2397. */  
  2398. function forumperm($permstr, $groupid = 0) {  
  2399.         global $_G;  
  2400.   
  2401.         $groupidarray = array($_G['groupid']);  
  2402.         if($groupid) {  
  2403.                 return preg_match("/(^|\t)(".$groupid.")(\t|$)/", $permstr);  
  2404.         }  
  2405.         foreach(explode("\t", $_G['member']['extgroupids']) as $extgroupid) {  
  2406.                 if($extgroupid = intval(trim($extgroupid))) {  
  2407.                         $groupidarray[] = $extgroupid;  
  2408.                 }  
  2409.         }  
  2410.         if($_G['setting']['verify']['enabled']) {  
  2411.                 getuserprofile('verify1');  
  2412.                 foreach($_G['setting']['verify'] as $vid => $verify) {  
  2413.                         if($verify['available'] && $_G['member']['verify'.$vid] == 1) {  
  2414.                                 $groupidarray[] = 'v'.$vid;  
  2415.                         }  
  2416.                 }  
  2417.         }  
  2418.         return preg_match("/(^|\t)(".implode('|', $groupidarray).")(\t|$)/", $permstr);  
  2419. }  
  2420.   
  2421. //检查权限  
  2422. function checkperm($perm) {  
  2423.         global $_G;  
  2424.         return defined('IN_ADMINCP') ? true : (empty($_G['group'][$perm])?'':$_G['group'][$perm]);  
  2425. }  
  2426.   
  2427. /**
  2428. * 时间段设置检测
  2429. * @param $periods - 那种时间段 $settings[$periods]  $settings['postbanperiods'] $settings['postmodperiods']
  2430. * @param $showmessage - 是否提示信息
  2431. * @return 返回检查结果
  2432. */  
  2433. function periodscheck($periods, $showmessage = 1) {  
  2434.         global $_G;  
  2435.         if(($periods == 'postmodperiods' || $periods == 'postbanperiods') && ($_G['setting']['postignorearea'] || $_G['setting']['postignoreip'])) {  
  2436.                 if($_G['setting']['postignoreip']) {  
  2437.                         foreach(explode("\n", $_G['setting']['postignoreip']) as $ctrlip) {  
  2438.                                 if(preg_match("/^(".preg_quote(($ctrlip = trim($ctrlip)), '/').")/", $_G['clientip'])) {  
  2439.                                         return false;  
  2440.                                         break;  
  2441.                                 }  
  2442.                         }  
  2443.                 }  
  2444.                 if($_G['setting']['postignorearea']) {  
  2445.                         $location = $whitearea = '';  
  2446.                         require_once libfile('function/misc');  
  2447.                         $location = trim(convertip($_G['clientip'], "./"));  
  2448.                         if($location) {  
  2449.                                 $whitearea = preg_quote(trim($_G['setting']['postignorearea']), '/');  
  2450.                                 $whitearea = str_replace(array("\\*"), array('.*'), $whitearea);  
  2451.                                 $whitearea = '.*'.$whitearea.'.*';  
  2452.                                 $whitearea = '/^('.str_replace(array("\r\n", ' '), array('.*|.*', ''), $whitearea).')$/i';  
  2453.                                 if(@preg_match($whitearea, $location)) {  
  2454.                                         return false;  
  2455.                                 }  
  2456.                         }  
  2457.                 }  
  2458.         }  
  2459.         if(!$_G['group']['disableperiodctrl'] && $_G['setting'][$periods]) {  
  2460.                 $now = dgmdate(TIMESTAMP, 'G.i', $_G['setting']['timeoffset']);  
  2461.                 foreach(explode("\r\n", str_replace(':', '.', $_G['setting'][$periods])) as $period) {  
  2462.                         list($periodbegin, $periodend) = explode('-', $period);  
  2463.                         if(($periodbegin > $periodend && ($now >= $periodbegin || $now < $periodend)) || ($periodbegin < $periodend && $now >= $periodbegin && $now < $periodend)) {  
  2464.                                 $banperiods = str_replace("\r\n", ', ', $_G['setting'][$periods]);  
  2465.                                 if($showmessage) {  
  2466.                                         showmessage('period_nopermission', NULL, array('banperiods' => $banperiods), array('login' => 1));  
  2467.                                 } else {  
  2468.                                         return TRUE;  
  2469.                                 }  
  2470.                         }  
  2471.                 }  
  2472.         }  
  2473.         return FALSE;  
  2474. }  
  2475.   
  2476. //新用户发言  
  2477. function cknewuser($return=0) {  
  2478.         global $_G;  
  2479.   
  2480.         $result = true;  
  2481.   
  2482.         if(!$_G['uid']) return true;  
  2483.   
  2484.         //不受防灌水限制  
  2485.         if(checkperm('disablepostctrl')) {  
  2486.                 return $result;  
  2487.         }  
  2488.         $ckuser = $_G['member'];  
  2489.   
  2490.         //见习时间  
  2491.         if($_G['setting']['newbiespan'] && $_G['timestamp']-$ckuser['regdate']<$_G['setting']['newbiespan']*60) {  
  2492.                 if(empty($return)) showmessage('no_privilege_newbiespan', '', array('newbiespan' => $_G['setting']['newbiespan']), array());  
  2493.                 $result = false;  
  2494.         }  
  2495.         //需要上传头像  
  2496.         if($_G['setting']['need_avatar'] && empty($ckuser['avatarstatus'])) {  
  2497.                 if(empty($return)) showmessage('no_privilege_avatar', '', array(), array());  
  2498.                 $result = false;  
  2499.         }  
  2500.         //强制新用户激活邮箱  
  2501.         if($_G['setting']['need_email'] && empty($ckuser['emailstatus'])) {  
  2502.                 if(empty($return)) showmessage('no_privilege_email', '', array(), array());  
  2503.                 $result = false;  
  2504.         }  
  2505.         //强制新用户好友个数  
  2506.         if($_G['setting']['need_friendnum']) {  
  2507.                 space_merge($ckuser, 'count');  
  2508.                 if($ckuser['friends'] < $_G['setting']['need_friendnum']) {  
  2509.                         if(empty($return)) showmessage('no_privilege_friendnum', '', array('friendnum' => $_G['setting']['need_friendnum']), array());  
  2510.                         $result = false;  
  2511.                 }  
  2512.         }  
  2513.         return $result;  
  2514. }  
  2515.   
  2516. function manyoulog($logtype, $uids, $action, $fid = '') {  
  2517.         helper_manyou::manyoulog($logtype, $uids, $action, $fid);  
  2518. }  
  2519.   
  2520. /**
  2521. * 用户操作日志
  2522. * @param int $uid 用户ID
  2523. * @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
  2524. * @return bool
  2525. */  
  2526. function useractionlog($uid, $action) {  
  2527.         return helper_log::useractionlog($uid, $action);  
  2528. }  
  2529.   
  2530. /**
  2531. * 得到用户操作的代码或代表字符,参数为数字返回字符串,参数为字符串返回数字
  2532. * @param string/int $var
  2533. * @return int/string 注意:如果失败返回false,请使用===判断,因为代码0代表tid
  2534. */  
  2535. function getuseraction($var) {  
  2536.         return helper_log::getuseraction($var);  
  2537. }  
  2538.   
  2539. /**
  2540. * 获取我的中心中展示的应用
  2541. */  
  2542. function getuserapp($panel = 0) {  
  2543.         return helper_manyou::getuserapp($panel);  
  2544. }  
  2545.   
  2546. /**
  2547. * 获取manyou应用本地图标路径
  2548. * @param <type> $appid
  2549. */  
  2550. function getmyappiconpath($appid, $iconstatus=0) {  
  2551.         return helper_manyou::getmyappiconpath($appid, $iconstatus);  
  2552. }  
  2553.   
  2554. //获取超时时间  
  2555. function getexpiration() {  
  2556.         global $_G;  
  2557.         $date = getdate($_G['timestamp']);  
  2558.         return mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']) + 86400;  
  2559. }  
  2560.   
  2561. function return_bytes($val) {  
  2562.     $val = trim($val);  
  2563.     $last = strtolower($val{strlen($val)-1});  
  2564.     switch($last) {  
  2565.         case 'g': $val *= 1024;  
  2566.         case 'm': $val *= 1024;  
  2567.         case 'k': $val *= 1024;  
  2568.     }  
  2569.     return $val;  
  2570. }  
  2571.   
  2572. function iswhitelist($host) {  
  2573.         global $_G;  
  2574.         static $iswhitelist = array();  
  2575.   
  2576.         if(isset($iswhitelist[$host])) {  
  2577.                 return $iswhitelist[$host];  
  2578.         }  
  2579.         $hostlen = strlen($host);  
  2580.         $iswhitelist[$host] = false;  
  2581.         if(!$_G['cache']['domainwhitelist']) {  
  2582.                 loadcache('domainwhitelist');  
  2583.         }  
  2584.         if(is_array($_G['cache']['domainwhitelist'])) foreach($_G['cache']['domainwhitelist'] as $val) {  
  2585.                 $domainlen = strlen($val);  
  2586.                 if($domainlen > $hostlen) {  
  2587.                         continue;  
  2588.                 }  
  2589.                 if(substr($host, -$domainlen) == $val) {  
  2590.                         $iswhitelist[$host] = true;  
  2591.                         break;  
  2592.                 }  
  2593.         }  
  2594.         if($iswhitelist[$host] == false) {  
  2595.                 $iswhitelist[$host] = $host == $_SERVER['HTTP_HOST'];  
  2596.         }  
  2597.         return $iswhitelist[$host];  
  2598. }  
  2599.   
  2600. /**
  2601. * 通过 AID 获取附件表名
  2602. * @param <int> $aid
  2603. */  
  2604. function getattachtablebyaid($aid) {  
  2605. //        $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE aid='$aid'");  
  2606.         $attach = C::t('forum_attachment')->fetch($aid);  
  2607.         $tableid = $attach['tableid'];  
  2608.         return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused');  
  2609. }  
  2610.   
  2611. /**
  2612. * 返回指定 TID 所对应的附件表编号
  2613. * @param <int> $tid
  2614. */  
  2615. function getattachtableid($tid) {  
  2616.         $tid = (string)$tid;  
  2617.         return intval($tid{strlen($tid)-1});  
  2618. }  
  2619.   
  2620. /**
  2621. * 通过 TID 获取附件表名
  2622. * @param <int> $tid
  2623. */  
  2624. function getattachtablebytid($tid) {  
  2625.         return 'forum_attachment_'.getattachtableid($tid);  
  2626. }  
  2627.   
  2628. /**
  2629. * 通过 PID 获取附件表名
  2630. * @param <int> $pid
  2631. */  
  2632. function getattachtablebypid($pid) {  
  2633.         $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE pid='$pid' LIMIT 1");  
  2634.         return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused');  
  2635. }  
  2636.   
  2637. /**
  2638. * 添加一个新的附件索引记录,并返回新附件 ID
  2639. * @param <int> $uid
  2640. */  
  2641. function getattachnewaid($uid = 0) {  
  2642.         global $_G;  
  2643.         $uid = !$uid ? $_G['uid'] : $uid;  
  2644. //        return DB::insert('forum_attachment', array('tid' => 0, 'pid' => 0, 'uid' => $uid, 'tableid' => 127), true);  
  2645.         return C::t('forum_attachment')->insert(array('tid' => 0, 'pid' => 0, 'uid' => $uid, 'tableid' => 127), true);  
  2646. }  
  2647.   
  2648. /**
  2649. * 获取 SEO设置
  2650. * @param string $page 调用哪个页面的
  2651. * @param array $data 可替换数据
  2652. * @return array('seotitle', 'seodescription', 'seokeywords')
  2653. */  
  2654. function get_seosetting($page, $data = array(), $defset = array()) {  
  2655.         return helper_seo::get_seosetting($page, $data, $defset);  
  2656. }  
  2657.   
  2658. /**
  2659. *
  2660. * 生成缩略图文件名
  2661. * @param String $fileStr: 原文件名,允许附带路径
  2662. * @param String $extend: 新文件名后缀
  2663. * @param Boolean $holdOldExt: 是否保留原扩展名
  2664. * @return 返加新的后缀文件名
  2665. */  
  2666. function getimgthumbname($fileStr, $extend='.thumb.jpg', $holdOldExt=true) {  
  2667.         if(empty($fileStr)) {  
  2668.                 return '';  
  2669.         }  
  2670.         //去掉原扩展名  
  2671.         if(!$holdOldExt) {  
  2672.                 $fileStr = substr($fileStr, 0, strrpos($fileStr, '.'));  
  2673.         }  
  2674.         $extend = strstr($extend, '.') ? $extend : '.'.$extend;  
  2675.         return $fileStr.$extend;  
  2676. }  
  2677.   
  2678. /**
  2679. * 更新数据的审核状态
  2680. * @param <string> $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
  2681. * @param <array/int> $ids ID 数组、ID 值
  2682. * @param <int> $status 状态 0=加入审核(默认) 1=忽略审核 2=审核通过
  2683. */  
  2684. function updatemoderate($idtype, $ids, $status = 0) {  
  2685.         helper_form::updatemoderate($idtype, $ids, $status);  
  2686. }  
  2687.   
  2688. /**
  2689. * 显示漫游应用公告
  2690. */  
  2691. function userappprompt() {  
  2692.         global $_G;  
  2693.   
  2694.         if($_G['setting']['my_app_status'] && $_G['setting']['my_openappprompt'] && empty($_G['cookie']['userappprompt'])) {  
  2695.                 $sid = $_G['setting']['my_siteid'];  
  2696.                 $ts = $_G['timestamp'];  
  2697.                 $key = md5($sid.$ts.$_G['setting']['my_sitekey']);  
  2698.                 $uchId = $_G['uid'] ? $_G['uid'] : 0;  
  2699.                 echo '<script type="text/javascript" src="http://notice.uchome.manyou.com/notice/userNotice?sId='.$sid.'&ts='.$ts.'&key='.$key.'&uchId='.$uchId.'" charset="UTF-8"></script>';  
  2700.         }  
  2701. }  
  2702.   
  2703. /**
  2704. * 安全的 intval, 可以支持 int(10) unsigned
  2705. * 支持最大整数 0xFFFFFFFF 4294967295
  2706. * @param mixed $int string|int|array
  2707. * @return mixed
  2708. */  
  2709. function dintval($int, $allowarray = false) {  
  2710.         $ret = intval($int);  
  2711.         if($int == $ret || !$allowarray && is_array($int)) return $ret;  
  2712.         if($allowarray && is_array($int)) {  
  2713.                 foreach($int as &$v) {  
  2714.                         $v = dintval($v, true);  
  2715.                 }  
  2716.                 return $int;  
  2717.         } elseif($int <= 0xffffffff) {  
  2718.                 $l = strlen($int);  
  2719.                 $m = substr($int, 0, 1) == '-' ? 1 : 0;  
  2720.                 if(($l - $m) === strspn($int,'0987654321', $m)) {  
  2721.                         return $int;  
  2722.                 }  
  2723.         }  
  2724.         return $ret;  
  2725. }  
  2726.   
  2727.   
  2728. function makeSearchSignUrl() {  
  2729.         return getglobal('setting/my_search_data/status') ? helper_manyou::makeSearchSignUrl() : array();  
  2730. }  
  2731.   
  2732. /**
  2733. * 获取批定类型的关联连接
  2734. *
  2735. * @param string $extent 内容所需关联链接范围 article, forum, group, blog
  2736. * @return string 有效的关联链接
  2737. */  
  2738. function get_related_link($extent) {  
  2739.         return helper_seo::get_related_link($extent);  
  2740. }  
  2741.   
  2742. /**
  2743. * 在给定内容中加入关联连接
  2744. *
  2745. * @param string $content 需要加入关联链接的内容
  2746. * @param string $extent 内容所需关联链接范围 article, forum, group, blog
  2747. * @return string 变更后的内容
  2748. */  
  2749. function parse_related_link($content, $extent) {  
  2750.         return helper_seo::parse_related_link($content, $extent);  
  2751. }  
  2752.   
  2753. function check_diy_perm($topic = array(), $flag = '') {  
  2754.         static $ret;  
  2755.         if(!isset($ret)) {  
  2756.                 global $_G;  
  2757.                 $common = !empty($_G['style']['tplfile']) || $_GET['inajax'];  
  2758.                 $blockallow = getstatus($_G['member']['allowadmincp'], 4) || getstatus($_G['member']['allowadmincp'], 5) || getstatus($_G['member']['allowadmincp'], 6);  
  2759.                 $ret['data'] = $common && $blockallow;  
  2760.                 $ret['layout'] = $common && ($_G['group']['allowdiy'] || (  
  2761.                                 CURMODULE === 'topic' && ($_G['group']['allowmanagetopic'] || $_G['group']['allowaddtopic'] && $topic && $topic['uid'] == $_G['uid'])  
  2762.                                 ));  
  2763.         }  
  2764.         return empty($flag) ? $ret['data'] || $ret['layout'] : $ret[$flag];  
  2765. }  
  2766.   
  2767. function strhash($string, $operation = 'DECODE', $key = '') {  
  2768.         $key = md5($key != '' ? $key : getglobal('authkey'));  
  2769.         if($operation == 'DECODE') {  
  2770.                 $hashcode = gzuncompress(base64_decode(($string)));  
  2771.                 $string = substr($hashcode, 0, -16);  
  2772.                 $hash = substr($hashcode, -16);  
  2773.                 unset($hashcode);  
  2774.         }  
  2775.   
  2776.         $vkey = substr(md5($string.substr($key, 0, 16)), 4, 8).substr(md5($string.substr($key, 16, 16)), 18, 8);  
  2777.   
  2778.         if($operation == 'DECODE') {  
  2779.                 return $hash == $vkey ? $string : '';  
  2780.         }  
  2781.   
  2782.         return base64_encode(gzcompress($string.$vkey));  
  2783. }  
  2784.   
  2785. function dunserialize($data) {  
  2786.         if(($ret = unserialize($data)) === false) {  
  2787.                 $ret = unserialize(stripslashes($data));  
  2788.         }  
  2789.         return $ret;  
  2790. }  
  2791.   
  2792. function browserversion($type) {  
  2793.         static $return = array();  
  2794.         static $types = array('ie' => 'msie', 'firefox' => '', 'chrome' => '', 'opera' => '', 'safari' => '', 'mozilla' => '', 'webkit' => '', 'maxthon' => '', 'qq' => 'qqbrowser');  
  2795.         if(!$return) {  
  2796.                 $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);  
  2797.                 $other = 1;  
  2798.                 foreach($types as $i => $v) {  
  2799.                         $v = $v ? $v : $i;  
  2800.                         if(strpos($useragent, $v) !== false) {  
  2801.                                 preg_match('/'.$v.'(\/|\s)([\d\.]+)/i', $useragent, $matches);  
  2802.                                 $ver = $matches[2];  
  2803.                                 $other = $ver !== 0 && $v != 'mozilla' ? 0 : $other;  
  2804.                         } else {  
  2805.                                 $ver = 0;  
  2806.                         }  
  2807.                         $return[$i] = $ver;  
  2808.                 }  
  2809.                 $return['other'] = $other;  
  2810.         }  
  2811.         return $return[$type];  
  2812. }  
  2813.   
  2814. function currentlang() {  
  2815.         $charset = strtoupper(CHARSET);  
  2816.         if($charset == 'GBK') {  
  2817.                 return 'SC_GBK';  
  2818.         } elseif($charset == 'BIG5') {  
  2819.                 return 'TC_BIG5';  
  2820.         } elseif($charset == 'UTF-8') {  
  2821.                 global $_G;  
  2822.                 if($_G['config']['output']['language'] == 'zh_cn') {  
  2823.                         return 'SC_UTF8';  
  2824.                 } elseif ($_G['config']['output']['language'] == 'zh_tw') {  
  2825.                         return 'TC_UTF8';  
  2826.                 }  
  2827.         } else {  
  2828.                 return '';  
  2829.         }  
  2830. }  
  2831.   
  2832. /*
  2833. * 尽量不要在此文件中添加全局函数
  2834. * 请在source/class/helper/目录下创建相应的静态函数集类文件
  2835. * 类的静态方法可以在产品中所有地方使用,使用方法类似:helper_form::submitcheck()
  2836. *
  2837. */  
  2838.   
  2839. ?>
复制代码


发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;

如何回报帮助你解决问题的坛友,好办法就是点击帖子下方的评分按钮给对方加【金币】不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号

关闭

站长推荐上一条 /1 下一条

QQ|侵权投诉|广告报价|手机版|小黑屋|西部数码代理|飘仙建站论坛 ( 豫ICP备2022021143号-1 )

GMT+8, 2024-5-13 18:05 , Processed in 0.075113 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表