vBulletin HACK--讨论区发言情况统计


原因:让管理员可以清楚知道讨论区的发言情况。
优点:可以指定日期(精确到月)、论坛或分类、某个用户进行月、周、日、小时的话题、帖子数统计;自动检测有效日期以供选择;自动检测统计图的比例。
缺点:有些时候统计太精确反倒显得累赘。
自评:从大哥K.W.的UltraThread(一个非常棒的Perl+MySQL讨论区系统)得到的启发,功能略比K.W.的强。曾经想过精简MySQL的语句,但因为起点太高,要考虑匹配的条件太多,所以就放弃了。
   其实,大家还可以增加一些细节上去,例如只能让管理员查看统计的结果(加入检验身份)、一次查看多个用户的结果(循环地将判断语句加入到变量中)、人气等等。但作为统计程序,我个人认为我现在写的已经够复杂的了。算了吧!
范例:http://gogosoft.oso.com.cn/forum/ 在右上方话题、帖子数的右边有连接。

步骤:很简单,建立一个文件、几个模板,绝对不需要修改数据库结构。
⒈建立文件 analysis.php ,内容为“
<?php

require("global.php");

$analysises=$DB_site->query_first("SELECT COUNT(postid) AS max FROM post
                                   GROUP BY YEAR(FROM_UNIXTIME(dateline)),MONTH(FROM_UNIXTIME(dateline))
                                  "
);
$widthtime=floor(500/$analysises[max]);

$analysises=$DB_site->query_first("SELECT MONTH(FROM_UNIXTIME(dateline)) AS month,
                                          YEAR(FROM_UNIXTIME(dateline)) AS year,
                                          DAYOFMONTH(FROM_UNIXTIME(dateline)) AS day
                                   FROM thread
                                   ORDER BY dateline"
);
$minyear=$analysises[year];
$minmonth=$analysises[month];
$minday=$analysises[day];

if (isset(
$action)==or $action=="") {
  
$action="analysispost";
}

if (isset(
$month)==or $month=="") {
  
$month="0";
}

if (isset(
$year)==or $year=="") {
  
$year=$minyear;
}

//if ($action=="analysispost") {

  // 分析分类/论坛的指定
  
if (isset($forumid)==or $forumid=="" or $forumid=="0") {
    
$analysisobject="全部分类/论坛";
    
$leftjoin_post="";
    
$leftjoin_thread="";
    
$catforumlimit="";
  } else {
    if (
substr($forumid,0,3)=="cat") {
      
$categoryid=substr($forumid,3);
      
$categoryid verifyid("category",$categoryid);
      
$analysises=$DB_site->query_first("SELECT title FROM category WHERE categoryid=$categoryid");
      
$analysisobject="分类:$analysises[title]";
      
$leftjoin_post="LEFT JOIN thread ON (thread.threadid=post.threadid)
  LEFT JOIN forum ON (forum.forumid=thread.forumid)
  LEFT JOIN category ON (category.categoryid=forum.categoryid)"
;
      
$leftjoin_thread="LEFT JOIN forum ON (forum.forumid=thread.forumid)
  LEFT JOIN category ON (category.categoryid=forum.categoryid)"
;
      
$catforumlimit="AND category.categoryid=$categoryid ";
    } else {
      
$forumid verifyid("forum",$forumid);
      
$analysises=$DB_site->query_first("SELECT title FROM forum WHERE forumid=$forumid");
      
$analysisobject="论坛:$analysises[title]";
      
$leftjoin_post="LEFT JOIN thread ON (thread.threadid=post.threadid)
  LEFT JOIN forum ON (forum.forumid=thread.forumid)"
;
      
$leftjoin_thread="LEFT JOIN forum ON (forum.forumid=thread.forumid)";
      
$catforumlimit="AND forum.forumid=$forumid ";
    }
  }

  
// 分析用户的指定
  
if (isset($username)==or $username=="" or $username=="用户名") {
    
$username="用户名";
    
$analysisuser="全部用户";
    
$userlimit_post="";
    
$userlimit_thread="";
  } else {
    
$user=$DB_site->query_first("SELECT userid,password FROM user
                                 WHERE username='"
.addslashes($username)."'");
    
$userid=$user[userid];
    
$analysisuser=$username;
    
$userlimit_post="AND post.userid=$userid ";
    
$userlimit_thread="AND thread.postusername='$username'";
  }
  
  
