找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4757|回复: 0

[内置扩展] Discuz x3.5 核心文件 function/function_forum.php 函数注释

[复制链接]
发表于 2024-6-23 13:20:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
[PHP] 纯文本查看 复制代码
<?php

/**
 *      [Discuz!] (C)2001-2099 Comsenz Inc.
 *      This is NOT a freeware, use is subject to license terms
 *
 *      $Id: function_forum.php 36345 2017-01-12 01:55:04Z nemohou $
 */

if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}
/**
 * 获取指定用户的Discuz!头像
 *
 * @param int $uid 用户ID
 * @param string $size 头像大小,可选参数,默认为空,代表默认大小
 * @param bool $returnsrc 是否返回头像的URL而不是直接输出,默认为FALSE
 * @return mixed 如果 $returnsrc 为 TRUE,则返回头像URL;否则直接输出头像
 */
function discuz_uc_avatar($uid, $size = '', $returnsrc = FALSE) {
    global $_G;
    return avatar($uid, $size, $returnsrc, FALSE, $_G['setting']['avatarmethod'], $_G['setting']['ucenterurl']);
}

/**
 * 删除指定附件
 *
 * @param array $attach 包含附件信息的数组
 * @return void
 */
function dunlink($attach) {
    global $_G;
    $filename = $attach['attachment'];
    $havethumb = $attach['thumb'];
    $remote = $attach['remote'];
    if($remote) {
        ftpcmd('delete', 'forum/'.$filename);
        $havethumb && ftpcmd('delete', 'forum/'.getimgthumbname($filename));
    } else {
        @unlink($_G['setting']['attachdir'].'/forum/'.$filename);
        $havethumb && @unlink($_G['setting']['attachdir'].'/forum/'.getimgthumbname($filename));
    }
    if($attach['aid']) {
        @unlink($_G['setting']['attachdir'].'image/'.$attach['aid'].'_100_100.jpg');
    }
}

/**
 * 根据给定的权限公式判断用户是否有访问权限
 *
 * @param string $formula 权限公式,可以是序列化的公式信息
 * @return bool 如果用户有权限,则返回TRUE;否则返回FALSE
 */
function formulaperm($formula) {
    global $_G;
    // 初步检查,如果是版主或者管理员,则直接通过
    if($_G['forum']['ismoderator']) {
        return TRUE;
    }

    $formula = dunserialize($formula);
    $medalperm = $formula['medal'];
    $permusers = $formula['users'];
    $permmessage = $formula['message'];
    // 检查是否启用了勋章权限控制
    if($_G['setting']['medalstatus'] && $medalperm) {
        $exists = 1;
        $_G['forum_formulamessage'] = '';
        $medalpermc = $medalperm;
        if($_G['uid']) {
            $memberfieldforum = C::t('common_member_field_forum')->fetch($_G['uid']);
            $medals = explode("\t", $memberfieldforum['medals']);
            unset($memberfieldforum);
            foreach($medalperm as $k => $medal) {
                foreach($medals as $r) {
                    list($medalid) = explode("|", $r);
                    if($medalid == $medal) {
                        $exists = 0;
                        unset($medalpermc[$k]);
                    }
                }
            }
        } else {
            $exists = 0;
        }
        if($medalpermc) {
            loadcache('medals');
            foreach($medalpermc as $medal) {
                if($_G['cache']['medals'][$medal]) {
                    $_G['forum_formulamessage'] .= '<img src="'.$_G['cache']['medals'][$medal]['image'].'" style="vertical-align:middle;" />&nbsp;'.$_G['cache']['medals'][$medal]['name'].'&nbsp; ';
                }
            }
            showmessage('forum_permforum_nomedal', NULL, array('forum_permforum_nomedal' => $_G['forum_formulamessage']), array('login' => 1));
        }
    }
    $formulatext = $formula[0];
    $formula = trim($formula[1]);
    // 检查是否为管理员或者版主,或者用户组有特殊权限
    if($_G['adminid'] == 1 || $_G['forum']['ismoderator'] || in_array($_G['groupid'], explode("\t", $_G['forum']['spviewperm']))) {
        return FALSE;
    }
    if($permusers) {
        $permusers = str_replace(array("\r\n", "\r"), array("\n", "\n"), $permusers);
        $permusers = explode("\n", trim($permusers));
        if(!in_array($_G['member']['username'], $permusers)) {
            showmessage('forum_permforum_disallow', NULL, array(), array('login' => 1));
        }
    }
    if(!$formula) {
        return FALSE;
    }
    // 对公式进行解析和计算,以判断用户是否有访问权限
    if(strexists($formula, '$memberformula[')) {
        preg_match_all("/\\\$memberformula\['(\w+?)'\]/", $formula, $a);
        $profilefields = array();
        foreach($a[1] as $field) {
            switch($field) {
                case 'regdate':
                    $formula = preg_replace_callback("/\{(\d{4})\-(\d{1,2})\-(\d{1,2})\}/", 'formulaperm_callback_123', $formula);
                case 'regday':
                    break;
                case 'regip':
                case 'lastip':
                    $formula = preg_replace("/\{([0-9a-fA-F\.\:\/]+?)\}/", "'\\1'", $formula);
                    $formula = preg_replace('/(\$memberformula\[\'(regip|lastip)\'\])\s*=+\s*\'([0-9a-fA-F\.\:\/]+?)\'/', "ip::check_ip(\\1, '\\3')", $formula);
                case 'buyercredit':
                case 'sellercredit':
                    space_merge($_G['member'], 'status');break;
                case substr($field, 0, 5) == 'field':
                    space_merge($_G['member'], 'profile');
                    $profilefields[] = $field;break;
            }
        }
        $memberformula = array();
        if($_G['uid']) {
            $memberformula = $_G['member'];
            if(in_array('regday', $a[1])) {
                $memberformula['regday'] = intval((TIMESTAMP - $memberformula['regdate']) / 86400);
            }
            if(in_array('regdate', $a[1])) {
                $memberformula['regdate'] = date('Y-m-d', $memberformula['regdate']);
            }
            $memberformula['lastip'] = $memberformula['lastip'] ? $memberformula['lastip'] : $_G['clientip'];
        } else {
            if(isset($memberformula['regip'])) {
                $memberformula['regip'] = $_G['clientip'];
            }
            if(isset($memberformula['lastip'])) {
                $memberformula['lastip'] = $_G['clientip'];
            }
        }
    }
    @eval("\$formulaperm = ($formula) ? TRUE : FALSE;");
    if(!$formulaperm) {
        if(!$permmessage) {
            $language = lang('forum/misc');
            $search = array('regdate', 'regday', 'regip', 'lastip', 'buyercredit', 'sellercredit', 'digestposts', 'posts', 'threads', 'oltime');
            $replace = array($language['formulaperm_regdate'], $language['formulaperm_regday'], $language['formulaperm_regip'], $language['formulaperm_lastip'], $language['formulaperm_buyercredit'], $language['formulaperm_sellercredit'], $language['formulaperm_digestposts'], $language['formulaperm_posts'], $language['formulaperm_threads'], $language['formulaperm_oltime']);
            for($i = 1; $i <= 8; $i++) {
                $search[] = 'extcredits'.$i;
                $replace[] = $_G['setting']['extcredits'][$i]['title'] ? $_G['setting']['extcredits'][$i]['title'] : $language['formulaperm_extcredits'].$i;
            }
            if($profilefields) {
                loadcache(array('fields_required', 'fields_optional'));
                foreach($profilefields as $profilefield) {
                    $search[] = $profilefield;
                    $replace[] = !empty($_G['cache']['fields_optional']['field_'.$profilefield]) ? $_G['cache']['fields_optional']['field_'.$profilefield]['title'] : $_G['cache']['fields_required']['field_'.$profilefield]['title'];
                }
            }
            $i = 0;$_G['forum_usermsg'] = '';
            foreach($search as $s) {
                if(in_array($s, array('digestposts', 'posts', 'threads', 'oltime', 'extcredits1', 'extcredits2', 'extcredits3', 'extcredits4', 'extcredits5', 'extcredits6', 'extcredits7', 'extcredits8'))) {
                    $_G['forum_usermsg'] .= strexists($formulatext, $s) ? '<br />&nbsp;&nbsp;&nbsp;'.$replace[$i].': '.(@eval('return intval(getuserprofile(\''.$s.'\'));')) : '';
                } elseif(in_array($s, array('regdate', 'regip', 'regday'))) {
                    $_G['forum_usermsg'] .= strexists($formulatext, $s) ? '<br />&nbsp;&nbsp;&nbsp;'.$replace[$i].': '.(@eval('return $memberformula[\''.$s.'\'];')) : '';
                }
                $i++;
            }
            $search = array_merge($search, array('and', 'or', '>=', '<=', '=='));
            $replace = array_merge($replace, array('&nbsp;&nbsp;<b>'.$language['formulaperm_and'].'</b>&nbsp;&nbsp;', '&nbsp;&nbsp;<b>'.$language['formulaperm_or'].'</b>&nbsp;&nbsp;', '&ge;', '&le;', '='));
            $_G['forum_formulamessage'] = str_replace($search, $replace, $formulatext);
        } else {
            $_G['forum_formulamessage'] = $permmessage;
        }

        if(!$permmessage) {
            showmessage('forum_permforum_nopermission', NULL, array('formulamessage' => $_G['forum_formulamessage'], 'usermsg' => $_G['forum_usermsg']), array('login' => 1));
        } else {
            showmessage('forum_permforum_nopermission_custommsg', NULL, array('formulamessage' => $_G['forum_formulamessage']), array('login' => 1));
        }
    }
    return TRUE;
}
/**
 * 根据给定的公式和类型,计算用户是否满足获得勋章的条件。
 *
 * @param string $formula 勋章获得的计算公式,可以包含各种条件和运算符。
 * @param int $type 计算类型,1代表检查是否满足获得条件,2代表检查是否满足保留条件。
 * @return mixed 如果用户满足条件,返回false;如果不满足条件,返回提示信息的字符串。
 */
