admin 发表于 2024-6-23 13:31:16

Discuz x3.5 核心文件 function/function_group.php 函数注释

<?php

/**
*       (C)2001-2099 Comsenz Inc.
*      This is NOT a freeware, use is subject to license terms
*
*      $Id: function_group.php 32367 2013-01-07 02:30:12Z liulanbo $
*/

if(!defined('IN_DISCUZ')) {
      exit('Access Denied');
}
/**
* 删除指定类型缓存数组中与指定论坛ID相关的缓存
*
* @param int $fid 论坛ID
* @param array $cachearray 缓存数组
*/
function delgroupcache($fid, $cachearray) {
    C::t('forum_groupfield')->delete_by_type($cachearray, $fid);
}

/**
* 检查用户是否有权限在指定论坛执行指定操作
*
* @param array &$forum 论坛信息
* @param int $uid 用户ID
* @param string $action 指定操作,默认为空
* @param string $isgroupuser 是否为组成员,默认为空
* @return mixed 返回值为-1表示无访问权限,'isgroupuser'表示是组成员,空字符串表示有访问权限但不是组成员
*/
function groupperm(&$forum, $uid, $action = '', $isgroupuser = '') {
    // 检查论坛状态和类型是否符合要求
    if($forum['status'] != 3 || $forum['type'] != 'sub') {
      return -1;
    }
    // 检查是否为创始人
    if(!empty($forum['founderuid']) && $forum['founderuid'] == $uid) {
      return 'isgroupuser';
    }
    // 获取或验证用户是否为组成员
    $isgroupuser = empty($isgroupuser) && $isgroupuser !== false ? C::t('forum_groupuser')->fetch_userinfo($uid, $forum['fid']) : $isgroupuser;
    // 检查是否为版主
    if($forum['ismoderator'] && !$isgroupuser) {
      return '';
    }
    // 检查加入方式和是否为版主
    if($forum['jointype'] < 0 && !$forum['ismoderator']) {
      return 1;
    }
    // 检查查看权限
    if(!$forum['gviewperm'] && !$isgroupuser) {
      return 2;
    }
    // 检查特定条件下的查看权限
    if($forum['jointype'] == 2 && (!$forum['gviewperm'] || $action == 'post') && !empty($isgroupuser['uid']) && $isgroupuser['level'] == 0) {
      return 3;
    }
    // 检查发帖权限
    if($action == 'post' && !$isgroupuser) {
      return 4;
    }
    // 检查用户等级
    if(is_array($isgroupuser['level']) && $isgroupuser['level'] === 0) {
      return 5;
    }
    return $isgroupuser ? 'isgroupuser' : '';
}

/**
* 获取论坛组列表
*
* @param string $orderby 排序方式,默认为'displayorder'
* @param array $fieldarray 需要获取的字段数组,默认为空数组
* @param int $num 每页显示数量,默认为1
* @param array $fids 指定的论坛ID数组,默认为空数组
* @param int $sort 排序方式标志,默认为0
* @param bool $getcount 是否只获取总数,默认为false
* @param array $grouplevel 组别等级数组,默认为空数组
* @return array 返回组列表数组,如果只获取总数则返回总数
*/
function grouplist($orderby = 'displayorder', $fieldarray = array(), $num = 1, $fids = array(), $sort = 0, $getcount = 0, $grouplevel = array()) {
    $query = C::t('forum_forum')->fetch_all_for_grouplist($orderby, $fieldarray, $num, $fids, $sort, $getcount);
    if($getcount) {
      return $query;
    }
    // 处理查询结果,格式化组信息
    $grouplist = array();
    foreach($query as $group) {
      $group['iconstatus'] = $group['icon'] ? 1 : 0;
      isset($group['icon']) && $group['icon'] = get_groupimg($group['icon'], 'icon');
      isset($group['banner']) && $group['banner'] = get_groupimg($group['banner']);
      $group['orderid'] = $orderid ? intval($orderid) : '';
      isset($group['dateline']) && $group['dateline'] = $group['dateline'] ? dgmdate($group['dateline'], 'd') : '';
      isset($group['lastupdate']) && $group['lastupdate'] = $group['lastupdate'] ? dgmdate($group['lastupdate'], 'd') : '';
      $group['level'] = !empty($grouplevel) ? intval($grouplevel[$group['fid']]) : 0;
      isset($group['description']) && $group['description'] = cutstr($group['description'], 130);
      $grouplist[$group['fid']] = $group;
      $orderid ++;
    }

    return $grouplist;
}