// 日期下拉菜单
  
$analysisitems ="<select name="month">n";
  
$analysisitems.="  <option value="0">全部</option>n";
  for (
$j=$minyear;$j<=date("Y");$j++) {
    
$fromonth=iif($j==$minyear,$minmonth,1);
    
$tomonth=iif($j==date("Y"),date("n"),12);
    for (
$i=$fromonth;$i<=$tomonth;$i++) {
      
$selected=iif($j.$i==$month,"selected","");
      
$analysisitems.="  <option value=$j$i $selected>$j-$i</option>n";
    }
  }
  
$analysisitems.="</select>";

  
$forums=$DB_site->query("SELECT category.categoryid, category.title AS categorytitle,
                                  forumid, forum.title AS forumtitle
                           FROM category
                           LEFT JOIN forum ON (category.categoryid = forum.categoryid)
                           WHERE category.displayorder<>0 AND forum.displayorder <> 0 AND active=1
                           ORDER BY category.displayorder, forum.displayorder"
);
  
$firstcat 0;
  
$jumpforumbit "";
  while (
$forum=$DB_site->fetch_array($forums)) {
     
$currentcat $forum[categoryid];
     if (
$usecategories == 1) {
         
$optionselected="";        
         if (
$firstcat != $currentcat) { // Print Category
            
$firstcat $forum[categoryid];
            
// This creates our "blank line" in the dropdown
            
$jumpforumid="";   
            
$jumpforumtitle="";
            eval(
"$jumpforumbits .= "".gettemplate("jumpforumbit")."n";");
            
$jumpforumid="cat$forum[categoryid]";
            
$jumpforumtitle="分类: $forum[categorytitle]";
            eval(
"$jumpforumbits .= "".gettemplate("jumpforumbit")."n";");
            
$jumpforumid="";
            
$jumpforumtitle="--------------------";
            eval(
"$jumpforumbits .= "".gettemplate("jumpforumbit")."n";");
         }
     } 

     
$jumpforumid=$forum[forumid];    
     
$jumpforumtitle="  $forum[forumtitle]";    
     if (
$forumid==$jumpforumid) {    
       
$optionselected="selected";    
       
$selectedone=1;    
     }    
     eval(
"$jumpforumbits .= "".gettemplate("jumpforumbit")."n";");
  }
  
$forumjump="<SELECT NAME="forumid">
<option selected value="
0">全部论坛</option>
$jumpforumbits
</SELECT>"
;

  
$analysis_bits="";

  
$analysis_bit="";
  if (
$month<>"0") {
    
$month_year=substr($month,0,4);
    
$month_month=substr($month,4);
    
$analysisdisc="$month_year 年 $month_month 月的统计结果";
    
$monthlimit_post="AND MONTH(FROM_UNIXTIME(post.dateline))=$month_month
                      AND YEAR(FROM_UNIXTIME(post.dateline))=$month_year"
;
    
$monthlimit_thread="AND MONTH(FROM_UNIXTIME(thread.dateline))=$month_month
                        AND YEAR(FROM_UNIXTIME(thread.dateline))=$month_year"
;
    
$fromday=iif($month_year.$month_month==$minyear.$minmonth,$minday,1);
    
$today=iif($month_year.$month_month==date("Yn"),date("j"),31);
    for (
$i=$fromday;$i<=$today;$i++) {
      if (!
checkdate($month_month,$i,$month_year)) break;
      
$analysises=$DB_site->query_first("SELECT COUNT(postid) AS posts FROM post
                                         $leftjoin_post
                                         WHERE DAYOFMONTH(FROM_UNIXTIME(post.dateline))=$i $monthlimit
                                               $catforumlimit"
);
      
$analysispost=$analysises[posts];
      
$analysises=$DB_site->query_first("SELECT COUNT(threadid) AS threads FROM thread
                                         $leftjoin_thread
                                         WHERE DAYOFMONTH(FROM_UNIXTIME(thread.dateline))=$i $monthlimit
                                               $catforumlimit"
);
      
$analysisthread=$analysises[threads];
      
$analysisname=$i;
      
$analysisthread_w=floor($analysisthread*$widthtime);
      
$analysispost_w=floor($analysispost*$widthtime);
      
$backcolor=iif($i%2==0,"{firstaltcolor}","{secondaltcolor}");
      eval(
"$analysis_bit .= "".gettemplate("analysis_bit")."";");
    }
    eval(
"$analysis_bits .= "".gettemplate("analysis_day")."";");
  } else {
    
$analysisdisc="全部的统计结果 (从 $minyear-$minmonth-$minday 到 ".date("Y-n-j").")";
    for (
$j=$minyear;$j<=date("Y");$j++) {
      
$fromonth=iif($j==$minyear,$minmonth,1);
      
$tomonth=iif($j==date("Y"),date("n"),12);
      for (
$i=$fromonth;$i<=$tomonth;$i++) {
        
$analysises=$DB_site->query_first("SELECT COUNT(postid) AS posts FROM post
                                           $leftjoin_post
                                           WHERE MONTH(FROM_UNIXTIME(post.dateline))=$i
                                                 AND YEAR(FROM_UNIXTIME(post.dateline))=$j
                                                 $catforumlimit $userlimit_post"
);
        
$analysispost=$analysises[posts];
        
$analysises=$DB_site->query_first("SELECT COUNT(threadid) AS threads FROM thread
                                           $leftjoin_thread
                                           WHERE MONTH(FROM_UNIXTIME(thread.dateline))=$i
                                                 AND YEAR(FROM_UNIXTIME(thread.dateline))=$j
                                                 $catforumlimit $userlimit_thread"
);
        
$analysisthread=$analysises[threads];
        
$analysisname="<a href="analysis.php?month=$j$i">$j-$i</a>";
        
$analysisthread_w=floor($analysisthread*$widthtime);
        
$analysispost_w=floor($analysispost*$widthtime);
        
$backcolor=iif($i%2==0,"{firstaltcolor}","{secondaltcolor}");
        eval(
"$analysis_bit .= "".gettemplate("analysis_bit")."";");
      }
    }
    eval(
"$analysis_bits .= "".gettemplate("analysis_month")."";");
  }

  