function medalformulaperm($formula, $type) {
    global $_G;

    // 解序列化公式字符串,获取公式配置
    $formula = dunserialize($formula);
    $permmessage = $formula['message'];
    $formula = $formula['medal'];

    // 检查用户组是否被允许获得该勋章
    if(!empty($formula['usergroupallow']) && is_array($formula['usergroups']) && !in_array($_G['groupid'], $formula['usergroups'])) {
        loadcache('usergroups');
        // 如果用户组不允许,返回相应的用户组权限提示信息
        $message = array();
        foreach($formula['usergroups'] as $groupid) {
            $message[] = $_G['cache']['usergroups'][$groupid]['grouptitle'].' ';
        }
        $_G['forum_formulamessage'] = implode(', ', $message);
        $_G['forum_usermsg'] = $_G['cache']['usergroups'][$_G['groupid']]['grouptitle'];
        return FALSE;
    }

    $formulatext = $formula[0];
    $formula = $formula[1];
    if(!$formula) {
        return FALSE;
    }

    // 处理公式中的$memberformula变量
    if(strexists($formula, '$memberformula[')) {
        preg_match_all("/\\\$memberformula\['(\w+?)'\]/", $formula, $a);
        $profilefields = array();
        foreach($a[1] as $field) {
            switch($field) {
                case 'regdate':
                    $formula = preg_replace_callback("/\{(\d{4})\-(\d{1,2})\-(\d{1,2})\}/", 'medalformulaperm_callback_123', $formula);
                case 'regday':
                    break;
                case 'regip':
                case 'lastip':
                    $formula = preg_replace("/\{([0-9a-fA-F\.\:\/]+?)\}/", "'\\1'", $formula);
                    $formula = preg_replace('/(\$memberformula\[\'(regip|lastip)\'\])\s*=+\s*\'([0-9a-fA-F\.\:\/]+?)\'/', "ip::check_ip(\\1, '\\3')", $formula);
                case 'buyercredit':
                case 'sellercredit':
                    space_merge($_G['member'], 'status');break;
                case substr($field, 0, 5) == 'field':
                    space_merge($_G['member'], 'profile');
                    $profilefields[] = $field;break;
            }
        }
        $memberformula = array();
        if($_G['uid']) {
            $memberformula = $_G['member'];
            if(in_array('regday', $a[1])) {
                $memberformula['regday'] = intval((TIMESTAMP - $memberformula['regdate']) / 86400);
            }
            if(in_array('regdate', $a[1])) {
                $memberformula['regdate'] = date('Y-m-d', $memberformula['regdate']);
            }
            $memberformula['lastip'] = $memberformula['lastip'] ? $memberformula['lastip'] : $_G['clientip'];
        } else {
            if(isset($memberformula['regip'])) {
                $memberformula['regip'] = $_G['clientip'];
            }
            if(isset($memberformula['lastip'])) {
                $memberformula['lastip'] = $_G['clientip'];
            }
        }
    }

    // 评估公式,并根据结果和类型返回相应的值
    @eval("\$formulaperm = ($formula) ? TRUE : FALSE;");
    if(!$formulaperm || $type == 1) {
        if(!$permmessage) {
            $language = lang('forum/misc');
            $search = array('regdate', 'regday', 'regip', 'lastip', 'buyercredit', 'sellercredit', 'digestposts', 'posts', 'threads', 'oltime');
            $replace = array($language['formulaperm_regdate'], $language['formulaperm_regday'], $language['formulaperm_regip'], $language['formulaperm_lastip'], $language['formulaperm_buyercredit'], $language['formulaperm_sellercredit'], $language['formulaperm_digestposts'], $language['formulaperm_posts'], $language['formulaperm_threads'], $language['formulaperm_oltime']);
            for($i = 1; $i <= 8; $i++) {
                $search[] = 'extcredits'.$i;
                $replace[] = $_G['setting']['extcredits'][$i]['title'] ? $_G['setting']['extcredits'][$i]['title'] : $language['formulaperm_extcredits'].$i;
            }
            if($profilefields) {
                loadcache(array('fields_required', 'fields_optional'));
                foreach($profilefields as $profilefield) {
                    $search[] = $profilefield;
                    $replace[] = !empty($_G['cache']['fields_optional']['field_'.$profilefield]) ? $_G['cache']['fields_optional']['field_'.$profilefield]['title'] : $_G['cache']['fields_required']['field_'.$profilefield]['title'];
                }
            }
            $i = 0;$_G['forum_usermsg'] = '';
            foreach($search as $s) {
                if(in_array($s, array('digestposts', 'posts', 'threads', 'oltime', 'extcredits1', 'extcredits2', 'extcredits3', 'extcredits4', 'extcredits5', 'extcredits6', 'extcredits7', 'extcredits8'))) {
                    $_G['forum_usermsg'] .= strexists($formulatext, $s) ? '<br />&nbsp;&nbsp;&nbsp;'.$replace[$i].': '.(@eval('return intval(getuserprofile(\''.$s.'\'));')) : '';
                } elseif(in_array($s, array('regdate', 'regip'))) {
                    $_G['forum_usermsg'] .= strexists($formulatext, $s) ? '<br />&nbsp;&nbsp;&nbsp;'.$replace[$i].': '.(@eval('return $memberformula[\''.$s.'\'];')) : '';
                }
                $i++;
            }
            $search = array_merge($search, array('and', 'or', '>=', '<=', '=='));
            $replace = array_merge($replace, array('&nbsp;&nbsp;<b>'.$language['formulaperm_and'].'</b>&nbsp;&nbsp;', '&nbsp;&nbsp;<b>'.$language['formulaperm_or'].'</b>&nbsp;&nbsp;', '&ge;', '&le;', '='));
            $permmessage = str_replace($search, $replace, $formulatext);
        }
        if(!$formulaperm) {
            $_G['forum_formulamessage'] = $permmessage;
        }

        return $permmessage;
    } elseif($formulaperm && $type == 2) {
        return FALSE;
    }
    return TRUE;
}

/**
 * 用于公式中处理日期格式的回调函数。
 *
 * @param array $matches 正则匹配到的内容数组。
 * @return string 返回格式化后的日期字符串。
 */
