<?php   if(!defined('DEDEINC')) exit('Request Error!');
/**
 * 會員登錄類
 *
 * @version        $Id: userlogin.class.php 1 15:59 2010年7月5日Z tianya $
 * @package        DedeCMS.Libraries
 * @copyright      Copyright (c) 2007 - 2010, DesDev, Inc.
 * @license        http://help.dedecms.com/usersguide/license.html
 * @link           http://www.dedecms.com
 */

// 使用緩存助手
helper('cache');
/**
 *  檢查用戶名的合法性
 *
 * @access    public
 * @param     string  $uid  用戶UID
 * @param     string  $msgtitle  提示標題
 * @param     string  $ckhas  檢查是否存在
 * @return    string
 */
function CheckUserID($uid, $msgtitle='用戶名', $ckhas=TRUE)
{
    global $cfg_mb_notallow,$cfg_mb_idmin,$cfg_md_idurl,$cfg_soft_lang,$dsql;
    if($cfg_mb_notallow != '')
    {
        $nas = explode(',', $cfg_mb_notallow);
        if(in_array($uid, $nas))
        {
            return $msgtitle.'為系統禁止的標識！';
        }
    }
    if($cfg_md_idurl=='Y' && preg_match("/[^a-z0-9]/i",$uid))
    {
        return $msgtitle.'必須由英文字母或數字組成！';
    }

    if($cfg_soft_lang=='utf-8')
    {
        $ck_uid = utf82gb($uid);
    }
    else
    {
        $ck_uid = $uid;
    }

    for($i=0; isset($ck_uid[$i]); $i++)
    {
        if(ord($ck_uid[$i]) > 0x80)
        {
            if(isset($ck_uid[$i+1]) && ord($ck_uid[$i+1])>0x40)
            {
                $i++;
            }
            else
            {
                return $msgtitle.'可能含有亂碼，建議你改用英文字母和數字組合！';
            }
        }
        else
        {
            if(preg_match("/[^0-9a-z@\.-]/i",$ck_uid[$i]))
            {
                return $msgtitle.'不能含有 [@]、[.]、[-]以外的特殊符號！';
            }
        }
    }
    if($ckhas)
    {
        $row = $dsql->GetOne("SELECT * FROM `#@__member` WHERE userid LIKE '$uid' ");
        if(is_array($row)) return $msgtitle."已經存在！";
    }
    return 'ok';
}

/**
 *  保存一則消息記錄
 *
 * @access    public
 * @param     string  $mid  用戶MID
 * @param     string  $mid  用戶ID
 * @param     string  $msg  保存消息
 * @return    string
 */
function PutSnsMsg($mid, $userid, $msg)
{
    global $dsql;
    $msg = addslashes($msg);
    $query = "INSERT INTO `#@__member_snsmsg`(`mid`, `userid`, `sendtime`, `msg`) VALUES('$mid', '$userid', '".time()."', '$msg'); ";
    $rs = $dsql->ExecuteNoneQuery($query);
    return $rs;
}

/**
 *  檢查用戶是否被禁言
 *
 * @return    void
 */
function CheckNotAllow()
{
    global $dsql, $cfg_ml, $cfg_mb_spacesta;
    if(empty($cfg_ml->M_ID)) return ;
    if($cfg_ml->M_Spacesta == -2)
    {
        ShowMsg("你已經被禁言，請與管理員聯繫！", "-1");
        exit();
    }else if($cfg_ml->M_Spacesta == -10)
    {
        ShowMsg("系統開啟了郵件審核機制，因此你的帳號需要審核後才能發信息！", "-1");
        exit();
    }
    else if($cfg_ml->M_Spacesta < 0)
    {
        ShowMsg('系統開啟了審核機制，因此你的帳號需要管理員審核後才能發信息！', '-1');
        exit();
    }
}

/**
 * 網站會員登錄類
 *
 * @package          MemberLogin
 * @subpackage       DedeCMS.Libraries
 * @link             http://www.dedecms.com
 */
class MemberLogin
{
    var $M_ID;
    var $M_LoginID;
    var $M_MbType;
    var $M_Money;
    var $M_Scores;
    var $M_UserName;
    var $M_Rank;
     var $M_Face;
    var $M_LoginTime;
    var $M_KeepTime;
    var $M_Spacesta;
    var $fields;
    var $isAdmin;
    var $M_UpTime;
    var $M_ExpTime;
    var $M_HasDay;
    var $M_JoinTime;
    var $M_Honor = '';
    var $memberCache='memberlogin';

