Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

X2主题热度的计算方式详解

[复制链接]
ted1006 发表于 2011-2-27 16:12:50 | 显示全部楼层 |阅读模式
*************************************************
** 代码讲解基于版本: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,然后通过下面的公式计算出此次回复应该增加的热度值:

  1. round($_G['setting']['heatthread']['reply'] * pow(0.8, $userreplies))
复制代码
含义是:每次被回复时主题热度增量 乘以 0.8 的(当前用户在当前主题中的总回复数)次幂 的值四舍五入为整数的结果。
举例:
主题每次被回复时主题热度增量为5,即 $_G['setting']['heatthread']['reply'] = 5
当前用户在当前主题中的总回复数为2,也就是已经回复过2次,即 $userreplies = 2
则当前用户在此主题中回复第3次时会增加的热度为:
  1. 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']。此处对应论坛中后台 → 全局 → 站点功能 → 主题评价的功能。
程序中,当对于主题的评价被提交后,便会按照如下公式算出此次评价应该增加的热度值:
  1. abs($_G['group']['allowrecommend']) * $_G['setting']['heatthread']['recommend']
复制代码
含义是:用户组中设定的“主题评价影响值”的绝对值 乘以 每次被评价时主题热度增量 的值。
其中的 $_G['group']['allowrecommend'] 是用户组中设定的“主题评价影响值”,设置位置:后台 → 用户 → 用户组 → 编辑某一个用户组 → 论坛相关 → 帖子相关 → 主题评价影响值。
举例:
主题评价影响值为2,即 $_G['group']['allowrecommend'] = 2
主题每次被评价时主题热度增量为3,即 $_G['setting']['heatthread']['recommend'] = 3
则当前用户为此主题做出评价是会增加的热度为:
  1. 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。
  1. function update_threadpartake($tid) {
  2.     global $_G;
  3.     if($_G['uid'] && $tid) {
  4.         if($_G['setting']['heatthread']['period']) {
  5.             $partaked = DB::result_first("SELECT uid FROM ".DB::table('forum_threadpartake')." WHERE tid='$tid' AND uid='$_G[uid]'");
  6.             if(!$partaked) {
  7.                 DB::query("INSERT INTO ".DB::table('forum_threadpartake')." (tid, uid, dateline) VALUES ('$tid', '$_G[uid]', ".TIMESTAMP.")");
  8.                 DB::query("UPDATE ".DB::table('forum_thread')." SET heats=heats+1 WHERE tid='$tid'", 'UNBUFFERED');
  9.             }
  10.         } else {
  11.             DB::query("UPDATE ".DB::table('forum_thread')." SET heats=heats+1 WHERE tid='$tid'", 'UNBUFFERED');
  12.         }
  13.     }
  14. }
复制代码
通过上面的描述可以看出,此逻辑的目的是在后台指定的时间周期内,一个人只会为一个主题增加一次热度值。但此函数只有往表 pre_forum_threadpartake 中插入数据的操作,那么在哪里对超过了设置的时间周期的记录进行清除的呢?答案是论坛的计划任务。
清除过期的热度增加记录,是在论坛的每日数据清理(source\include\cron\cron_cleanup_daily.php文件)计划任务中的。他会根据设置的时间周期,每日自动清理过期的记录。
  1. if($settingnew['heatthread']['type'] == 2 && $settingnew['heatthread']['period']) {
  2.     $partakeperoid = 86400 * $settingnew['heatthread']['period'];
  3.     DB::query("DELETE FROM ".DB::table('forum_threadpartake')." WHERE dateline<'$_G[timestamp]'-$partakeperoid", 'UNBUFFERED');
  4. }
复制代码
在此种方式下可以增加主题的操作有:
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 就可以找到对应的代码位置了。

希望大家对主题的热度有一个系统的了解,如果在热度的增加上出现问题,可以按照此流程进行一些排查。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-12-22 11:28 , Processed in 0.021071 second(s), 3 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表