转:http://www.zlnxn.com/discuz%E4%B8%8B%E7%A7%AF%E5%88%86%E7%AD%96%E7%95%A5%E7%9A%84%E6%B7%BB%E5%8A%A0%E5%8F%8A%E7%AD%96%E7%95%A5%E9%99%90%E5%88%B6%E7%9A%84%E5%AE%9E%E7%8E%B0/
最近新的项目主要是做一个积分&金币&勋章体系,是基于Discuz的二次开发,所以难免要去研究一下Discuz的积分体系。首先去看了一下后台的积分设置,有些积分策略通过简单的设置后就可以用,但是有若干项积分策略则需要自己添加,并实现策略的限制。添加并不难,直接在数据库里插入相应的数据即可,最关键的是策略限制的实现。这里简单介绍一下何为策略限制,比如DZ(Discuz)原有的积分策略里有这么一条:每天登录一次,积分+2,金钱+1,奖励的次数为10次,这就是一个完整的积分策略,策略限制就是:每天登录-如何判定每次登录是在同一天;奖励次数10次-如何控制这个次数。
接下来就要深入到代码层面去跟踪分析,经过分析发现,策略限制的实现大概是这么一个思路:(1)从缓存文件中读取后台设置的积分策略(方法:loadcache(‘creditrule‘));(2)根据(1)得到的数组再从数据库中读出积分变化日志(方法:getrulelog());(3)根据(2)得到的结果开始实现积分策略的限制,该限制的实现主要通过switch($rule[‘cycletype‘])来控制分支走向,$rule[‘cycletype‘]也就是每个积分策略的周期类型,不同的周期的类型对应于不同的处理方式,每个积分策略动作的逻辑部分就是在这下面来实现。所以要新增一个积分策略,在数据库中添加完记录后,限制的实现就要在这个switch($rule[‘cycletype‘])控制语句下面来做,根据你所新增加的积分策略的周期类型,相应的增加case,然后在case下面实现所谓的限制(即:动作的逻辑部分)。
下面主要讲一下积分策略里最重要的一个方法:execrule($action, $uid = 0, $needle = ‘‘, $coef = 1, $update = 1, $fid = 0),该方法位于/source/class/class_credit。参数:$action-积分的动作,比如每天登录对应$action=daylogin,如果需要新增加一个积分策略,名称为:连续5天登录,那么$action可以取为login_continuous;$uid-用户id,这个不用多说;$needle-基本上用不着;$coef-积分系数;$update-控制是否进行积分变化日志的写入以及积分变化的最终执行,一般情况下使用默认的就可以;$fid-论坛id,主要用来读取个别论坛的积分的相关限制,一般使用默认。该方法主要分三部分:(1)getrule(),读取后台设置的积分策略,结果返回的是一个数组$rule,数组中包含rulename,cycletype,cycletime,rewardnum以及extcredits1-extcredits8中的某几项等,目的有二:a.作为updatemembercount()最终执行积分变化的重要参数;b.为积分策略限制提供相关数据。(2)getrulelog(),读取积分变化日志,作为限制实现的前期准备工作,也包括最初的一些判定;(3)switch($rule[‘cycletype‘]),限制真正开始实现的位置,关于这个控制语句上面已做介过绍,这里就不详说,这个控制语句最终决定参数$updatecredit的值是true还是false,即能否执行积分变化的操作:updatecreditbyrule()。实质上最终实现积分变化的方法是:updatemembercount()。这里说一个小窍门,就是如果你的积分策略限制很简单,而且也不需要缓存,写入日志等等这些的话,完全可以直接绕开DZ复杂的处理流程,只需要准备好一个数组$rule和$uid,比如array(‘extcredits2‘=>1,‘extcredits8‘=>5),$uid=1,然后直接调用updatemembercount($rule,$uid)就可以完成积分变化的操作了。但是如果为了程序的执行效率,也为了方便查看和分析积分的变化,个人建议还是沿用DZ的处理流程比较好。另外有一点值得注意的是:在后台添加完积分策略后,一定要记得清一下缓存,否则调用getrule()就会出现问题,得不到正确的$rule。今天就是因为没注意到清缓存,才导致浪费了很多时间,当时相当的困惑,最后是一步一步的跟踪代码才找到了原因。
在跟踪代码的时候利用die,exit,showmessage设置断点是不错的一种方式,另外建议大家使用ZEND 这个IDE作为开发工具,不仅因为它是IDE,还有一点比较重要:在跟踪代码的时候利用快捷键Ctrl和鼠标能够快速定位到下一个方法或者变量,具体操作方法是:先按下Ctrl然后用鼠标点击相关的方法或者变量就能够快速定位到了。这种方法对于像DZ这样一点儿注释也没有而且完全按照自己的产品思路封装起来的代码来说还是比较管用的。虽说DZ的代码读起来很恶心,没有注释,完全封装,不过还是有很多值得学习的地方,比如诸如缓存之类的东西,代码上的处理等等。最近因为项目和论坛业务的关系会比较多的接触DZ,希望能从中多学点有价值的东西,融为己用。
综上所述就是如何在DZ下面新增一个积分策略的大概过程,阅读此文的童鞋,若有觉得不妥的地方还请不吝指正,互相学习,互相借鉴,共同进步。