function formulaperm_callback_123($matches) {
    return '\''.$matches[1].'-'.sprintf('%02d', $matches[2]).'-'.sprintf('%02d', $matches[3]).'\'';
}

/**
 * 计算用户组过期时间。
 *
 * @param array $terms 包含用户组过期条件的数组。
 * @return int 返回用户组的最短过期时间。
 */
function groupexpiry($terms) {
    $terms = is_array($terms) ? $terms : dunserialize($terms);
    $groupexpiry = isset($terms['main']['time']) ? intval($terms['main']['time']) : 0;
    if(is_array($terms['ext'])) {
        foreach($terms['ext'] as $expiry) {
            if((!$groupexpiry && $expiry) || $expiry < $groupexpiry) {
                $groupexpiry = $expiry;
            }
        }
    }
    return $groupexpiry;
}

/**
 * 生成论坛主题类型的下拉选择菜单。
 *
 * @param int $curtypeid 当前选择的类型ID。
 * @return string 返回包含选择菜单的HTML代码。
 */
function typeselect($curtypeid = 0) {
    global $_G;
    if($threadtypes = $_G['forum']['threadtypes']) {
        $html = '<select name="typeid" id="typeid"><option value="0">&nbsp;</option>';
        foreach($threadtypes['types'] as $typeid => $name) {
            $html .= '<option value="'.$typeid.'" '.($curtypeid == $typeid ? 'selected' : '').'>'.strip_tags($name).'</option>';
        }
        $html .= '</select>';
        return $html;
    } else {
        return '';
    }
}

/**
 * 更新版主操作记录。
 *
 * @param string $modaction 版主操作的类型。
 * @param int $posts 操作涉及的帖子数量,默认为1。
 */
function updatemodworks($modaction, $posts = 1) {
    global $_G;
    $today = dgmdate(TIMESTAMP, 'Y-m-d');
    if($_G['setting']['modworkstatus'] && $modaction && $posts) {
        $affect_rows = C::t('forum_modwork')->increase_count_posts_by_uid_modaction_dateline(1, $posts, $_G['uid'], $modaction, $today);
        if(!$affect_rows) {
            C::t('forum_modwork')->insert(array(
                'uid' => $_G['uid'],
                'modaction' => $modaction,
                'dateline' => $today,
                'count' => 1,
                'posts' => $posts,
            ));
        }
    }
}
/**
 * 构建SQL语句的特定部分,用于更新指定字段的位状态。
 *
 * @param string $fieldname 要操作的数据库字段名。
 * @param int $position 指定位子字段的位置。
 * @param bool $value 指定要设置的状态值,true为启用,false为禁用。
 * @return string 返回构建的SQL更新语句部分。
 */
function buildbitsql($fieldname, $position, $value) {
    // 初始化SQL片段,准备设置字段值
    $t = " `$fieldname`=`$fieldname`";
    // 根据$value的真伪,选择性地添加设置状态的语句
    if($value) {
        $t .= ' | '.setstatus($position, 1); // 启用状态
    } else {
        $t .= ' & '.setstatus($position, 0); // 禁用状态
    }
    // 返回完整的SQL语句部分
    return $t.' ';
}

/**
 * 显示用户没有权限的消息
 *
 * @param string $type 操作类型,对应不同的权限
 * @param int $fid 论坛版块ID
 * @param string $formula 权限公式,可选,用于自定义权限消息
 * @global array $_G 全局变量数组
 * @return void 无返回值,直接输出消息并终止执行
 */
function showmessagenoperm($type, $fid, $formula = '') {
    global $_G;
    loadcache('usergroups'); // 加载用户组缓存

    // 如果存在权限公式,则解析并获取自定义权限消息
    if($formula) {
        $formula = dunserialize($formula);
        $permmessage = stripslashes($formula['message']);
    }

    // 初始化用户组、无权限用户组和论坛权限数组
    $usergroups = $nopermgroup = $forumnoperms = array();
    // 默认无权限设置
    $nopermdefault = array(
        'viewperm' => array(),
        'getattachperm' => array(),
        'postperm' => array(7),
        'replyperm' => array(7),
        'postattachperm' => array(7),
    );
    // 权限类型数组
    $perms = array('viewperm', 'postperm', 'replyperm', 'getattachperm', 'postattachperm');

    // 根据用户组类型分配权限
    foreach($_G['cache']['usergroups'] as $gid => $usergroup) {
        $usergroups[$gid] = $usergroup['type'];
        $grouptype = $usergroup['type'] == 'member' ? 0 : 1;
        $nopermgroup[$grouptype][] = $gid;
    }

    // 获取当前论坛版块信息
    if($fid == $_G['forum']['fid']) {
        $forum = $_G['forum'];
    } else {
        $forum = C::t('forum_forumfield')->fetch($fid);
    }

    // 遍历权限类型,获取每个类型的具体权限设置
    foreach($perms as $perm) {
        $permgroups = explode("\t", $forum[$perm]);
        $membertype = $forum[$perm] ? array_intersect($nopermgroup[0], $permgroups) : TRUE;
        $forumnoperm = $forum[$perm] ? array_diff(array_keys($usergroups), $permgroups) : $nopermdefault[$perm];
        foreach($forumnoperm as $groupid) {
            $nopermtype = $membertype && $groupid == 7 ? 'login' : ($usergroups[$groupid] == 'system' || $usergroups[$groupid] == 'special' ? 'none' : ($membertype ? 'upgrade' : 'none'));
            $forumnoperms[$fid][$perm][$groupid] = array($nopermtype, $permgroups);
        }
    }

    // 获取当前用户组的权限信息,用于显示
    $v = $forumnoperms[$fid][$type][$_G['groupid']][0];
    $gids = $forumnoperms[$fid][$type][$_G['groupid']][1];
    $comma = $permgroups = '';
    // 拼接具有权限的用户组名称或验证类型名称
    if(is_array($gids)) {
        foreach($gids as $gid) {
            if($gid && $_G['cache']['usergroups'][$gid]) {
                $permgroups .= $comma.$_G['cache']['usergroups'][$gid]['grouptitle'];
                $comma = ', ';
            } elseif($_G['setting']['verify']['enabled'] && substr($gid, 0, 1) == 'v') {
                $vid = substr($gid, 1);
                $permgroups .= $comma.$_G['setting']['verify'][$vid]['title'];
                $comma = ', ';
            }
        }
    }

    // 判断是否使用自定义消息
    $custom = 0;
    if($permmessage) {
        $message = $permmessage;
        $custom = 1;
    } else {
        // 根据权限设置获取系统消息
        if($v) {
            $message = $type.'_'.$v.'_nopermission';
        } else {
            $message = 'group_nopermission';
        }
    }

    // 显示权限消息
    showmessage($message, NULL, array('fid' => $fid, 'permgroups' => $permgroups, 'grouptitle' => $_G['group']['grouptitle']), array('login' => 1), $custom);
}
/**
 * 加载论坛板块或主题
 *
 * 本函数用于根据提供的板块ID(fid)或主题ID(tid)加载相应的论坛数据。
 * 如果没有提供fid或tid,将尝试从全局变量或GET请求中获取。
 *
 * @param int $fid 板块ID,如果未提供,则尝试从GET请求中获取
 * @param int $tid 主题ID,如果未提供,则尝试从GET请求中获取
 * @global array $_G 全局变量数组
 * @return void
 */