    //php5構造函數
    function __construct($kptime = -1, $cache=FALSE)
    {
        global $dsql;
        if($kptime==-1){
            $this->M_KeepTime = 3600 * 24 * 7;
        }else{
            $this->M_KeepTime = $kptime;
        }
        $formcache = FALSE;
        $this->M_ID = $this->GetNum(GetCookie("DedeUserID"));
        $this->M_LoginTime = GetCookie("DedeLoginTime");
        $this->fields = array();
        $this->isAdmin = FALSE;
        if(empty($this->M_ID))
        {
            $this->ResetUser();
        }else{
            $this->M_ID = intval($this->M_ID);
            
            if ($cache)
            {
                $this->fields = GetCache($this->memberCache, $this->M_ID);
                if( empty($this->fields) )
                {
                    $this->fields = $dsql->GetOne("Select * From `#@__member` where mid='{$this->M_ID}' ");
                } else {
                    $formcache = TRUE;
                }
            } else {
                $this->fields = $dsql->GetOne("Select * From `#@__member` where mid='{$this->M_ID}' ");
            }
                
            if(is_array($this->fields)){
                #api{{
                if(defined('UC_API') && @include_once DEDEROOT.'/uc_client/client.php')
                {
                    if($data = uc_get_user($this->fields['userid']))
                    {
                        if(uc_check_avatar($data[0]) && !strstr($this->fields['face'],UC_API))
                        {
                            $this->fields['face'] = UC_API.'/avatar.php?uid='.$data[0].'&size=middle';
                            $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET `face`='".$this->fields['face']."' WHERE `mid`='{$this->M_ID}'");
                        }
                    }
                }
                #/aip}}
            
                //間隔一小時更新一次用戶登錄時間
                if(time() - $this->M_LoginTime > 3600)
                {
                    $dsql->ExecuteNoneQuery("update `#@__member` set logintime='".time()."',loginip='".GetIP()."' where mid='".$this->fields['mid']."';");
                    PutCookie("DedeLoginTime",time(),$this->M_KeepTime);
                }
                $this->M_LoginID = $this->fields['userid'];
                $this->M_MbType = $this->fields['mtype'];
                $this->M_Money = $this->fields['money'];
                $this->M_UserName = $this->fields['uname'];
                $this->M_Scores = $this->fields['scores'];
                $this->M_Face = $this->fields['face'];
                $this->M_Rank = $this->fields['rank'];
                $this->M_Spacesta = $this->fields['spacesta'];
                $sql = "Select titles From #@__scores where integral<={$this->fields['scores']} order by integral desc";
                $scrow = $dsql->GetOne($sql);
                $this->fields['honor'] = $scrow['titles'];
                $this->M_Honor = $this->fields['honor'];
                if($this->fields['matt']==10) $this->isAdmin = TRUE;
                $this->M_UpTime = $this->fields['uptime'];
                $this->M_ExpTime = $this->fields['exptime'];
                $this->M_JoinTime = MyDate('Y-m-d',$this->fields['jointime']);
                if($this->M_Rank>10 && $this->M_UpTime>0){
                    $this->M_HasDay = $this->Judgemember();
                }
                if( !$formcache )
                {
                    SetCache($this->memberCache, $this->M_ID, $this->fields, 1800);
                }
            }else{
                $this->ResetUser();
            }
        }
    }

    function MemberLogin($kptime = -1)
    {
        $this->__construct($kptime);
    }
    
    /**
     *  刪除緩存,每次登錄時和在修改用戶資料的地方會清除
     *
     * @access    public
     * @param     string
     * @return    string
     */
    function DelCache($mid)
    {
        DelCache($this->memberCache, $mid);
    }
    
    /**
     *  判斷會員是否到期
     *
     * @return    string
     */
    function Judgemember()
    {
        global $dsql,$cfg_mb_rank;
        $nowtime = time();
        $mhasDay = $this->M_ExpTime - ceil(($nowtime - $this->M_UpTime)/3600/24) + 1;
        if($mhasDay <= 0){
           $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET uptime='0',exptime='0',
                                         rank='$cfg_mb_rank' WHERE mid='".$this->fields['mid']."';");
        }
        return $mhasDay;
    }

    /**
     *  退出cookie的會話
     *
     * @return    void
     */
    function ExitCookie()
    {
        $this->ResetUser();
    }

    /**
     *  驗證用戶是否已經登錄
     *
     * @return    bool
     */
    function IsLogin()
    {
        if($this->M_ID > 0) return TRUE;
        else return FALSE;
    }

    /**
     *  檢測用戶上傳空間
     *
     * @return    int
     */
    function GetUserSpace()
    {
        global $dsql;
        $uid = $this->M_ID;
        $row = $dsql->GetOne("SELECT sum(filesize) AS fs FROM `#@__uploads` WHERE mid='$uid'; ");
        return $row['fs'];
    }

    /**
     *  檢查用戶空間信息
     *
     * @return    void
     */
    function CheckUserSpace()
    {
        global $cfg_mb_max;
        $uid = $this->M_ID;
        $hasuse = $this->GetUserSpace();
        $maxSize = $cfg_mb_max * 1024 * 1024;
        if($hasuse >= $maxSize)
        {
            ShowMsg('你的空間已滿，不允許上傳新文件！','-1');
            exit();
        }
    }

