vBulletin HACK--以vB代码实现的投票系统


更新:增加了开放/关闭投票功能,更稳定。
原因:1.1.4版本中没有投票功能,但投票又是颇重要的。
优点:识别当前用户曾否投票(以数据库形式存储,绝非Cookie);在帖子中显示投票结果(百分比、投票用户名);以帖子的形式显示投票项目,不像其他大部分的投票HACK,一个投票项目一个话题,无法进行其它交谈;提出投票的用户可以随时关闭、开放投票;
缺点:不登录的话,就无法查看投票情况。同一帖子如果一两个或以上的投票项目存在,则无法显示第二个或以后的投票情况——但可以投票。
自评:曾经从vBulletin下了一个 Poll Hack 回来,但觉得很复杂,需要修改很多地方的源代码,界面也累赘。鉴于新版本将内置此功能,所以本人就写了个环保些的,不用那么多改动的投票HACK。

步骤:
⒈打开 global.php ,查找“
function bbcodeparse2($bbcode,$forumid=0,$allowsmilie=1) {
”,在后面(适当位置)加入“
  global $bbusername,$bbpassword,$threadid,$postid;
”(如果已经有其中若干个变量的声明,则可以省略它),查找本函数段关于解释 [code] 部分,例如“
      $bbcode=str_replace("[code]rn","</normalfont><blockquote><pre><smallfont>代码:</smallfont><hr>",$bbcode);
      $bbcode=str_replace("[code]","</normalfont><blockquote><pre><smallfont>代码:</smallfont><hr>",$bbcode);
      $bbcode=str_replace("[/code]rn","<hr></pre><normalfont></blockquote>",$bbcode);
      $bbcode=str_replace("[/code]","<hr></pre><normalfont></blockquote>",$bbcode);
”(我提供的包装“代码”两字忘记汉化了,抱歉),在此之前(如果有《code HACK》则 应在HACK前),加入“
      // Hack gogopoll
      if (eregi("\[poll=([^\[]*)\]",$bbcode,$regs)) {
        $pollitem = array();
        $pollname=$regs[1];
        $pollbits=$DB_site->query("SELECT pollitem,polls,user FROM poll WHERE pollname='$pollname'");
        $pollopenclose="关闭";
        $pollopenclosed="开放";
        while ($pollbit=$DB_site->fetch_array($pollbits)) {
          if ($pollbit[pollitem]=="" AND $pollbit[polls]==0 AND $pollbit[user]=="") {
            $pollopenclose="开放";
            $pollopenclosed="关闭";
          }
          $pollitem[$pollbit[pollitem]]=$pollbit[polls];
          $polluser[$pollbit[pollitem]]=substr($pollbit[user],1,-1);
          $pollsum+=$pollbit[polls];
        }
        $pollsum=max(1,$pollsum);
        if ($bbusername!="" or $bbpassword!="") {
          $bbcode=eregi_replace("\[poll=([^\[]*)\]","<form method=post action=poll.php>n<input type=hidden name=pollname value="\1"><input type=hidden name=threadid value=$threadid><input type=hidden name=postid value=$postid>n题目:<b>\1</b>(目前$pollopenclosed)",$bbcode);
          $bbcode=eregi_replace("\[/poll\]","<input type=submit value="投票" name="action"><input type=submit value="$pollopenclose" name="action"><input type=hidden name=username value=$bbusername><input type=hidden name=password value=$bbpassword>n</form>",$bbcode);
          while (eregi("\[pi\]([^\[]*)\[/pi\]",$bbcode,$regs)) {
            $poll=$regs[1];
            $pollvalue=eregi_replace("<[^<]*>","",$poll);
            $bbcode=eregi_replace("\[pi\](".$poll.")\[/pi\]","<input type=radio name=pollitem value=$pollvalue>$poll (".floor($pollitem[$pollvalue])."票, ".floor($pollitem[$pollvalue]/$pollsum*100)."%, $polluser[$pollvalue])",$bbcode);
          }
        } else {
          $bbcode=eregi_replace("\[poll=([^\[]*)\](.*)\[/poll\]","<b>此处为投票内容,请登录才可以使用!</b>",$bbcode);    // Footer
        }
      }
      // End Hack gogopoll
”;

⒉新增模板 error_pollclosed ,内容为“
投票已经关闭,请返回浏览其它帖子。
”,新增模板 error_usernoclose ,内容为“
抱歉!你没有权限关闭或开放此投票。
”,新增模板 error_userpolled ,内容为“
您已经投了票!请使用后退键自行返回帖子
”,新增模板 redirect_pollclosethanks ,内容为“
感谢您关闭投票, $username. 您现在将返回投票帖.
”,新增模板 redirect_pollopenthanks ,内容为“
感谢您开放投票, $username. 您现在将返回投票帖.
”,新增模板 redirect_pollthanks ,内容为“
感谢您发表投票, $username. 您现在将返回投票帖.
”。

⒊新建文件 poll.php ,内容为“
<?php

require("global.php");

checkipban();

// ############################### start post poll ###############################

  //check valid username and password and get user id
  
$userid=verifyusername($username,$password);

  
$userinfo=$DB_site->query_first("SELECT canpost FROM user WHERE userid=$userid");
  if (
$userinfo[canpost]==0) {
    echo 
standarderror($bbtitle,gettemplate("error_usernopost",0));
    exit;
  }

if (
$action=="投票") {
  if (
$pollinfo=$DB_site->query_first("SELECT * FROM poll
                                                WHERE pollname='$pollname' AND pollitem=''
                                                      AND polls=0 AND user=''"
)) {
    echo 
standarderror($bbtitle,gettemplate("error_pollclosed",0));
    exit;
  }

// Check if user polled
  
if ($usersinfo=$DB_site->query("SELECT user FROM poll WHERE pollname='$pollname'")) {
    while (
$userinfo=$DB_site->fetch_array($usersinfo)) $alluser.=$userinfo[user];
    if (
eregi(",($username),",$alluser)) {
//      echo standarderror($bbtitle,gettemplate("error_userpolled",0));
//      exit;
    
}
  }
  
// Check if db exist
  
if ($pollinfo=$DB_site->query_first("SELECT user FROM poll WHERE pollname='$pollname' AND pollitem='$pollitem'")) {
    
$users.=$pollinfo[user].$username.",";
    
$DB_site->query("UPDATE poll SET polls=polls+1, user='".$users."' WHERE pollname='$pollname' AND pollitem='$pollitem'");
  } else {
    
$DB_site->query("INSERT INTO poll VALUES ('$pollname','$pollitem',1,',$username,')");
  }

  
$DB_site->query("UPDATE thread SET lastpost=".time().",lastposter='".addslashes($username)."' WHERE threadid=$threadid");
  
$DB_site->query("UPDATE post SET dateline=".time()." WHERE postid=$postid");

  eval(
"echo standardredirect($bbtitle,"".gettemplate("redirect_pollthanks")."","showthread.php?postid=$postid");");
}

if (
$action=="关闭") {
  
$userinfo=$DB_site->query_first("SELECT userid FROM post WHERE postid=$postid");
  if (
$userid==$userinfo[userid]) {
    
$DB_site->query("INSERT INTO poll VALUES ('$pollname','',0,'')");
    eval(
"echo standardredirect($bbtitle,"".gettemplate("redirect_pollclosethanks")."","showthread.php?postid=$postid");");
  } else {
    echo 
standarderror($bbtitle,gettemplate("error_usernoclose",0));
    exit;
  }
}

if (
$action=="开放") {
  
$userinfo=$DB_site->query_first("SELECT userid FROM post WHERE postid=$postid");
  if (
$userid==$userinfo[userid]) {
    
$DB_site->query("DELETE FROM poll 
                     WHERE pollname='$pollname' AND pollitem='' AND polls=0 AND user=''"
);
    eval(
"echo standardredirect($bbtitle,"".gettemplate("redirect_pollopenthanks")."","showthread.php?postid=$postid");");
  } else {
    echo 
standarderror($bbtitle,gettemplate("error_usernoclose",0));
    exit;
  }
}
?>
”。完成!

使用此投票功能很简单,,只需要在帖子内容中加入如下格式的vB代码“
[poll=投票项目/问题]
[pi]第一选项[/pi]
[pi]第二选项[/pi]
……
[pi]第若干选项[/pi]
[/poll]
”即可。悄悄话内容可以使用任意的vB代码、笑脸、HTML代码——如果被允许。
范例:http://gogosoft.oso.com.cn/forum/showthread.php?threadid=5