function loadforum($fid = null, $tid = null) {
	global $_G;

	// 尝试从参数或GET请求中获取主题ID,并转换为整数
	$tid = intval(isset($tid) ? $tid : getgpc('tid'));

	// 如果提供了板块ID,则转换为整数,否则从GET请求中获取
	if(isset($fid)) {
		$fid = intval($fid);
	} else {
		$fid = getgpc('fid');
		// 如果未获取到板块ID,且GET请求中存在群组ID(gid),则尝试使用群组ID
		if(!$fid && getgpc('gid')) {
			$fid = intval(getgpc('gid'));
		}
	}


	if(isset($_G['forum']['fid']) && $_G['forum']['fid'] == $fid || isset($_G['thread']['tid']) && $_G['thread']['tid'] == $tid){
		return null;
	}
	if(!empty($_GET['archiver'])) {//X1.5的Archiver兼容
		if($fid) {
			dheader('location: archiver/?fid-'.$fid.'.html');
		} elseif($tid) {
			dheader('location: archiver/?tid-'.$tid.'.html');
		} else {
			dheader('location: archiver/');
		}
	}
	if(defined('IN_ARCHIVER') && $_G['setting']['archiverredirect'] && !IS_ROBOT) {
		dheader('location: ../forum.php'.($_G['mod'] ? '?mod='.$_G['mod'].(!empty($_GET['fid']) ? '&fid='.$_GET['fid'] : (!empty($_GET['tid']) ? '&tid='.$_GET['tid'] : '')) : ''));
	}
	if(isset($_G['setting']['forumpicstyle'])) {
		$_G['setting']['forumpicstyle'] = dunserialize($_G['setting']['forumpicstyle']);
		empty($_G['setting']['forumpicstyle']['thumbwidth']) && $_G['setting']['forumpicstyle']['thumbwidth'] = 203;
		empty($_G['setting']['forumpicstyle']['thumbheight']) && $_G['setting']['forumpicstyle']['thumbheight'] = 0;
	} else {
		$_G['setting']['forumpicstyle'] = array('thumbwidth' => 203, 'thumbheight' => 0);
	}
	if($fid) {
		$fid = is_numeric($fid) ? intval($fid) : (!empty($_G['setting']['forumfids'][$fid]) ? $_G['setting']['forumfids'][$fid] : 0);
	}

	$modthreadkey = isset($_GET['modthreadkey']) && $_GET['modthreadkey'] == modauthkey($tid) ? $_GET['modthreadkey'] : '';
	$_G['forum_auditstatuson'] = $modthreadkey ? true : false;

	$metadescription = $hookscriptmessage = '';
	$adminid = $_G['adminid'];

	if(!empty($tid) || !empty($fid)) {

		if(!empty ($tid)) {
			$archiveid = !empty($_GET['archiveid']) ? intval($_GET['archiveid']) : null;
			$_G['thread'] = get_thread_by_tid($tid, $archiveid);
			$_G['thread']['allreplies'] = $_G['thread']['replies'] + $_G['thread']['comments'];
			if(!$_G['forum_auditstatuson'] && !empty($_G['thread'])
					&& !($_G['thread']['displayorder'] >= 0 || (in_array($_G['thread']['displayorder'], array(-4,-3,-2)) && $_G['uid'] && $_G['thread']['authorid'] == $_G['uid']))) {
				$_G['thread'] = null;
			}

			$_G['forum_thread'] = & $_G['thread'];

			if(empty($_G['thread'])) {
				$fid = $tid = 0;
			} else {
				$fid = $_G['thread']['fid'];
				$tid = $_G['thread']['tid'];
			}
		}

		if($fid) {
			$forum = C::t('forum_forum')->fetch_info_by_fid($fid);
		}

		if($forum) {
			if($_G['uid']) {
				if($_G['member']['accessmasks']) {
					$query = C::t('forum_access')->fetch_all_by_fid_uid($fid, $_G['uid']);
					$forum['allowview'] = $query[0]['allowview'];
					$forum['allowpost'] = $query[0]['allowpost'];
					$forum['allowreply'] = $query[0]['allowreply'];
					$forum['allowgetattach'] = $query[0]['allowgetattach'];
					$forum['allowgetimage'] = $query[0]['allowgetimage'];
					$forum['allowpostattach'] = $query[0]['allowpostattach'];
					$forum['allowpostimage'] = $query[0]['allowpostimage'];
				}
				if($adminid == 3) {
					$forum['ismoderator'] = C::t('forum_moderator')->fetch_uid_by_fid_uid($fid, $_G['uid']);
				}
			}
			$forum['ismoderator'] = !empty($forum['ismoderator']) || $adminid == 1 || $adminid == 2 ? 1 : 0;
			$fid = $forum['fid'];
			$gorup_admingroupids = $_G['setting']['group_admingroupids'] ? dunserialize($_G['setting']['group_admingroupids']) : array('1' => '1');

			if($forum['status'] == 3) {
				if(!empty($forum['moderators'])) {
					$forum['moderators'] = dunserialize($forum['moderators']);
				} else {
					require_once libfile('function/group');
					$forum['moderators'] = update_groupmoderators($fid);
				}
				if($_G['uid'] && $_G['adminid'] != 1) {
					$forum['ismoderator'] = !empty($forum['moderators'][$_G['uid']]) ? 1 : 0;
					$_G['adminid'] = 0;
					if($forum['ismoderator'] || $gorup_admingroupids[$_G['groupid']]) {
						$_G['adminid'] = $_G['adminid'] ? $_G['adminid'] : 3;
						if(!empty($gorup_admingroupids[$_G['groupid']])) {
							$forum['ismoderator'] = 1;
							$_G['adminid'] = 2;
						}

						$group_userperm = dunserialize($_G['setting']['group_userperm']);
						if(is_array($group_userperm)) {
							$_G['group'] = array_merge($_G['group'], $group_userperm);
							$_G['group']['allowmovethread'] = $_G['group']['allowcopythread'] = $_G['group']['allowedittypethread']= 0;
						}
					}
				}
			}
			foreach(array('threadtypes', 'threadsorts', 'creditspolicy', 'modrecommend') as $key) {
				$forum[$key] = !empty($forum[$key]) ? dunserialize($forum[$key]) : array();
				if(!is_array($forum[$key])) {
					$forum[$key] = array();
				}
			}

			if(!empty($forum['threadtypes']['types'])) {
				safefilter($forum['threadtypes']['types']);
			}
			if(!empty($forum['threadtypes']['options']['name'])) {
				safefilter($forum['threadtypes']['options']['name']);
			}
			if(!empty($forum['threadsorts']['types'])) {
				safefilter($forum['threadsorts']['types']);
			}

			if($forum['status'] == 3) {
				$_G['isgroupuser'] = 0;
				$_G['basescript'] = 'group';
				if($forum['level'] == 0) {
					$levelinfo = C::t('forum_grouplevel')->fetch_by_credits($forum['commoncredits']);
					$levelid = $levelinfo['levelid'];
					$forum['level'] = $levelid;
					C::t('forum_forum')->update_group_level($levelid, $fid);
				}
				if($forum['level'] != -1) {
					loadcache('grouplevels');
					$grouplevel = $_G['grouplevels'][$forum['level']];
					if(!empty($grouplevel['icon'])) {
						$valueparse = parse_url($grouplevel['icon']);
						if(!isset($valueparse['host'])) {
							$grouplevel['icon'] = $_G['setting']['attachurl'].'common/'.$grouplevel['icon'];
						}
					}
				}

				$group_postpolicy = $grouplevel['postpolicy'];
				if(is_array($group_postpolicy)) {
					$forum = array_merge($forum, $group_postpolicy);
				}
				$forum['allowfeed'] = $_G['setting']['group_allowfeed'];
				if($_G['uid']) {
					if(!empty($forum['moderators'][$_G['uid']])) {
						$_G['isgroupuser'] = 1;
					} else {
						$groupuserinfo = C::t('forum_groupuser')->fetch_userinfo($_G['uid'], $fid);
						$_G['isgroupuser'] = $groupuserinfo['level'];
						if($_G['isgroupuser'] <= 0 && empty($forum['ismoderator'])) {
							$_G['group']['allowrecommend'] = $_G['cache']['usergroup_'.$_G['groupid']]['allowrecommend'] = 0;
							$_G['group']['allowcommentpost'] = $_G['cache']['usergroup_'.$_G['groupid']]['allowcommentpost'] = 0;
							$_G['group']['allowcommentitem'] = $_G['cache']['usergroup_'.$_G['groupid']]['allowcommentitem'] = 0;
							$_G['group']['raterange'] = $_G['cache']['usergroup_'.$_G['groupid']]['raterange'] = array();
							$_G['group']['allowvote'] = $_G['cache']['usergroup_'.$_G['groupid']]['allowvote'] = 0;
						} else {
							$_G['isgroupuser'] = 1;
						}
					}
				}
			}
		} else {
			$fid = 0;
		}
	}

	$_G['fid'] = $fid;
	$_G['tid'] = $tid;
	$_G['forum'] = &$forum;
	$_G['current_grouplevel'] = &$grouplevel;

	if(empty($_G['uid'])) {
		$_G['group']['allowpostactivity'] = $_G['group']['allowpostpoll'] = $_G['group']['allowvote'] = $_G['group']['allowpostreward'] = $_G['group']['allowposttrade'] = $_G['group']['allowpostdebate'] = $_G['group']['allowpostrushreply'] = 0;
	}
	if(!empty($_G['forum']['widthauto'])) {
		$_G['widthauto'] = $_G['forum']['widthauto'];
	}
}
/**
 * 根据主题ID获取主题信息
 *
 * @param int $tid 主题ID
 * @param null $forcetableid 强制使用的表ID,如果为null,则自动判断
 * @return array 返回主题信息数组,如果找不到则返回空数组
 */