/**
* 获取指定用户的组列表
*
* @param int $uid 用户ID
* @param string $orderby 排序方式,默认为空
* @param array $fieldarray 需要获取的字段数组,默认为空数组
* @param int $num 每页显示数量,默认为0
* @param int $start 起始位置,默认为0
* @param bool $ismanager 是否只获取管理员组,默认为0
* @param int $count 获取组数量,默认为0
* @return mixed 返回组列表数组或查询结果
*/
function mygrouplist($uid, $orderby = '', $fieldarray = array(), $num = 0, $start = 0, $ismanager = 0, $count = 0) {
    $uid = intval($uid);
    if(empty($uid)) {
      return array();
    }
    $groupfids = $grouplevel = array();
    // 查询用户所属的组
    $query = C::t('forum_groupuser')->fetch_all_group_for_user($uid, $count, $ismanager, $start, $num);
    if($count == 1) {
      return $query;
    }
    foreach($query as $group) {
      $groupfids[] = $group['fid'];
      $grouplevel[$group['fid']] = $group['level'];
    }
    if(empty($groupfids)) {
      return false;
    }
    // 获取组信息
    $mygrouplist = grouplist($orderby, $fieldarray, $num, $groupfids, 0, 0, $grouplevel);

    return $mygrouplist;
}

/**
* 获取群组图片的URL
*
* @param string $imgname 图片名称
* @param string $imgtype 图片类型,默认为空。可选值:'icon'
* @return string 返回图片的URL。若图片名称不为空,返回图片的完整URL;若为空且类型为'icon',返回群组图标默认图片的URL;否则返回空字符串。
*/
function get_groupimg($imgname, $imgtype = '') {
      global $_G;
      // 构造图片的默认路径
      $imgpath = $_G['setting']['attachurl'].'group/'.$imgname;
      if($imgname) {
                // 如果图片名称不为空,直接返回图片路径
                return $imgpath;
      } else {
                // 图片名称为空时的处理
                if($imgtype == 'icon') {
                        // 如果类型为'icon',返回默认群组图标图片的URL
                        return STATICURL.'image/common/groupicon.gif';
                } else {
                        // 其他情况下返回空字符串
                        return '';
                }
      }
}

