找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 20190|回复: 0

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

[复制链接]
发表于 2024-3-27 21:35:58 | 显示全部楼层 |阅读模式

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

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

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

/**
 *      [Discuz!] (C)2001-2099 Comsenz Inc.
 *      This is NOT a freeware, use is subject to license terms
 *
 *      $Id: function_member.php 35030 2014-10-23 07:43:23Z laoguozhang $
 */

if(!defined('IN_DISCUZ')) {
        exit('Access Denied');
}
/**
 * 用户登录函数
 *
 * @param string $username 用户名、UID、邮箱或安全手机号
 * @param string $password 用户密码
 * @param int $questionid 安全问题ID(暂未使用)
 * @param string $answer 安全问题答案(暂未使用)
 * @param string $loginfield 登录方式标识,默认为'username',可选'uid'、'email'、'auto'、'secmobile'
 * @param string $ip 用户登录的IP地址,默认为空
 * @return array 返回登录结果,包括状态(status)、用户信息(member)和UC登录结果(ucresult)
 */
function userlogin($username, $password, $questionid, $answer, $loginfield = 'username', $ip = '') {
    $return = array();

    // 根据登录字段确定登录类型
    if($loginfield == 'uid' && getglobal('setting/uidlogin')) {
        $isuid = 1;
    } elseif($loginfield == 'email') {
        $isuid = 2;
    } elseif($loginfield == 'auto') {
        $isuid = 3;
    } elseif($loginfield == 'secmobile' && getglobal('setting/secmobilelogin')) {
        $isuid = 4;
    } else {
        $isuid = 0;
    }

    // 加载UCenter通信函数,如未定义则先加载
    if(!function_exists('uc_user_login')) {
        loaducenter();
    }

    // 处理自动登录逻辑
    if($isuid == 3) {
        // 根据用户名尝试登录,支持UID、邮箱和安全手机号
        if(!strcmp(dintval($username), $username) && getglobal('setting/uidlogin')) {
            $return['ucresult'] = uc_user_login($username, $password, 1, 1, $questionid, $answer, $ip, 1);
        } elseif(isemail($username)) {
            $return['ucresult'] = uc_user_login($username, $password, 2, 1, $questionid, $answer, $ip, 1);
        } elseif(preg_match('/^(\d{1,12}|\d{1,3}-\d{1,12})$/', $username) && getglobal('setting/secmobilelogin')) {
            $username = strpos($username, '-') === false ? (getglobal('setting/smsdefaultcc') . '-' . $username) : $username;
            $return['ucresult'] = uc_user_login($username, $password, 4, 1, $questionid, $answer, $ip, 1);
        }
        // 如果登录失败且不是因为账户不存在,则尝试使用用户名密码登录
        if($return['ucresult'][0] <= 0 && $return['ucresult'][0] != -3) {
            $return['ucresult'] = uc_user_login(addslashes($username), $password, 0, 1, $questionid, $answer, $ip);
        }
    } else {
        // 处理非自动登录类型
        if($isuid == 4) {
            $username = strpos($username, '-') === false ? (getglobal('setting/smsdefaultcc') . '-' . $username) : $username;
        }
        $return['ucresult'] = uc_user_login(addslashes($username), $password, $isuid, 1, $questionid, $answer, $ip);
    }

    // 解析UC登录结果
    $tmp = array();
    $duplicate = '';
    list($tmp['uid'], $tmp['username'], $tmp['password'], $tmp['email'], $duplicate) = $return['ucresult'];
    $return['ucresult'] = $tmp;

    // 检查登录结果,登录失败或用户数据重复则返回
    if($duplicate && $return['ucresult']['uid'] > 0 || $return['ucresult']['uid'] <= 0) {
        $return['status'] = 0;
        return $return;
    }

    // 获取用户详细信息
    $member = getuserbyuid($return['ucresult']['uid'], 1);
    if(!$member || empty($member['uid'])) {
        $return['status'] = -1;
        return $return;
    }
    $return['member'] = $member;

    // 登录成功
    $return['status'] = 1;
    if($member['_inarchive']) {
        // 如果用户是归档用户,则将其移回主表
        C::t('common_member_archive')->move_to_master($member['uid']);
    }
    // 更新用户邮箱,解决可能的邮箱变更问题
    if($member['email'] != $return['ucresult']['email']) {
        C::t('common_member')->update($return['ucresult']['uid'], array('email' => $return['ucresult']['email']));
    }

    return $return;
}
/**
 * 设置登录状态
 *
 * 用于在用户成功登录后,设置用户的登录状态,包括但不限于用户ID、用户名、管理员等级、用户组等信息,
 * 同时更新会话信息、设置登录相关的cookie,以及更新统计信息。
 *
 * @param array $member 包含用户登录信息的数组,至少应包含uid、username、adminid、groupid等字段
 * @param int $cookietime 登录cookie的有效时间,单位为秒
 */
