DX 2.0 class_credits.php解析

<?php

class credit {

    var $checklowerlimit = true;
    var $coef = 1;
    var $extrasql = array();

    function credit() {}

    function &instance() {
        static $object;
        if(empty($object)) {
            $object = new credit();
        }
        return $object;
    }
    //按照规则执行
    //例子:updatecreditbyaction('daylogin', $this->var['uid']);
    //action 规则名称
    //uid    操作用户
    //needle 防重字符串
    //coef   积分放大倍数
    //update 是否执行更新操作
    //fid    版块id
    function execrule($action, $uid = 0, $needle = '', $coef = 1, $update = 1, $fid = 0) {
        global $_G;

        $this->coef = $coef;
        $uid = intval($uid ? $uid : $_G['uid']);
        $fid = $fid ? $fid : (isset($_G['fid']) && $_G['fid'] ? $_G['fid'] : 0);
        //获取版块下的积分规则
        $rule = $this->getrule($action, $fid);
        //初使化更新积分状态
        $updatecredit = false;
        //该次操作是否可以执行
        $enabled = false;
        //检测该次操作是否可用(扩展的8个积分是否需要添加)
        if($rule) {
            for ($i = 1; $i<=8; $i++) {
                if(!empty($rule['extcredits'.$i])) {
                    $enabled = true; break;
                }
            }
        }

        if($enabled) {
            $rulelog = array();
            $fids = $rule['fids'] ? explode(',', $rule['fids']) : array();
            $fid = in_array($fid, $fids) ? $fid : 0;
            //获取规则日志 (uid,rid,fid)为索引
            $rulelog = $this->getrulelog($rule['rid'], $uid, $fid);
            //norepeat 是否去重1:去重;0:不去重
            if($rulelog && $rule['norepeat']) {
                $rulelog = array_merge($rulelog, $this->getchecklogbyclid($rulelog['clid'], $uid));
                $rulelog['norepeat'] = $rule['norepeat'];
            }
            //rewardnum   奖励次数
            if($rule['rewardnum'] && $rule['rewardnum'] < $coef) {
                $coef = $rule['rewardnum'];
            }
           
            //规则策略日志不存在时
            if(empty($rulelog)) {
                $logarr = array(
                    'uid' => $uid,
                    'rid' => $rule['rid'],
                    'fid' => $fid,
                    'total' => $coef,
                    'cyclenum' => $coef,
                    'dateline' => $_G['timestamp']
                );
                //cycletype  奖励周期0:一次;1:每天;2:整点;3:间隔分钟;4:不限
                if(in_array($rule['cycletype'], array(2,3))) {
                    $logarr['starttime'] = $_G['timestamp'];
                }
                //将规则策略信息转换成入库数组
                $logarr = $this->addlogarr($logarr, $rule, false);
                if($update) {
                    $clid = DB::insert('common_credit_rule_log', $logarr, 1);
                    if($rule['norepeat']) {
                        $rulelog['isnew'] = 1;
                        $rulelog['clid'] = $clid;
                        $rulelog['uid'] = $uid;
                        $rulelog['norepeat'] = $rule['norepeat'];
                        //规则策略防重,防欺骗信息
                        $this->updatecheating($rulelog, $needle, true);
                    }
                }
                $updatecredit = true;
            } else {
                //规则策略防重状态
                $newcycle = false;
                $logarr = array();
                switch($rule['cycletype']) {
                    case 0:
                        break;
                    case 1:
                    case 4:
                        if($rule['cycletype'] == 1) {
                            $today = strtotime(dgmdate($_G['timestamp'], 'Y-m-d'));
                            if($rulelog['dateline'] < $today && $rule['rewardnum']) {
                                $rulelog['cyclenum'] =  0;
                                $newcycle = true;
                            }
                        }
                        if(empty($rule['rewardnum']) || $rulelog['cyclenum'] < $rule['rewardnum']) {
                            if($rule['norepeat']) {
                                $repeat = $this->checkcheating($rulelog, $needle, $rule['norepeat']);
                                if($repeat && !$newcycle) {
                                    return false;
                                }
                            }
                            if($rule['rewardnum']) {
                                $remain = $rule['rewardnum'] - $rulelog['cyclenum'];
                                if($remain < $coef) {
                                    $coef = $remain;
                                }
                            }
                            $cyclenunm = $newcycle ? $coef : "cyclenum+'$coef'";
                            $logarr = array(
                                'cyclenum' => "cyclenum=$cyclenunm",
                                'total' => "total=total+'$coef'",
                                'dateline' => "dateline='$_G[timestamp]'"
                            );
                            $updatecredit = true;
                        }
                        break;

                    case 2:
                    case 3:
                        $nextcycle = 0;
                        if($rulelog['starttime']) {
                            if($rule['cycletype'] == 2) {
                                $start = strtotime(dgmdate($rulelog['starttime'], 'Y-m-d H:00:00'));
                                $nextcycle = $start+$rule['cycletime']*3600;
                            } else {
                                $nextcycle = $rulelog['starttime']+$rule['cycletime']*60;
                            }
                        }
                        if($_G['timestamp'] <= $nextcycle && $rulelog['cyclenum'] < $rule['rewardnum']) {
                            if($rule['norepeat']) {
                                $repeat = $this->checkcheating($rulelog, $needle, $rule['norepeat']);
                                if($repeat && !$newcycle) {
                                    return false;
                                }
                            }
                            if($rule['rewardnum']) {
                                $remain = $rule['rewardnum'] - $rulelog['cyclenum'];
                                if($remain < $coef) {
                                    $coef = $remain;
                                }
                            }
                            $cyclenunm = 'cyclenum+'.$coef;
                            $logarr = array(
                                'cyclenum' => "cyclenum=cyclenum+'$cyclenunm'",
                                'total' => "total=total+'$coef'",
                                'dateline' => "dateline='$_G[timestamp]'"
                            );
                            $updatecredit = true;
                        } elseif($_G['timestamp'] >= $nextcycle) {
                            $newcycle = true;
                            $logarr = array(
                                'cyclenum' => "cyclenum=$coef",
                                'total' => "total=total+'$coef'",
                                'dateline' => "dateline='$_G[timestamp]'",
                                'starttime' => "starttime='$_G[timestamp]'",
                            );
                            $updatecredit = true;
                        }
                        break;
                }
                if($update) {
                    if($rule['norepeat'] && $needle) {
                        $this->updatecheating($rulelog, $needle, $newcycle);
                    }
                    if($logarr) {
                        $logarr = $this->addlogarr($logarr, $rule, true);
                        DB::query("UPDATE ".DB::table('common_credit_rule_log')." SET ".implode(',', $logarr)." WHERE clid='$rulelog[clid]'");
                    }
                }

            }

        }
        if($update && ($updatecredit || $this->extrasql)) {
            if(!$updatecredit) {
                for($i = 1; $i <= 8; $i++) {
                    if(isset($_G['setting']['extcredits'][$i])) {
                        $rule['extcredits'.$i] = 0;
                    }
                }
            }
            $this->updatecreditbyrule($rule, $uid, $coef, $fid);
        }
        $rule['updatecredit'] = $updatecredit;

        return $rule;
    }
    //积分下限
    //checklowerlimit('reply', 0, 1, $_G['forum']['fid']);
    //rule
    //uid
    //coef
    //fid
    function lowerlimit($rule, $uid = 0, $coef = 1, $fid = 0) {
        global $_G;

        $uid = $uid ? $uid : intval($_G['uid']);
        //$_G['setting']['creditspolicy']['lowerlimit']  可用扩展积分的下限数
        if($this->checklowerlimit && $uid && $_G['setting']['creditspolicy']['lowerlimit']) {
            //当前操作的会员扩展积分信息
            $member = DB::fetch_first("SELECT * FROM ".DB::table('common_member_count')." WHERE uid='$uid'");
            $fid = $fid ? $fid : (isset($_G['fid']) && $_G['fid'] ? $_G['fid'] : 0);
            //获取对应的积分策略信息
            $rule = is_array($rule) ? $rule : $this->getrule($rule, $fid);
            for($i = 1; $i <= 8; $i++) {
                if($_G['setting']['extcredits'][$i] && $rule['extcredits'.$i]) {
                    //某扩展积分的下限
                    $limit = (float)$_G['setting']['creditspolicy']['lowerlimit'][$i];
                    //积分策略(即该次操作要添加或者删除多少对应的扩展积分)
                    $extcredit = (float)$rule['extcredits'.$i] * $coef;
                    if($extcredit < 0 && ($member['extcredits'.$i] + $extcredit) < $limit) {
                        return $i;
                    }
                }
            }
        }
        return true;
    }
    //更新积分通过某种规则策略
    //rule 积分规则信息
    //uids 用户id
    //coef 积分放大倍数
    function updatecreditbyrule($rule, $uids = 0, $coef = 1, $fid = 0) {
        global $_G;

        $this->coef = intval($coef);
        $fid = $fid ? $fid : (isset($_G['fid']) && $_G['fid'] ? $_G['fid'] : 0);
        $uids = $uids ? $uids : intval($_G['uid']);
        $rule = is_array($rule) ? $rule : $this->getrule($rule, $fid);
        $creditarr = array();
        $updatecredit = false;
        for($i = 1; $i <= 8; $i++) {
            if(isset($_G['setting']['extcredits'][$i])) {
                $creditarr['extcredits'.$i] = intval($rule['extcredits'.$i]) * $this->coef;
                $updatecredit = true;
            }
        }
        if($updatecredit || $this->extrasql) {
            $this->updatemembercount($creditarr, $uids, is_array($uids) ? false : true, $this->coef > 0 ? urldecode($rule['rulenameuni']) : '');
        }
    }
    //更新用户积分
    //creditarr 积分数据
    //uids      用户id
    //checkgroup 是否检测用户组
    //ruletxt
    function updatemembercount($creditarr, $uids = 0, $checkgroup = true, $ruletxt = '') {
        global $_G;

        if(!$uids) $uids = intval($_G['uid']);
        $uids = is_array($uids) ? $uids : array($uids);
        if($uids && ($creditarr || $this->extrasql)) {
            if($this->extrasql) $creditarr = array_merge($creditarr, $this->extrasql);
            $sql = array();
            //允许的规则策略
            $allowkey = array('posts', 'threads', 'digestposts');

            foreach($creditarr as $key => $value) {
                if(!empty($key) && in_array($key, $allowkey)) {
                    $value = intval($value);
                    $sql[] = "$key=$key+'$value'";
                    if($creditnotice && substr($key, 0, 10) == 'extcredits') {
                        $i = substr($key, 10);
                        $_G['cookiecredits'][$i] += $value;
                    }
                }
            }
            if($creditnotice) {
                dsetcookie('creditnotice', implode('D', $_G['cookiecredits']).'D'.$_G['uid']);
                dsetcookie('creditbase', '0D'.implode('D', $_G['cookiecreditsbase']));
                if(!empty($_G['cookiecreditsrule'])) {
                    dsetcookie('creditrule', strip_tags(implode("\t", $_G['cookiecreditsrule'])));
                }
            }
            if($sql) {
                DB::query("UPDATE ".DB::table('common_member_count')." SET ".implode(',', $sql)." WHERE uid IN (".dimplode($uids).")", 'UNBUFFERED');
            }
            //检测用户组
            if($checkgroup && count($uids) == 1) $this->checkusergroup($uids[0]);
            $this->extrasql = array();
        }
    }
    //统计用户积分
    //uid 用户id
    function countcredit($uid, $update = true) {
        global $_G;

        $credits = 0;
        //总积分计算公式
        //creditsformula的信息为$member['post']+-*/等信息
        if($uid && !empty($_G['setting']['creditsformula'])) {
            $member = DB::fetch_first("SELECT * FROM ".DB::table('common_member_count')." WHERE uid='$uid'");
            eval("\$credits = round(".$_G['setting']['creditsformula'].");");
            if($uid == $_G['uid']) {
                //更新用户总积分
                if($update && $_G['member']['credits'] != $credits) {
                    DB::update('common_member', array('credits'=>intval($credits)), array('uid' => $uid));
                    $_G['member']['credits'] = $credits;
                }
            } elseif($update) {
                DB::update('common_member', array('credits'=>intval($credits)), array('uid' => $uid));
            }
        }
        return $credits;
    }
    //检测用户的用户组
    //uid  用户id
    function checkusergroup($uid) {
        global $_G;
        //加载用户缓存信息
        loadcache('usergroups');
        $uid = intval($uid ? $uid : $_G['uid']);
        $groupid = 0;
        if(!$uid) return $groupid;
        if($uid != $_G['uid']) {
            $member = DB::fetch_first("SELECT * FROM ".DB::table('common_member')." WHERE uid='$uid'");
        } else {
            $member = $_G['member'];
        }
        if(empty($member)) return $groupid;
       
        //统计用户总积分
        $credits = $this->countcredit($uid, false);
        $updatearray = array();
        $groupid = $member['groupid'];
        //原用户组信息
        $group = $_G['cache']['usergroups'][$member['groupid']];
        //如果原总分与更新后的总积分(新总积分)不同时
        if($member['credits'] != $credits) {
            $updatearray['credits'] = $credits;
            $member['credits'] = $credits;
        }
        $member['credits'] = $member['credits'] == '' ? 0 : $member['credits'] ;
        //默认不发送升级通知
        $sendnotify = false;
        //判断是否更新用户组信息
        if(empty($group) || $group['type'] == 'member' && !($member['credits'] >= $group['creditshigher'] && $member['credits'] < $group['creditslower'])) {
            $newgroup = DB::fetch_first("SELECT grouptitle, groupid FROM ".DB::table('common_usergroup')." WHERE type='member' AND $member[credits]>=creditshigher AND $member[credits]<creditslower LIMIT 1");
            if(!empty($newgroup)) {
                if($member['groupid'] != $newgroup['groupid']) {
                    $updatearray['groupid'] = $groupid = $newgroup['groupid'];
                    $sendnotify = true;
                }
            }
        }
        //更新用户组信息
        if($updatearray) {
            DB::update('common_member', $updatearray, array('uid' => $uid));
        }
        //发送更新通知
        if($sendnotify) {
            notification_add($uid, 'system', 'user_usergroup', array('usergroup' => '<a href="home.php?mod=spacecp&ac=credit&op=usergroup">'.$newgroup['grouptitle'].'</a>'), 1);
        }
        //返回用户组id
        return $groupid;

    }
    //删除积分记录
    //后台积分策略处有该操作动作
    function deletelogbyfid($rid, $fid) {

        $fid = intval($fid);
        if($rid && $fid) {
            $lids = array();
            $query = DB::query("SELECT * FROM ".DB::table('common_credit_rule_log')." WHERE rid='$rid' AND fid='$fid'");
            while($value = DB::fetch($query)) {
                $lids[$value['clid']] = $value['clid'];
            }
            if($lids) {
                DB::query("DELETE FROM ".DB::table('common_credit_rule_log')." WHERE clid IN (".dimplode($lids).")");
                DB::query("DELETE FROM ".DB::table('common_credit_rule_log_field')." WHERE clid IN (".dimplode($lids).")");
            }
        }
    }
    //规则策略防重
    //rulelog  规则策略防重信息
    //needle  
    //newcycle
    function updatecheating($rulelog, $needle, $newcycle) {
        if($needle) {
            $logarr = array();
            switch($rulelog['norepeat']) {
                case 0:
                    break;
                case 1:
                    $info = empty($rulelog['info'])||$newcycle ? $needle : $rulelog['info'].','.$needle;
                    $logarr['info'] = addslashes($info);
                    break;
                case 2:
                    $user = empty($rulelog['user'])||$newcycle ? $needle : $rulelog['user'].','.$needle;
                    $logarr['user'] = addslashes($user);
                    break;
                case 3:
                    $app = empty($rulelog['app'])||$newcycle ? $needle : $rulelog['app'].','.$needle;
                    $logarr['app'] = addslashes($app);
                break;
            }
            if($rulelog['isnew']) {
                $logarr['clid'] = $rulelog['clid'];
                $logarr['uid'] = $rulelog['uid'];
                DB::insert('common_credit_rule_log_field', $logarr);
            } elseif($logarr) {
                DB::update('common_credit_rule_log_field', $logarr, array('uid'=>$rulelog['uid'], 'clid'=>$rulelog['clid']));
            }
        }
    }
    //添加积分记录
    //logarr 规则策略日志信息
    //rule   规则信息
    function addlogarr($logarr, $rule, $issql = 0) {
        global $_G;

        for($i = 1; $i <= 8; $i++) {
            if($_G['setting']['extcredits'][$i]) {
                $extcredit = intval($rule['extcredits'.$i]) * $this->coef;
                if($issql) {
                    $logarr['extcredits'.$i] = 'extcredits'.$i."='$extcredit'";
                } else {
                    $logarr['extcredits'.$i] = $extcredit;
                }
            }
        }
        return $logarr;
    }
    //获取规则某版块下的积分规则
    //action  规则action名称
    //fid     版块id
    function getrule($action, $fid = 0) {
        global $_G;

        if(empty($action)) {
            return false;
        }
        $fid = $fid ? $fid : (isset($_G['fid']) && $_G['fid'] ? $_G['fid'] : 0);
        //版块状态`status`(0:隐藏 1:正常 3:群组)
        if($_G['forum'] && $_G['forum']['status'] == 3) {
            $group_creditspolicy = $_G['grouplevels'][$_G['forum']['level']]['creditspolicy'];
            if(is_array($group_creditspolicy) && empty($group_creditspolicy[$action])) {
                return false;
            } else {
                $fid = 0;
            }
        }
        //加载积分规则(可查看后台,积分设置处)
        loadcache('creditrule');
        $rule = false;
        if(is_array($_G['cache']['creditrule'][$action])) {
            $rule = $_G['cache']['creditrule'][$action];
            $rulenameuni = $rule['rulenameuni'];
            if($rule['fids'] && $fid) {
                $fid = intval($fid);
                $fids = explode(',', $rule['fids']);
                if(in_array($fid, $fids)) {
                    //获取  版块积分策略
                    $policy = unserialize(DB::result_first("SELECT creditspolicy FROM ".DB::table('forum_forumfield')." WHERE fid='$fid'"));
                    if(isset($policy[$action])) {
                        $rule = $policy[$action];
                        $rule['rulenameuni'] = $rulenameuni;
                    }
                }
            }

            for($i = 1; $i <= 8; $i++) {
                if(empty($_G['setting']['extcredits'][$i])) {
                    unset($rule['extcredits'.$i]);
                    continue;
                }
                $rule['extcredits'.$i] = intval($rule['extcredits'.$i]);
            }
        }
        return $rule;
    }
    //规则日志(通过rid,uid,fid来得到一条规则策略信息)
    //rid 规则id
    //uid 用户id
    //fid 版块id
    function getrulelog($rid, $uid = 0, $fid = 0) {
        global $_G;

        $log = array();
        $uid = $uid ? $uid : $_G['uid'];
        if($rid && $uid) {
            $sql = " AND fid='$fid'";
            $query = DB::query("SELECT * FROM ".DB::table('common_credit_rule_log')." WHERE uid='$uid' AND rid='$rid' $sql");
            $log = DB::fetch($query);
        }
        return $log;
    }

    function checkcheating($rulelog, $needle, $checktype) {

        $repeat = false;
        switch($checktype) {
            case 0:
                break;
            case 1:
                $infoarr = explode(',', $rulelog['info']);
                if(!empty($rulelog['info']) && in_array($needle, $infoarr)) {
                    $repeat = true;
                }
                break;
            case 2:
                $userarr = explode(',', $rulelog['user']);
                if(!empty($rulelog['user']) && in_array($needle, $userarr)) {
                    $repeat = true;
                }
                break;
            case 3:
                $apparr = explode(',', $rulelog['app']);
                if(!empty($rulelog['app']) && in_array($needle, $apparr)) {
                    $repeat = true;
                }
                break;
        }
        return $repeat;
    }

    function getchecklogbyclid($clid, $uid = 0) {
        global $_G;

        $logarr = array();
        $uid = $uid ? $uid : $_G['uid'];
        if($clid && $uid) {
            $query = DB::query("SELECT info, user, app FROM ".DB::table('common_credit_rule_log_field')." WHERE uid='$uid' AND clid='$clid'");
            if(DB::num_rows($query)) {
                $logarr = DB::fetch($query);
            }
        }
        return $logarr;
    }
}

?>
 

你可能感兴趣的:(dz)