DISCUZ 架构:积分系统代码分析
1.登陆积分显示
首先是登陆,登陆的时候论坛从cdb_members中取出一些发帖数,积分,扩展积分等等设置,在./include/common.inc.php中有如下代码:
| 以下为引用的内容: $membertablefields = ‘m.uid AS discuz_uid, m.username AS discuz_user, m.password AS discuz_pw, m.secques AS discuz_secques, m.adminid, m.groupid, m.groupexpiry, m.extgroupids, m.email, m.timeoffset, m.tpp, m.ppp, m.posts, m.digestposts, m.oltime, m.pageviews, m.credits, m.extcredits1, m.extcredits2, m.extcredits3, m.extcredits4, m.extcredits5, m.extcredits6, m.extcredits7, m.extcredits8, m.timeformat, m.dateformat, m.pmsound, m.sigstatus, m.invisible, m.lastvisit, m.lastactivity, m.lastpost, m.newpm, m.accessmasks, m.xspacestatus, m.editormode, m.customshow’; |
以上就是取出数据库中的会员用到的字段。
发帖,回复,发附件,下附件等的积分增加或减少
2.发帖,回复积分增减
(1)原理分析:
| 以下为引用的内容: 是这样一个过程,发帖的时候前台看到的文件是:post.php, 然后引用如下文件: include/common.inc.php DZ通用函数库 include/post.func.php 发帖用到的函数库 include/discuzcode.func.php 解析Discuz Code用到的 |
接下来跟据传入的action判断引用到哪个文件继续处理
| 以下为引用的内容: include/newthread.inc.php(新帖) include/newreply.inc.php(回复) include/supesite_import.inc.php(导入到supersite) |
(2)代码分析:
下面就以发新帖来分析一下Discuz对于积分的处理。
第一部分:post.php
以下为引用的内容:
这个文件是发新帖,回复,投票都会用到的,所以它的作用就是初始化一些全局的东西,我就不全文件分析了,只分析一些与积分有关的部分。
| $postcredits = $forum['postcredits'] ? $forum['postcredits'] : $creditspolicy['post']; $replycredits = $forum['replycredits'] ? $forum['replycredits'] : $creditspolicy['reply']; $digestcredits = $forum['digestcredits'] ? $forum['digestcredits'] : $creditspolicy['digest']; $postattachcredits = $forum['postattachcredits'] ? $forum['postattachcredits'] : $creditspolicy['postattach']; |
这一部分的作用就是取出当前论坛的一些积分设置,和我们前面分析的数据表cdb_forumfields对应,得到会员发帖,回复等加多少分。
第二部分:include/newthread.inc.php
| 以下为引用的内容: 这个文件处理发新帖的特定请求。 if(isset($poll)) { $special = 1; } elseif(isset($trade)) { $special = 2; } elseif(isset($reward)) { $special = 3; } elseif(isset($activity)) { $special = 4; } else { $special = 0; } 这一部分的代码是用来判断帖子的类型的,1为投票,2为交易帖,3为悬赏,4为活动,0为普通帖。 $price = intval($price); $price = $maxprice && !$special ? ($price <= $maxprice ? $price : $maxprice) : 0; 这里是帖子价格的赋值,超过了最大的价格的处理,特殊帖子的价格处理。 } elseif($special == 3 && $allowpostreward) { $rewardprice = intval($rewardprice); if(!$rewardprice) { showmessage(‘reward_credits_please’); } elseif($rewardprice > 32767) { showmessage(‘reward_credits_overflow’); } elseif($rewardprice < $minrewardprice || ($maxrewardprice > 0 && $rewardprice > $maxrewardprice)) { showmessage(‘reward_credits_between’); } elseif(($realprice = $rewardprice + ceil($rewardprice * $creditstax)) > $_DSESSION["extcredits$creditstrans"]) { showmessage(‘reward_credits_shortage’); } $price = $rewardprice; $db->query(“UPDATE {$tablepre}members SET extcredits$creditstrans=extcredits$creditstrans-$realprice WHERE uid=’$discuz_uid’”); $searcharray[] = ‘[local]‘.$localid[$key].’[/local]‘; $pregarray[] = ‘/\[localimg=(\d{1,3}),(\d{1,3})\]‘.$localid[$key].’\[\/localimg\]/is’; $replacearray[] = ‘[attach]‘.$db->insert_id().’[/attach]‘; } $message = str_replace($searcharray, $replacearray, preg_replace($pregarray, $replacearray, $message)); $db->query(“UPDATE {$tablepre}posts SET message=’$message’ WHERE pid=’$pid’”); updatecredits($discuz_uid, $postattachcredits, count($attachments)); } 如果帖子中带有附件的话,就把附件插入cdb_attachments表,然后注意到$message这一个变量在这里用到了替换,这里的作用是图文混排。接下来往cdb_posts写一条记录,再用include/global.func.php定义到一个函数updatecredits来更新积分。 给Discuz的一个小建议:可以判断是不是postattachcredits为0,为0就可以不执行updatecredits这个函数,虽然在函数定义的时候也有判断,不过在这里判断似乎更好。 if($modnewthreads) { $db->query(“UPDATE {$tablepre}forums SET todayposts=todayposts+1 WHERE fid=’$fid’”, ‘UNBUFFERED’); } else { if($digest) { $lastpost = “$tid\t$subject\t$timestamp\t$author”; if($allowuseblog && $isblog && $blog) { } 3.下载附件积分增减这一部分主要用到的就是attachment.php这个文件了,下面就来分析这个文件中与积分中有关系的代码:
这一段的意思是:当一个附件不是图像的时候,取出该论坛对于下载附件的积分设置,比方说是-5分,那么就调用updatecredits(global.func中定义)这个函数更新一下积分。 P.S.:相关函数分析: updatepostcredits函数,定义于./include/post.func.php
可以看到这个函数有三个传入参数,$operator表示加还是减,$uidarray表示会员的id数组,$creditsarray表示要加减的积分数组。调用方法如: updatepostcredits(‘+’, 1, 1); 表示给uid为1的会员加1个积分 |