function setloginstatus($member, $cookietime) {
    global $_G;
    $_G['uid'] = intval($member['uid']);
    $_G['username'] = $member['username'];
    $_G['adminid'] = $member['adminid'];
    $_G['groupid'] = $member['groupid'];
    $_G['formhash'] = formhash();
    $_G['session']['invisible'] = getuserprofile('invisible');
    $_G['member'] = $member;
    loadcache('usergroup_'.$_G['groupid']);
    C::app()->session->isnew = true;
    C::app()->session->updatesession();

    // 设置登录认证cookie
    dsetcookie('auth', authcode("{$member['password']}\t{$member['uid']}", 'ENCODE'), $cookietime, 1, true);
    dsetcookie('loginuser');
    dsetcookie('activationauth');
    dsetcookie('pmnum');

    // 更新登录统计信息
    include_once libfile('function/stat');
    updatestat('login', 1);
    if(defined('IN_MOBILE')) {
        updatestat('mobilelogin', 1);
    }
    if($_G['setting']['connect']['allow'] && $_G['member']['conisbind']) {
        updatestat('connectlogin', 1);
    }
    // 更新用户积分
    $rule = updatecreditbyaction('daylogin', $_G['uid']);
    if(!$rule['updatecredit']) {
        checkusergroup($_G['uid']);
    }
}

/**
 * 登录检查
 *
 * 用于检查用户登录名是否可用,如果是,则返回可以登录的标志;如果不可用,根据失败次数返回相应的延迟时间。
 *
 * @param string $username 用户输入的用户名
 * @return int 返回值为0表示可以登录,大于0表示需要等待的时间(秒)
 */
function logincheck($username) {
    global $_G;

    $return = 0;
    $username = trim($username);
    loaducenter();
    if(function_exists('uc_user_logincheck')) {
        // 如果存在与UCenter的登录检查函数,则调用UCenter的登录检查
        $return = uc_user_logincheck(addslashes($username), $_G['clientip']);
    } else {
        // 不存在时,进行本地登录检查
        $login = C::t('common_failedlogin')->fetch_ip($_G['clientip']);
        $return = (!$login || (TIMESTAMP - $login['lastupdate'] > 900)) ? 5 : max(0, 5 - $login['count']);

        if(!$login) {
            C::t('common_failedlogin')->insert(array(
                'ip' => $_G['clientip'],
                'count' => 0,
                'lastupdate' => TIMESTAMP
            ), false, true);
        } elseif(TIMESTAMP - $login['lastupdate'] > 900) {
            C::t('common_failedlogin')->insert(array(
                'ip' => $_G['clientip'],
                'count' => 0,
                'lastupdate' => TIMESTAMP
            ), false, true);
            C::t('common_failedlogin')->delete_old(901);
        }
    }
    return $return;
}

/**
 * 登录失败处理
 *
 * 当用户登录失败时,记录登录失败信息,防止恶意登录攻击。
 *
 * @param string $username 用户输入的用户名
 */
function loginfailed($username) {
    global $_G;

    loaducenter();
    if(function_exists('uc_user_logincheck')) {
        // 如果存在与UCenter的登录检查函数,则不进行处理
        return;
    }
    // 记录登录失败信息
    C::t('common_failedlogin')->update_failed($_G['clientip']);
}
/**
 * 检查IP尝试次数是否超过限制。
 *
 * @param $numiptry int 尝试次数限制。
 * @param $timeiptry int 时间限制(秒)。超过此时间限制,尝试次数将被重置。
 * @return bool 如果尝试次数超过限制,返回true;否则,返回false。
 */
function failedipcheck($numiptry, $timeiptry) {
        global $_G;
        if(!$numiptry) {
                return false;
        }
        // 检查当前IP在指定时间内尝试的次数是否已达到或超过限制
        return $numiptry <= C::t('common_failedip')->get_ip_count($_G['clientip'], TIMESTAMP - $timeiptry);
}