function get_thread_by_tid($tid, $forcetableid = null) {
    global $_G;

    $ret = array();
    // 检查tid是否为数字
    if(!is_numeric($tid)) {
        return $ret;
    }
    // 加载主题表ID的缓存
    loadcache('threadtableids');
    $threadtableids = array(0);
    // 处理表ID的选择
    if(!empty($_G['cache']['threadtableids'])) {
        if($forcetableid === null || ($forcetableid > 0 && !in_array($forcetableid, $_G['cache']['threadtableids']))) {
            $threadtableids = array_merge($threadtableids, $_G['cache']['threadtableids']);
        } else {
            $threadtableids = array(intval($forcetableid));
        }
    }
    // 去重并遍历每个表ID查询主题信息
    $threadtableids = array_unique($threadtableids);
    foreach($threadtableids as $tableid) {
        $tableid = $tableid > 0 ? $tableid : 0;
        $ret = C::t('forum_thread')->fetch_thread($tid, $tableid);
        // 如果找到主题信息,处理并返回
        if($ret) {
            $ret['threadtable'] = C::t('forum_thread')->get_table_name($tableid);
            $ret['threadtableid'] = $tableid;
            $ret['posttable'] = 'forum_post'.($ret['posttableid'] ? '_'.$ret['posttableid'] : '');
            break;
        }
    }

    // 如果未找到主题信息,返回空数组,或者根据设置优化视图
    if(!is_array($ret)) {
        $ret = array();
    } elseif(getglobal('setting/optimizeviews')) {
        if(($row = C::t('forum_threadaddviews')->fetch($tid))) {
            $ret['addviews'] = intval($row['addviews']);
            $ret['views'] += $ret['addviews'];
        }
    }

    return $ret;
}

/**
 * 根据帖子ID获取帖子信息
 *
 * @param int $pid 帖子ID
 * @param string $fields 需要查询的字段,默认为'*'
 * @param string $addcondiction 添加的查询条件,默认为空
 * @param null $forcetable 强制使用的表名或表ID,如果为null,则自动判断
 * @return array 返回帖子信息数组,如果找不到则返回空数组
 */
function get_post_by_pid($pid, $fields = '*', $addcondiction = '', $forcetable = null) {
    global $_G;

    $ret = array();
    // 检查pid是否为数字
    if(!is_numeric($pid)) {
        return $ret;
    }

    // 加载帖子表信息缓存
    loadcache('posttable_info');

    $posttableids = array(0);
    // 处理表ID的选择
    if($_G['cache']['posttable_info']) {
        if(isset($forcetable)) {
            if(is_numeric($forcetable) && array_key_exists($forcetable, $_G['cache']['posttable_info'])) {
                $posttableids[] = $forcetable;
            } elseif(substr($forcetable, 0, 10) == 'forum_post') {
                $posttableids[] = $forcetable;
            }
        } else {
            $posttableids = array_keys($_G['cache']['posttable_info']);
        }
    }

    // 遍历每个表ID查询帖子信息
    foreach ($posttableids as $id) {
        $table = empty($id) ? 'forum_post' : (is_numeric($id) ? 'forum_post_'.$id : $id);
        $ret = C::t('forum_post')->fetch_by_pid_condition($id, $pid, $addcondiction, $fields);
        // 如果找到帖子信息,处理并返回
        if($ret) {
            $ret['posttable'] = $table;
            break;
        }
    }

    // 如果未找到帖子信息,返回空数组
    if(!is_array($ret)) {
        $ret = array();
    }

    return $ret;
}

/**
 * 根据主题ID和帖子ID获取帖子信息
 *
 * @param int $tid 主题ID
 * @param int $pid 帖子ID
 * @return array 返回帖子信息数组
 */
function get_post_by_tid_pid($tid, $pid) {
    static $postlist = array();
    if(empty($postlist[$pid])) {
        // 从数据库获取帖子信息
        $postlist[$pid] = C::t('forum_post')->fetch_post('tid:'.$tid, $pid, false);
        if($postlist[$pid] && $postlist[$pid]['tid'] == $tid) {
            // 获取帖子作者信息并更新到帖子信息中
            $user = getuserbyuid($postlist[$pid]['authorid']);
            $postlist[$pid]['adminid'] = $user['adminid'];
        } else {
            $postlist[$pid] = array();
        }
    }
    return $postlist[$pid];
}

/**
 * 设置RSS认证信息
 */
function set_rssauth() {
    global $_G;
    // 检查是否开启RSS功能并且用户已登录
    if($_G['setting']['rssstatus'] && $_G['uid']) {
        $auth = authcode($_G['uid']."\t".($_G['fid'] ? $_G['fid'] : '').
        "\t".substr(md5($_G['member']['password']), 0, 8), 'ENCODE', md5($_G['config']['security']['authkey']));
    } else {
        $auth = '0';
    }
    $_G['rssauth'] = rawurlencode($auth);
}

/**
 * 检查论坛板块是否允许RSS访问
 *
 * @param array $forum 包含板块信息的数组
 * @return bool 返回板块是否允许RSS访问
 */
function rssforumperm($forum) {
    $is_allowed = $forum['type'] != 'group' && (!$forum['viewperm'] || ($forum['viewperm'] && forumperm($forum['viewperm'], 7)));
    return $is_allowed;
}
/**
 * 上传图标或横幅
 *
 * @param array &$data 上传数据,包含状态、扩展ID等
 * @param array $file 上传的文件信息
 * @param string $type 文件类型(例如:icon或banner)
 * @return string|boolean 上传成功返回文件路径,失败返回空字符串或false
 */
function upload_icon_banner(&$data, $file, $type) {
    global $_G;
    // 设置默认的扩展ID为论坛ID
    $data['extid'] = empty($data['extid']) ? $data['fid'] : $data['extid'];
    if(empty($data['extid'])) return '';

    // 检查群组图片大小限制
    if($data['status'] == 3 && $_G['setting']['group_imgsizelimit']) {
        $file['size'] > ($_G['setting']['group_imgsizelimit'] * 1024) && showmessage('file_size_overflow', '', array('size' => $_G['setting']['group_imgsizelimit'] * 1024));
    }
    $upload = new discuz_upload();
    $uploadtype = $data['status'] == 3 ? 'group' : 'common'; // 根据状态确定上传类型

    if(!$upload->init($file, $uploadtype, $data['extid'], $type)) {
        return false;
    }

    if(!$upload->save()) {
        if(!defined('IN_ADMINCP')) {
            showmessage($upload->errormessage());
        } else {
            cpmsg($upload->errormessage(), '', 'error');
        }
    }
    // 如果是群组图标,生成缩略图
    if($data['status'] == 3 && $type == 'icon') {
        require_once libfile('class/image');
        $img = new image;
        $img->Thumb($upload->attach['target'], './'.$uploadtype.'/'.$upload->attach['attachment'], 200, 200, 'fixwr');
    }
    return $upload->attach['attachment'];
}

