本帖最后由 otherbank 于 2011-9-9 09:04 编辑
经测试Discuz! X2系统有一个积分BUG:就是你从一个版块复制主题到另一个版块时给发帖者的积分是按照原版块积分规则增加,按道理说应该按照新版块的积分规则来增加。
BUG分析:
1,在帖子页点击复制按钮,弹出复制选择框,用chrome浏览器审查元素,截图如下:
form表单的提交位置:- <form id="topicadminform" method="post" autocomplete="off" action="forum.php?mod=topicadmin&action=copy&modsubmit=yes&infloat=yes&modclick=yes" onsubmit="ajaxpost('topicadminform', 'return_mods', 'return_mods', 'onerror');return false;" fwin="mods">
复制代码 可知表单以post的方式提交给forum.php页面;forum.php页面引入了核心类并实例化,还引入了核心函数和论坛处理函数。
2,由forum.php?mod=topicadmin&action=copy&modsubmit=yes&infloat=yes&modclick=yes参数可知调用的是source/module/forum/forum_topicadmin.php 这个模组,source/module/forum/forum_topicadmin.php 引入了require_once libfile('function/post')也就是source/function/function_post.php函数;
其中它的67行代码--71行代码如下:- if(preg_match('/^\w+$/', $_G['gp_action']) && file_exists($topicadminfile = libfile('topicadmin/'.$_G['gp_action'], 'include'))) {
- require_once $topicadminfile;
- } else {
- showmessage('undefined_action', NULL);
- }
复制代码 可知文件调用到source/include/topicadmin/topicadmin_copy.php文件
3,可见source/include/topicadmin/topicadmin_copy.php文件是处理复制主题这个操作的程序文件,下面就是分析这个页面哪个函数调用了积分操作,source/include/topicadmin/topicadmin_copy.php程序文件中有一个函数:- updatepostcredits('+', $post['authorid'], 'post', $_G['fid']);
复制代码 经搜索这个函数来自,上一个页面source/module/forum/forum_topicadmin.php 调用的source/function/function_post.phpp函数,于是去这个函数中查询updatepostcredits()的作用。
4,source/function/function_post.phpp文件中updatepostcredits()函数又调用的开始引入的核心类中的函数updatecreditbyaction(),到此才看到核心类的代码:- function updatecreditbyaction($action, $uid = 0, $extrasql = array(), $needle = '', $coef = 1, $update = 1, $fid = 0) {
- include_once libfile('class/credit');
- $credit = & credit::instance();
- if($extrasql) {
- $credit->extrasql = $extrasql;
- }
- return $credit->execrule($action, $uid, $needle, $coef, $update, $fid);
- }
复制代码 可以看出函数引用了真正的分数处理类source/class/class_credit.php.
5,到类source/class/class_credit.php中看到类实例化中改变积分的函数是updatemembercount();代码是function_credit.php的270-271行:- if($sql) {
- DB::query("UPDATE ".DB::table('common_member_count')." SET ".implode(',', $sql)." WHERE uid IN (".dimplode($uids).")", 'UNBUFFERED');
- }
复制代码 整理下参数传递步骤:forum.php -->source/module/forum/forum_topicadmin.php -->source/include/topicadmin/topicadmin_copy.php -->source/function/function_post.phpp -->source/class/class_core.php-->source/class/class_credit.php
仔细研究代码,积分规则的参数传递来源源自source/include/topicadmin/topicadmin_copy.php 文件函数 updatepostcredits('+', $post['authorid'], 'post', $_G['fid']);而这个$_G['fid']的数值就是当前版块也就是主题转出前版块的fid值,后面的函数会以这个参数输出积分规则。而这个地方我们需要的是转入版块的fid指,也就是从表单提交上来的copyto的值,所以这样修改一下就OK了:
updatepostcredits('+', $post['authorid'], 'post', $copyto);
问题处理很简单,步骤如下,只需要修改一行代码即可:
source/include/topicadmin/topicadmin_copy.php文件81行代码- updatepostcredits('+', $post['authorid'], 'post', $_G['fid']);
复制代码 修改为:- updatepostcredits('+', $post['authorid'], 'post', $copyto);
复制代码 |