/**
* 生成组选择下拉菜单
*
* @param int $fup 一级组类型ID,默认为0
* @param int $groupid 二级组类型ID,默认为0
* @param int $ajax 是否为AJAX请求,1为是,其他为否,默认为1
* @return array 返回包含一级和二级组选择菜单的数组
*/
function get_groupselect($fup = 0, $groupid = 0, $ajax = 1) {
      global $_G;
      loadcache('grouptype');
      // 获取一级和二级组类型缓存
      $firstgroup = $_G['cache']['grouptype']['first'];
      $secondgroup = $_G['cache']['grouptype']['second'];
      // 初始化返回的组选择数组
      $grouptypeselect = array('first' => '', 'second' => '');

      if($ajax) {
                // 如果是AJAX请求,处理一级和二级组选择
                $fup = intval($fup);
                $groupid = intval($groupid);
                // 生成一级组选择菜单
                foreach($firstgroup as $gid => $group) {
                        $selected = $fup == $gid ? 'selected="selected"' : '';
                        $grouptypeselect['first'] .= '<option value="'.$gid.'" '.$selected.'>'.$group['name'].'</option>';
                }

                // 如果指定了fup,且存在二级组,则生成二级组选择菜单
                if($fup && !empty($firstgroup[$fup]['secondlist'])) {
                        foreach($firstgroup[$fup]['secondlist'] as $sgid) {
                              $selected = $sgid == $groupid ? 'selected="selected"' : '';
                              $grouptypeselect['second'] .= '<option value="'.$sgid.'" '.$selected.'>'.$secondgroup[$sgid]['name'].'</option>';
                        }
                }
      } else {
                // 非AJAX请求,处理一级及一级下二级组选择
                foreach($firstgroup as $gid => $group) {
                        // 生成一级组选择菜单
                        $gselected = $groupid == $gid ? 'selected="selected"' : '';
                        $grouptypeselect .= '<option value="'.$gid.'" '.$gselected.'>'.$group['name'].'</option>';
                        // 如果该组存在二级组,生成二级组选择菜单
                        if(is_array($group['secondlist'])) {
                              foreach($group['secondlist'] as $secondid) {
                                        $selected = $groupid == $secondid ? 'selected="selected"' : '';
                                        $grouptypeselect .= '<option value="'.$secondid.'" '.$selected.'>'.$secondgroup[$secondid]['name'].'</option>';
                              }
                        }
                        $grouptypeselect .= '</optgroup>';
                }
      }
      return $grouptypeselect;
}
/**
* 生成小组导航栏
*
* @param array $forum 包含论坛信息的数组,必须包含fid和name,如果为子版块还需要包含fup
* @return array 返回一个包含导航HTML字符串、一级分类信息和二级分类信息的数组
*/
function get_groupnav($forum) {
      global $_G;
      // 检查输入的论坛信息是否为空
      if(empty($forum) || empty($forum['fid']) || empty($forum['name'])) {
                return '';
      }
      // 加载分类缓存
      loadcache('grouptype');
      $groupnav = '';
      $groupsecond = $_G['cache']['grouptype']['second'];
      // 根据版块类型确定二级分类信息
      if($forum['type'] == 'sub') {
                $secondtype = !empty($groupsecond[$forum['fup']]) ? $groupsecond[$forum['fup']] : array();
      } else {
                $secondtype = !empty($groupsecond[$forum['fid']]) ? $groupsecond[$forum['fid']] : array();
      }
      // 计算顶级分类ID和信息
      $firstid = !empty($secondtype) ? $secondtype['fup'] : (!empty($forum['fup']) ? $forum['fup'] : $forum['fid']);
      $firsttype = $_G['cache']['grouptype']['first'][$firstid];
      // 生成一级分类导航
      if($firsttype) {
                $groupnav = ' <em>›</em> <a href="group.php?gid='.$firsttype['fid'].'">'.$firsttype['name'].'</a>';
      }
      // 生成二级分类导航
      if($secondtype) {
                $groupnav .= ' <em>›</em> <a href="group.php?sgid='.$secondtype['fid'].'">'.$secondtype['name'].'</a>';
      }
      // 生成子版块导航
      if($forum['type'] == 'sub') {
                $mod_action = $_GET['mod'] == 'forumdisplay' || $_GET['mod'] == 'viewthread' ? 'mod=forumdisplay&action=list' : 'mod=group';
                $groupnav .= ($groupnav ? ' <em>›</em> ' : '').'<a href="forum.php?'.$mod_action.'&fid='.$forum['fid'].'">'.$forum['name'].'</a>';
      }
      return array('nav' => $groupnav, 'first' => $firsttype, 'second' => $secondtype);
}