/**
 * 生成多页链接
 *
 * @param int $total 总数量
 * @param int $perpage 每页数量
 * @param int $page 当前页码
 * @param string $link 链接基础部分
 * @return string 生成的分页链接
 */
function arch_multi($total, $perpage, $page, $link) {
    $pages = @ceil($total / $perpage) + 1;
    $pagelink = '';
    if($pages > 1) {
        $pagelink .= lang('forum/archiver', 'page') . ": \n";
        $pagestart = $page - 10 < 1 ? 1 : $page - 10;
        $pageend = $page + 10 >= $pages ? $pages : $page + 10;
        for($i = $pagestart; $i < $pageend; $i++) {
            $pagelink .= ($i == $page ? "<strong>[$i]</strong>" : "<a href=\"$link&page=$i\">$i</a>")." \n";
        }
    }
    return $pagelink;
}

/**
 * 加载存档文件
 *
 * @param string $path 文件路径
 * @return string 完整的文件路径
 */
function loadarchiver($path) {
    global $_G;
    if(!$_G['setting']['archiver']) {
        require_once DISCUZ_ROOT . "./source/archiver/common/header.php";
        echo '<div id="content">'.lang('message', 'forum_archiver_disabled').'</div>';
        require_once DISCUZ_ROOT . "./source/archiver/common/footer.php";
        exit;
    }
    $filename = $path . '.php';
    return DISCUZ_ROOT . "./source/archiver/$filename";
}

/**
 * 更新帖子参与度
 *
 * @param int $tid 帖子ID
 * @param boolean $getsetarr 是否返回更新设置数组
 * @return array|void 返回更新设置数组或者无返回
 */
function update_threadpartake($tid, $getsetarr = false) {
    global $_G;
    $setarr = array();
    if($_G['uid'] && $tid) {
        if($_G['setting']['heatthread']['period']) {
            $partaked = C::t('forum_threadpartake')->fetch_threadpartake($tid, $_G['uid']);
            $partaked = $partaked['uid'];
            if(!$partaked) {
                C::t('forum_threadpartake')->insert(array('tid' => $tid, 'uid' => $_G['uid'], 'dateline' => TIMESTAMP));
                $setarr = C::t('forum_thread')->increase($tid, array('heats' => 1), false, 0, $getsetarr);
            }
        } else {
            $setarr = C::t('forum_thread')->increase($tid, array('heats' => 1), false, 0, $getsetarr);
        }
    }
    if($getsetarr) {
        return $setarr;
    }
}

/**
 * 获取帖子封面路径
 *
 * @param int $tid 帖子ID
 * @param int $cover 指定封面版本
 * @param int $getfilename 是否只返回文件名
 * @return string 封面路径或文件名
 */
function getthreadcover($tid, $cover = 0, $getfilename = 0) {
    global $_G;
    if(empty($tid)) {
        return '';
    }
    $coverpath = '';
    $covername = 'threadcover/'.substr(md5($tid), 0, 2).'/'.substr(md5($tid), 2, 2).'/'.$tid.'.jpg';
    if($getfilename) {
        return $covername;
    }
    if($cover) {
        $coverpath = ($cover < 0 ? $_G['setting']['ftp']['attachurl'] : $_G['setting']['attachurl']).'forum/'.$covername;
    }
    return $coverpath;
}

/**
 * 转换未使用的附件关联信息
 *
 * @param int $aid 附件ID
 * @param int $tid 主题ID
 * @param int $pid 帖子ID
 * @return void
 */
function convertunusedattach($aid, $tid, $pid) {
    if(!$aid) {
        return;
    }
    global $_G;
    $attach = C::t('forum_attachment_n')->fetch_by_aid_uid(127, $aid, $_G['uid']);
    if(!$attach) {
        return;
    }
    $attach = daddslashes($attach);
    $attach['tid'] = $tid;
    $attach['pid'] = $pid;
    C::t('forum_attachment_n')->insert_attachment('tid:'.$tid, $attach);
    C::t('forum_attachment')->update($attach['aid'], array('tid' => $tid, 'pid' => $pid, 'tableid' => getattachtableid($tid)));
    C::t('forum_attachment_unused')->delete($attach['aid']);
}

/**
 * 更新附件关联的帖子ID
 *
 * @param string $idtype 关联类型
 * @param array $ids 关联ID列表
 * @param int $oldtid 旧帖子ID
 * @param int $newtid 新帖子ID
 * @return void
 */
function updateattachtid($idtype, $ids, $oldtid, $newtid) {
    foreach(C::t('forum_attachment_n')->fetch_all_by_id('tid:'.$oldtid, $idtype, $ids) as $attach) {
        $attach['tid'] = $newtid;
        C::t('forum_attachment_n')->insert_attachment('tid:'.$newtid, $attach);
    }
    C::t('forum_attachment_n')->delete_by_id('tid:'.$oldtid, $idtype, $ids);
    C::t('forum_attachment')->update_by_id($idtype, $ids, $newtid);
}
/**
 * 更新帖子信息
 *
 * @param array $data 包含帖子数据的数组
 * @param string $condition 更新条件
 * @param bool $unbuffered 是否使用缓冲查询,默认为false
 * @param bool $posttableid 帖子表ID,默认为false
 * @return bool 操作结果,通常为false
 */
function updatepost($data, $condition, $unbuffered = false, $posttableid = false) {
    return false;
}

/**
 * 插入帖子
 *
 * @param array $data 包含帖子数据的数组
 * @return int 插入的帖子ID,失败则返回false
 */
function insertpost($data) {
    // 如果$data中包含tid,尝试获取帖子信息并确定帖子所属的表ID
    if(isset($data['tid'])) {
        $thread = C::t('forum_thread')->fetch_thread($data['tid']);
        $tableid = $thread['posttableid'];
        // 如果帖子回复数为0且存在沙发,则删除沙发帖
        if($thread['replies'] <= 0 && C::t('forum_sofa')->fetch($thread['tid'])) {
            C::t('forum_sofa')->delete($thread['tid']);
        }
    } else {
        // 如果没有提供tid,则默认tid和tableid为0
        $tableid = $data['tid'] = 0;
    }
    // 插入帖子到forum_post_tableid表并获取插入的PID
    $pid = C::t('forum_post_tableid')->insert(array('pid' => null), true);

    // 合并数据并插入到forum_post表
    $data = array_merge($data, array('pid' => $pid));
    C::t('forum_post')->insert_post($tableid, $data);
    // 如果PID是1024的倍数,删除forum_post_tableid中PID小于等于该值的记录
    if($pid % 1024 == 0) {
        C::t('forum_post_tableid')->delete_by_lesspid($pid);
    }
    // 保存最大帖子ID缓存
    savecache('max_post_id', $pid);
    return $pid;
}

/**
 * 根据字符串内容判断帖子是否需要审核
 *
 * @param string $string 帖子的主题和内容
 * @return array 包含帖子是否需要审核的信息
 */
function threadmodstatus($string) {
    global $_G;
    // 检查是否在指定时间范围内需要审核
    $postmodperiods = periodscheck('postmodperiods', 0);
    if($postmodperiods) {
        $modnewthreads = $modnewreplies = 1;
    } else {
        // 根据用户组和论坛设置判断帖子是否需要审核
        $censormod = censormod($string);
        $modnewthreads = (!$_G['group']['allowdirectpost'] || $_G['group']['allowdirectpost'] == 1) && $_G['forum']['modnewposts'] || $censormod ? 1 : 0;
        $modnewreplies = (!$_G['group']['allowdirectpost'] || $_G['group']['allowdirectpost'] == 2) && $_G['forum']['modnewposts'] == 2 || $censormod ? 1 : 0;

        // 考虑论坛状态对审核需求的影响
        if($_G['forum']['status'] == 3) {
            $modnewthreads = !$_G['group']['allowgroupdirectpost'] || $_G['group']['allowgroupdirectpost'] == 1 || $censormod ? 1 : 0;
            $modnewreplies = !$_G['group']['allowgroupdirectpost'] || $_G['group']['allowgroupdirectpost'] == 2 || $censormod ? 1 : 0;
        }
    }

    // 处理允许发布URL的权限
    $_G['group']['allowposturl'] = $_G['forum']['status'] != 3 ? $_G['group']['allowposturl'] : $_G['group']['allowgroupposturl'];
    if($_G['group']['allowposturl'] == 1) {
        if(!$postmodperiods) {
            $censormod = censormod($string);
        }
        if($censormod) {
            $modnewthreads = $modnewreplies = 1;
        }
    }
    return array($modnewthreads, $modnewreplies);
}

