Discuz!X2主题热度的计算方式详解
时间:2011-10-24 17:21
主题热度可以真实的反应主题的火热程度,此数据较为客观公正,可以根据主题参与人次或者回复和评价数来增加主题的热度值。
*************************************************
** 代码讲解基于版本:Discuz! X 2.0 GBK **
*************************************************
主题热度可以真实的反应主题的火热程度,此数据较为客观公正,可以根据主题参与人次或者回复和评价数来增加主题的热度值。
主题热度存储在 pre_forum_thread 表的 heats 字段中。
一、如何设置:
涉及的文件:source\admincp\admincp_setting.php
搜索关键字:$settingnew['heatthread']
设置位置:后台 → 全局 → 站点功能 → 主题热度
对于热度的计算方式有两种:
1、按热度公式:其值为 1,程序中的判断代码为 $_G['setting']['heatthread']['type'] == 1
2、按参与人次:其值为 2,程序中的判断代码为 $_G['setting']['heatthread']['type'] == 2
二、如何应用:
1、按热度公式计算,会涉及两个参数:
1)单次回复热度值:
涉及的文件:source\include\post\post_newreply.php
搜索关键字:$_G['setting']['heatthread']['reply']
表示主题每次被回复时主题热度增量,默认值“5”,程序中取值代码为 $_G['setting']['heatthread']['reply']。
程序中,当对于主题的回复被提交后,首先要判断最后一次发帖人是不是当前用户,不是才会为主题增加热度值。即当前用户连续回帖,只有第一次回帖会为主题计入热度值,中间有其他用户参与回帖后,当前用户再回帖才会继续为主题计入热度值。
当可以为主题计入热度值是,首先要统计出当前用户在当前主题中的总回复数 $userreplies,然后通过下面的公式计算出此次回复应该增加的热度值:
round($_G['setting']['heatthread']['reply'] * pow(0.8, $userreplies))
含义是:每次被回复时主题热度增量 乘以 0.8 的(当前用户在当前主题中的总回复数)次幂 的值四舍五入为整数的结果。
举例:
主题每次被回复时主题热度增量为5,即 $_G['setting']['heatthread']['reply'] = 5
当前用户在当前主题中的总回复数为2,也就是已经回复过2次,即 $userreplies = 2
则当前用户在此主题中回复第3次时会增加的热度为:php实例计算
round(5 * 0.8^2) = round(5 * 0.64) = round(3.2) = 3
由此可以看出,回复第一次累计的热度最多,之后累计的热度会逐渐递减,当第22回复时将不再累计该主题的热度。
2)单次评价热度值:
涉及的文件:source\module\forum\forum_misc.php
搜索关键字:$_G['setting']['heatthread']['recommend']
表示主题每次被评价时主题热度增量,默认值“3”,程序中取值代
码为 $_G['setting']['heatthread']['recommend']。此处对应论坛中后台 → 全局 → 站点功能 → 主题评价的功能。
程序中,当对于主题的评价被提交后,便会按照如下公式算出此次评价应该增加的热度值:
abs($_G['group']['allowrecommend']) * $_G['setting']['heatthread']['recommend']
含义是:用户组中设定的“主题评价影响值”的绝对值 乘以 每次被评价时主题热度增量 的值。
其中的 $_G['group']['allowrecommend'] 是用户组中设定的“主题评价影响值”,设置位置:后台 → 用户
→ 用户组 → 编辑某一个用户组 → 论坛相关 → 帖子相关 → 主题评价影响值。
举例:
主题评价影响值为2,即 $_G['group']['allowrecommend'] = 2
主题每次被评价时主题热度增量为3,即 $_G['setting']['heatthread']['recommend'] = 3
则当前用户为此主题做出评价是会增加的热度为:
abs(2) * 3 = 6
2、按参与人次计算,会涉及一个参数:用户热度值周期(天)
涉及的文件:source\function\function_forum.php
搜索关键字:function update_threadpartake
此参数以天为单位,一个周期内某用户多次参与主题,只加一次热度。0代表不设置周期,只要参与一次,热度就加1。为避免用户刷热度,建议不要设置为0。回复、点评、评论、收藏、分享等都算作参与主题的动作。程序中取值代码为 $_G['setting']['heatthread']['period']。
程序中将此方式计算主题热度包装成为了一个函数(update_threadpartake),供程序中各个位置调用。
函数的大致工作逻辑为:
1)如果在后台设置了用户热度值的周期($_G['setting']['heatthread']['period'] 有值),则会在表 pre_forum_threadpartake 中查询是否包含当前用户($_G['uid'])当前主题($tid)的记录
(1) 如果没有记录,则会往这个表中增加一条记录,用以表示当前用户已经为此主题在当前周期内增加过热度值了,然后为主题的热度值加1。
(2) 如果有记录,则不再为主题增加热度。
2)如果在后台没有设置用户热度值的周期($_G['setting']['heatthread']['period'] 的值为0),则会直接为当前主题的热度值加1。
function update_threadpartake($tid) {
global $_G;
if($_G['uid'] && $tid) {
if($_G['setting']['heatthread']['period']) {
$partaked = DB::result_first("SELECT uid FROM ".DB::table('forum_threadpartake')." WHERE tid='$tid' AND uid='$_G[uid]'");
if(!$partaked) {
DB::query("INSERT INTO ".DB::table('forum_threadpartake')." (tid, uid, dateline) VALUES ('$tid', '$_G[uid]', ".TIMESTAMP.")");
DB::query("UPDATE ".DB::table('forum_thread')." SET heats=heats+1 WHERE tid='$tid'", 'UNBUFFERED');
}
} else {
DB::query("UPDATE "
.DB::table('forum_thread')." SET heats=heats+1 WHERE tid='$tid'", 'UNBUFFERED');
}
}
}
通过上面的描述可以看出,此逻辑的目的是在后台指定的时间周期内,一个人只会为一个主题增加一次热度值。但此函数只有往表 pre_forum_threadpartake 中插入数据的操作,那么在哪里对超过了设置的时间周期的记录进行清除的呢?答案是论坛的计划任务。
清除过期的热度增加记录,是在论坛的每日数据清理(source\include\cron\cron_cleanup_daily.php文件)计划任务中的。他会根据设置的时间周期,每日自动清理过期的记录。
if($settingnew['heatthread']['type'] == 2 && $settingnew['heatthread']['period']) {
$partakeperoid = 86400 * $settingnew['heatthread']['period'];
DB::query("DELETE FROM ".DB::table('forum_threadpartake')." WHERE dateline<'$_G[timestamp]'-$partakeperoid", 'UNBUFFERED');
}
在此种方式下可以增加主题的操作有:
1)回帖:source\include\post\post_newreply.php
2)收藏:source\include\spacecp\spacecp_favorite.php
3)分享:source\include\spacecp\spacecp_share.php
4)评分:source\module\forum\forum_misc.php
5)评价:source\module\forum\forum_misc.php
在以上文件中搜索 update_threadpartake 就可以到对应的代码位置了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论