/**
* 获取已浏览的小组列表
*
* @return array 返回一个包含已浏览小组信息的数组列表
*/
function get_viewedgroup() {
      $groupviewed_list = $list = array();
      $groupviewed = getcookie('groupviewed');
      // 从cookie中获取已浏览的小组ID列表
      $groupviewed = $groupviewed ? explode(',', $groupviewed) : array();
      if($groupviewed) {
                // 根据小组ID列表查询小组信息
                $query = C::t('forum_forum')->fetch_all_info_by_fids($groupviewed);
                foreach($query as $row) {
                        $icon = get_groupimg($row['icon'], 'icon');
                        // 组装小组信息
                        $list[$row['fid']] = array('fid' => $row['fid'], 'name' => $row['name'], 'icon' => $icon, 'membernum' => $row['membernum']);
                }
      }
      // 将小组信息数组按ID列表顺序排列
      foreach($groupviewed as $fid) {
                $groupviewed_list[$fid] = $list[$fid];
      }
      return $groupviewed_list;
}

/**
* 获取指定论坛组的帖子列表
*
* @param int $fid 论坛组ID
* @param string $type 获取帖子的类型(replies, views, dateline, lastpost, digest, comments)
* @param int $timestamp 根据时间戳筛选帖子,0为不筛选
* @param int $num 返回帖子的数量,默认为10
* @return array 返回包含帖子信息的数组
*/
function getgroupthread($fid, $type, $timestamp = 0, $num = 10) {
    // 定义有效的帖子类型数组
    $typearray = array('replies', 'views', 'dateline', 'lastpost', 'digest', 'comments');
    // 检查并设置请求的帖子类型
    $type = in_array($type, $typearray) ? $type : '';

    $groupthreadlist = array();
    // 当类型有效时,根据条件获取帖子信息
    if($type) {
      $dateline = $lastpost = $digest = null;
      // 根据类型和时间戳设置查询条件
      if($timestamp && in_array($type, array('dateline', 'lastpost'))) {
            if($type == 'dateline') {
                $dateline = TIMESTAMP - $timestamp;
            } else {
                $lastpost = TIMESTAMP - $timestamp;
            }
      }
      // 特殊处理消化帖
      if($type == 'digest') {
            $digest = 0;
            $type = 'dateline';
      }
      // 获取并格式化帖子信息
      foreach(C::t('forum_thread')->fetch_all_group_thread_by_fid_displayorder($fid, 0, $dateline, $lastpost, $digest, $type, 0, $num) as $thread) {
            $groupthreadlist[$thread['tid']] = array(
                'tid' => $thread['tid'],
                'subject' => $thread['subject'],
                'special' => $thread['special'],
                'closed' => $thread['closed'],
                'dateline' => dgmdate($thread['dateline'], 'd'),
                'author' => $thread['author'],
                'authorid' => $thread['authorid'],
                'views' => $thread['views'],
                'replies' => $thread['replies'],
                'comments' => $thread['comments'],
                'lastpost' => dgmdate($thread['lastpost'], 'u'),
                'lastposter' => $thread['lastposter'],
                'lastposterenc' => rawurlencode($thread['lastposter']),
            );
      }
    }

    return $groupthreadlist;
}