/**
 * 保存主题发布信息
 *
 * @param int $tid 主题ID
 * @param bool $passapproval 是否通过审核,默认为false
 * @return int 操作结果,1为成功,0为主题不存在,-1为需审核,-2为回复需审核
 */
function threadpubsave($tid, $passapproval = false) {
    global $_G;
    // 执行插件钩子
    if($_G['setting']['plugins']['func'][HOOKTYPE]['threadpubsave']) {
        $hookparam = func_get_args();
        hookscript('threadpubsave', 'global', 'funcs', array('param' => $hookparam, 'step' => 'check'), 'threadpubsave');
    }
    // 获取主题信息
    $thread = C::t('forum_thread')->fetch_by_tid_displayorder($tid, -4, '=', !$passapproval ? $_G['uid'] : null);
    if(!$thread) {
        return 0;
    }
    // 获取主题帖子信息
    $threadpost = C::t('forum_post')->fetch_threadpost_by_tid_invisible($tid);
    $thread['message'] = $threadpost['message'];

    // 初始化变量
    $modworksql = 0;
    $displayorder = 0;
    $dateline = $_G['timestamp'];
    $moderatepids = $saveposts = array();
    $return = 1;

    // 判断帖子是否需要审核
    list($modnewthreads) = threadmodstatus($thread['subject']."\t".$thread['message']);
    if($modnewthreads && $passapproval === false) {
        // 如果需要审核,则更新审核信息并通知管理员
        updatemoderate('tid', $tid);
        manage_addnotify('verifythread');
        $displayorder = -2;
        $modworksql = 1;
        $return = -1;
        C::t('forum_post')->update_by_tid('tid:'.$tid, $tid, array('dateline' => $dateline), false, false, 1);
    } else {
        // 如果不需要审核,则更新帖子时间
        C::t('forum_post')->update_by_tid('tid:'.$tid, $tid, array('dateline' => $dateline, 'invisible' => '0'), false, false, 1);
    }

    // 更新主题信息
    C::t('forum_thread')->update($tid, array('displayorder'=>$displayorder, 'dateline'=>$_G['timestamp'], 'lastpost'=>$_G['timestamp']));
    $posts = $thread['replies'] + 1;
    // 如果有回复,则处理每个回复
    if($thread['replies']) {
        $saveposts = C::t('forum_post')->fetch_all_by_tid('tid:'.$tid, $tid, true, '', 0, 0, 0);
        foreach($saveposts as $post) {
            $dateline++;
            $invisible = 0;
            list(, $modnewreplies) = threadmodstatus($post['subject']."\t".$post['message']);
            if($modnewreplies) {
                $moderatepids[] = $post['pid'];
                $verifypost = true;
                $invisible = -2;
                $modworksql = 1;
                $return = -2;
            }
            // 更新回复信息
            C::t('forum_post')->update_post('tid:'.$tid, $post['pid'], array('dateline' => $dateline, 'invisible' => $invisible));
            // 更新用户积分
            updatepostcredits('+', $thread['authorid'], 'reply', $thread['fid']);
        }
    }
    // 如果有需要审核的帖子,更新审核信息并通知管理员
    if($moderatepids) {
        updatemoderate('pid', $moderatepids);
        manage_addnotify('verifypost');
    }
    // 更新用户积分
    updatepostcredits('+', $thread['authorid'], 'post', $thread['fid']);
    // 更新附件积分
    $attachcount = C::t('forum_attachment_n')->count_by_id('tid:'.$thread['tid'], 'tid', $thread['tid']);
    updatecreditbyaction('postattach', $thread['authorid'], array(), '', $attachcount, 1, $thread['fid']);
    // 如果论坛为分类讨论区,则更新用户在该分类下的帖子数
    if($_G['forum']['status'] == 3) {
        C::t('forum_groupuser')->update_counter_for_user($thread['authorid'], $thread['fid'], 1);
    }

    // 更新论坛和分类讨论区的最新帖子信息
    $subject = str_replace("\t", ' ', $thread['subject']);
    $lastpost = $thread['tid']."\t".$subject."\t".$thread['lastpost']."\t".$thread['lastposter'];
    C::t('forum_forum')->update($_G['fid'], array('lastpost' => $lastpost));
    C::t('forum_forum')->update_forum_counter($thread['fid'], 1, $posts, $posts, $modworksql);
    // 更新父版块的最新帖子信息
    if($_G['forum']['type'] == 'sub') {
        C::t('forum_forum')->update($_G['forum']['fup'], array('lastpost' => $lastpost));
    }
    // 执行插件钩子
    if($_G['setting']['plugins']['func'][HOOKTYPE]['threadpubsave']) {
        hookscript('threadpubsave', 'global', 'funcs', array('param' => $hookparam, 'step' => 'save', 'posts' => $saveposts), 'threadpubsave');
    }
    return $return;
}
/**
 * 获取相关收藏集
 *
 * @param int $tid 主题ID
 * @param bool $all 是否获取全部相关收藏集,默认为false,即获取设置数量内的收藏集
 * @param int &$num 返回相关收藏集的数量
 * @param int &$more 如果收藏集数量超过设置的最大显示数量,$more设为1,否则设为0
 * @return array 返回收藏集信息数组,如果无相关收藏集则返回null
 */
function getrelatecollection($tid, $all = false, &$num = null, &$more = null) {
    global $_G;

    $maxdisplay = $_G['setting']['collectionnum']; // 获取设置的收藏集显示数量
    if(!$maxdisplay) return; // 如果设置为不显示,则直接返回

    $tidrelate = C::t('forum_collectionrelated')->fetch($tid); // 获取指定主题的收藏集信息
    $ctids = explode("\t", $tidrelate['collection'], -1); // 解析收藏集ID字符串为数组
    $num = count($ctids); // 计算收藏集数量

    if(!$ctids || !$num) {
        $more = $num = 0;
        return null;
    }
    if($all !== true && $num > $maxdisplay) {
        $more = 1; // 如果未设置获取全部且收藏集数量超过最大显示数量,则设置$more为1
    } else {
        $maxdisplay = 0; // 否则设置$maxdisplay为0,表示获取全部
    }
    return C::t('forum_collection')->fetch_all($ctids, 'follownum', 'DESC', 0, $maxdisplay, '', $tid); // 获取收藏集信息
}

/**
 * 设置@列表的Cookie
 *
 * @param array $uids 要设置的UID列表
 */
function set_atlist_cookie($uids) {
    global $_G;
    $atlist = $tmp = array();
    $num = 0;
    $maxlist = 10; // 设置@列表的最大数量
    if(empty($uids)) {
        return;
    }
    $newnum = count($uids); // 新的@列表数量
    if($newnum >= $maxlist) {
        $uids = array_slice($uids, 0, $maxlist); // 如果超过最大数量,则截取前$maxlist个UID
        dsetcookie('atlist', implode(',', $uids), 86400 * 360); // 设置Cookie
        return;
    }
    if($_G['cookie']['atlist']) {
        $atlist = explode(',', $_G['cookie']['atlist']);
        foreach($atlist as $key => $val) {
            if(!in_array($val, $uids)) {
                $num++;
                if($num == ($maxlist - $newnum)) {
                    break;
                }
                $tmp[$key] = $val;
            }
        }
    }
    dsetcookie('atlist', implode(',', $uids).($tmp ? ','.implode(',', $tmp) : ''), 86400 * 360); // 更新或设置Cookie
}

/**
 * 检查HTTP_REFERER是否来自指定搜索引擎
 *
 * @return bool 返回true表示HTTP_REFERER来自指定搜索引擎,否则返回false
 */