/**
 * 记录一个失败的IP尝试。
 */
function failedip() {
        global $_G;
        // 插入当前IP到失败尝试表中
        C::t('common_failedip')->insert_ip($_G['clientip']);
}

/**
 * 获取邀请码信息。
 *
 * @return array 包含邀请码相关用户信息的数组,如果不存在有效邀请码则返回空数组。
 */
function getinvite() {
        global $_G;

        // 如果注册功能关闭,则直接返回空数组
        if($_G['setting']['regstatus'] == 1) return array();
        $result = array();
        $cookies = empty($_G['cookie']['invite_auth']) ? array() : explode(',', $_G['cookie']['invite_auth']);
        $cookiecount = count($cookies);

        // 处理通过URL传入的邀请码
        $_GET['invitecode'] = trim($_GET['invitecode']);
        if($cookiecount == 2 || $_GET['invitecode']) {
                $id = intval($cookies[0]);
                $code = trim($cookies[1]);
                if($_GET['invitecode']) {
                        // 通过邀请码查询邀请信息
                        $invite = C::t('common_invite')->fetch_by_code($_GET['invitecode']);
                        $code = trim($_GET['invitecode']);
                } else {
                        // 通过ID查询邀请信息
                        $invite = C::t('common_invite')->fetch($id);
                }
                // 验证邀请信息的有效性
                if(!empty($invite)) {
                        if($invite['code'] == $code && empty($invite['fuid']) && (empty($invite['endtime']) || $_G['timestamp'] < $invite['endtime'])) {
                                $result['uid'] = $invite['uid'];
                                $result['id'] = $invite['id'];
                        }
                }
        } elseif($cookiecount == 3) { // 处理通过cookie传入的邀请码
                $uid = intval($cookies[0]);
                $code = trim($cookies[1]);

                $invite_code = helper_invite::generate_key($uid);
                if($code === $invite_code) {
                        $member = getuserbyuid($uid);
                        if($member) {
                                $usergroup = C::t('common_usergroup')->fetch($member['groupid']);
                                // 如果用户组不允许邀请或邀请需要付费,则返回空数组
                                if(!$usergroup['allowinvite'] || $usergroup['inviteprice'] > 0) return array();
                        } else {
                                return array();
                        }
                        $result['uid'] = $uid;
                }
        }

        // 如果获取到有效的邀请信息,填充邀请者用户名
        if($result['uid']) {
                $member = getuserbyuid($result['uid']);
                $result['username'] = $member['username'];
        } else {
                // 如果没有有效的邀请信息,清除邀请cookie
                dsetcookie('invite_auth', '');
        }

        return $result;
}
/**
 * 替换字符串中的站点变量
 *
 * @param string $string 需要替换的字符串
 * @param array $replaces 用户自定义的替换数组,默认为空数组
 * @return string 替换后的字符串
 */
function replacesitevar($string, $replaces = array()) {
        global $_G;
        // 定义站点变量
        $sitevars = array(
                '{sitename}' => $_G['setting']['sitename'],
                '{bbname}' => $_G['setting']['bbname'],
                '{time}' => dgmdate(TIMESTAMP, 'Y-n-j H:i'),
                '{adminemail}' => $_G['setting']['adminemail'],
                '{username}' => $_G['member']['username'],
                '{myname}' => $_G['member']['username']
        );
        // 合并用户自定义替换数组和站点变量
        $replaces = array_merge($sitevars, $replaces);
        // 替换字符串并返回
        return str_replace(array_keys($replaces), array_values($replaces), $string);
}

/**
 * 清除用户cookie
 */
function clearcookies() {
        global $_G;
        // 遍历cookie,除去特定的键值,其余全部清除
        foreach($_G['cookie'] as $k => $v) {
                if($k != 'widthauto') {
                        dsetcookie($k);
                }
        }
        // 重置用户登录状态
        $_G['uid'] = $_G['adminid'] = 0;
        $_G['username'] = $_G['member']['password'] = '';
}

/**
 * 处理犯罪记录相关操作
 *
 * @param string $fun 要执行的操作
 * @return mixed 操作结果,失败返回false
 */
