Discuz开发之function_core常用函数解析

[复制链接]
admin 发表于 2018-10-18 07:32:41 | 显示全部楼层 |阅读模式 0
  1. <?php

  2. /**
  3. *      [Discuz!] (C)2001-2099 Comsenz Inc.
  4. *      This is NOT a freeware, use is subject to license terms
  5. *
  6. *      $Id: function_core.php 34523 2014-05-15 04:22:29Z nemohou $
  7. */

  8. if(!defined('IN_DISCUZ')) {
  9.         exit('Access Denied');
  10. }

  11. define('DISCUZ_CORE_FUNCTION', true);

  12. /**
  13. * like url encode, but can encode full url, not only the parms
  14. * this function to encode URLs according to RFC 3986(exclude char ',(,) )
  15. * @param type $url
  16. * @return type
  17. */
  18. function durlencode($url) {
  19.         static $fix = array('%21', '%2A','%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
  20.         static $replacements = array('!', '*', ';', ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]");
  21.         return str_replace($fix, $replacements, urlencode($url));
  22. }

  23. /**
  24. * 系统错误处理
  25. * @param <type> $message 错误信息a
  26. * @param <type> $show 是否显示信息
  27. * @param <type> $save 是否存入日志
  28. * @param <type> $halt 是否中断访问
  29. */
  30. function system_error($message, $show = true, $save = true, $halt = true) {
  31.         discuz_error::system_error($message, $show, $save, $halt);
  32. }

  33. /**
  34. * 更新 session
  35. * @global <type> $_G
  36. * @staticvar boolean $updated
  37. * @return boolean
  38. */
  39. function updatesession() {
  40.         return C::app()->session->updatesession();
  41. }

  42. /**
  43. * 设置全局 $_G 中的变量
  44. * @global <array> $_G
  45. * @param <string> $key 键
  46. * @param <string> $value 值
  47. * @return true
  48. *
  49. * @example
  50. * setglobal('test', 1); // $_G['test'] = 1;
  51. * setglobal('config/test/abc') = 2; //$_G['config']['test']['abc'] = 2;
  52. *
  53. */
  54. function setglobal($key , $value, $group = null) {
  55.         global $_G;
  56.         $key = explode('/', $group === null ? $key : $group.'/'.$key);
  57.         $p = &$_G;
  58.         foreach ($key as $k) {
  59.                 if(!isset($p[$k]) || !is_array($p[$k])) {
  60.                         $p[$k] = array();
  61.                 }
  62.                 $p = &$p[$k];
  63.         }
  64.         $p = $value;
  65.         return true;
  66. }

  67. /**
  68. * 获取全局变量 $_G 当中的某个数值
  69. * @example
  70. * $v = getglobal('test'); // $v = $_G['test']
  71. * $v = getglobal('test/hello/ok');  // $v = $_G['test']['hello']['ok']
  72. *
  73. * @global  $_G
  74. * @param string $key
  75. *
  76. * @return type
  77. */
  78. function getglobal($key, $group = null) {
  79.         global $_G;
  80.         $key = explode('/', $group === null ? $key : $group.'/'.$key);
  81.         $v = &$_G;
  82.         foreach ($key as $k) {
  83.                 if (!isset($v[$k])) {
  84.                         return null;
  85.                 }
  86.                 $v = &$v[$k];
  87.         }
  88.         return $v;
  89. }

  90. /**
  91. * 取出 get, post, cookie 当中的某个变量
  92. *
  93. * @param string $k  key 值
  94. * @param string $type 类型
  95. * @return mix
  96. */
  97. function getgpc($k, $type='GP') {
  98.         $type = strtoupper($type);
  99.         switch($type) {
  100.                 case 'G': $var = &$_GET; break;
  101.                 case 'P': $var = &$_POST; break;
  102.                 case 'C': $var = &$_COOKIE; break;
  103.                 default:
  104.                         if(isset($_GET[$k])) {
  105.                                 $var = &$_GET;
  106.                         } else {
  107.                                 $var = &$_POST;
  108.                         }
  109.                         break;
  110.         }

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

  112. }

  113. /**
  114. * 根据uid 获取用户基本数据
  115. * @staticvar array $users 存放已经获取的用户的信息,避免重复查库
  116. * @param <int> $uid
  117. * @param int $fetch_archive 0:只查询主表,1:查询主表和存档表,2只查询存档表
  118. * @return <array>
  119. */
  120. function getuserbyuid($uid, $fetch_archive = 0) {
  121.         static $users = array();
  122.         if(empty($users[$uid])) {
  123.                 $users[$uid] = C::t('common_member'.($fetch_archive === 2 ? '_archive' : ''))->fetch($uid);
  124.                 if($fetch_archive === 1 && empty($users[$uid])) {
  125.                         $users[$uid] = C::t('common_member_archive')->fetch($uid);
  126.                 }
  127.         }
  128.         if(!isset($users[$uid]['self']) && $uid == getglobal('uid') && getglobal('uid')) {
  129.                 $users[$uid]['self'] = 1;
  130.         }
  131.         return $users[$uid];
  132. }

  133. /**
  134. * 获取当前用户的扩展资料
  135. * @param $field 字段
  136. */
  137. function getuserprofile($field) {
  138.         global $_G;
  139.         if(isset($_G['member'][$field])) {
  140.                 return $_G['member'][$field];
  141.         }
  142.         static $tablefields = array(
  143.                 'count'                => array('extcredits1','extcredits2','extcredits3','extcredits4','extcredits5','extcredits6','extcredits7','extcredits8','friends','posts','threads','digestposts','doings','blogs','albums','sharings','attachsize','views','oltime','todayattachs','todayattachsize', 'follower', 'following', 'newfollower', 'blacklist'),
  144.                 'status'        => array('regip','lastip','lastvisit','lastactivity','lastpost','lastsendmail','invisible','buyercredit','sellercredit','favtimes','sharetimes','profileprogress'),
  145.                 'field_forum'        => array('publishfeed','customshow','customstatus','medals','sightml','groupterms','authstr','groups','attentiongroup'),
  146.                 'field_home'        => array('videophoto','spacename','spacedescription','domain','addsize','addfriend','menunum','theme','spacecss','blockposition','recentnote','spacenote','privacy','feedfriend','acceptemail','magicgift','stickblogs'),
  147.                 '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'),
  148.                 'verify'        => array('verify1', 'verify2', 'verify3', 'verify4', 'verify5', 'verify6', 'verify7'),
  149.         );
  150.         $profiletable = '';
  151.         foreach($tablefields as $table => $fields) {
  152.                 if(in_array($field, $fields)) {
  153.                         $profiletable = $table;
  154.                         break;
  155.                 }
  156.         }
  157.         if($profiletable) {
  158.                 /*$data = array();
  159.                 if($_G['uid']) {
  160.                         //$data = DB::fetch_first("SELECT ".implode(', ', $tablefields[$profiletable])." FROM ".DB::table('common_member_'.$profiletable)." WHERE uid='$_G[uid]'");
  161.                         $data = C::t('common_member_'.$profiletable)->fetch($_G['uid']);
  162.                 }
  163.                 if(!$data) {
  164.                         foreach($tablefields[$profiletable] as $k) {
  165.                                 $data[$k] = '';
  166.                         }
  167.                 }
  168.                 $_G['member'] = array_merge(is_array($_G['member']) ? $_G['member'] : array(), $data);*/

  169.                 if(is_array($_G['member']) && $_G['member']['uid']) {
  170.                         space_merge($_G['member'], $profiletable);
  171.                 } else {
  172.                         foreach($tablefields[$profiletable] as $k) {
  173.                                 $_G['member'][$k] = '';
  174.                         }
  175.                 }
  176.                 return $_G['member'][$field];
  177.         }
  178.         return null;
  179. }

  180. /**
  181. * 对字符串或者输入进行 addslashes 操作
  182. * @param <mix> $string
  183. * @param <int> $force
  184. * @return <mix>
  185. */
  186. function daddslashes($string, $force = 1) {
  187.         if(is_array($string)) {
  188.                 $keys = array_keys($string);
  189.                 foreach($keys as $key) {
  190.                         $val = $string[$key];
  191.                         unset($string[$key]);
  192.                         $string[addslashes($key)] = daddslashes($val, $force);
  193.                 }
  194.         } else {
  195.                 $string = addslashes($string);
  196.         }
  197.         return $string;
  198. }

  199. /**
  200. * 对字符串进行加密和解密
  201. * @param <string> $string
  202. * @param <string> $operation  DECODE 解密 | ENCODE  加密
  203. * @param <string> $key 当为空的时候,取全局密钥
  204. * @param <int> $expiry 有效期,单位秒
  205. * @return <string>
  206. */
  207. function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
  208.         $ckey_length = 4;
  209.         $key = md5($key != '' ? $key : getglobal('authkey'));
  210.         $keya = md5(substr($key, 0, 16));
  211.         $keyb = md5(substr($key, 16, 16));
  212.         $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

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

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

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

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

  223.         for($j = $i = 0; $i < 256; $i++) {
  224.                 $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  225.                 $tmp = $box[$i];
  226.                 $box[$i] = $box[$j];
  227.                 $box[$j] = $tmp;
  228.         }

  229.         for($a = $j = $i = 0; $i < $string_length; $i++) {
  230.                 $a = ($a + 1) % 256;
  231.                 $j = ($j + $box[$a]) % 256;
  232.                 $tmp = $box[$a];
  233.                 $box[$a] = $box[$j];
  234.                 $box[$j] = $tmp;
  235.                 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  236.         }

  237.         if($operation == 'DECODE') {
  238.                 if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
  239.                         return substr($result, 26);
  240.                 } else {
  241.                         return '';
  242.                 }
  243.         } else {
  244.                 return $keyc.str_replace('=', '', base64_encode($result));
  245.         }

  246. }

  247. function fsocketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) {
  248.         $fp = '';
  249.         if(function_exists('fsockopen')) {
  250.                 $fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout);
  251.         } elseif(function_exists('pfsockopen')) {
  252.                 $fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout);
  253.         } elseif(function_exists('stream_socket_client')) {
  254.                 //note php5支持
  255.                 $fp = @stream_socket_client($hostname.':'.$port, $errno, $errstr, $timeout);
  256.         }
  257.         return $fp;
  258. }

  259. /**
  260. * 远程文件文件请求兼容函数
  261. */
  262. function dfsockopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE', $allowcurl = TRUE, $position = 0, $files = array()) {
  263.         require_once libfile('function/filesock');
  264.         return _dfsockopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block, $encodetype, $allowcurl, $position, $files);
  265. }

  266. /**
  267. * HTML转义字符
  268. * @param $string - 字符串
  269. * @param $flags 参见手册 htmlspecialchars
  270. * @return 返回转义好的字符串
  271. */
  272. function dhtmlspecialchars($string, $flags = null) {
  273.         if(is_array($string)) {
  274.                 foreach($string as $key => $val) {
  275.                         $string[$key] = dhtmlspecialchars($val, $flags);
  276.                 }
  277.         } else {
  278.                 if($flags === null) {
  279.                         $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
  280.                         if(strpos($string, '&#') !== false) {
  281.                                 $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
  282.                         }
  283.                 } else {
  284.                         if(PHP_VERSION < '5.4.0') {
  285.                                 $string = htmlspecialchars($string, $flags);
  286.                         } else {
  287.                                 if(strtolower(CHARSET) == 'utf-8') {
  288.                                         $charset = 'UTF-8';
  289.                                 } else {
  290.                                         $charset = 'ISO-8859-1';
  291.                                 }
  292.                                 $string = htmlspecialchars($string, $flags, $charset);
  293.                         }
  294.                 }
  295.         }
  296.         return $string;
  297. }

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

  308. /**
  309. * 同 php header函数, 针对 location 跳转做了特殊处理
  310. * @param <type> $string
  311. * @param <type> $replace
  312. * @param <type> $http_response_code
  313. */
  314. function dheader($string, $replace = true, $http_response_code = 0) {
  315.         //noteX 手机header跳转的统一修改(IN_MOBILE)
  316.         $islocation = substr(strtolower(trim($string)), 0, 8) == 'location';
  317.         if(defined('IN_MOBILE') && strpos($string, 'mobile') === false && $islocation) {
  318.                 if (strpos($string, '?') === false) {
  319.                         $string = $string.'?mobile='.IN_MOBILE;
  320.                 } else {
  321.                         if(strpos($string, '#') === false) {
  322.                                 $string = $string.'&mobile='.IN_MOBILE;
  323.                         } else {
  324.                                 $str_arr = explode('#', $string);
  325.                                 $str_arr[0] = $str_arr[0].'&mobile='.IN_MOBILE;
  326.                                 $string = implode('#', $str_arr);
  327.                         }
  328.                 }
  329.         }
  330.         $string = str_replace(array("\r", "\n"), array('', ''), $string);
  331.         if(empty($http_response_code) || PHP_VERSION < '4.3' ) {
  332.                 @header($string, $replace);
  333.         } else {
  334.                 @header($string, $replace, $http_response_code);
  335.         }
  336.         if($islocation) {
  337.                 exit();
  338.         }
  339. }

  340. /**
  341. * 设置cookie
  342. * @param $var - 变量名
  343. * @param $value - 变量值
  344. * @param $life - 生命期
  345. * @param $prefix - 前缀
  346. */
  347. function dsetcookie($var, $value = '', $life = 0, $prefix = 1, $httponly = false) {

  348.         global $_G;

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

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

  353.         if($value == '' || $life < 0) {
  354.                 $value = '';
  355.                 $life = -1;
  356.         }

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

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

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

  370. /**
  371. * 获取cookie
  372. */
  373. function getcookie($key) {
  374.         global $_G;
  375.         return isset($_G['cookie'][$key]) ? $_G['cookie'][$key] : '';
  376. }

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

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

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

  392.         $useragent = strtolower(empty($useragent) ? $_SERVER['HTTP_USER_AGENT'] : $useragent);
  393.         if(strpos($useragent, 'http://') === false && dstrpos($useragent, $kw_browsers)) return false;
  394.         if(dstrpos($useragent, $kw_spiders)) return true;
  395.         return false;
  396. }
  397. /**
  398. * 检查是否是以手机浏览器进入(IN_MOBILE)
  399. */
  400. function checkmobile() {
  401.         global $_G;
  402.         $mobile = array();
  403.         static $touchbrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
  404.                                 'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
  405.                                 'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
  406.                                 'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
  407.                                 'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
  408.                                 'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
  409.                                 'benq', 'haier', '^lct', '320x320', '240x320', '176x220', 'windows phone');
  410.         static $wmlbrowser_list = array('cect', 'compal', 'ctl', 'lg', 'nec', 'tcl', 'alcatel', 'ericsson', 'bird', 'daxian', 'dbtel', 'eastcom',
  411.                         'pantech', 'dopod', 'philips', 'haier', 'konka', 'kejian', 'lenovo', 'benq', 'mot', 'soutec', 'nokia', 'sagem', 'sgh',
  412.                         'sed', 'capitel', 'panasonic', 'sonyericsson', 'sharp', 'amoi', 'panda', 'zte');

  413.         static $pad_list = array('ipad');//note 包含ipad,WebOS HP Touchpad,Samsung Galaxy Pad

  414.         $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);

  415.         //note 判断是否为pad浏览器
  416.         if(dstrpos($useragent, $pad_list)) {
  417.                 return false;
  418.         }
  419.         if(($v = dstrpos($useragent, $touchbrowser_list, true))){
  420.                 $_G['mobile'] = $v;
  421.                 return '2'; //默认触屏版
  422.         }
  423.         //note wml版手机浏览器 //isset($_SERVER[HTTP_X_WAP_PROFILE]) or isset($_SERVER[HTTP_PROFILE]) 这两个属性暂不使用
  424.         if(($v = dstrpos($useragent, $wmlbrowser_list))) {
  425.                 $_G['mobile'] = $v;
  426.                 return '3'; //wml版
  427.         }
  428.         $brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');
  429.         if(dstrpos($useragent, $brower)) return false;

  430.         $_G['mobile'] = 'unknown';
  431.         if(isset($_G['mobiletpl'][$_GET['mobile']])) {
  432.                 return true;
  433.         } else {
  434.                 return false;
  435.         }
  436. }

  437. /**
  438. * 字符串方式实现 preg_match("/(s1|s2|s3)/", $string, $match)
  439. * @param string $string 源字符串
  440. * @param array $arr 要查找的字符串 如array('s1', 's2', 's3')
  441. * @param bool $returnvalue 是否返回找到的值
  442. * @return bool
  443. */
  444. function dstrpos($string, $arr, $returnvalue = false) {
  445.         if(empty($string)) return false;
  446.         foreach((array)$arr as $v) {
  447.                 if(strpos($string, $v) !== false) {
  448.                         $return = $returnvalue ? $v : true;
  449.                         return $return;
  450.                 }
  451.         }
  452.         return false;
  453. }

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

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

  471. /**
  472. * 产生随机码
  473. * @param $length - 要多长
  474. * @param $numberic - 数字还是字符串
  475. * @return 返回字符串
  476. */
  477. function random($length, $numeric = 0) {
  478.         $seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
  479.         $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
  480.         if($numeric) {
  481.                 $hash = '';
  482.         } else {
  483.                 $hash = chr(rand(1, 26) + rand(0, 1) * 32 + 64);
  484.                 $length--;
  485.         }
  486.         $max = strlen($seed) - 1;
  487.         for($i = 0; $i < $length; $i++) {
  488.                 $hash .= $seed{mt_rand(0, $max)};
  489.         }
  490.         return $hash;
  491. }

  492. /**
  493. * 判断一个字符串是否在另一个字符串中存在
  494. *
  495. * @param string 原始字串 $string
  496. * @param string 查找 $find
  497. * @return boolean
  498. */
  499. function strexists($string, $find) {
  500.         return !(strpos($string, $find) === FALSE);
  501. }

  502. /**
  503. * 获取头像
  504. *
  505. * @param int $uid 需要获取的用户UID值
  506. * @param string $size 获取尺寸 'small', 'middle', 'big'
  507. * @param boolean $returnsrc 是否直接返回图片src
  508. * @param boolean $real 是否返回真实图片
  509. * @param boolean $static 是否返回真实路径
  510. * @param string $ucenterurl 强制uc路径
  511. */
  512. function avatar($uid, $size = 'middle', $returnsrc = FALSE, $real = FALSE, $static = FALSE, $ucenterurl = '') {
  513.         global $_G;
  514.         if($_G['setting']['plugins']['func'][HOOKTYPE]['avatar']) {
  515.                 $_G['hookavatar'] = '';
  516.                 $param = func_get_args();
  517.                 hookscript('avatar', 'global', 'funcs', array('param' => $param), 'avatar');
  518.                 if($_G['hookavatar']) {
  519.                         return $_G['hookavatar'];
  520.                 }
  521.         }
  522.         static $staticavatar;
  523.         if($staticavatar === null) {
  524.                 $staticavatar = $_G['setting']['avatarmethod'];
  525.         }

  526.         $ucenterurl = empty($ucenterurl) ? $_G['setting']['ucenterurl'] : $ucenterurl;
  527.         $size = in_array($size, array('big', 'middle', 'small')) ? $size : 'middle';
  528.         $uid = abs(intval($uid));
  529.         if(!$staticavatar && !$static) {
  530.                 return $returnsrc ? $ucenterurl.'/avatar.php?uid='.$uid.'&size='.$size.($real ? '&type=real' : '') : '<img src="'.$ucenterurl.'/avatar.php?uid='.$uid.'&size='.$size.($real ? '&type=real' : '').'" />';
  531.         } else {
  532.                 $uid = sprintf("%09d", $uid);
  533.                 $dir1 = substr($uid, 0, 3);
  534.                 $dir2 = substr($uid, 3, 2);
  535.                 $dir3 = substr($uid, 5, 2);
  536.                 $file = $ucenterurl.'/data/avatar/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($uid, -2).($real ? '_real' : '').'_avatar_'.$size.'.jpg';
  537.                 return $returnsrc ? $file : '<img src="'.$file.'" onerror="this.onerror=null;this.src=\''.$ucenterurl.'/images/noavatar_'.$size.'.gif\'" />';
  538.         }
  539. }

  540. /**
  541. * 加载语言
  542. * 语言文件统一为 $lang = array();
  543. * @param $file - 语言文件,可包含路径如 forum/xxx home/xxx
  544. * @param $langvar - 语言文字索引
  545. * @param $vars - 变量替换数组
  546. * @return 语言文字
  547. */
  548. function lang($file, $langvar = null, $vars = array(), $default = null) {
  549.         global $_G;
  550.         $fileinput = $file;
  551.         list($path, $file) = explode('/', $file);
  552.         if(!$file) {
  553.                 $file = $path;
  554.                 $path = '';
  555.         }
  556.         if(strpos($file, ':') !== false) {
  557.                 $path = 'plugin';
  558.                 list($file) = explode(':', $file);
  559.         }

  560.         if($path != 'plugin') {
  561.                 $key = $path == '' ? $file : $path.'_'.$file;
  562.                 if(!isset($_G['lang'][$key])) {
  563.                         //#start
  564.                         $_akey = '#file#source/language/'.($path == '' ? '' : $path.'/').'lang_'.$file.'.php';
  565.                         C::analysisStart($_akey);
  566.                         //#end
  567.                         include DISCUZ_ROOT.'./source/language/'.($path == '' ? '' : $path.'/').'lang_'.$file.'.php';
  568.                         //#start
  569.                         C::analysisStop($_akey);
  570.                         //#end
  571.                         $_G['lang'][$key] = $lang;
  572.                 }
  573.                 //noteX 合并手机语言包(IN_MOBILE)
  574.                 if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) {
  575.                         //#start
  576.                         $_akey = '#file#source/language/mobile/lang_template.php';
  577.                         C::analysisStart($_akey);
  578.                         //#end
  579.                         include DISCUZ_ROOT.'./source/language/mobile/lang_template.php';
  580.                         //#start
  581.                         C::analysisStop($_akey);
  582.                         //#end
  583.                         $_G['lang'][$key] = array_merge($_G['lang'][$key], $lang);
  584.                 }
  585.                 if($file != 'error' && !isset($_G['cache']['pluginlanguage_system'])) {
  586.                         loadcache('pluginlanguage_system');
  587.                 }
  588.                 if(!isset($_G['hooklang'][$fileinput])) {
  589.                         if(isset($_G['cache']['pluginlanguage_system'][$fileinput]) && is_array($_G['cache']['pluginlanguage_system'][$fileinput])) {
  590.                                 $_G['lang'][$key] = array_merge($_G['lang'][$key], $_G['cache']['pluginlanguage_system'][$fileinput]);
  591.                         }
  592.                         $_G['hooklang'][$fileinput] = true;
  593.                 }
  594.                 $returnvalue = &$_G['lang'];
  595.         } else {
  596.                 if(empty($_G['config']['plugindeveloper'])) {
  597.                         loadcache('pluginlanguage_script');
  598.                 } elseif(!isset($_G['cache']['pluginlanguage_script'][$file]) && preg_match("/^[a-z]+[a-z0-9_]*$/i", $file)) {
  599.                         if(@include(DISCUZ_ROOT.'./data/plugindata/'.$file.'.lang.php')) {
  600.                                 $_G['cache']['pluginlanguage_script'][$file] = $scriptlang[$file];
  601.                         } else {
  602.                                 loadcache('pluginlanguage_script');
  603.                         }
  604.                 }
  605.                 $returnvalue = & $_G['cache']['pluginlanguage_script'];
  606.                 $key = &$file;
  607.         }
  608.         $return = $langvar !== null ? (isset($returnvalue[$key][$langvar]) ? $returnvalue[$key][$langvar] : null) : $returnvalue[$key];
  609.         $return = $return === null ? ($default !== null ? $default : $langvar) : $return;
  610.         $searchs = $replaces = array();
  611.         if($vars && is_array($vars)) {
  612.                 foreach($vars as $k => $v) {
  613.                         $searchs[] = '{'.$k.'}';
  614.                         $replaces[] = $v;
  615.                 }
  616.         }
  617.         if(is_string($return) && strpos($return, '{_G/') !== false) {
  618.                 preg_match_all('/\{_G\/(.+?)\}/', $return, $gvar);
  619.                 foreach($gvar[0] as $k => $v) {
  620.                         $searchs[] = $v;
  621.                         $replaces[] = getglobal($gvar[1][$k]);
  622.                 }
  623.         }
  624.         $return = str_replace($searchs, $replaces, $return);
  625.         return $return;
  626. }

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

  640.         if(empty($timecompare) || $tplrefresh == 1 || ($tplrefresh > 1 && !($timestamp % $tplrefresh))) {
  641.                 if(empty($timecompare) || @filemtime(DISCUZ_ROOT.$subtpl) > $timecompare) {
  642.                         require_once DISCUZ_ROOT.'/source/class/class_template.php';
  643.                         $template = new template();
  644.                         $template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);
  645.                         //更新页面和模块的关联
  646.                         if($targettplname === null) {
  647.                                 $targettplname = getglobal('style/tplfile');
  648.                                 if(!empty($targettplname)) {
  649.                                         include_once libfile('function/block');
  650.                                         $targettplname = strtr($targettplname, ':', '_');
  651.                                         update_template_block($targettplname, getglobal('style/tpldirectory'), $template->blocks);
  652.                                 }
  653.                                 $targettplname = true;
  654.                         }
  655.                         return TRUE;
  656.                 }
  657.         }
  658.         return FALSE;
  659. }

  660. /**
  661. * 解析模板
  662. * @return 返回域名
  663. */
  664. function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') {
  665.         global $_G;

  666.         static $_init_style = false;
  667.         if($_init_style === false) {
  668.                 C::app()->_init_style();
  669.                 $_init_style = true;
  670.         }
  671.         $oldfile = $file; //原模板
  672.         if(strpos($file, ':') !== false) {
  673.                 $clonefile = '';
  674.                 list($templateid, $file, $clonefile) = explode(':', $file);
  675.                 $oldfile = $file;
  676.                 $file = empty($clonefile) ? $file : $file.'_'.$clonefile;
  677.                 if($templateid == 'diy') {
  678.                         $indiy = false; //是否存在DIY
  679.                         $_G['style']['tpldirectory'] = $tpldir ? $tpldir : (defined('TPLDIR') ? TPLDIR : ''); //模板文件所在的目录,DIY保存时使用
  680.                         $_G['style']['prefile'] = ''; //非预览环境标记预览文件是否存在
  681.                         $diypath = DISCUZ_ROOT.'./data/diy/'.$_G['style']['tpldirectory'].'/'; //DIY模板文件目录
  682.                         $preend = '_diy_preview'; //预览文件后缀
  683.                         $_GET['preview'] = !empty($_GET['preview']) ? $_GET['preview'] : ''; //是否预览
  684.                         $curtplname = $oldfile;//当前模板名
  685.                         $basescript = $_G['mod'] == 'viewthread' && !empty($_G['thread']) ? 'forum' : $_G['basescript']; //帖子查看页归到froum中
  686.                         if(isset($_G['cache']['diytemplatename'.$basescript])) {
  687.                                 $diytemplatename = &$_G['cache']['diytemplatename'.$basescript];//当前应用的DIY文件缓存
  688.                         } else {
  689.                                 if(!isset($_G['cache']['diytemplatename'])) {
  690.                                         loadcache('diytemplatename');
  691.                                 }
  692.                                 $diytemplatename = &$_G['cache']['diytemplatename'];//所有DIY文件缓存
  693.                         }
  694.                         $tplsavemod = 0; //公共DIY页面标记
  695.                         //独立DIY页面 || 分区或版块没有指定模板 && 公共DIY页面
  696.                         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')) {
  697.                                 $tpldir = 'data/diy/'.$_G['style']['tpldirectory'].'/'; //文件目录
  698.                                 !$gettplfile && $_G['style']['tplsavemod'] = $tplsavemod; //独立DIY页面标记:1,公共DIY页面标记:0
  699.                                 $curtplname = $file; //当前模板名
  700.                                 if(isset($_GET['diy']) && $_GET['diy'] == 'yes' || isset($_GET['diy']) && $_GET['preview'] == 'yes') { //DIY模式或预览模式下做以下判断
  701.                                         $flag = file_exists($diypath.$file.$preend.'.htm'); //预览文件是否存在
  702.                                         if($_GET['preview'] == 'yes') { //预览环境
  703.                                                 $file .= $flag ? $preend : ''; //使用预览模板文件
  704.                                         } else {
  705.                                                 $_G['style']['prefile'] = $flag ? 1 : ''; //非预览环境标记预览文件是否存在
  706.                                         }
  707.                                 }
  708.                                 $indiy = true;
  709.                         } else {
  710.                                 $file = $primaltpl ? $primaltpl : $oldfile; //无DIY页面则使用原模板
  711.                         }
  712.                         //根据模板自动刷新开关$tplrefresh 更新DIY模板
  713.                         $tplrefresh = $_G['config']['output']['tplrefresh'];
  714.                         //在有DIY生成模板文件时 && 自动刷新开启 && DIY生成模板文件修改时间 < 原模板修改修改
  715.                         if($indiy && ($tplrefresh ==1 || ($tplrefresh > 1 && !($_G['timestamp'] % $tplrefresh))) && filemtime($diypath.$file.'.htm') < filemtime(DISCUZ_ROOT.$_G['style']['tpldirectory'].'/'.($primaltpl ? $primaltpl : $oldfile).'.htm')) {
  716.                                 //原模板更改则更新DIY模板,如果更新失败则删除DIY模板
  717.                                 if (!updatediytemplate($file, $_G['style']['tpldirectory'])) {
  718.                                         unlink($diypath.$file.'.htm');
  719.                                         $tpldir = '';
  720.                                 }
  721.                         }

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

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

  728.                 } else {
  729.                         $tpldir = './source/plugin/'.$templateid.'/template';
  730.                 }
  731.         }

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

  736.         //noteX 将页面模板加一层Mobile目录,用以定位手机模板页面(IN_MOBILE)
  737.         if(defined('IN_MOBILE') && !defined('TPL_DEFAULT') && strpos($file, $_G['mobiletpl'][IN_MOBILE].'/') === false || (isset($_G['forcemobilemessage']) && $_G['forcemobilemessage'])) {
  738.                 if(IN_MOBILE == 2) {
  739.                         $oldfile .= !empty($_G['inajax']) && ($oldfile == 'common/header' || $oldfile == 'common/footer') ? '_ajax' : '';
  740.                 }
  741.                 $file = $_G['mobiletpl'][IN_MOBILE].'/'.$oldfile;
  742.         }

  743.         //确保$tpldir有值
  744.         if(!$tpldir) {
  745.                 $tpldir = './template/default';
  746.         }
  747.         $tplfile = $tpldir.'/'.$file.'.htm';

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

  749.         //noteX 手机模板的判断(IN_MOBILE)
  750.         if(defined('IN_MOBILE') && !defined('TPL_DEFAULT')) {
  751.                 //首先判断是否是DIY模板,如果是就删除可能存在的forumdisplay_1中的数字
  752.                 if(strpos($tpldir, 'plugin')) {
  753.                         if(!file_exists(DISCUZ_ROOT.$tpldir.'/'.$file.'.htm') && !file_exists(DISCUZ_ROOT.$tpldir.'/'.$file.'.php')) {
  754.                                 $url = $_SERVER['REQUEST_URI'].(strexists($_SERVER['REQUEST_URI'], '?') ? '&' : '?').'mobile=no';
  755.                                 showmessage('mobile_template_no_found', '', array('url' => $url));
  756.                         } else {
  757.                                 $mobiletplfile = $tpldir.'/'.$file.'.htm';
  758.                         }
  759.                 }
  760.                 !$mobiletplfile && $mobiletplfile = $file.'.htm';
  761.                 if(strpos($tpldir, 'plugin') && (file_exists(DISCUZ_ROOT.$mobiletplfile) || file_exists(substr(DISCUZ_ROOT.$mobiletplfile, 0, -4).'.php'))) {
  762.                         $tplfile = $mobiletplfile;
  763.                 } elseif(!file_exists(DISCUZ_ROOT.TPLDIR.'/'.$mobiletplfile) && !file_exists(substr(DISCUZ_ROOT.TPLDIR.'/'.$mobiletplfile, 0, -4).'.php')) {
  764.                         $mobiletplfile = './template/default/'.$mobiletplfile;
  765.                         if(!file_exists(DISCUZ_ROOT.$mobiletplfile) && !$_G['forcemobilemessage']) {
  766.                                 $tplfile = str_replace($_G['mobiletpl'][IN_MOBILE].'/', '', $tplfile);
  767.                                 $file = str_replace($_G['mobiletpl'][IN_MOBILE].'/', '', $file);
  768.                                 define('TPL_DEFAULT', true);
  769.                         } else {
  770.                                 $tplfile = $mobiletplfile;
  771.                         }
  772.                 } else {
  773.                         $tplfile = TPLDIR.'/'.$mobiletplfile;
  774.                 }
  775.         }

  776.         $cachefile = './data/template/'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';
  777.         //非系统模板目录 && $tplfile模板文件不存在 && .php后缀的模板文件不存在 && //当前模板目录+原模板文件不存在
  778.         if($templateid != 1 && !file_exists(DISCUZ_ROOT.$tplfile) && !file_exists(substr(DISCUZ_ROOT.$tplfile, 0, -4).'.php')
  779.                         && !file_exists(DISCUZ_ROOT.($tplfile = $tpldir.$filebak.'.htm'))) {
  780.                 $tplfile = './template/default/'.$filebak.'.htm';
  781.         }

  782.         if($gettplfile) {
  783.                 return $tplfile;
  784.         }
  785.         checktplrefresh($tplfile, $tplfile, @filemtime(DISCUZ_ROOT.$cachefile), $templateid, $cachefile, $tpldir, $file);
  786.         return DISCUZ_ROOT.$cachefile;
  787. }

  788. /**
  789. * 数据签名
  790. * @param string $str 源数据
  791. * @param int $length 返回值的长度,8-32位之间
  792. * @return string
  793. */
  794. function dsign($str, $length = 16){
  795.         return substr(md5($str.getglobal('config/security/authkey')), 0, ($length ? max(8, $length) : 16));
  796. }

  797. /**
  798. * 对某id进行个性化md5
  799. */
  800. function modauthkey($id) {
  801.         return md5(getglobal('username').getglobal('uid').getglobal('authkey').substr(TIMESTAMP, 0, -7).$id);
  802. }

  803. /**
  804. * 获得当前应用页面选中的导航id
  805. */
  806. function getcurrentnav() {
  807.         global $_G;
  808.         if(!empty($_G['mnid'])) {
  809.                 return $_G['mnid'];
  810.         }
  811.         $mnid = '';
  812.         $_G['basefilename'] = $_G['basefilename'] == $_G['basescript'] ? $_G['basefilename'] : $_G['basescript'].'.php';
  813.         if(isset($_G['setting']['navmns'][$_G['basefilename']])) {
  814.                 if($_G['basefilename'] == 'home.php' && $_GET['mod'] == 'space' && (empty($_GET['do']) || in_array($_GET['do'], array('follow', 'view')))) {
  815.                         $_GET['mod'] = 'follow';
  816.                 }
  817.                 foreach($_G['setting']['navmns'][$_G['basefilename']] as $navmn) {
  818.                         if($navmn[0] == array_intersect_assoc($navmn[0], $_GET) || ($navmn[0]['mod'] == 'space' && $_GET['mod'] == 'spacecp' && ($navmn[0]['do'] == $_GET['ac'] || $navmn[0]['do'] == 'album' && $_GET['ac'] == 'upload'))) {
  819.                                 $mnid = $navmn[1];
  820.                         }
  821.                 }

  822.         }
  823.         if(!$mnid && isset($_G['setting']['navdms'])) {
  824.                 foreach($_G['setting']['navdms'] as $navdm => $navid) {
  825.                         if(strpos(strtolower($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']), $navdm) !== false && strpos(strtolower($_SERVER['HTTP_HOST']), $navdm) === false) {
  826.                                 $mnid = $navid;
  827.                                 break;
  828.                         }
  829.                 }
  830.         }
  831.         if(!$mnid && isset($_G['setting']['navmn'][$_G['basefilename']])) {
  832.                 $mnid = $_G['setting']['navmn'][$_G['basefilename']];
  833.         }
  834.         return $mnid;
  835. }

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

  841. /**
  842. * 读取缓存
  843. * @param $cachenames - 缓存名称数组或字串
  844. */
  845. function loadcache($cachenames, $force = false) {
  846.         global $_G;
  847.         static $loadedcache = array();
  848.         $cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
  849.         $caches = array();
  850.         foreach ($cachenames as $k) {
  851.                 if(!isset($loadedcache[$k]) || $force) {
  852.                         $caches[] = $k;
  853.                         $loadedcache[$k] = true;
  854.                 }
  855.         }

  856.         if(!empty($caches)) {
  857.                 $cachedata = C::t('common_syscache')->fetch_all($caches);
  858.                 foreach($cachedata as $cname => $data) {
  859.                         if($cname == 'setting') {
  860.                                 $_G['setting'] = $data;
  861.                         } elseif($cname == 'usergroup_'.$_G['groupid']) {
  862.                                 $_G['cache'][$cname] = $_G['group'] = $data;
  863.                         } elseif($cname == 'style_default') {
  864.                                 $_G['cache'][$cname] = $_G['style'] = $data;
  865.                         } elseif($cname == 'grouplevels') {
  866.                                 $_G['grouplevels'] = $data;
  867.                         } else {
  868.                                 $_G['cache'][$cname] = $data;
  869.                         }
  870.                 }
  871.         }
  872.         return true;
  873. }

  874. /**
  875. * 格式化时间
  876. * @param $timestamp - 时间戳
  877. * @param $format - dt=日期时间 d=日期 t=时间 u=个性化 其他=自定义
  878. * @param $timeoffset - 时区
  879. * @return string
  880. */
  881. function dgmdate($timestamp, $format = 'dt', $timeoffset = '9999', $uformat = '') {
  882.         global $_G;
  883.         $format == 'u' && !$_G['setting']['dateconvert'] && $format = 'dt';
  884.         static $dformat, $tformat, $dtformat, $offset, $lang;
  885.         if($dformat === null) {
  886.                 $dformat = getglobal('setting/dateformat');
  887.                 $tformat = getglobal('setting/timeformat');
  888.                 $dtformat = $dformat.' '.$tformat;
  889.                 $offset = getglobal('member/timeoffset');
  890.                 $sysoffset = getglobal('setting/timeoffset');
  891.                 $offset = $offset == 9999 ? ($sysoffset ? $sysoffset : 0) : $offset;
  892.                 $lang = lang('core', 'date');
  893.         }
  894.         $timeoffset = $timeoffset == 9999 ? $offset : $timeoffset;
  895.         $timestamp += $timeoffset * 3600;
  896.         $format = empty($format) || $format == 'dt' ? $dtformat : ($format == 'd' ? $dformat : ($format == 't' ? $tformat : $format));
  897.         if($format == 'u') {
  898.                 $todaytimestamp = TIMESTAMP - (TIMESTAMP + $timeoffset * 3600) % 86400 + $timeoffset * 3600;
  899.                 $s = gmdate(!$uformat ? $dtformat : $uformat, $timestamp);
  900.                 $time = TIMESTAMP + $timeoffset * 3600 - $timestamp;
  901.                 if($timestamp >= $todaytimestamp) {
  902.                         if($time > 3600) {
  903.                                 $return = intval($time / 3600).' '.$lang['hour'].$lang['before'];
  904.                         } elseif($time > 1800) {
  905.                                 $return = $lang['half'].$lang['hour'].$lang['before'];
  906.                         } elseif($time > 60) {
  907.                                 $return = intval($time / 60).' '.$lang['min'].$lang['before'];
  908.                         } elseif($time > 0) {
  909.                                 $return = $time.' '.$lang['sec'].$lang['before'];
  910.                         } elseif($time == 0) {
  911.                                 $return = $lang['now'];
  912.                         } else {
  913.                                 $return = $s;
  914.                         }
  915.                         if($time >=0 && !defined('IN_MOBILE')) {
  916.                                 $return = '<span title="'.$s.'">'.$return.'</span>';
  917.                         }
  918.                 } elseif(($days = intval(($todaytimestamp - $timestamp) / 86400)) >= 0 && $days < 7) {
  919.                         if($days == 0) {
  920.                                 $return = $lang['yday'].' '.gmdate($tformat, $timestamp);
  921.                         } elseif($days == 1) {
  922.                                 $return = $lang['byday'].' '.gmdate($tformat, $timestamp);
  923.                         } else {
  924.                                 $return = ($days + 1).' '.$lang['day'].$lang['before'];
  925.                         }
  926.                         if(!defined('IN_MOBILE')) {
  927.                                 $return = '<span title="'.$s.'">'.$return.'</span>';
  928.                         }
  929.                 } else {
  930.                         $return = $s;
  931.                 }
  932.                 return $return;
  933.         } else {
  934.                 return gmdate($format, $timestamp);
  935.         }
  936. }

  937. /**
  938.         得到时间戳
  939. */
  940. function dmktime($date) {
  941.         if(strpos($date, '-')) {
  942.                 $time = explode('-', $date);
  943.                 return mktime(0, 0, 0, $time[1], $time[2], $time[0]);
  944.         }
  945.         return 0;
  946. }

  947. /**
  948. *        个性化数字
  949. */
  950. function dnumber($number) {
  951.         return abs($number) > 10000 ? '<span title="'.$number.'">'.intval($number / 10000).lang('core', '10k').'</span>' : $number;
  952. }

  953. /**
  954. * 更新缓存
  955. * @param $cachename - 缓存名称
  956. * @param $data - 缓存数据
  957. */
  958. function savecache($cachename, $data) {
  959.         C::t('common_syscache')->insert($cachename, $data);
  960. }

  961. /**
  962. * 更新缓存 savecache的别名
  963. * @param $cachename - 缓存名称
  964. * @param $data - 缓存数据
  965. */
  966. function save_syscache($cachename, $data) {
  967.         savecache($cachename, $data);
  968. }

  969. /**
  970. * Portal模块
  971. * @param $parameter - 参数集合
  972. */
  973. function block_get($parameter) {
  974.         include_once libfile('function/block');
  975.         block_get_batch($parameter);
  976. }

  977. /**
  978. * Portal 模块显示
  979. *
  980. * @param $parameter - 参数集合
  981. */
  982. function block_display($bid) {
  983.         include_once libfile('function/block');
  984.         block_display_batch($bid);
  985. }

  986. //连接字符
  987. function dimplode($array) {
  988.         if(!empty($array)) {
  989.                 $array = array_map('addslashes', $array);
  990.                 return "'".implode("','", is_array($array) ? $array : array($array))."'";
  991.         } else {
  992.                 return 0;
  993.         }
  994. }

  995. /**
  996. * 返回库文件的全路径
  997. *
  998. * @param string $libname 库文件分类及名称
  999. * @param string $folder 模块目录'module','include','class'
  1000. * @return string
  1001. *
  1002. * @example require DISCUZ_ROOT.'./source/function/function_cache.php'
  1003. * @example 我们可以利用此函数简写为:require libfile('function/cache');
  1004. *
  1005. */
  1006. function libfile($libname, $folder = '') {
  1007.         $libpath = '/source/'.$folder;
  1008.         if(strstr($libname, '/')) {
  1009.                 list($pre, $name) = explode('/', $libname);
  1010.                 $path = "{$libpath}/{$pre}/{$pre}_{$name}";
  1011.                 //return realpath("{$libpath}/{$pre}/{$pre}_{$name}.php");
  1012.         } else {
  1013.                 $path = "{$libpath}/{$libname}";
  1014.                 //return realpath("{$libpath}/{$libname}.php");
  1015.         }
  1016.         return preg_match('/^[\w\d\/_]+$/i', $path) ? realpath(DISCUZ_ROOT.$path.'.php') : false;
  1017. }

  1018. /**
  1019. * 针对uft-8进行特殊处理的strlen
  1020. * @param string $str
  1021. * @return int
  1022. */
  1023. function dstrlen($str) {
  1024.         if(strtolower(CHARSET) != 'utf-8') {
  1025.                 return strlen($str);
  1026.         }
  1027.         $count = 0;
  1028.         for($i = 0; $i < strlen($str); $i++){
  1029.                 $value = ord($str[$i]);
  1030.                 if($value > 127) {
  1031.                         $count++;
  1032.                         if($value >= 192 && $value <= 223) $i++;
  1033.                         elseif($value >= 224 && $value <= 239) $i = $i + 2;
  1034.                         elseif($value >= 240 && $value <= 247) $i = $i + 3;
  1035.                     }
  1036.                     $count++;
  1037.         }
  1038.         return $count;
  1039. }

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

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

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

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

  1059.                         $t = ord($string[$n]);
  1060.                         if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
  1061.                                 $tn = 1; $n++; $noc++;
  1062.                         } elseif(194 <= $t && $t <= 223) {
  1063.                                 $tn = 2; $n += 2; $noc += 2;
  1064.                         } elseif(224 <= $t && $t <= 239) {
  1065.                                 $tn = 3; $n += 3; $noc += 2;
  1066.                         } elseif(240 <= $t && $t <= 247) {
  1067.                                 $tn = 4; $n += 4; $noc += 2;
  1068.                         } elseif(248 <= $t && $t <= 251) {
  1069.                                 $tn = 5; $n += 5; $noc += 2;
  1070.                         } elseif($t == 252 || $t == 253) {
  1071.                                 $tn = 6; $n += 6; $noc += 2;
  1072.                         } else {
  1073.                                 $n++;
  1074.                         }

  1075.                         if($noc >= $length) {
  1076.                                 break;
  1077.                         }

  1078.                 }
  1079.                 if($noc > $length) {
  1080.                         $n -= $tn;
  1081.                 }

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

  1083.         } else {
  1084.                 $_length = $length - 1;
  1085.                 for($i = 0; $i < $length; $i++) {
  1086.                         //ASCII 码值小于等于127时直接累加字符,大于127时一次取两位累加
  1087.                         //但当只剩一位时且遇到大于127字符时则舍去此字符,避免大于裁减长度
  1088.                         if(ord($string[$i]) <= 127) {
  1089.                                 $strcut .= $string[$i];
  1090.                         } else if($i < $_length) {
  1091.                                 $strcut .= $string[$i].$string[++$i];
  1092.                         }
  1093.                 }
  1094.         }

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

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

  1104. //去掉slassh
  1105. function dstripslashes($string) {
  1106.         if(empty($string)) return $string;
  1107.         if(is_array($string)) {
  1108.                 foreach($string as $key => $val) {
  1109.                         $string[$key] = dstripslashes($val);
  1110.                 }
  1111.         } else {
  1112.                 $string = stripslashes($string);
  1113.         }
  1114.         return $string;
  1115. }

  1116. /**
  1117. * 论坛 aid url 生成
  1118. */
  1119. function aidencode($aid, $type = 0, $tid = 0) {
  1120.         global $_G;
  1121.         $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;
  1122.         return rawurlencode(base64_encode($s));
  1123. }

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

  1132. /**
  1133. * 获取rewrite字符串
  1134. * @param string $type 需要获取的rewite
  1135. * @param boolean $returntype true:直接返回href, false:返回a标签
  1136. * @param string $host 可选网站域名
  1137. * @return string
  1138. */
  1139. function rewriteoutput($type, $returntype, $host) {
  1140.         global $_G;
  1141.         $fextra = '';
  1142.         if($type == 'forum_forumdisplay') {
  1143.                 list(,,, $fid, $page, $extra) = func_get_args();
  1144.                 $r = array(
  1145.                         '{fid}' => empty($_G['setting']['forumkeys'][$fid]) ? $fid : $_G['setting']['forumkeys'][$fid],
  1146.                         '{page}' => $page ? $page : 1,
  1147.                 );
  1148.         } elseif($type == 'forum_viewthread') {
  1149.                 list(,,, $tid, $page, $prevpage, $extra) = func_get_args();
  1150.                 $r = array(
  1151.                         '{tid}' => $tid,
  1152.                         '{page}' => $page ? $page : 1,
  1153.                         '{prevpage}' => $prevpage && !IS_ROBOT ? $prevpage : 1,
  1154.                 );
  1155.         } elseif($type == 'home_space') {
  1156.                 list(,,, $uid, $username, $extra) = func_get_args();
  1157.                 $_G['setting']['rewritecompatible'] && $username = rawurlencode($username);
  1158.                 $r = array(
  1159.                         '{user}' => $uid ? 'uid' : 'username',
  1160.                         '{value}' => $uid ? $uid : $username,
  1161.                 );
  1162.         } elseif($type == 'home_blog') {
  1163.                 list(,,, $uid, $blogid, $extra) = func_get_args();
  1164.                 $r = array(
  1165.                         '{uid}' => $uid,
  1166.                         '{blogid}' => $blogid,
  1167.                 );
  1168.         } elseif($type == 'group_group') {
  1169.                 list(,,, $fid, $page, $extra) = func_get_args();
  1170.                 $r = array(
  1171.                         '{fid}' => $fid,
  1172.                         '{page}' => $page ? $page : 1,
  1173.                 );
  1174.         } elseif($type == 'portal_topic') {
  1175.                 list(,,, $name, $extra) = func_get_args();
  1176.                 $r = array(
  1177.                         '{name}' => $name,
  1178.                 );
  1179.         } elseif($type == 'portal_article') {
  1180.                 list(,,, $id, $page, $extra) = func_get_args();
  1181.                 $r = array(
  1182.                         '{id}' => $id,
  1183.                         '{page}' => $page ? $page : 1,
  1184.                 );
  1185.         } elseif($type == 'forum_archiver') {
  1186.                 list(,, $action, $value, $page, $extra) = func_get_args();
  1187.                 $host = '';
  1188.                 $r = array(
  1189.                         '{action}' => $action,
  1190.                         '{value}' => $value,
  1191.                 );
  1192.                 if($page) {
  1193.                         $fextra = '?page='.$page;
  1194.                 }
  1195.         } elseif($type == 'plugin') {
  1196.                 list(,, $pluginid, $module,, $param, $extra) = func_get_args();
  1197.                 $host = '';
  1198.                 $r = array(
  1199.                         '{pluginid}' => $pluginid,
  1200.                         '{module}' => $module,
  1201.                 );
  1202.                 if($param) {
  1203.                         $fextra = '?'.$param;
  1204.                 }
  1205.         }
  1206.         $href = str_replace(array_keys($r), $r, $_G['setting']['rewriterule'][$type]).$fextra;
  1207.         if(!$returntype) {
  1208.                 return '<a href="'.$host.$href.'"'.(!empty($extra) ? stripslashes($extra) : '').'>';
  1209.         } else {
  1210.                 return $host.$href;
  1211.         }
  1212. }

  1213. /**
  1214. * 手机模式下替换所有链接为mobile=yes形式
  1215. * @param $file - 正则匹配到的文件字符串
  1216. * @param $file - 要被替换的字符串
  1217. * @$replace 替换后字符串
  1218. */
  1219. function mobilereplace($file, $replace) {
  1220.         return helper_mobile::mobilereplace($file, $replace);
  1221. }

  1222. /**
  1223. * 手机的output函数
  1224. */
  1225. function mobileoutput() {
  1226.         helper_mobile::mobileoutput();
  1227. }

  1228. /**
  1229. * 系统输出
  1230. * @return 返回内容
  1231. */
  1232. function output() {

  1233.         global $_G;

  1234.         //===================================
  1235.         //判断写入页面缓存
  1236.         //===================================
  1237.         //writepagecache();

  1238.         if(defined('DISCUZ_OUTPUTED')) {
  1239.                 return;
  1240.         } else {
  1241.                 define('DISCUZ_OUTPUTED', 1);
  1242.         }

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

  1247.         //noteX 手机模式下重新制作页面输出(IN_MOBILE)
  1248.         if(defined('IN_MOBILE')) {
  1249.                 mobileoutput();
  1250.         }
  1251.         if(!defined('IN_MOBILE') && !defined('IN_ARCHIVER')) {
  1252.                 $tipsService = Cloud::loadClass('Service_DiscuzTips');
  1253.                 $tipsService->show();
  1254.         }
  1255.         $havedomain = implode('', $_G['setting']['domain']['app']);
  1256.         if($_G['setting']['rewritestatus'] || !empty($havedomain)) {
  1257.                 $content = ob_get_contents();
  1258.                 $content = output_replace($content);


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

  1261.                 echo $content;
  1262.         }

  1263.         //生成静态文件
  1264.         if(isset($_G['makehtml'])) {
  1265.                 helper_makehtml::make_html();
  1266.         }

  1267.         if($_G['setting']['ftp']['connid']) {
  1268.                 @ftp_close($_G['setting']['ftp']['connid']);
  1269.         }
  1270.         $_G['setting']['ftp'] = array();

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

  1283.         if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG && @include(libfile('function/debug'))) {
  1284.                 function_exists('debugmessage') && debugmessage();
  1285.         }
  1286. }

  1287. function output_replace($content) {
  1288.         global $_G;
  1289.         if(defined('IN_MODCP') || defined('IN_ADMINCP')) return $content;
  1290.         if(!empty($_G['setting']['output']['str']['search'])) {
  1291.                 if(empty($_G['setting']['domain']['app']['default'])) {
  1292.                         $_G['setting']['output']['str']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['str']['replace']);
  1293.                 }
  1294.                 $content = str_replace($_G['setting']['output']['str']['search'], $_G['setting']['output']['str']['replace'], $content);
  1295.         }
  1296.         if(!empty($_G['setting']['output']['preg']['search']) && (empty($_G['setting']['rewriteguest']) || empty($_G['uid']))) {
  1297.                 if(empty($_G['setting']['domain']['app']['default'])) {
  1298.                         $_G['setting']['output']['preg']['search'] = str_replace('\{CURHOST\}', preg_quote($_G['siteurl'], '/'), $_G['setting']['output']['preg']['search']);
  1299.                         $_G['setting']['output']['preg']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['preg']['replace']);
  1300.                 }

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

  1303.         return $content;
  1304. }

  1305. /**
  1306. * ajax footer使用输出页面内容
  1307. */
  1308. function output_ajax() {
  1309.         global $_G;
  1310.         $s = ob_get_contents();
  1311.         ob_end_clean();
  1312.         $s = preg_replace("/([\\x01-\\x08\\x0b-\\x0c\\x0e-\\x1f])+/", ' ', $s);
  1313.         $s = str_replace(array(chr(0), ']]>'), array(' ', ']]>'), $s);
  1314.         if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG && @include(libfile('function/debug'))) {
  1315.                 function_exists('debugmessage') && $s .= debugmessage(1);
  1316.         }
  1317.         $havedomain = implode('', $_G['setting']['domain']['app']);
  1318.         if($_G['setting']['rewritestatus'] || !empty($havedomain)) {
  1319.         $s = output_replace($s);
  1320.         }
  1321.         return $s;
  1322. }

  1323. /**
  1324. * 运行钩子
  1325. */
  1326. function runhooks($scriptextra = '') {
  1327.         if(!defined('HOOKTYPE')) {
  1328.                 define('HOOKTYPE', !defined('IN_MOBILE') ? 'hookscript' : 'hookscriptmobile');
  1329.         }
  1330.         if(defined('CURMODULE')) {
  1331.                 global $_G;
  1332.                 if($_G['setting']['plugins']['func'][HOOKTYPE]['common']) {
  1333.                         hookscript('common', 'global', 'funcs', array(), 'common');
  1334.                 }
  1335.                 hookscript(CURMODULE, $_G['basescript'], 'funcs', array(), '', $scriptextra);
  1336.         }
  1337. }

  1338. /**
  1339. * 执行插件脚本
  1340. */
  1341. function hookscript($script, $hscript, $type = 'funcs', $param = array(), $func = '', $scriptextra = '') {
  1342.         global $_G;
  1343.         static $pluginclasses;
  1344.         if($hscript == 'home') {
  1345.                 if($script == 'space') {
  1346.                         $scriptextra = !$scriptextra ? $_GET['do'] : $scriptextra;
  1347.                         $script = 'space'.(!empty($scriptextra) ? '_'.$scriptextra : '');
  1348.                 } elseif($script == 'spacecp') {
  1349.                         $scriptextra = !$scriptextra ? $_GET['ac'] : $scriptextra;
  1350.                         $script .= !empty($scriptextra) ? '_'.$scriptextra : '';
  1351.                 }
  1352.         }
  1353.         if(!isset($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {
  1354.                 return;
  1355.         }
  1356.         if(!isset($_G['cache']['plugin'])) {
  1357.                 loadcache('plugin');
  1358.         }
  1359.         foreach((array)$_G['setting'][HOOKTYPE][$hscript][$script]['module'] as $identifier => $include) {
  1360.                 if($_G['pluginrunlist'] && !in_array($identifier, $_G['pluginrunlist'])) {
  1361.                         continue;
  1362.                 }
  1363.                 $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']);
  1364.                 if($hooksadminid[$identifier]) {
  1365.                         //#start
  1366.                         $_akey = '#file#source/plugin/'.$include.'.class.php';
  1367.                         C::analysisStart($_akey);
  1368.                         //#end;
  1369.                         @include_once DISCUZ_ROOT.'./source/plugin/'.$include.'.class.php';
  1370.                         //#start
  1371.                         C::analysisStop($_akey);
  1372.                         //#end
  1373.                 }
  1374.         }
  1375.         if(@is_array($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {
  1376.                 $_G['inhookscript'] = true;
  1377.                 $funcs = !$func ? $_G['setting'][HOOKTYPE][$hscript][$script][$type] : array($func => $_G['setting'][HOOKTYPE][$hscript][$script][$type][$func]);
  1378.                 foreach($funcs as $hookkey => $hookfuncs) {
  1379.                         foreach($hookfuncs as $hookfunc) {
  1380.                                 if($hooksadminid[$hookfunc[0]]) {
  1381.                                         $classkey = (HOOKTYPE != 'hookscriptmobile' ? '' : 'mobile').'plugin_'.($hookfunc[0].($hscript != 'global' ? '_'.$hscript : ''));
  1382.                                         if(!class_exists($classkey, false)) {
  1383.                                                 continue;
  1384.                                         }
  1385.                                         if(!isset($pluginclasses[$classkey])) {
  1386.                                                 $pluginclasses[$classkey] = new $classkey;
  1387.                                         }
  1388.                                         if(!method_exists($pluginclasses[$classkey], $hookfunc[1])) {
  1389.                                                 continue;
  1390.                                         }
  1391.                                         //#start
  1392.                                         $_akey = '#function#'.$classkey.'::'.$hookfunc[1];
  1393.                                         C::analysisStart($_akey);
  1394.                                         //#end
  1395.                                         $return = $pluginclasses[$classkey]->$hookfunc[1]($param);
  1396.                                         //#start
  1397.                                         C::analysisStop($_akey);
  1398.                                         //#end

  1399.                                         if(substr($hookkey, -7) == '_extend' && !empty($_G['setting']['pluginhooks'][$hookkey])) {
  1400.                                                 continue;
  1401.                                         }

  1402.                                         if(is_array($return)) {
  1403.                                                 if(!isset($_G['setting']['pluginhooks'][$hookkey]) || is_array($_G['setting']['pluginhooks'][$hookkey])) {
  1404.                                                         foreach($return as $k => $v) {
  1405.                                                                 $_G['setting']['pluginhooks'][$hookkey][$k] .= $v;
  1406.                                                         }
  1407.                                                 } else {
  1408.                                                         foreach($return as $k => $v) {
  1409.                                                                 $_G['setting']['pluginhooks'][$hookkey][$k] = $v;
  1410.                                                         }
  1411.                                                 }
  1412.                                         } else {
  1413.                                                 if(!is_array($_G['setting']['pluginhooks'][$hookkey])) {
  1414.                                                         $_G['setting']['pluginhooks'][$hookkey] .= $return;
  1415.                                                 } else {
  1416.                                                         foreach($_G['setting']['pluginhooks'][$hookkey] as $k => $v) {
  1417.                                                                 $_G['setting']['pluginhooks'][$hookkey][$k] .= $return;
  1418.                                                         }
  1419.                                                 }
  1420.                                         }
  1421.                                 }
  1422.                         }
  1423.                 }
  1424.         }
  1425.         $_G['inhookscript'] = false;
  1426. }

  1427. function hookscriptoutput($tplfile) {
  1428.         global $_G;
  1429.         if(!empty($_G['hookscriptoutput'])) {
  1430.                 return;
  1431.         }
  1432. //        //note mobiledata
  1433. //        if(!empty($_GET['mobiledata'])) {
  1434. //                require_once libfile('class/mobiledata');
  1435. //                $mobiledata = new mobiledata();
  1436. //                if($mobiledata->validator()) {
  1437. //                        $mobiledata->outputvariables();
  1438. //                }
  1439. //        }
  1440.         hookscript('global', 'global');
  1441.         if(defined('CURMODULE')) {
  1442.                 $param = array('template' => $tplfile, 'message' => $_G['hookscriptmessage'], 'values' => $_G['hookscriptvalues']);
  1443.                 hookscript(CURMODULE, $_G['basescript'], 'outputfuncs', $param);
  1444.         }
  1445.         $_G['hookscriptoutput'] = true;
  1446. }

  1447. /**
  1448. * 获取插件模块
  1449. */
  1450. function pluginmodule($pluginid, $type) {
  1451.         global $_G;
  1452.         //note 过滤插件ID
  1453.         $pluginid = $pluginid ? preg_replace("/[^A-Za-z0-9_:]/", '', $pluginid) : '';
  1454.         if(!isset($_G['cache']['plugin'])) {
  1455.                 loadcache('plugin');
  1456.         }
  1457.         list($identifier, $module) = explode(':', $pluginid);
  1458.         if(!is_array($_G['setting']['plugins'][$type]) || !array_key_exists($pluginid, $_G['setting']['plugins'][$type])) {
  1459.                 showmessage('plugin_nonexistence');
  1460.         }
  1461.         if(!empty($_G['setting']['plugins'][$type][$pluginid]['url'])) {
  1462.                 dheader('location: '.$_G['setting']['plugins'][$type][$pluginid]['url']);
  1463.         }
  1464.         $directory = $_G['setting']['plugins'][$type][$pluginid]['directory'];
  1465.         if(empty($identifier) || !preg_match("/^[a-z]+[a-z0-9_]*\/$/i", $directory) || !preg_match("/^[a-z0-9_\-]+$/i", $module)) {
  1466.                 showmessage('undefined_action');
  1467.         }
  1468.         if(@!file_exists(DISCUZ_ROOT.($modfile = './source/plugin/'.$directory.$module.'.inc.php'))) {
  1469.                 showmessage('plugin_module_nonexistence', '', array('mod' => $modfile));
  1470.         }
  1471.         return DISCUZ_ROOT.$modfile;
  1472. }
  1473. /**
  1474. * 执行积分规则
  1475. * @param String $action:  规则action名称
  1476. * @param Integer $uid: 操作用户
  1477. * @param array $extrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1')
  1478. * @param String $needle: 防重字符串
  1479. * @param Integer $coef: 积分放大倍数
  1480. * @param Integer $update: 是否执行更新操作
  1481. * @param Integer $fid: 版块ID
  1482. * @return 返回积分策略
  1483. */
  1484. function updatecreditbyaction($action, $uid = 0, $extrasql = array(), $needle = '', $coef = 1, $update = 1, $fid = 0) {

  1485.         //include_once libfile('class/credit');
  1486.         $credit = credit::instance();
  1487.         if($extrasql) {
  1488.                 $credit->extrasql = $extrasql;
  1489.         }
  1490.         return $credit->execrule($action, $uid, $needle, $coef, $update, $fid);
  1491. }

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

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

  1512.         $credit = & credit::instance();
  1513.         if($extrasql) {
  1514.                 $credit->extrasql = $extrasql;
  1515.         }
  1516.         return $credit->updatecreditbyrule($action, $uids, $coef, $fid);
  1517. }

  1518. /**
  1519. * 添加积分
  1520. * @param Integer $uids: 用户uid或者uid数组
  1521. * @param String $dataarr: member count相关操作数组,例: array('threads' => 1, 'doings' => -1)
  1522. * @param Boolean $checkgroup: 是否检查用户组 true or false
  1523. * @param String $operation: 操作类型
  1524. * @param Integer $relatedid:
  1525. * @param String $ruletxt: 积分规则文本
  1526. * @param String $customtitle: 自定义积分记录标题
  1527. * @param String $custommemo: 自定义积分记录说明
  1528. */

  1529. function updatemembercount($uids, $dataarr = array(), $checkgroup = true, $operation = '', $relatedid = 0, $ruletxt = '', $customtitle = '', $custommemo = '') {
  1530.         if(!empty($uids) && (is_array($dataarr) && $dataarr)) {
  1531.                 require_once libfile('function/credit');
  1532.                 return _updatemembercount($uids, $dataarr, $checkgroup, $operation, $relatedid, $ruletxt, $customtitle, $custommemo);
  1533.         }
  1534.         return true;
  1535. }

  1536. /**
  1537. * 校验用户组
  1538. * @param $uid
  1539. */
  1540. function checkusergroup($uid = 0) {
  1541.         $credit = & credit::instance();
  1542.         $credit->checkusergroup($uid);
  1543. }

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

  1547.         $operator = str_replace(
  1548.                 array('+', '-', '*', '/', '(', ')', '{', '}', '\''),
  1549.                 array('\+', '\-', '\*', '\/', '\(', '\)', '\{', '\}', '\\\''),
  1550.                 $operator
  1551.         );

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

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

  1567. //临时调试通用
  1568. function debug($var = null, $vardump = false) {
  1569.         echo '<pre>';
  1570.         $vardump = empty($var) ? true : $vardump;
  1571.         if($vardump) {
  1572.                 var_dump($var);
  1573.         } else {
  1574.                 print_r($var);
  1575.         }
  1576.         exit();
  1577. }

  1578. /**
  1579. * 调试信息
  1580. */
  1581. function debuginfo() {
  1582.         global $_G;
  1583.         if(getglobal('setting/debug')) {
  1584.                 $db = & DB::object();
  1585.                 $_G['debuginfo'] = array(
  1586.                     'time' => number_format((microtime(true) - $_G['starttime']), 6),
  1587.                     'queries' => $db->querynum,
  1588.                     'memory' => ucwords(C::memory()->type)
  1589.                     );
  1590.                 if($db->slaveid) {
  1591.                         $_G['debuginfo']['queries'] = 'Total '.$db->querynum.', Slave '.$db->slavequery;
  1592.                 }
  1593.                 return TRUE;
  1594.         } else {
  1595.                 return FALSE;
  1596.         }
  1597. }

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

  1605.         if(empty($_G['setting']['focus']) || !array_key_exists($module, $_G['setting']['focus']) || !empty($_G['cookie']['nofocus_'.$module]) || !$_G['setting']['focus'][$module]) {
  1606.                 return null;
  1607.         }
  1608.         loadcache('focus');
  1609.         if(empty($_G['cache']['focus']['data']) || !is_array($_G['cache']['focus']['data'])) {
  1610.                 return null;
  1611.         }
  1612.         $focusid = $_G['setting']['focus'][$module][array_rand($_G['setting']['focus'][$module])];
  1613.         return $focusid;
  1614. }

  1615. /**
  1616. * 检查验证码正确性
  1617. * @param $value 验证码变量值
  1618. */
  1619. function check_seccode($value, $idhash, $fromjs = 0, $modid = '') {
  1620.         return helper_seccheck::check_seccode($value, $idhash, $fromjs, $modid);
  1621. }

  1622. /**
  1623. * 检查验证问答正确性
  1624. * @param $value 验证问答变量值
  1625. */
  1626. function check_secqaa($value, $idhash) {
  1627.         return helper_seccheck::check_secqaa($value, $idhash);
  1628. }

  1629. /**
  1630. * 检查是否需要启用验证码、验证问答
  1631. */
  1632. function seccheck($rule, $param = array()) {
  1633.         return helper_seccheck::seccheck($rule, $param);
  1634. }

  1635. function make_seccode($seccode = '') {
  1636.         return helper_seccheck::make_seccode($seccode);
  1637. }

  1638. function make_secqaa() {
  1639.         return helper_seccheck::make_secqaa();
  1640. }

  1641. /**
  1642. * 获取广告
  1643. */
  1644. function adshow($parameter) {
  1645.         global $_G;
  1646.         if($_G['inajax'] || $_G['group']['closead']) {
  1647.                 return;
  1648.         }
  1649.         if(isset($_G['config']['plugindeveloper']) && $_G['config']['plugindeveloper'] == 2) {
  1650.                 return '<hook>[ad '.$parameter.']</hook>';
  1651.         }
  1652.         $params = explode('/', $parameter);
  1653.         $customid = 0;
  1654.         $customc = explode('_', $params[0]);
  1655.         if($customc[0] == 'custom') {
  1656.                 $params[0] = $customc[0];
  1657.                 $customid = $customc[1];
  1658.         }
  1659.         $adcontent = null;
  1660.         if(empty($_G['setting']['advtype']) || !in_array($params[0], $_G['setting']['advtype'])) {
  1661.                 $adcontent = '';
  1662.         }
  1663.         if($adcontent === null) {
  1664.                 loadcache('advs');
  1665.                 $adids = array();
  1666.                 $evalcode = &$_G['cache']['advs']['evalcode'][$params[0]];
  1667.                 $parameters = &$_G['cache']['advs']['parameters'][$params[0]];
  1668.                 $codes = &$_G['cache']['advs']['code'][$_G['basescript']][$params[0]];
  1669.                 if(!empty($codes)) {
  1670.                         foreach($codes as $adid => $code) {
  1671.                                 $parameter = &$parameters[$adid];
  1672.                                 $checked = true;
  1673.                                 @eval($evalcode['check']);
  1674.                                 if($checked) {
  1675.                                         $adids[] = $adid;
  1676.                                 }
  1677.                         }
  1678.                         if(!empty($adids)) {
  1679.                                 $adcode = $extra = '';
  1680.                                 @eval($evalcode['create']);
  1681.                                 if(empty($notag)) {
  1682.                                         $adcontent = '<div'.($params[1] != '' ? ' class="'.$params[1].'"' : '').$extra.'>'.$adcode.'</div>';
  1683.                                 } else {
  1684.                                         $adcontent = $adcode;
  1685.                                 }
  1686.                         }
  1687.                 }
  1688.         }
  1689.         $adfunc = 'ad_'.$params[0];
  1690.         $_G['setting']['pluginhooks'][$adfunc] = null;
  1691.         hookscript('ad', 'global', 'funcs', array('params' => $params, 'content' => $adcontent), $adfunc);
  1692.         if(!$_G['setting']['hookscript']['global']['ad']['funcs'][$adfunc]) {
  1693.                 hookscript('ad', $_G['basescript'], 'funcs', array('params' => $params, 'content' => $adcontent), $adfunc);
  1694.         }
  1695.         return $_G['setting']['pluginhooks'][$adfunc] === null ? $adcontent : $_G['setting']['pluginhooks'][$adfunc];
  1696. }

  1697. /**
  1698. * 显示提示信息
  1699. * @param $message - 提示信息,可中文也可以是 lang_message.php 中的数组 key 值
  1700. * @param $url_forward - 提示后跳转的 url
  1701. * @param $values - 提示信息中可替换的变量值 array(key => value ...) 形式
  1702. * @param $extraparam - 扩展参数 array(key => value ...) 形式
  1703. *        跳转控制
  1704.                 header                header跳转
  1705.                 location        location JS 跳转,限于 msgtype = 2、3
  1706.                 timeout                定时跳转
  1707.                 refreshtime        自定义跳转时间
  1708.                 closetime        自定义关闭时间,限于 msgtype = 2,值为 true 时为默认
  1709.                 locationtime        自定义跳转时间,限于 msgtype = 2,值为 true 时为默认
  1710.         内容控制
  1711.                 alert                alert 图标样式 right/info/error
  1712.                 return                显示请返回
  1713.                 redirectmsg        下载时用的提示信息,当跳转时显示的信息样式
  1714.                                          0:如果您的浏览器没有自动跳转,请点击此链接
  1715.                                          1:如果 n 秒后下载仍未开始,请点击此链接
  1716.                 msgtype                信息样式
  1717.                                          1:非 Ajax
  1718.                                          2:Ajax 弹出框
  1719.                                          3:Ajax 只显示信息文本
  1720.                 showmsg                显示信息文本
  1721.                 showdialog        关闭原弹出框显示 showDialog 信息,限于 msgtype = 2
  1722.                 login                未登录时显示登录链接
  1723.                 extrajs                扩展 js
  1724.                 striptags        过滤 HTML 标记
  1725.         Ajax 控制
  1726.                 handle                执行 js 回调函数
  1727.                 showid                控制显示的对象 ID
  1728. */
  1729. function showmessage($message, $url_forward = '', $values = array(), $extraparam = array(), $custom = 0) {
  1730.         require_once libfile('function/message');
  1731.         return dshowmessage($message, $url_forward, $values, $extraparam, $custom);
  1732. }

  1733. /**
  1734. * 检查是否正确提交了表单
  1735. * @param $var 需要检查的变量
  1736. * @param $allowget 是否允许GET方式
  1737. * @param $seccodecheck 验证码检测是否开启
  1738. * @return 返回是否正确提交了表单
  1739. */
  1740. function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) {
  1741.         if(!getgpc($var)) {
  1742.                 return FALSE;
  1743.         } else {
  1744.                 return helper_form::submitcheck($var, $allowget, $seccodecheck, $secqaacheck);
  1745.         }
  1746. }

  1747. /**
  1748. * 分页
  1749. * @param $num - 总数
  1750. * @param $perpage - 每页数
  1751. * @param $curpage - 当前页
  1752. * @param $mpurl - 跳转的路径
  1753. * @param $maxpages - 允许显示的最大页数
  1754. * @param $page - 最多显示多少页码
  1755. * @param $autogoto - 最后一页,自动跳转
  1756. * @param $simple - 是否简洁模式(简洁模式不显示上一页、下一页和页码跳转)
  1757. * @return 返回分页代码
  1758. */
  1759. function multi($num, $perpage, $curpage, $mpurl, $maxpages = 0, $page = 10, $autogoto = FALSE, $simple = FALSE, $jsfunc = FALSE) {
  1760.         return $num > $perpage ? helper_page::multi($num, $perpage, $curpage, $mpurl, $maxpages, $page, $autogoto, $simple, $jsfunc) : '';
  1761. }

  1762. /**
  1763. * 只有上一页下一页的分页(无需知道数据总数)
  1764. * @param $num - 本次所取数据条数
  1765. * @param $perpage - 每页数
  1766. * @param $curpage - 当前页
  1767. * @param $mpurl - 跳转的路径
  1768. * @return 返回分页代码
  1769. */
  1770. function simplepage($num, $perpage, $curpage, $mpurl) {
  1771.         return helper_page::simplepage($num, $perpage, $curpage, $mpurl);
  1772. }

  1773. /**
  1774. * 词语过滤
  1775. * @param $message - 词语过滤文本
  1776. * @return 成功返回原始文本,否则提示错误或被替换
  1777. */
  1778. function censor($message, $modword = NULL, $return = FALSE) {
  1779.         return helper_form::censor($message, $modword, $return);
  1780. }

  1781. /**
  1782.         词语过滤,检测是否含有需要审核的词
  1783. */
  1784. function censormod($message) {
  1785.         return getglobal('group/ignorecensor') || !$message ? false :helper_form::censormod($message);
  1786. }

  1787. //获取用户附属表信息,累加到第一个变量$values
  1788. function space_merge(&$values, $tablename, $isarchive = false) {
  1789.         global $_G;

  1790.         $uid = empty($values['uid'])?$_G['uid']:$values['uid'];//默认当前用户
  1791.         $var = "member_{$uid}_{$tablename}";
  1792.         if($uid) {
  1793.                 if(!isset($_G[$var])) {
  1794.                         //$query = DB::query("SELECT * FROM ".DB::table('common_member_'.$tablename)." WHERE uid='$uid'");
  1795.                         //if($_G[$var] = DB::fetch($query)) {
  1796.                         $ext = $isarchive ? '_archive' : '';
  1797.                         if(($_G[$var] = C::t('common_member_'.$tablename.$ext)->fetch($uid)) !== false) {
  1798.                                 if($tablename == 'field_home') {
  1799.                                         //隐私设置
  1800.                                         $_G['setting']['privacy'] = empty($_G['setting']['privacy']) ? array() : (is_array($_G['setting']['privacy']) ? $_G['setting']['privacy'] : dunserialize($_G['setting']['privacy']));
  1801.                                         $_G[$var]['privacy'] = empty($_G[$var]['privacy'])? array() : is_array($_G[$var]['privacy']) ? $_G[$var]['privacy'] : dunserialize($_G[$var]['privacy']);
  1802.                                         foreach (array('feed','view','profile') as $pkey) {
  1803.                                                 if(empty($_G[$var]['privacy'][$pkey]) && !isset($_G[$var]['privacy'][$pkey])) {
  1804.                                                         $_G[$var]['privacy'][$pkey] = isset($_G['setting']['privacy'][$pkey]) ? $_G['setting']['privacy'][$pkey] : array();//取站点默认设置
  1805.                                                 }
  1806.                                         }
  1807.                                         //邮件提醒
  1808.                                         $_G[$var]['acceptemail'] = empty($_G[$var]['acceptemail'])? array() : dunserialize($_G[$var]['acceptemail']);
  1809.                                         if(empty($_G[$var]['acceptemail'])) {
  1810.                                                 $_G[$var]['acceptemail'] = empty($_G['setting']['acceptemail'])?array():dunserialize($_G['setting']['acceptemail']);
  1811.                                         }
  1812.                                 }
  1813.                         } else {
  1814.                                 //插入默认数据
  1815.                                 //DB::insert('common_member_'.$tablename, array('uid'=>$uid));
  1816.                                 C::t('common_member_'.$tablename.$ext)->insert(array('uid'=>$uid));
  1817.                                 $_G[$var] = array();
  1818.                         }
  1819.                 }
  1820.                 $values = array_merge($values, $_G[$var]);
  1821.         }
  1822. }

  1823. /*
  1824. * 运行log记录
  1825. */
  1826. function runlog($file, $message, $halt=0) {
  1827.         helper_log::runlog($file, $message, $halt);
  1828. }

  1829. /*
  1830. * 处理搜索关键字
  1831. */
  1832. function stripsearchkey($string) {
  1833.         $string = trim($string);
  1834.         $string = str_replace('*', '%', addcslashes($string, '%_'));
  1835.         //$string = str_replace('_', '\_', $string);
  1836.         return $string;
  1837. }

  1838. /*
  1839. * 递归创建目录
  1840. */
  1841. function dmkdir($dir, $mode = 0777, $makeindex = TRUE){
  1842.         if(!is_dir($dir)) {
  1843.                 dmkdir(dirname($dir), $mode, $makeindex);
  1844.                 @mkdir($dir, $mode);
  1845.                 if(!empty($makeindex)) {
  1846.                         @touch($dir.'/index.html'); @chmod($dir.'/index.html', 0777);
  1847.                 }
  1848.         }
  1849.         return true;
  1850. }

  1851. /**
  1852. * 刷新重定向
  1853. */
  1854. function dreferer($default = '') {
  1855.         global $_G;

  1856.         $default = empty($default) && $_ENV['curapp'] ? $_ENV['curapp'].'.php' : '';
  1857.         $_G['referer'] = !empty($_GET['referer']) ? $_GET['referer'] : $_SERVER['HTTP_REFERER'];
  1858.         $_G['referer'] = substr($_G['referer'], -1) == '?' ? substr($_G['referer'], 0, -1) : $_G['referer'];

  1859.         if(strpos($_G['referer'], 'member.php?mod=logging')) {
  1860.                 $_G['referer'] = $default;
  1861.         }

  1862.         $reurl = parse_url($_G['referer']);
  1863.         /**
  1864.          * 判断host是否相同,不同时做进一步的校验
  1865.          * 当解析到的host与HTTP_HOST,相同的,不管是不是加www均给予放行
  1866.          */
  1867.         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']))) {
  1868.                 //校验是否在应用域名或版块域名配置中
  1869.                 if(!in_array($reurl['host'], $_G['setting']['domain']['app']) && !isset($_G['setting']['domain']['list'][$reurl['host']])) {
  1870.                         $domainroot = substr($reurl['host'], strpos($reurl['host'], '.')+1);
  1871.                         //是否为子域名,如果不为子域名则跳到index.php
  1872.                         if(empty($_G['setting']['domain']['root']) || (is_array($_G['setting']['domain']['root']) && !in_array($domainroot, $_G['setting']['domain']['root']))) {
  1873.                                 $_G['referer'] = $_G['setting']['domain']['defaultindex'] ? $_G['setting']['domain']['defaultindex'] : 'index.php';
  1874.                         }
  1875.                 }
  1876.         } elseif(empty($reurl['host'])) {
  1877.                 $_G['referer'] = $_G['siteurl'].'./'.$_G['referer'];
  1878.         }

  1879.         $_G['referer'] = durlencode($_G['referer']);
  1880.         return$_G['referer'];
  1881. }

  1882. /**
  1883. * 远程FTP使用
  1884. */
  1885. function ftpcmd($cmd, $arg1 = '') {
  1886.         static $ftp;
  1887.         $ftpon = getglobal('setting/ftp/on');
  1888.         if(!$ftpon) {
  1889.                 return $cmd == 'error' ? -101 : 0;
  1890.         } elseif($ftp == null) {
  1891.                 $ftp = & discuz_ftp::instance();
  1892.         }
  1893.         if(!$ftp->enabled) {
  1894.                 return $ftp->error();
  1895.         } elseif($ftp->enabled && !$ftp->connectid) {
  1896.                 $ftp->connect();
  1897.         }
  1898.         switch ($cmd) {
  1899.                 case 'upload' : return $ftp->upload(getglobal('setting/attachdir').'/'.$arg1, $arg1); break;
  1900.                 case 'delete' : return $ftp->ftp_delete($arg1); break;
  1901.                 case 'close'  : return $ftp->ftp_close(); break;
  1902.                 case 'error'  : return $ftp->error(); break;
  1903.                 case 'object' : return $ftp; break;
  1904.                 default       : return false;
  1905.         }

  1906. }

  1907. /**
  1908. * 编码转换
  1909. * @param <string> $str 要转码的字符
  1910. * @param <string> $in_charset 输入字符集
  1911. * @param <string> $out_charset 输出字符集(默认当前)
  1912. * @param <boolean> $ForceTable 强制使用码表(默认不强制)
  1913. *
  1914. */
  1915. function diconv($str, $in_charset, $out_charset = CHARSET, $ForceTable = FALSE) {
  1916.         global $_G;

  1917.         $in_charset = strtoupper($in_charset);
  1918.         $out_charset = strtoupper($out_charset);

  1919.         if(empty($str) || $in_charset == $out_charset) {
  1920.                 return $str;
  1921.         }

  1922.         $out = '';

  1923.         if(!$ForceTable) {
  1924.                 if(function_exists('iconv')) {
  1925.                         $out = iconv($in_charset, $out_charset.'//IGNORE', $str);
  1926.                 } elseif(function_exists('mb_convert_encoding')) {
  1927.                         $out = mb_convert_encoding($str, $out_charset, $in_charset);
  1928.                 }
  1929.         }

  1930.         if($out == '') {
  1931.                 $chinese = new Chinese($in_charset, $out_charset, true);
  1932.                 $out = $chinese->Convert($str);
  1933.         }

  1934.         return $out;
  1935. }

  1936. function widthauto() {
  1937.         global $_G;
  1938.         if($_G['disabledwidthauto']) {
  1939.                 return 0;
  1940.         }
  1941.         if(!empty($_G['widthauto'])) {
  1942.                 return $_G['widthauto'] > 0 ? 1 : 0;
  1943.         }
  1944.         if($_G['setting']['switchwidthauto'] && !empty($_G['cookie']['widthauto'])) {
  1945.                 return $_G['cookie']['widthauto'] > 0 ? 1 : 0;
  1946.         } else {
  1947.                 return $_G['setting']['allowwidthauto'] ? 0 : 1;
  1948.         }
  1949. }
  1950. /**
  1951. * 重建数组
  1952. * @param <string> $array 需要反转的数组
  1953. * @return array 原数组与的反转后的数组
  1954. */
  1955. function renum($array) {
  1956.         $newnums = $nums = array();
  1957.         foreach ($array as $id => $num) {
  1958.                 $newnums[$num][] = $id;
  1959.                 $nums[$num] = $num;
  1960.         }
  1961.         return array($nums, $newnums);
  1962. }

  1963. /**
  1964. * 字节格式化单位
  1965. * @param $filesize - 大小(字节)
  1966. * @return 返回格式化后的文本
  1967. */
  1968. function sizecount($size) {
  1969.         if($size >= 1073741824) {
  1970.                 $size = round($size / 1073741824 * 100) / 100 . ' GB';
  1971.         } elseif($size >= 1048576) {
  1972.                 $size = round($size / 1048576 * 100) / 100 . ' MB';
  1973.         } elseif($size >= 1024) {
  1974.                 $size = round($size / 1024 * 100) / 100 . ' KB';
  1975.         } else {
  1976.                 $size = intval($size) . ' Bytes';
  1977.         }
  1978.         return $size;
  1979. }

  1980. function swapclass($class1, $class2 = '') {
  1981.         static $swapc = null;
  1982.         $swapc = isset($swapc) && $swapc != $class1 ? $class1 : $class2;
  1983.         return $swapc;
  1984. }

  1985. /**
  1986. * 写入运行日志
  1987. */
  1988. function writelog($file, $log) {
  1989.         helper_log::writelog($file, $log);
  1990. }

  1991. /**
  1992. * 取得某标志位的数值 (0|1)
  1993. *
  1994. * @param 数值 $status
  1995. * @param 位置 $position
  1996. * @return 0 | 1
  1997. */
  1998. function getstatus($status, $position) {
  1999.         $t = $status & pow(2, $position - 1) ? 1 : 0;
  2000.         return $t;
  2001. }

  2002. /**
  2003. * 设置某一bit位的数值 0 or 1
  2004. *
  2005. * @param int $position  1-16
  2006. * @param int $value  0|1
  2007. * @param 原始数值 $baseon  0x0000-0xffff
  2008. * @return int
  2009. */
  2010. function setstatus($position, $value, $baseon = null) {
  2011.         $t = pow(2, $position - 1);
  2012.         if($value) {
  2013.                 $t = $baseon | $t;
  2014.         } elseif ($baseon !== null) {
  2015.                 $t = $baseon & ~$t;
  2016.         } else {
  2017.                 $t = ~$t;
  2018.         }
  2019.         return $t & 0xFFFF;
  2020. }

  2021. /**
  2022. * 通知
  2023. * @param Integer $touid: 通知给谁
  2024. * @param String $type: 通知类型
  2025. * @param String $note: 语言key
  2026. * @param Array $notevars: 语言变量对应的值
  2027. * @param Integer $system: 是否为系统通知 0:非系统通知; 1:系统通知
  2028. */
  2029. function notification_add($touid, $type, $note, $notevars = array(), $system = 0) {
  2030.         return helper_notification::notification_add($touid, $type, $note, $notevars, $system);
  2031. }

  2032. /**
  2033. * 发送管理通知
  2034. * @param $type - 通知类型
  2035. */
  2036. function manage_addnotify($type, $from_num = 0, $langvar = array()) {
  2037.         helper_notification::manage_addnotify($type, $from_num, $langvar);
  2038. }

  2039. /**
  2040. * 发送短消息(兼容提醒)
  2041. * @param $toid - 接收方id
  2042. * @param $subject - 标题
  2043. * @param $message - 内容
  2044. * @param $fromid - 发送方id
  2045. */
  2046. function sendpm($toid, $subject, $message, $fromid = '', $replypmid = 0, $isusername = 0, $type = 0) {
  2047.         return helper_pm::sendpm($toid, $subject, $message, $fromid, $replypmid, $isusername, $type);
  2048. }

  2049. //获得用户组图标
  2050. function g_icon($groupid, $return = 0) {
  2051.         global $_G;
  2052.         if(empty($_G['cache']['usergroups'][$groupid]['icon'])) {
  2053.                 $s =  '';
  2054.         } else {
  2055.                 if(substr($_G['cache']['usergroups'][$groupid]['icon'], 0, 5) == 'http:') {
  2056.                         $s = '<img src="'.$_G['cache']['usergroups'][$groupid]['icon'].'" alt="" class="vm" />';
  2057.                 } else {
  2058.                         $s = '<img src="'.$_G['setting']['attachurl'].'common/'.$_G['cache']['usergroups'][$groupid]['icon'].'" alt="" class="vm" />';
  2059.                 }
  2060.         }
  2061.         if($return) {
  2062.                 return $s;
  2063.         } else {
  2064.                 echo $s;
  2065.         }
  2066. }
  2067. //从数据库中更新DIY模板文件
  2068. function updatediytemplate($targettplname = '', $tpldirectory = '') {
  2069.         $r = false;
  2070.         //$where = empty($targettplname) ? '' : " WHERE targettplname='$targettplname'";
  2071.         //$query = DB::query("SELECT * FROM ".DB::table('common_diy_data')."$where");
  2072.         $alldata = !empty($targettplname) ? array( C::t('common_diy_data')->fetch($targettplname, $tpldirectory)) : C::t('common_diy_data')->range();
  2073.         require_once libfile('function/portalcp');
  2074.         //while($value = DB::fetch($query)) {
  2075.         foreach($alldata as $value) {
  2076.                 $r = save_diy_data($value['tpldirectory'], $value['primaltplname'], $value['targettplname'], dunserialize($value['diycontent']));
  2077.         }
  2078.         return $r;
  2079. }

  2080. //获得用户唯一串
  2081. function space_key($uid, $appid=0) {
  2082.         global $_G;
  2083.         //$siteuniqueid = DB::result_first("SELECT svalue FROM ".DB::table('common_setting')." WHERE skey='siteuniqueid'");
  2084.         return substr(md5($_G['setting']['siteuniqueid'].'|'.$uid.(empty($appid)?'':'|'.$appid)), 8, 16);
  2085. }


  2086. //note post分表相关函数
  2087. /**
  2088. *
  2089. * 通过tid得到相应的单一post表名或post表集合
  2090. * @param <mix> $tids: 允许传进单个tid,也可以是tid集合
  2091. * @param $primary: 是否只查主题表 0:遍历所有表;1:只查主表
  2092. * @return 当传进来的是单一的tid将直接返回表名,否则返回表集合的二维数组例:array('forum_post' => array(tids),'forum_post_1' => array(tids))
  2093. * @TODO tid传进来的是字符串的,返回单个表名,传进来的是数组的,不管是不是一个数组,返回的还是数组,保证进出值对应
  2094. */
  2095. function getposttablebytid($tids, $primary = 0) {
  2096.         return table_forum_post::getposttablebytid($tids, $primary);
  2097. }

  2098. /**
  2099. * 获取论坛帖子表名
  2100. * @param <int> $tableid: 分表ID,默认为:fourm_post表
  2101. * @param <boolean> $prefix: 是否默认带有表前缀
  2102. * @return forum_post or forum_post_*
  2103. */
  2104. function getposttable($tableid = 0, $prefix = false) {
  2105.         return table_forum_post::getposttable($tableid, $prefix);
  2106. }

  2107. /**
  2108. * 内存读写接口函数
  2109. * <code>
  2110. * memory('get', 'keyname') === false;//缓存中没有这个keyname时结果为true
  2111. * </code>
  2112. *  * @param 命令 $cmd (set|get|rm|check|inc|dec)
  2113. * @param 键值 $key
  2114. * @param 数据 $value 当$cmd=get|rm时,$value即为$prefix;当$cmd=inc|dec时,$value为$step,默认为1
  2115. * @param 有效期 $ttl
  2116. * @param 键值的前缀 $prefix
  2117. * @return mix
  2118. *
  2119. * @example set : 写入内存 $ret = memory('set', 'test', 'ok')
  2120. * @example get : 读取内存 $data = memory('get', 'test')
  2121. * @example rm : 删除内存  $ret = memory('rm', 'test')
  2122. * @example check : 检查内存功能是否可用 $allow = memory('check')
  2123. */
  2124. function memory($cmd, $key='', $value='', $ttl = 0, $prefix = '') {
  2125.         if($cmd == 'check') {
  2126.                 return  C::memory()->enable ? C::memory()->type : '';
  2127.         } elseif(C::memory()->enable && in_array($cmd, array('set', 'get', 'rm', 'inc', 'dec'))) {
  2128.                 if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
  2129.                         if(is_array($key)) {
  2130.                                 foreach($key as $k) {
  2131.                                         C::memory()->debug[$cmd][] = ($cmd == 'get' || $cmd == 'rm' ? $value : '').$prefix.$k;
  2132.                                 }
  2133.                         } else {
  2134.                                 C::memory()->debug[$cmd][] = ($cmd == 'get' || $cmd == 'rm' ? $value : '').$prefix.$key;
  2135.                         }
  2136.                 }
  2137.                 switch ($cmd) {
  2138.                         case 'set': return C::memory()->set($key, $value, $ttl, $prefix); break;
  2139.                         case 'get': return C::memory()->get($key, $value); break;
  2140.                         case 'rm': return C::memory()->rm($key, $value); break;
  2141.                         case 'inc': return C::memory()->inc($key, $value ? $value : 1); break;
  2142.                         case 'dec': return C::memory()->dec($key, $value ? $value : -1); break;
  2143.                 }
  2144.         }
  2145.         return null;
  2146. }

  2147. /**
  2148. * ip允许访问
  2149. * @param $ip 要检查的ip地址
  2150. * @param - $accesslist 允许访问的ip地址
  2151. * @param 返回结果
  2152. */
  2153. function ipaccess($ip, $accesslist) {
  2154.         return preg_match("/^(".str_replace(array("\r\n", ' '), array('|', ''), preg_quote($accesslist, '/')).")/", $ip);
  2155. }

  2156. /**
  2157. * ip限制访问
  2158. * @param $ip 要检查的ip地址
  2159. * @param - $accesslist 允许访问的ip地址
  2160. * @param 返回结果
  2161. */
  2162. function ipbanned($onlineip) {
  2163.         global $_G;

  2164.         if($_G['setting']['ipaccess'] && !ipaccess($onlineip, $_G['setting']['ipaccess'])) {
  2165.                 return TRUE;
  2166.         }

  2167.         loadcache('ipbanned');
  2168.         if(empty($_G['cache']['ipbanned'])) {
  2169.                 return FALSE;
  2170.         } else {
  2171.                 if($_G['cache']['ipbanned']['expiration'] < TIMESTAMP) {
  2172.                         require_once libfile('function/cache');
  2173.                         updatecache('ipbanned');
  2174.                 }
  2175.                 return preg_match("/^(".$_G['cache']['ipbanned']['regexp'].")$/", $onlineip);
  2176.         }
  2177. }

  2178. //获得统计数
  2179. function getcount($tablename, $condition) {
  2180.         if(empty($condition)) {
  2181.                 $where = '1';
  2182.         } elseif(is_array($condition)) {
  2183.                 $where = DB::implode_field_value($condition, ' AND ');
  2184.         } else {
  2185.                 $where = $condition;
  2186.         }
  2187.         $ret = intval(DB::result_first("SELECT COUNT(*) AS num FROM ".DB::table($tablename)." WHERE $where"));
  2188.         return $ret;
  2189. }

  2190. /**
  2191. * 系统级消息
  2192. */
  2193. function sysmessage($message) {
  2194.         //require libfile('function/sysmessage');
  2195.         //show_system_message($message);
  2196.         helper_sysmessage::show($message);
  2197. }

  2198. /**
  2199. * 论坛权限
  2200. * @param $permstr - 权限信息
  2201. * @param $groupid - 只判断用户组
  2202. * @return 0 无权限 > 0 有权限
  2203. */
  2204. function forumperm($permstr, $groupid = 0) {
  2205.         global $_G;

  2206.         $groupidarray = array($_G['groupid']);
  2207.         if($groupid) {
  2208.                 return preg_match("/(^|\t)(".$groupid.")(\t|$)/", $permstr);
  2209.         }
  2210.         foreach(explode("\t", $_G['member']['extgroupids']) as $extgroupid) {
  2211.                 if($extgroupid = intval(trim($extgroupid))) {
  2212.                         $groupidarray[] = $extgroupid;
  2213.                 }
  2214.         }
  2215.         if($_G['setting']['verify']['enabled']) {
  2216.                 getuserprofile('verify1');
  2217.                 foreach($_G['setting']['verify'] as $vid => $verify) {
  2218.                         if($verify['available'] && $_G['member']['verify'.$vid] == 1) {
  2219.                                 $groupidarray[] = 'v'.$vid;
  2220.                         }
  2221.                 }
  2222.         }
  2223.         return preg_match("/(^|\t)(".implode('|', $groupidarray).")(\t|$)/", $permstr);
  2224. }

  2225. //检查权限
  2226. function checkperm($perm) {
  2227.         global $_G;
  2228.         return defined('IN_ADMINCP') ? true : (empty($_G['group'][$perm])?'':$_G['group'][$perm]);
  2229. }

  2230. /**
  2231. * 时间段设置检测
  2232. * @param $periods - 那种时间段 $settings[$periods]  $settings['postbanperiods'] $settings['postmodperiods']
  2233. * @param $showmessage - 是否提示信息
  2234. * @return 返回检查结果
  2235. */
  2236. function periodscheck($periods, $showmessage = 1) {
  2237.         global $_G;
  2238.         if(($periods == 'postmodperiods' || $periods == 'postbanperiods') && ($_G['setting']['postignorearea'] || $_G['setting']['postignoreip'])) {
  2239.                 if($_G['setting']['postignoreip']) {
  2240.                         foreach(explode("\n", $_G['setting']['postignoreip']) as $ctrlip) {
  2241.                                 if(preg_match("/^(".preg_quote(($ctrlip = trim($ctrlip)), '/').")/", $_G['clientip'])) {
  2242.                                         return false;
  2243.                                         break;
  2244.                                 }
  2245.                         }
  2246.                 }
  2247.                 if($_G['setting']['postignorearea']) {
  2248.                         $location = $whitearea = '';
  2249.                         require_once libfile('function/misc');
  2250.                         $location = trim(convertip($_G['clientip'], "./"));
  2251.                         if($location) {
  2252.                                 $whitearea = preg_quote(trim($_G['setting']['postignorearea']), '/');
  2253.                                 $whitearea = str_replace(array("\\*"), array('.*'), $whitearea);
  2254.                                 $whitearea = '.*'.$whitearea.'.*';
  2255.                                 $whitearea = '/^('.str_replace(array("\r\n", ' '), array('.*|.*', ''), $whitearea).')$/i';
  2256.                                 if(@preg_match($whitearea, $location)) {
  2257.                                         return false;
  2258.                                 }
  2259.                         }
  2260.                 }
  2261.         }
  2262.         if(!$_G['group']['disableperiodctrl'] && $_G['setting'][$periods]) {
  2263.                 $now = dgmdate(TIMESTAMP, 'G.i', $_G['setting']['timeoffset']);
  2264.                 foreach(explode("\r\n", str_replace(':', '.', $_G['setting'][$periods])) as $period) {
  2265.                         list($periodbegin, $periodend) = explode('-', $period);
  2266.                         if(($periodbegin > $periodend && ($now >= $periodbegin || $now < $periodend)) || ($periodbegin < $periodend && $now >= $periodbegin && $now < $periodend)) {
  2267.                                 $banperiods = str_replace("\r\n", ', ', $_G['setting'][$periods]);
  2268.                                 if($showmessage) {
  2269.                                         showmessage('period_nopermission', NULL, array('banperiods' => $banperiods), array('login' => 1));
  2270.                                 } else {
  2271.                                         return TRUE;
  2272.                                 }
  2273.                         }
  2274.                 }
  2275.         }
  2276.         return FALSE;
  2277. }

  2278. //新用户发言
  2279. function cknewuser($return=0) {
  2280.         global $_G;

  2281.         $result = true;

  2282.         if(!$_G['uid']) return true;

  2283.         //不受防灌水限制
  2284.         if(checkperm('disablepostctrl')) {
  2285.                 return $result;
  2286.         }
  2287.         $ckuser = $_G['member'];

  2288.         //见习时间
  2289.         if($_G['setting']['newbiespan'] && $_G['timestamp']-$ckuser['regdate']<$_G['setting']['newbiespan']*60) {
  2290.                 if(empty($return)) showmessage('no_privilege_newbiespan', '', array('newbiespan' => $_G['setting']['newbiespan']), array());
  2291.                 $result = false;
  2292.         }
  2293.         //需要上传头像
  2294.         if($_G['setting']['need_avatar'] && empty($ckuser['avatarstatus'])) {
  2295.                 if(empty($return)) showmessage('no_privilege_avatar', '', array(), array());
  2296.                 $result = false;
  2297.         }
  2298.         //强制新用户激活邮箱
  2299.         if($_G['setting']['need_email'] && empty($ckuser['emailstatus'])) {
  2300.                 if(empty($return)) showmessage('no_privilege_email', '', array(), array());
  2301.                 $result = false;
  2302.         }
  2303.         //强制新用户好友个数
  2304.         if($_G['setting']['need_friendnum']) {
  2305.                 space_merge($ckuser, 'count');
  2306.                 if($ckuser['friends'] < $_G['setting']['need_friendnum']) {
  2307.                         if(empty($return)) showmessage('no_privilege_friendnum', '', array('friendnum' => $_G['setting']['need_friendnum']), array());
  2308.                         $result = false;
  2309.                 }
  2310.         }
  2311.         return $result;
  2312. }

  2313. function manyoulog($logtype, $uids, $action, $fid = '') {
  2314.         helper_manyou::manyoulog($logtype, $uids, $action, $fid);
  2315. }

  2316. /**
  2317. * 用户操作日志
  2318. * @param int $uid 用户ID
  2319. * @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
  2320. * @return bool
  2321. */
  2322. function useractionlog($uid, $action) {
  2323.         return helper_log::useractionlog($uid, $action);
  2324. }

  2325. /**
  2326. * 得到用户操作的代码或代表字符,参数为数字返回字符串,参数为字符串返回数字
  2327. * @param string/int $var
  2328. * @return int/string 注意:如果失败返回false,请使用===判断,因为代码0代表tid
  2329. */
  2330. function getuseraction($var) {
  2331.         return helper_log::getuseraction($var);
  2332. }

  2333. /**
  2334. * 获取我的中心中展示的应用
  2335. */
  2336. function getuserapp($panel = 0) {
  2337.         return helper_manyou::getuserapp($panel);
  2338. }

  2339. /**
  2340. * 获取manyou应用本地图标路径
  2341. * @param <type> $appid
  2342. */
  2343. function getmyappiconpath($appid, $iconstatus=0) {
  2344.         return helper_manyou::getmyappiconpath($appid, $iconstatus);
  2345. }

  2346. //获取超时时间
  2347. function getexpiration() {
  2348.         global $_G;
  2349.         $date = getdate($_G['timestamp']);
  2350.         return mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']) + 86400;
  2351. }

  2352. function return_bytes($val) {
  2353.     $val = trim($val);
  2354.     $last = strtolower($val{strlen($val)-1});
  2355.     switch($last) {
  2356.         case 'g': $val *= 1024;
  2357.         case 'm': $val *= 1024;
  2358.         case 'k': $val *= 1024;
  2359.     }
  2360.     return $val;
  2361. }

  2362. function iswhitelist($host) {
  2363.         global $_G;
  2364.         static $iswhitelist = array();

  2365.         if(isset($iswhitelist[$host])) {
  2366.                 return $iswhitelist[$host];
  2367.         }
  2368.         $hostlen = strlen($host);
  2369.         $iswhitelist[$host] = false;
  2370.         if(!$_G['cache']['domainwhitelist']) {
  2371.                 loadcache('domainwhitelist');
  2372.         }
  2373.         if(is_array($_G['cache']['domainwhitelist'])) foreach($_G['cache']['domainwhitelist'] as $val) {
  2374.                 $domainlen = strlen($val);
  2375.                 if($domainlen > $hostlen) {
  2376.                         continue;
  2377.                 }
  2378.                 if(substr($host, -$domainlen) == $val) {
  2379.                         $iswhitelist[$host] = true;
  2380.                         break;
  2381.                 }
  2382.         }
  2383.         if($iswhitelist[$host] == false) {
  2384.                 $iswhitelist[$host] = $host == $_SERVER['HTTP_HOST'];
  2385.         }
  2386.         return $iswhitelist[$host];
  2387. }

  2388. /**
  2389. * 通过 AID 获取附件表名
  2390. * @param <int> $aid
  2391. */
  2392. function getattachtablebyaid($aid) {
  2393. //        $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE aid='$aid'");
  2394.         $attach = C::t('forum_attachment')->fetch($aid);
  2395.         $tableid = $attach['tableid'];
  2396.         return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused');
  2397. }

  2398. /**
  2399. * 返回指定 TID 所对应的附件表编号
  2400. * @param <int> $tid
  2401. */
  2402. function getattachtableid($tid) {
  2403.         $tid = (string)$tid;
  2404.         return intval($tid{strlen($tid)-1});
  2405. }

  2406. /**
  2407. * 通过 TID 获取附件表名
  2408. * @param <int> $tid
  2409. */
  2410. function getattachtablebytid($tid) {
  2411.         return 'forum_attachment_'.getattachtableid($tid);
  2412. }

  2413. /**
  2414. * 通过 PID 获取附件表名
  2415. * @param <int> $pid
  2416. */
  2417. function getattachtablebypid($pid) {
  2418.         $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE pid='$pid' LIMIT 1");
  2419.         return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused');
  2420. }

  2421. /**
  2422. * 添加一个新的附件索引记录,并返回新附件 ID
  2423. * @param <int> $uid
  2424. */
  2425. function getattachnewaid($uid = 0) {
  2426.         global $_G;
  2427.         $uid = !$uid ? $_G['uid'] : $uid;
  2428. //        return DB::insert('forum_attachment', array('tid' => 0, 'pid' => 0, 'uid' => $uid, 'tableid' => 127), true);
  2429.         return C::t('forum_attachment')->insert(array('tid' => 0, 'pid' => 0, 'uid' => $uid, 'tableid' => 127), true);
  2430. }

  2431. /**
  2432. * 获取 SEO设置
  2433. * @param string $page 调用哪个页面的
  2434. * @param array $data 可替换数据
  2435. * @return array('seotitle', 'seodescription', 'seokeywords')
  2436. */
  2437. function get_seosetting($page, $data = array(), $defset = array()) {
  2438.         return helper_seo::get_seosetting($page, $data, $defset);
  2439. }

  2440. /**
  2441. *
  2442. * 生成缩略图文件名
  2443. * @param String $fileStr: 原文件名,允许附带路径
  2444. * @param String $extend: 新文件名后缀
  2445. * @param Boolean $holdOldExt: 是否保留原扩展名
  2446. * @return 返加新的后缀文件名
  2447. */
  2448. function getimgthumbname($fileStr, $extend='.thumb.jpg', $holdOldExt=true) {
  2449.         if(empty($fileStr)) {
  2450.                 return '';
  2451.         }
  2452.         //去掉原扩展名
  2453.         if(!$holdOldExt) {
  2454.                 $fileStr = substr($fileStr, 0, strrpos($fileStr, '.'));
  2455.         }
  2456.         $extend = strstr($extend, '.') ? $extend : '.'.$extend;
  2457.         return $fileStr.$extend;
  2458. }

  2459. /**
  2460. * 更新数据的审核状态
  2461. * @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
  2462. * @param <array/int> $ids ID 数组、ID 值
  2463. * @param <int> $status 状态 0=加入审核(默认) 1=忽略审核 2=审核通过
  2464. */
  2465. function updatemoderate($idtype, $ids, $status = 0) {
  2466.         helper_form::updatemoderate($idtype, $ids, $status);
  2467. }

  2468. /**
  2469. * 显示漫游应用公告
  2470. */
  2471. function userappprompt() {
  2472.         global $_G;

  2473.         if($_G['setting']['my_app_status'] && $_G['setting']['my_openappprompt'] && empty($_G['cookie']['userappprompt'])) {
  2474.                 $sid = $_G['setting']['my_siteid'];
  2475.                 $ts = $_G['timestamp'];
  2476.                 $key = md5($sid.$ts.$_G['setting']['my_sitekey']);
  2477.                 $uchId = $_G['uid'] ? $_G['uid'] : 0;
  2478.                 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>';
  2479.         }
  2480. }

  2481. /**
  2482. * 安全的 intval, 可以支持 int(10) unsigned
  2483. * 支持最大整数 0xFFFFFFFF 4294967295
  2484. * @param mixed $int string|int|array
  2485. * @return mixed
  2486. */
  2487. function dintval($int, $allowarray = false) {
  2488.         $ret = intval($int);
  2489.         if($int == $ret || !$allowarray && is_array($int)) return $ret;
  2490.         if($allowarray && is_array($int)) {
  2491.                 foreach($int as &$v) {
  2492.                         $v = dintval($v, true);
  2493.                 }
  2494.                 return $int;
  2495.         } elseif($int <= 0xffffffff) {
  2496.                 $l = strlen($int);
  2497.                 $m = substr($int, 0, 1) == '-' ? 1 : 0;
  2498.                 if(($l - $m) === strspn($int,'0987654321', $m)) {
  2499.                         return $int;
  2500.                 }
  2501.         }
  2502.         return $ret;
  2503. }


  2504. function makeSearchSignUrl() {
  2505.         return getglobal('setting/my_search_data/status') ? helper_manyou::makeSearchSignUrl() : array();
  2506. }

  2507. /**
  2508. * 获取批定类型的关联连接
  2509. *
  2510. * @param string $extent 内容所需关联链接范围 article, forum, group, blog
  2511. * @return string 有效的关联链接
  2512. */
  2513. function get_related_link($extent) {
  2514.         return helper_seo::get_related_link($extent);
  2515. }

  2516. /**
  2517. * 在给定内容中加入关联连接
  2518. *
  2519. * @param string $content 需要加入关联链接的内容
  2520. * @param string $extent 内容所需关联链接范围 article, forum, group, blog
  2521. * @return string 变更后的内容
  2522. */
  2523. function parse_related_link($content, $extent) {
  2524.         return helper_seo::parse_related_link($content, $extent);
  2525. }

  2526. function check_diy_perm($topic = array(), $flag = '') {
  2527.         static $ret;
  2528.         if(!isset($ret)) {
  2529.                 global $_G;
  2530.                 $common = !empty($_G['style']['tplfile']) || $_GET['inajax'];
  2531.                 $blockallow = getstatus($_G['member']['allowadmincp'], 4) || getstatus($_G['member']['allowadmincp'], 5) || getstatus($_G['member']['allowadmincp'], 6);
  2532.                 $ret['data'] = $common && $blockallow;
  2533.                 $ret['layout'] = $common && ($_G['group']['allowdiy'] || (
  2534.                                 CURMODULE === 'topic' && ($_G['group']['allowmanagetopic'] || $_G['group']['allowaddtopic'] && $topic && $topic['uid'] == $_G['uid'])
  2535.                                 ));
  2536.         }
  2537.         return empty($flag) ? $ret['data'] || $ret['layout'] : $ret[$flag];
  2538. }

  2539. function strhash($string, $operation = 'DECODE', $key = '') {
  2540.         $key = md5($key != '' ? $key : getglobal('authkey'));
  2541.         if($operation == 'DECODE') {
  2542.                 $hashcode = gzuncompress(base64_decode(($string)));
  2543.                 $string = substr($hashcode, 0, -16);
  2544.                 $hash = substr($hashcode, -16);
  2545.                 unset($hashcode);
  2546.         }

  2547.         $vkey = substr(md5($string.substr($key, 0, 16)), 4, 8).substr(md5($string.substr($key, 16, 16)), 18, 8);

  2548.         if($operation == 'DECODE') {
  2549.                 return $hash == $vkey ? $string : '';
  2550.         }

  2551.         return base64_encode(gzcompress($string.$vkey));
  2552. }

  2553. function dunserialize($data) {
  2554.         if(($ret = unserialize($data)) === false) {
  2555.                 $ret = unserialize(stripslashes($data));
  2556.         }
  2557.         return $ret;
  2558. }

  2559. function browserversion($type) {
  2560.         static $return = array();
  2561.         static $types = array('ie' => 'msie', 'firefox' => '', 'chrome' => '', 'opera' => '', 'safari' => '', 'mozilla' => '', 'webkit' => '', 'maxthon' => '', 'qq' => 'qqbrowser');
  2562.         if(!$return) {
  2563.                 $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
  2564.                 $other = 1;
  2565.                 foreach($types as $i => $v) {
  2566.                         $v = $v ? $v : $i;
  2567.                         if(strpos($useragent, $v) !== false) {
  2568.                                 preg_match('/'.$v.'(\/|\s)([\d\.]+)/i', $useragent, $matches);
  2569.                                 $ver = $matches[2];
  2570.                                 $other = $ver !== 0 && $v != 'mozilla' ? 0 : $other;
  2571.                         } else {
  2572.                                 $ver = 0;
  2573.                         }
  2574.                         $return[$i] = $ver;
  2575.                 }
  2576.                 $return['other'] = $other;
  2577.         }
  2578.         return $return[$type];
  2579. }

  2580. function currentlang() {
  2581.         $charset = strtoupper(CHARSET);
  2582.         if($charset == 'GBK') {
  2583.                 return 'SC_GBK';
  2584.         } elseif($charset == 'BIG5') {
  2585.                 return 'TC_BIG5';
  2586.         } elseif($charset == 'UTF-8') {
  2587.                 global $_G;
  2588.                 if($_G['config']['output']['language'] == 'zh_cn') {
  2589.                         return 'SC_UTF8';
  2590.                 } elseif ($_G['config']['output']['language'] == 'zh_tw') {
  2591.                         return 'TC_UTF8';
  2592.                 }
  2593.         } else {
  2594.                 return '';
  2595.         }
  2596. }

  2597. /*
  2598. * 尽量不要在此文件中添加全局函数
  2599. * 请在source/class/helper/目录下创建相应的静态函数集类文件
  2600. * 类的静态方法可以在产品中所有地方使用,使用方法类似:helper_form::submitcheck()
  2601. *
  2602. */

  2603. ?>
复制代码


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

本版积分规则