function viewthread_is_search_referer() {
    $regex = "((http|https)\:\/\/)?";
    $regex .= "([a-z]*.)?(toutiao.com|m.sm.cn|[url]www.so.com[/url]|sogou.com|bing.com|baidu.com|google.com|google.cn|google.com.hk)(.[a-z]{2,3})?\/";
    if(preg_match("/^$regex/", $_SERVER['HTTP_REFERER'])) {
        return true;
    }
    return false;
}

/**
 * 生成字符串话题的图片表示
 *
 * @param string $value 要生成图片的字符串
 * @param string $key 生成图片的标识关键字,默认与$value相同
 * @param bool $force 是否强制重新生成图片,默认为false
 * @param int $rlength 如果指定,将对字符串进行截断,使其长度不超过此参数
 * @return string 返回图片的URL地址
 */
function stringtopic($value, $key = '', $force = false, $rlength = 0) {
    if($key === '') {
        $key = $value; // 如果未指定$key,则使用$value作为$key
    }
    // 计算图片存储路径和URL
    $basedir = !getglobal('setting/attachdir') ? './data/attachment' : getglobal('setting/attachdir');
    $url = !getglobal('setting/attachurl') ? './data/attachment/' : getglobal('setting/attachurl');
    $subdir1 = substr(md5($key), 0, 2);
    $subdir2 = substr(md5($key), 2, 2);
    $target = 'temp/'.$subdir1.'/'.$subdir2.'/';
    $targetname = substr(md5($key), 8, 16).'.png';
    discuz_upload::check_dir_exists('temp', $subdir1, $subdir2); // 检查目录是否存在,不存在则创建
    // 检查是否需要重新生成图片
    if(!$force && file_exists($basedir.'/'.$target.$targetname)) {
        return $url.$target.$targetname; // 如果存在则直接返回图片URL
    }
    $value = str_replace("\n", '', $value); // 去除字符串中的换行符
    // 默认字体设置
    $fontfile = $fontname = '';
    $ttfenabled = false;
    $size = 10;
    $w = 130;
    $rowh = 25;
    // 处理字符串,按换行符分割
    $value = explode("\r", $value);
    // 如果指定了最大长度,则对字符串进行截断
    if($rlength) {
        $temp = array();
        foreach($value as $str) {
            $strlen = dstrlen($str);
            if($strlen > $rlength) {
                for($i = 0; $i < $strlen; $i++) {
                    $sub = cutstr($str, $rlength, '');
                    $temp[] = $sub;
                    $str = substr($str, strlen($sub));
                    $strlen = $strlen - $rlength;
                }
            } else {
                $temp[] = $str;
            }
        }
        $value = $temp;
        unset($temp);
    }
    // 使用TrueType字体绘制文本
    if(function_exists('imagettftext')) {
        $fontroot = DISCUZ_ROOT.'./static/image/seccode/font/ch/';
        $dirs = opendir($fontroot);
        while($entry = readdir($dirs)) {
            if($entry != '.' && $entry != '..' && in_array(strtolower(fileext($entry)), array('ttf', 'ttc'))) {
                $fontname = $entry;
                break;
            }
        }
        if(!empty($fontname)) {
            $fontfile = DISCUZ_ROOT.'./static/image/seccode/font/ch/'.$fontname;
        }
        if($fontfile) {
            if(strtoupper(CHARSET) != 'UTF-8') {
                include DISCUZ_ROOT.'./source/class/class_chinese.php';
                $cvt = new Chinese(CHARSET, 'utf8');
                $value = $cvt->Convert(implode("\r", $value));
                $value = explode("\r", $value);
            }
            $ttfenabled = true;
        }
    }

    // 计算文本的宽度和高度
    foreach($value as $str) {
        if($ttfenabled) {
            $box = imagettfbbox($size, 0, $fontfile, $str);
            $height = max($box[1], $box[3]) - min($box[5], $box[7]);
            $len = (max($box[2], $box[4]) - min($box[0], $box[6]));
            $rowh = max(array($height, $rowh));
        } else {
            $len = strlen($str) * 12;
        }
        $w = max(array($len, $w));
    }
    $h = $rowh * count($value) + count($value) * 2;
    // 创建图片并绘制文本
    $im = @imagecreate($w, $h);
    $background_color = imagecolorallocate($im, 255, 255, 255); // 设置背景颜色
    $text_color = imagecolorallocate($im, 60, 60, 60); // 设置文本颜色
    $h = $ttfenabled ? $rowh : 4;
    foreach($value as $str) {
        if($ttfenabled) {
            imagettftext($im, $size, 0, 0, $h, $text_color, $fontfile, $str);
            $h += 2;
        } else {
            imagestring($im, $size, 0, $h, $str, $text_color);
        }
        $h += $rowh;
    }
    imagepng($im, $basedir.'/'.$target.$targetname); // 保存图片
    imagedestroy($im);
    return $url.$target.$targetname; // 返回图片URL
}
/**
 * 获取回复背景样式
 *
 * 根据用户设置或全局设置, 获取并返回回复内容的背景图片样式。
 *
 * @param string $replybg 用户自定义的回复背景图片名称。
 * @return string 返回背景图片的样式字符串,如果没有设置,则返回空字符串。
 */
function getreplybg($replybg = '') {
	global $_G;
	$style = '';
	// 检查是否允许自定义回复背景
	if(getglobal('setting/allowreplybg')) {
		// 处理用户自定义回复背景
		if($replybg) {
			$bgurl = $replybg;
			// 检查文件是否存在,确保附件URL正确
			if(file_exists($_G['setting']['attachurl'].'common/'.$replybg)) {
				$bgurl = $_G['setting']['attachurl'].'common/'.$replybg;
			}
		// 处理全局默认回复背景
		} elseif($_G['setting']['globalreplybg']) {
			$bgurl = $_G['setting']['globalreplybg'];
			// 检查文件是否存在,确保附件URL正确
			if(file_exists($_G['setting']['attachurl'].'common/'.$_G['setting']['globalreplybg'])) {
				$bgurl = $_G['setting']['attachurl'].'common/'.$_G['setting']['globalreplybg'];
			}
		}
		// 如果设置了背景图片,则生成样式字符串
		if($bgurl) {
			$style = ' style="background-image: url('.$bgurl.');"';
		}
	}
	return $style;
}

/**
 * 安全过滤数据
 *
 * 对数组或字符串进行安全过滤,替换BBCODE为HTML标签,并移除潜在的XSS攻击向量。
 *
 * @param &$data 需要进行安全过滤的数据,可以是数组或字符串。
 */
function safefilter(&$data) {
	if(is_array($data)) {
		// 递归处理数组中的每个元素
		foreach($data as $k => $v) {
			safefilter($data[$k]);
		}
	} else {
		// 替换和清理特定的BBCODE以及HTML标签,避免XSS攻击
		$data = str_replace(array(
			'[/color]', '[b]', '[/b]', '[s]', '[/s]', '[i]', '[/i]', '[u]', '[/u]',
			), array(
			'</font>', '<b>', '</b>', '<strike>', '</strike>', '<i>', '</i>', '<u>', '</u>'
			), preg_replace(array(
			"/\[color=([#\w]+?)\]/i",
			"/\[color=((rgb|rgba)\([\d\s\.,]+?\))\]/i",
			), array(
			"<font color=\"\\1\">",
			"<font style=\"color:\\1\">",
			), strip_tags($data)));
	}
}

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

本版积分规则

QQ|Archiver|手机版|新秀网络验证系统API[软著登字第13061951号] ( 豫ICP备2021033257号-1 )

GMT+8, 2026-1-7 16:57 , Processed in 0.276458 second(s), 63 queries , Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表
slot777
slot qris
atlas123
KAPAK123
MENARA123
BARONG123
VIRGO123
HORAS123
KAKEK123
ION123
PATEN123
SALAM123
TUYUL123
KUNGLO123
PINTU123
JOKI123
INTI123
JADI123
MENANGBET
JADIJP
ACEH123
TINGGIBET
SUMBER4D
PULANG4D
POLAMAXWIN
INTAN123
dingin4d
paten123
slotsultan
slot sultan