$analysis_bit="";
  for (
$i=0;$i<7;$i++) {
    
$analysises=$DB_site->query_first("SELECT COUNT(postid) AS posts FROM post
                                       $leftjoin_post
                                       WHERE WEEKDAY(FROM_UNIXTIME(post.dateline))=$i $monthlimit
                                             $catforumlimit $userlimit_post"
);
    
$analysispost=$analysises[posts];
    
$analysises=$DB_site->query_first("SELECT COUNT(threadid) AS threads FROM thread
                                       $leftjoin_thread
                                       WHERE WEEKDAY(FROM_UNIXTIME(thread.dateline))=$i $monthlimit
                                             $catforumlimit $userlimit_thread"
);
    
$analysisthread=$analysises[threads];
    
$analysisname=$i+1;
    
$analysisthread_w=floor($analysisthread*$widthtime);
    
$analysispost_w=floor($analysispost*$widthtime);
    
$backcolor=iif($i%2==0,"{firstaltcolor}","{secondaltcolor}");
    eval(
"$analysis_bit .= "".gettemplate("analysis_bit")."";");
  }
  eval(
"$analysis_bits .= "".gettemplate("analysis_week")."";");

  
$analysis_bit="";
  for (
$i=0;$i<24;$i++) {
    
$analysises=$DB_site->query_first("SELECT COUNT(postid) AS posts FROM post
                                       $leftjoin_post
                                       WHERE HOUR(FROM_UNIXTIME(post.dateline))=$i $monthlimit
                                             $catforumlimit $userlimit_post"
);
    
$analysispost=$analysises[posts];
    
$analysises=$DB_site->query_first("SELECT COUNT(threadid) AS threads FROM thread
                                       $leftjoin_thread
                                       WHERE HOUR(FROM_UNIXTIME(thread.dateline))=$i $monthlimit
                                             $catforumlimit $userlimit_thread"
);
    
$analysisthread=$analysises[threads];
    
$analysisname=($i+1).":00-".($i+1).":59";
    
$analysisthread_w=floor($analysisthread*$widthtime);
    
$analysispost_w=floor($analysispost*$widthtime);
    
$backcolor=iif($i%2==0,"{firstaltcolor}","{secondaltcolor}");
    eval(
"$analysis_bit .= "".gettemplate("analysis_bit")."";");
  }
  eval(
"$analysis_bits .= "".gettemplate("analysis_hour")."";");

  eval(
"echo dovars("".gettemplate("analysis_home")."");");

//}

?>
”。

