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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了discuzX2/source/function/function_core.php通用核心函数库文件分析相关的知识,希望对你有一定的参考价值。

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

以上是关于discuzX2/source/function/function_core.php通用核心函数库文件分析的主要内容,如果未能解决你的问题,请参考以下文章

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