|
- <?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');
- }
- /**
- * 用戶登錄函數(shù)
- *
- * @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地址,默認為空
- * [url=home.php?mod=space&uid=33239]@return[/url] array 返回登錄結果,包括狀態(tài)(status)、用戶信息(member)和UC登錄結果(ucresult)
- */
- function userlogin($username, $password, $questionid, $answer, $loginfield = 'username', $ip = '') {
- $return = array();
-
- // 根據(jù)登錄字段確定登錄類型
- 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通信函數(shù),如未定義則先加載
- if(!function_exists('uc_user_login')) {
- loaducenter();
- }
-
- // 處理自動登錄邏輯
- if($isuid == 3) {
- // 根據(jù)用戶名嘗試登錄,支持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;
-
- // 檢查登錄結果,登錄失敗或用戶數(shù)據(jù)重復則返回
- 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;
- }
- /**
- * 設置登錄狀態(tài)
- *
- * 用于在用戶成功登錄后,設置用戶的登錄狀態(tài),包括但不限于用戶ID、用戶名、管理員等級、用戶組等信息,
- * 同時更新會話信息、設置登錄相關的cookie,以及更新統(tǒng)計信息。
- *
- * @param array $member 包含用戶登錄信息的數(shù)組,至少應包含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');
-
- // 更新登錄統(tǒng)計信息
- 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']);
- }
- }
-
- /**
- * 登錄檢查
- *
- * 用于檢查用戶登錄名是否可用,如果是,則返回可以登錄的標志;如果不可用,根據(jù)失敗次數(shù)返回相應的延遲時間。
- *
- * @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的登錄檢查函數(shù),則調用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的登錄檢查函數(shù),則不進行處理
- return;
- }
- // 記錄登錄失敗信息
- C::t('common_failedlogin')->update_failed($_G['clientip']);
- }
- /**
- * 檢查IP嘗試次數(shù)是否超過限制。
- *
- * @param $numiptry int 嘗試次數(shù)限制。
- * @param $timeiptry int 時間限制(秒)。超過此時間限制,嘗試次數(shù)將被重置。
- * @return bool 如果嘗試次數(shù)超過限制,返回true;否則,返回false。
- */
- function failedipcheck($numiptry, $timeiptry) {
- global $_G;
- if(!$numiptry) {
- return false;
- }
- // 檢查當前IP在指定時間內(nèi)嘗試的次數(shù)是否已達到或超過限制
- 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 包含邀請碼相關用戶信息的數(shù)組,如果不存在有效邀請碼則返回空數(shù)組。
- */
- function getinvite() {
- global $_G;
-
- // 如果注冊功能關閉,則直接返回空數(shù)組
- 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']);
- // 如果用戶組不允許邀請或邀請需要付費,則返回空數(shù)組
- 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 用戶自定義的替換數(shù)組,默認為空數(shù)組
- * @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']
- );
- // 合并用戶自定義替換數(shù)組和站點變量
- $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);
- }
- }
- // 重置用戶登錄狀態(tài)
- $_G['uid'] = $_G['adminid'] = 0;
- $_G['username'] = $_G['member']['password'] = '';
- }
-
- /**
- * 處理犯罪記錄相關操作
- *
- * @param string $fun 要執(zhí)行的操作
- * @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();
- // 根據(jù)傳入的函數(shù)名執(zhí)行不同的操作
- 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;
- }
-
- /**
- * 檢查并更新關注的動態(tài)
- */
- 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');
- }
- // 設置最后一次檢查動態(tài)的時間
- 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)) {
- // 檢查是否有新的動態(tài)
- $count = C::t('home_follow_feed')->count_by_uid_dateline($uids, $lastcheckfeed);
- if($count) {
- // 有新動態(tài),添加通知
- notification_add($_G['uid'], 'follow', 'member_follow', array('count' => $count, 'from_id'=>$_G['uid'], 'from_idtype' => 'follow'), 1);
- }
- }
- }
- // 更新檢查動態(tài)的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);
- }
-
- ?>
復制代碼
|
|