⒉新增模板 analysis_bit ,内容为“
<tr bgcolor="$backcolor">
<td nowrap><normalfont>$analysisname</normalfont></td>
<td align="center"><normalfont>$analysisthread</normalfont></td>
<td align="center"><normalfont>$analysispost</normalfont></td>
<td><img src="images/bar_t.gif" width="$analysisthread_w" height="6" border="0"><br><img src="images/bar_p.gif" width="$analysispost_w" height="6" border="0"></td>
</tr>
”,新增模板 analysis_day ,内容为“
<br><br><normalfont>每天发表的情况</normalfont>
<table width="100%" cellspacing="0" cellpadding="0"><tr>
<td width="100%" bgcolor="{tablebordercolor}">
<table border=0 cellpadding=4 cellspacing=1 width=100%>
<tr>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>天</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>话题数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>帖子数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="70%" align="center">
<normalfont color="{tableheadtextcolor}"><B>图</B></normalfont></td>
</tr>
$analysis_bit
</table>
</td></tr>
<tr><td align="right"><a href="#top"><smallfont>↑顶部</smallfont></a>
</td></tr></table>
”,新增模板 analysis_home ,内容为“
{htmldoctype}
<HTML>
<HEAD>
<TITLE>$bbtitle 统计</TITLE>
$cssinclude
</HEAD>
<body>
$header

<table border="0" width="100%"><tr>
<td valign="top" align="left"><a href="index.php"><img src="$titleimage" border="0"></a></td>

<td valign="middle" align="center" nowrap>
$fivelinks
</td></tr></table>
<form method="post" action="analysis.php">
<p align="right"><a name="top"></a>
<input type="submit" value="查看">$analysisitems$forumjump<input type="text" name="username" size="6" value="$username" onFocus="this.select()" onMouseOver="this.focus()"><smallfont>的统计结果 |
<a href="analysis.php">全部统计</a></smallfont>
</form>
<p><normalfont><b>$analysisobject $analysisuser</b>的<b>$analysisdisc</b></normalfont>
$analysis_bits

$footer

</body>
</html>
”,新增模板 analysis_hour ,内容为“
&nbsp;<br><normalfont><a name=hour>每小时发表的情况</a></normalfont>
<table width="100%" cellspacing="0" cellpadding="0"><tr>
<td width="100%" bgcolor="{tablebordercolor}">
<table border=0 cellpadding=4 cellspacing=1 width=100%>
<tr>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>小时</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>话题数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>帖子数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="70%" align="center">
<normalfont color="{tableheadtextcolor}"><B>图</B></normalfont></td>
</tr>
$analysis_bit
</table>
</td></tr>
<tr><td align="right"><a href="#top"><smallfont>↑顶部</smallfont></a>
</td></tr></table>
”,新增模板 analysis_month ,内容为“
<br><br><normalfont>每月发表的情况</normalfont>
<table width="100%" cellspacing="0" cellpadding="0"><tr>
<td width="100%" bgcolor="{tablebordercolor}">
<table border=0 cellpadding=4 cellspacing=1 width=100%>
<tr>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>月</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>话题数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>帖子数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="70%" align="center">
<normalfont color="{tableheadtextcolor}"><B>图</B></normalfont></td>
</tr>
$analysis_bit
</table></td></tr>
<tr><td align="right"><a href="#top"><smallfont>↑顶部</smallfont></a>
</td></tr></table>
”,新增模板 analysis_week ,内容为“
&nbsp;<br><normalfont><a name="week">每星期发表的情况</a></normalfont>
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr>
<td bgcolor="{tablebordercolor}" width="100%">
<table border=0 cellpadding=4 cellspacing=1 width="100%">
<tr>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>星期</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>话题数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="10%" align="center">
<normalfont color="{tableheadtextcolor}"><B>帖子数</B></normalfont></td>
<td bgcolor="{tableheadbgcolor}" width="70%" align="center">
<normalfont color="{tableheadtextcolor}"><B>图</B></normalfont></td>
</tr>
$analysis_bit
</table></td></tr>
<tr><td align="right"><a href="#top"><smallfont>↑顶部</smallfont></a>
</td></tr></table>
”。完成!

使用时,缺省地,程序统计全部论坛的全部用户的全部情况,你可以选择某一年月(经程序自动检测全部可用绝无多余)、某一论坛或分类、某一用户这三个条件中的任一个或一个以上。