<?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; } } ?>