    /**
     *  更新用戶信息統計表
     *
     * @access    public
     * @param     string  $field  字段信息
     * @param     string  $uptype  更新類型
     * @return    string
     */
    function UpdateUserTj($field, $uptype='add')
    {
        global $dsql;
        $mid = $this->M_ID;
        $arr = $dsql->GetOne("Select * `#@__member_tj` where mid='$mid' ");
        if(!is_array($arr))
        {
            $arr = array('article'=>0,'album'=>0,'archives'=>0,'homecount'=>0,'pagecount'=>0,'feedback'=>0,'friend'=>0,'stow'=>0);
        }
        extract($arr);
        if(isset($$field))
        {
            if($uptype=='add')
            {
                $$field++;
            }
            else if($$field > 0)
            {
                $$field--;
            }
        }
        $inquery = "INSERT INTO `#@__member_tj` (`mid`,`article`,`album`,`archives`,`homecount`,`pagecount`,`feedback`,`friend`,`stow`)
               VALUES ('$mid','$article','$album','$archives','$homecount','$pagecount','$feedback','$friend','$stow'); ";
        $dsql->ExecuteNoneQuery("Delete From `#@__member_tj` where mid='$mid' ");
        $dsql->ExecuteNoneQuery($inquery);
    }

    //
    /**
     *  重置用戶信息
     *
     * @return    void
     */
    function ResetUser()
    {
        $this->fields = '';
        $this->M_ID = 0;
        $this->M_LoginID = '';
        $this->M_Rank = 0;
        $this->M_Face = "";
        $this->M_Money = 0;
        $this->M_UserName = "";
        $this->M_LoginTime = 0;
        $this->M_MbType = '';
        $this->M_Scores = 0;
        $this->M_Spacesta = -2;
        $this->M_UpTime = 0;
        $this->M_ExpTime = 0;
        $this->M_JoinTime = 0;
        $this->M_HasDay = 0;
        DropCookie('DedeUserID');
        DropCookie('DedeLoginTime');
    }

    /**
     *  獲取整數值
     *
     * @access    public
     * @param     string  $fnum  處理的數值
     * @return    string
     */
    function GetNum($fnum){
        $fnum = preg_replace("/[^0-9\.]/", '', $fnum);
        return $fnum;
    }

    /**
     *  用戶登錄
     *  把登錄密碼轉為指定長度md5數據
     *
     * @access    public
     * @param     string  $pwd  需要加密的密碼
     * @return    string
     */
    function GetEncodePwd($pwd)
    {
        global $cfg_mb_pwdtype;
        if(empty($cfg_mb_pwdtype)) $cfg_mb_pwdtype = '32';
        switch($cfg_mb_pwdtype)
        {
            case 'l16':
                return substr(md5($pwd), 0, 16);
            case 'r16':
                return substr(md5($pwd), 16, 16);
            case 'm16':
                return substr(md5($pwd), 8, 16);
            default:
                return md5($pwd);
        }
    }
    
    /**
     *  把數據庫密碼轉為特定長度
     *  如果數據庫密碼是明文的，本程序不支持
     *
     * @access    public
     * @param     string
     * @return    string
     */
    function GetShortPwd($dbpwd)
    {
        global $cfg_mb_pwdtype;
        if(empty($cfg_mb_pwdtype)) $cfg_mb_pwdtype = '32';
        $dbpwd = trim($dbpwd);
        if(strlen($dbpwd)==16)
        {
            return $dbpwd;
        }
        else
        {
            switch($cfg_mb_pwdtype)
            {
                case 'l16':
                    return substr($dbpwd, 0, 16);
                case 'r16':
                    return substr($dbpwd, 16, 16);
                case 'm16':
                    return substr($dbpwd, 8, 16);
                default:
                    return $dbpwd;
            }
        }
    }
    
    /**
     *  檢查用戶是否合法
     *
     * @access    public
     * @param     string  $loginuser  登錄用戶名
     * @param     string  $loginpwd  用戶密碼
     * @return    string
     */
    function CheckUser(&$loginuser, $loginpwd)
    {
        global $dsql;

        //檢測用戶名的合法性
        $rs = CheckUserID($loginuser,'用戶名',FALSE);

        //用戶名不正確時返回驗證錯誤，原登錄名通過引用返回錯誤提示信息
        if($rs!='ok')
        {
            $loginuser = $rs;
            return '0';
        }

        //matt=10 是管理員關連的前台帳號，為了安全起見，這個帳號只能從後台登錄，不能直接從前台登錄
        $row = $dsql->GetOne("SELECT mid,matt,pwd,logintime FROM `#@__member` WHERE userid LIKE '$loginuser' ");
        if(is_array($row))
        {
            if($this->GetShortPwd($row['pwd']) != $this->GetEncodePwd($loginpwd))
            {
                return -1;
            }
            else
            {
                //管理員帳號不允許從前台登錄
                if($row['matt']==10) {
                    return -2;
                }
                else {
                    $this->PutLoginInfo($row['mid'], $row['logintime']);
                    return 1;
                }
            }
        }
        else
        {
            return 0;
        }
    }