/**
* 获取论坛组的缓存数据
*
* @param int $fid 论坛组ID
* @param array $typearray 需要获取的缓存类型数组
* @param int $timestamp 根据时间戳筛选帖子,0为不筛选
* @param int $num 返回数据的数量,默认为10
* @param int $privacy 隐私等级
* @param bool $force 是否强制重新获取数据
* @return array 返回缓存数据数组
*/
function getgroupcache($fid, $typearray = array(), $timestamp = 0, $num = 10, $privacy = 0, $force = 0) {
    $groupcache = array();

    // 非强制刷新时,尝试从数据库读取缓存数据
    if(!$force) {
      $query = C::t('forum_groupfield')->fetch_all_group_cache($fid, $typearray, $privacy);
      foreach($query as $group) {
            $groupcache[$group['type']] = dunserialize($group['data']);
            $groupcache[$group['type']]['dateline'] = $group['dateline'];
      }
    }

    // 定义各类型缓存的有效时间
    $cachetimearray = array('replies' => 3600, 'views' => 3600, 'dateline' => 900, 'lastpost' => 3600, 'digest' => 86400, 'ranking' => 86400, 'activityuser' => 3600);
    // 定义特定类型数据的额外处理方式
    $userdataarray = array('activityuser' => 'lastupdate', 'newuserlist' => 'joindateline');
    // 遍历类型数组,获取或更新缓存数据
    foreach($typearray as $type) {
      if(empty($groupcache[$type]) || (!empty($cachetimearray[$type]) && TIMESTAMP - $groupcache[$type]['dateline'] > $cachetimearray[$type])) {
            // 根据类型获取相应的数据
            if($type == 'ranking') {
                $groupcache[$type]['data'] = getgroupranking($fid, $groupcache[$type]['data']['today']);
            } elseif(in_array($type, array('activityuser', 'newuserlist'))) {
                $num = $type == 'activityuser' ? 50 : 8;
                $groupcache[$type]['data'] = C::t('forum_groupuser')->groupuserlist($fid, $userdataarray[$type], $num, '', "AND level>'0'");
            } else {
                $groupcache[$type]['data'] = getgroupthread($fid, $type, $timestamp, $num);
            }
            // 如果不是强制刷新且有有效的fid,则更新缓存数据到数据库
            if(!$force && $fid) {
                C::t('forum_groupfield')->insert(array('fid' => $fid, 'dateline' => TIMESTAMP, 'type' => $type, 'data' => serialize($groupcache[$type])), false, true);
            }
      }
    }

    return $groupcache;
}

/**
* 获取论坛组的排名信息
*
* @param string $fid 论坛组ID
* @param string $nowranking 当前排名
* @return array 返回论坛组的排名数据
*/
function getgroupranking($fid = '', $nowranking = '') {
    $topgroup = $rankingdata = $topyesterday = array();
    $ranking = 1;
    // 获取所有论坛组的排名基础数据
    $query = C::t('forum_forum')->fetch_all_group_for_ranking();
    foreach($query as $group) {
      $topgroup[$group['fid']] = $ranking++;
    }

    // 如果有指定的论坛组ID,计算其排名
    if($fid && $topgroup) {
      $rankingdata['yesterday'] = intval($nowranking);
      $rankingdata['today'] = intval($topgroup[$fid]);
      // 计算排名趋势
      $rankingdata['trend'] = $rankingdata['yesterday'] ? grouptrend($rankingdata['yesterday'], $rankingdata['today']) : 0;
      $topgroup = $rankingdata;
    }

    return $topgroup;
}

/**
* 获取指定论坛组的在线成员信息
*
* @param int $fid 论坛组ID
* @param bool $getlist 是否获取成员列表
* @return array 返回在线成员信息,包括总数和列表
*/
function grouponline($fid, $getlist = '') {
    $fid = intval($fid);
    if(empty($getlist)) {
      // 仅获取在线成员总数
      $onlinemember = (array)C::app()->session->count_by_fid($fid);
      $onlinemember['count'] = $onlinemember ? intval($onlinemember) : 0;
    } else {
      // 获取在线成员列表
      $onlinemember = array('count' => 0, 'list' => array());
      $onlinemember['list'] = C::app()->session->fetch_all_by_fid($fid);
      $onlinemember['count'] = count($onlinemember['list']);
    }
    return $onlinemember;
}

/**
* 计算论坛组排名趋势
*
* @param int $yesterday 昨天的排名
* @param int $today 今天的排名
* @return int 返回排名变化趋势
*/
function grouptrend($yesterday, $today) {
    $trend = $yesterday - $today;
    return $trend;
}