function crime($fun) {
        if(!$fun) {
                return false;
        }
        include_once libfile('class/member');
        $crimerecord = & crime_action_ctl::instance();
        $arg_list = func_get_args();
        // 根据传入的函数名执行不同的操作
        if($fun == 'recordaction') {
                list(, $uid, $action, $reason) = $arg_list;
                return $crimerecord->$fun($uid, $action, $reason);
        } elseif($fun == 'getactionlist') {
                list(, $uid) = $arg_list;
                return $crimerecord->$fun($uid);
        } elseif($fun == 'getcount') {
                list(, $uid, $action) = $arg_list;
                return $crimerecord->$fun($uid, $action);
        } elseif($fun == 'search') {
                list(, $action, $username, $operator, $starttime, $endtime, $reason, $start, $limit) = $arg_list;
                return $crimerecord->$fun($action, $username, $operator, $starttime, $endtime, $reason, $start, $limit);
        } elseif($fun == 'actions') {
                return crime_action_ctl::$actions;
        }
        return false;
}

/**
 * 检查并更新关注的动态
 */
function checkfollowfeed() {
        global $_G;

        if($_G['uid']) {
                $lastcheckfeed = 0;
                if(!empty($_G['cookie']['lastcheckfeed'])) {
                        $time = explode('|', $_G['cookie']['lastcheckfeed']);
                        if($time[0] == $_G['uid']) {
                                $lastcheckfeed = $time[1];
                        }
                }
                if(!$lastcheckfeed) {
                        $lastcheckfeed = getuserprofile('lastactivity');
                }
                // 设置最后一次检查动态的时间
                dsetcookie('lastcheckfeed', $_G['uid'].'|'.TIMESTAMP, 31536000);
                // 获取关注的用户
                $followuser = C::t('home_follow')->fetch_all_following_by_uid($_G['uid']);
                $uids = array_keys($followuser);
                if(!empty($uids)) {
                        // 检查是否有新的动态
                        $count = C::t('home_follow_feed')->count_by_uid_dateline($uids, $lastcheckfeed);
                        if($count) {
                                // 有新动态,添加通知
                                notification_add($_G['uid'], 'follow', 'member_follow', array('count' => $count, 'from_id'=>$_G['uid'], 'from_idtype' => 'follow'), 1);
                        }
                }
        }
        // 更新检查动态的cookie
        dsetcookie('checkfollow', 1, 30);
}

/**
 * 验证邮箱格式及合法性
 *
 * @param string $email 需要验证的邮箱地址
 */
function checkemail($email) {
        global $_G;

        $email = strtolower(trim($email));
        if(strlen($email) > 255) {
                // 邮箱地址过长
                showmessage('profile_email_illegal', '', array(), array('handle' => false));
        }
        if($_G['setting']['regmaildomain']) {
                // 检查邮箱域名是否合法
                $maildomainexp = '/('.str_replace("\r\n", '|', preg_quote(trim($_G['setting']['maildomainlist']), '/')).')$/i';
                if($_G['setting']['regmaildomain'] == 1 && !preg_match($maildomainexp, $email)) {
                        showmessage('profile_email_domain_illegal', '', array(), array('handle' => false));
                } elseif($_G['setting']['regmaildomain'] == 2 && preg_match($maildomainexp, $email)) {
                        showmessage('profile_email_domain_illegal', '', array(), array('handle' => false));
                }
        }

        // 调用ucenter接口验证邮箱
        loaducenter();
        $ucresult = uc_user_checkemail($email);

        // 处理ucenter返回的结果
        if($ucresult == -4) {
                showmessage('profile_email_illegal', '', array(), array('handle' => false));
        } elseif($ucresult == -5) {
                showmessage('profile_email_domain_illegal', '', array(), array('handle' => false));
        } elseif($ucresult == -6) {
                showmessage('profile_email_duplicate', '', array(), array('handle' => false));
        }
}

/**
 * 生成获取密码的签名链接
 *
 * @param int $uid 用户ID
 * @param string $idstring 用户注册ID字符串
 * @return string 签名链接
 */
function make_getpws_sign($uid, $idstring) {
        global $_G;
        $link = "member.php?mod=getpasswd&uid={$uid}&id={$idstring}";
        return dsign($link);
}

?>

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

本版积分规则

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

GMT+8, 2026-1-21 12:19 , Processed in 0.240364 second(s), 60 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