    /**
     *  保存用戶cookie
     *
     * @access    public
     * @param     string  $uid  用戶ID
     * @param     string  $logintime  登錄限制時間
     * @return    void
     */
    function PutLoginInfo($uid, $logintime=0)
    {
        global $cfg_login_adds, $dsql;
        //登錄增加積分(上一次登錄時間必須大於兩小時)
        if(time() - $logintime > 7200 && $cfg_login_adds > 0)
        {
            $dsql->ExecuteNoneQuery("Update `#@__member` set `scores`=`scores`+{$cfg_login_adds} where mid='$uid' ");
        }
        $this->M_ID = $uid;
        $this->M_LoginTime = time();
        $loginip = GetIP();
        $inquery = "UPDATE `#@__member` SET loginip='$loginip',logintime='".$this->M_LoginTime."' WHERE mid='".$uid."'";
        $dsql->ExecuteNoneQuery($inquery);
        if($this->M_KeepTime > 0)
        {
            PutCookie('DedeUserID',$uid,$this->M_KeepTime);
            PutCookie('DedeLoginTime',$this->M_LoginTime,$this->M_KeepTime);
        }
        else
        {
            PutCookie('DedeUserID',$uid);
            PutCookie('DedeLoginTime',$this->M_LoginTime);
        }
    }

    /**
     *  獲得會員目前的狀態
     *
     * @access    public
     * @param     string  $dsql  數據庫連接
     * @return    string
     */
    function GetSta($dsql)
    {
        $sta = '';
        if($this->M_Rank==0)
        {
            $sta .= "你目前的身份是：普通會員";
        }else{
            $row = $dsql->GetOne("Select membername From `#@__arcrank` where rank='".$this->M_Rank."'");
            $sta .= "你目前的身份是：".$row['membername'];
            $rs = $dsql->GetOne("Select id From `#@__admin` where userid='".$this->M_LoginID."'");
            if(!is_array($rs)){
                if($this->M_Rank>10 && $this->M_HasDay>0) $sta .= " 剩餘天數: <font color='red'>".$this->M_HasDay."</font>  天 ";
                elseif($this->M_Rank>10) $sta .= " <font color='red'>會員升級已經到期</font> ";
          }
        }
        $sta .= " 擁有金幣：{$this->M_Money} 個， 積分：{$this->M_Scores} 分。";
        return $sta;
    }
    
    /**
     *  記錄會員操作日誌
     *
     * @access    public
     * @param     string  $type 記錄類型
     * @param     string  $title 記錄標題
     * @param     string  $note記錄描述
     * @param     string  $aid涉及到的內容的id
     * @return    string
     */
    function RecordFeeds($type, $title, $note, $aid)
    {
        global $dsql,$cfg_mb_feedcheck;
        //確定是否需要記錄
        if (in_array($type,array('add','addsoft','feedback','addfriends','stow'))){
            $ntime = time();
            $title = cn_substrR($title,255);
            if(in_array($type,array('add','addsoft','feedback','stow')))
            {
                $rcdtype = array('add'=>' 成功發佈了', 'addsoft'=>' 成功發佈了軟件',
                                 'feedback'=>' 評論了文章','stow'=>' 收藏了');
                //內容發佈處理
                $arcrul = " <a href='/plus/view.php?aid=".$aid."'>".$title."</a>";
                $title = addslashes($rcdtype[$type].$arcrul);
            } else if ($type == 'addfriends')
            {
                //添加好友處理
                $arcrul = " <a href='/member/index.php?uid=".$aid."'>".$aid."</a>";
                $title = addslashes(' 與'. $arcrul."成為好友");
            }
            $note = Html2Text($note);
            $aid = (isset($aid) && is_numeric($aid) ? $aid : 0);
            $ischeck = ($cfg_mb_feedcheck == 'Y')? 0 : 1;
            $query = "INSERT INTO `#@__member_feed` (`mid`, `userid`, `uname`, `type`, `aid`, `dtime`,`title`, `note`, `ischeck`) 
                        Values('$this->M_ID', '$this->M_LoginID', '$this->M_UserName', '$type', '$aid', '$ntime', '$title', '$note', '$ischeck'); ";
            $rs = $dsql->ExecuteNoneQuery($query);
            return $rs;
        } else {
            return FALSE;
        }
    }
}//End Class