/**
* 写入用户组已查看的论坛版块信息
* @param $fid 论坛版块ID
*/
function write_groupviewed($fid) {
      $fid = intval($fid);
      if($fid) {
                // 设置已查看版块数量限制
                $groupviewed_limit = 8;
                // 获取已保存的查看版块信息
                $groupviewed = getcookie('groupviewed');
                // 若当前版块ID不在已查看版块列表中,则进行添加
                if(!strexists(",$groupviewed,", ",$fid,")) {
                        // 如果已有查看版块,则将其拆分成数组;若无,则初始化为空数组
                        $groupviewed = $groupviewed ? explode(',', $groupviewed) : array();
                        // 将当前版块ID添加到数组中
                        $groupviewed[] = $fid;
                        // 如果已查看版块数量超过限制,则移除最早查看的版块
                        if(count($groupviewed) > $groupviewed_limit) {
                              array_shift($groupviewed);
                        }
                        // 将更新后的已查看版块列表保存到cookie中
                        dsetcookie('groupviewed', implode(',', $groupviewed), 86400);
                }
      }
}

/**
* 更新版块的管理员和版主信息
* @param $fid 论坛版块ID
* @return array 返回版块的管理员和版主信息,若无则返回空数组
*/
function update_groupmoderators($fid) {
      if(empty($fid)) return false;
      // 获取版块的管理员和版主信息
      $moderators = C::t('forum_groupuser')->groupuserlist($fid, 'level_join', 0, 0, array('level' => array('1', '2')), array('username', 'level'));
      if(!empty($moderators)) {
                // 更新版块信息,保存管理员和版主信息
                C::t('forum_forumfield')->update($fid, array('moderators' => serialize($moderators)));
                return $moderators;
      } else {
                return array();
      }
}

/**
* 更新用户所属用户组信息
* @param $uids 用户ID数组
* @return array 返回更新后的用户所属用户组信息
*/
function update_usergroups($uids) {
      global $_G;
      if(empty($uids)) return '';
      if(!is_array($uids)) $uids = array($uids);
      foreach($uids as $uid) {
                // 初始化变量
                $groups = $grouptype = $usergroups = array();
                // 获取用户所属版块信息
                $fids = C::t('forum_groupuser')->fetch_all_fid_by_uids($uid);
                $query = C::t('forum_forum')->fetch_all_info_by_fids($fids);
                // 整理版块信息,按上级版块分类
                foreach($query as $group) {
                        $groups[$group['fid']] = $group['name'];
                        $typegroup[$group['fup']][] = $group['fid'];
                }
                if(!empty($typegroup)) {
                        // 获取各上级版块的信息
                        $fups = array_keys($typegroup);
                        $query = C::t('forum_forum')->fetch_all_info_by_fids($fups);
                        // 整理并归类版块信息
                        foreach($query as $fup) {
                              $grouptype[$fup['fid']] = array('fid' => $fup['fid'], 'fup' => $fup['fup'], 'name' => $fup['name']);
                              $grouptype[$fup['fid']]['groups'] = implode(',', $typegroup[$fup['fid']]);
                        }
                        // 组装用户所属用户组信息
                        $usergroups = array('groups' => $groups, 'grouptype' => $grouptype);
                        if(!empty($usergroups)) {
                              // 更新用户的关注组信息,移除已不存在的组
                              $setarr = array();
                              $member = C::t('common_member_field_forum')->fetch($uid);
                              $attentiongroups = $member['attentiongroup'];
                              if($attentiongroups) {
                                        $attentiongroups = explode(',', $attentiongroups);
                                        $updateattention = 0;
                                        foreach($attentiongroups as $key => $val) {
                                                if(empty($usergroups['groups'][$val])) {
                                                      unset($attentiongroups[$key]);
                                                      $updateattention = 1;
                                                }
                                        }
                                        if($updateattention) {
                                                $setarr['attentiongroup'] = implode(',', $attentiongroups);
                                                C::t('common_member_field_forum')->update($uid, $setarr);
                                        }
                                        $_G['member']['attentiongroup'] = implode(',', $attentiongroups);
                              }
                        }
                }
      }
      return $usergroups;
}

?>
页: [1]
查看完整版本: Discuz x3.5 核心文件 function/function_group.php 函数注释