RatingExtension/Source Code

From PeacockWiki

(Difference between revisions)
Jump to: navigation, search
Revision as of 02:11, 30 July 2006 (edit)
Trevorp (Talk | contribs)

← Previous diff
Revision as of 04:34, 30 July 2006 (edit)
Trevorp (Talk | contribs)

Next diff →
Line 1: Line 1:
<pre><?php <pre><?php
-#If html request requests file, serve file+################################################################################
 +# Core Code #
 +################################################################################
 +# This section handles the core functions of this extension #
 +# * Serving Files #
 +# * Recording Ratings #
 +# * Displaying Ratings #
 +################################################################################
 + 
 +#-------------------------------------------------------------------------------
 +# If html request requests file, serve file #
 +# Files are requested by adding the ?file= GET parameter #
 +#-------------------------------------------------------------------------------
if(isset($_GET['file'])) if(isset($_GET['file']))
doFile(); doFile();
-#If html request contains rate information, process it+#-------------------------------------------------------------------------------
 +# If html request contains rate information, process it #
 +# Rating information indicated by ?rate= GET parameter #
 +# #
 +# MediaWiki engine is started by imitating the code in index.php #
 +# This ensures database functions are working #
 +#-------------------------------------------------------------------------------
if(isset($_GET['rate'])) if(isset($_GET['rate']))
{ {
Line 15: Line 33:
$action = $wgRequest->getVal( 'action', 'view' ); $action = $wgRequest->getVal( 'action', 'view' );
$title = $wgRequest->getVal( 'title' ); $title = $wgRequest->getVal( 'title' );
- $wgTitle = $mediaWiki->checkInitialQueries( $title,$action,$wgOut, $wgRequest, $wgContLang );+ $wgTitle = $mediaWiki->checkInitialQueries($title, $action, $wgOut,
 + $wgRequest, $wgContLang);
#Record Rating #Record Rating
#---------------- #----------------
- $sql = "REPLACE INTO `ratings` (`page_oldid`, `user_id`, `page_rating`) VALUES (".$_GET['oldid'].", '".($wgUser->getID()?$wgUser->getID():$wgUser->getName())."', ".$_GET['rate'].")";+ $sql = "REPLACE INTO `ratings` (`page_oldid`, `user_id`, `page_rating`) '.
 + 'VALUES (".$_GET['oldid'].", '".
 + ($wgUser->getID()?$wgUser->getID():$wgUser->getName()).
 + "', ".$_GET['rate'].")";
$dbr =& wfGetDB( DB_WRITE ); $dbr =& wfGetDB( DB_WRITE );
$res=wfQuery($sql, DB_WRITE, ""); $res=wfQuery($sql, DB_WRITE, "");
Line 31: Line 53:
} }
-#get oldid of current page+#-------------------------------------------------------------------------------
 +# Initialize extension #
 +# Sets up credit information, and hooks #
 +#-------------------------------------------------------------------------------
 +if(isset($wgScriptPath))
 +{
 +$wgExtensionCredits["parserhook"][]=array(
 + 'name' => 'Rating Extension',
 + 'version' => '0.1',
 + 'url' => 'http://wiki.peacocktech.com/wiki/RatingExtension',
 + 'author' => '[http://about.peacocktech.com/trevorp/ Trevor Peacock]',
 + 'description' => 'Adds rating mechanism' );
 + $wgHooks['OutputPageBeforeHTML'][] = 'InsertRating';
 + $wgHooks['SkinTemplateSetupPageCss'][] = 'RatingCss';
 +}
 + 
 +#-------------------------------------------------------------------------------
 +# Insert rating to top of page #
 +#-------------------------------------------------------------------------------
 +function InsertRating($parserOutput, $text) {
 + global $wgArticle;
 + $oldid=getOldID($wgArticle);
 + if($oldid)
 + $text='<div id="ratingsection">'.
 + getRatingHTML(getRating($oldid), $oldid).'</div>'.$text;
 +}
 + 
 + 
 + 
 +#-------------------------------------------------------------------------------
 +# Add CSS into skin for rating #
 +#-------------------------------------------------------------------------------
 +function RatingCss(&$css) {
 + global $wgScriptPath;
 + $css = "/*<![CDATA[*/".
 + " @import \"$wgScriptPath/?file=rating.css\"; ".
 + "/*]]>*/";
 + return true;
 +}
 + 
 +################################################################################
 +# Supporting Functions #
 +################################################################################
 +# These functions support the core functions of the extension #
 +################################################################################
 + 
 +#-------------------------------------------------------------------------------
 +# Use the mediawiki engine to run the given sql code and return an object #
 +# containing the first result of the query #
 +#-------------------------------------------------------------------------------
 +#run sql code
 +function runQuery($sql)
 +{
 + $dbr =& wfGetDB( DB_SLAVE );
 + $res=wfQuery($sql, DB_SLAVE, "");
 + return $dbr->fetchObject( $res );
 +}
 + 
 +#-------------------------------------------------------------------------------
 +# Return the oldid of the current page #
 +# If oldid=0 (most current revision) take the latest oldid from the database #
 +# for the current article #
 +#-------------------------------------------------------------------------------
function getOldID($article) function getOldID($article)
{ {
Line 38: Line 122:
return $oldid; return $oldid;
$dbr =& wfGetDB( DB_SLAVE ); $dbr =& wfGetDB( DB_SLAVE );
- $sql = "SELECT MAX(`rc_this_oldid`) AS `rc_this_oldid` FROM recentchanges WHERE rc_cur_id=".$article->getID().";";+ $sql = "SELECT MAX(`rc_this_oldid`) AS `rc_this_oldid` FROM recentchanges '.
- $res=wfQuery($sql, DB_WRITE, "");+ 'WHERE rc_cur_id=".$article->getID().";";
 + $res=wfQuery($sql, DB_SLAVE, "");
$row=$dbr->fetchObject( $res ); $row=$dbr->fetchObject( $res );
if($row->rc_this_oldid) if($row->rc_this_oldid)
Line 46: Line 131:
} }
-#run sql code+#-------------------------------------------------------------------------------
-function runQuery($sql)+# Performs a SQL query to fetch a rating for page oldid #
-{+#-------------------------------------------------------------------------------
- $dbr =& wfGetDB( DB_SLAVE );+
- $res=wfQuery($sql, DB_SLAVE, "");+
- return $dbr->fetchObject( $res );+
-}+
- +
-#perform sql query to fetch rating for a given oldid+
function getRatingData($oldid) function getRatingData($oldid)
{ {
- $sql="SELECT COUNT(*) AS `count`, AVG(`page_rating`) AS `rating` FROM ratings WHERE `page_oldid`=".$oldid." GROUP BY `page_oldid`;";+ $sql="SELECT COUNT(*) AS `count`, AVG(`page_rating`) AS `rating` '.
 + 'FROM ratings WHERE `page_oldid`=".$oldid." GROUP BY `page_oldid`;";
return runQuery($sql); return runQuery($sql);
} }
-#fetch/calculate rating from database+#-------------------------------------------------------------------------------
 +# Fetch and calculate a rating for page oldid #
 +# If there are not enough ratings for the current revivion, cycle #
 +# older revisions to gather a minimum number of ratings #
 +#-------------------------------------------------------------------------------
function getRating($oldid) function getRating($oldid)
{ {
Line 71: Line 155:
$finalrating='?'; $finalrating='?';
$currentcount=number_format($ratingdata->count, 0); $currentcount=number_format($ratingdata->count, 0);
 + #If there are not enough ratings for the current revision
if($rating->count<$countlimit) if($rating->count<$countlimit)
{ {
$count=$ratingdata->count; $count=$ratingdata->count;
$rating=$count*$ratingdata->rating; $rating=$count*$ratingdata->rating;
-# echo "not enough data ($rating/$count)\n";+ #cycle older revisions looking for more ratings
- while($oldid=$wgTitle->getPreviousRevisionID($oldid))+ while($oldid=$wgTitle->getPreviousRevisionID($oldid))
{ {
-# echo "trying previous ratings\n"; 
$ratingdata=getRatingData($oldid); $ratingdata=getRatingData($oldid);
 + #If still not enough ratings
if($count+$ratingdata->count<$countlimit) if($count+$ratingdata->count<$countlimit)
{ {
$count+=$ratingdata->count; $count+=$ratingdata->count;
$rating+=$ratingdata->count*$ratingdata->rating; $rating+=$ratingdata->count*$ratingdata->rating;
-# echo "still not enough data ($rating/$count)\n"; 
} }
- else+ else #found enough ratings
{ {
$rating+=($countlimit-$count)*$ratingdata->rating; $rating+=($countlimit-$count)*$ratingdata->rating;
$count=$countlimit; $count=$countlimit;
-# echo "enough data ($rating/$count)\n"; 
$finalrating=$rating/$count; $finalrating=$rating/$count;
$oldid=false; $oldid=false;
Line 98: Line 181:
else else
$finalrating=$rating/$count; $finalrating=$rating/$count;
- + 
 + #format rating data
if(is_numeric($finalrating)) if(is_numeric($finalrating))
$finalrating=($finalrating-1)*1.25; $finalrating=($finalrating-1)*1.25;
- $ratingarray=array('display'=>(is_numeric($finalrating)?number_format($finalrating, 2):$finalrating)." ($currentcount ratings)",+ $ratingarray=array('display'=>
 + (is_numeric($finalrating)?number_format($finalrating, 2):$finalrating).
 + " ($currentcount ratings)",
'count'=>$currentcount, 'count'=>$currentcount,
'rating'=>(is_numeric($finalrating)?$finalrating:0)); 'rating'=>(is_numeric($finalrating)?$finalrating:0));
Line 107: Line 193:
} }
-#Generate html code to insert into page+#-------------------------------------------------------------------------------
 +# Given the rating array and the page oldid, generate HTML code to be #
 +# displayed #
 +#-------------------------------------------------------------------------------
function getRatingHTML($rating, $oldid) function getRatingHTML($rating, $oldid)
{ {
Line 113: Line 202:
$countlimit=3; $countlimit=3;
$html=''; $html='';
 + #generate stars
for($x=0;$x<=4;$x++) for($x=0;$x<=4;$x++)
{ {
- $html.='<a href="'.$wgTitle->getFullURL('oldid='.$oldid.'&rate='.($x+1)).'">'.+ $html.='<a href="'.
- '<img src="'.$wgScriptPath.'/extensions/rating/star';+ $wgTitle->getFullURL('oldid='.$oldid.'&rate='.($x+1)).'">'.
- if($rating['rating']>=$x+1)+ '<img src="?file=star';
 + if($rating['rating']>=$x+1) #larger than current star : filled
$html.='4'.($rating['count']<$countlimit?'b':''); $html.='4'.($rating['count']<$countlimit?'b':'');
- elseif($rating['rating']>$x+0.75)+ elseif($rating['rating']>$x+0.75) #3/4 current star : 3/4 filled
$html.='3'.($rating['count']<$countlimit?'b':''); $html.='3'.($rating['count']<$countlimit?'b':'');
- elseif($rating['rating']>$x+0.5)+ elseif($rating['rating']>$x+0.5) #1/2 current star : 1/2 filled
$html.='2'.($rating['count']<$countlimit?'b':''); $html.='2'.($rating['count']<$countlimit?'b':'');
- elseif($rating['rating']>$x+0.25)+ elseif($rating['rating']>$x+0.25) #1/4 current star : 1/4 filled
$html.='1'.($rating['count']<$countlimit?'b':''); $html.='1'.($rating['count']<$countlimit?'b':'');
- else+ else #less than current star : empty
$html.='0'; $html.='0';
$html.='.png" align=bottom/></a>'."\n"; $html.='.png" align=bottom/></a>'."\n";
} }
 + #add text rating
$html.=' '.$rating['display'].''; $html.=' '.$rating['display'].'';
$html=($rating['count']<$countlimit?'<b>'.$html.'</b>':$html); $html=($rating['count']<$countlimit?'<b>'.$html.'</b>':$html);
return $html; return $html;
-} 
- 
-#Insert rating to top of page 
-function InsertRating($parserOutput, $text) { 
- global $wgArticle; 
- $oldid=getOldID($wgArticle); 
- if($oldid) 
- $text='<div id="ratingsection">'.getRatingHTML(getRating($oldid), $oldid).'</div>'.$text; 
-} 
- 
- 
-#set up extension info 
-if(isset($wgScriptPath)) 
-{ 
-$wgExtensionCredits["parserhook"][]=array( 
- 'name' => 'Rating Extension', 
- 'version' => '0.1', 
- 'url' => 'http://wiki.peacocktech.com/wiki/RatingExtension', 
- 'author' => '[http://about.peacocktech.com/trevorp/ Trevor Peacock]', 
- 'description' => 'Adds rating mechanism' ); 
- $wgHooks['OutputPageBeforeHTML'][] = 'InsertRating'; 
- $wgHooks['SkinTemplateSetupPageCss'][] = 'RatingCss'; 
-} 
- 
-#Add CSS into skin for rating 
-function RatingCss(&$css) { 
- global $wgScriptPath; 
- $css = "/*<![CDATA[*/". 
- " @import \"$wgScriptPath/?file=rating.css\"; ". 
- "/*]]>*/"; 
- return true; 
} }
-#Return file if requested+#-------------------------------------------------------------------------------
 +# Return a file and exit. #
 +# File determined by ?file= GET parameter #
 +#-------------------------------------------------------------------------------
function doFile() function doFile()
{ {
switch ($_GET['file']) switch ($_GET['file'])
{ {
 + #Star .png files
 + case "star0.png":
 + case "star1.png":
 + case "star1b.png":
 + case "star2.png":
 + case "star2b.png":
 + case "star3.png":
 + case "star3b.png":
 + case "star4.png":
 + case "star4b.png":
 + header("Content-type: image/png");
 + echo readFile('extensions/rating/'.$_GET['file']);
 + die();
 + #extension css styling
case "rating.css": case "rating.css":
header("Content-type: text/css"); header("Content-type: text/css");
Line 181: Line 259:
#ratingsection b { #ratingsection b {
-// border: 1px solid black; 
color: red; color: red;
padding: 4px; padding: 4px;

Revision as of 04:34, 30 July 2006

<?php

################################################################################
# Core Code                                                                    #
################################################################################
# This section handles the core functions of this extension                    #
#   * Serving Files                                                            #
#   * Recording Ratings                                                        #
#   * Displaying Ratings                                                       #
################################################################################

#-------------------------------------------------------------------------------
# If html request requests file, serve file                                    #
# Files are requested by adding the ?file= GET parameter                       #
#-------------------------------------------------------------------------------
if(isset($_GET['file']))
  doFile();

#-------------------------------------------------------------------------------
# If html request contains rate information, process it                        #
# Rating information indicated by ?rate= GET parameter                         #
#                                                                              #
# MediaWiki engine is started by imitating the code in index.php               #
# This ensures database functions are working                                  #
#-------------------------------------------------------------------------------
if(isset($_GET['rate']))
{
  #Init
  #----------------
  require_once( 'includes/Setup.php' );
  require_once( "includes/Wiki.php" );
  $mediaWiki = new MediaWiki();
  $action = $wgRequest->getVal( 'action', 'view' );
  $title = $wgRequest->getVal( 'title' );
  $wgTitle = $mediaWiki->checkInitialQueries($title, $action, $wgOut,
    $wgRequest, $wgContLang);


  #Record Rating
  #----------------
  $sql = "REPLACE INTO `ratings` (`page_oldid`, `user_id`, `page_rating`) '.
    'VALUES (".$_GET['oldid'].", '".
    ($wgUser->getID()?$wgUser->getID():$wgUser->getName()).
    "', ".$_GET['rate'].")";
  $dbr =& wfGetDB( DB_WRITE );
  $res=wfQuery($sql, DB_WRITE, "");
  
  #Return to refering page and exit
  #----------------
  $wgTitle->invalidateCache();
  header( 'Location: '.$_SERVER["HTTP_REFERER"] ) ;
  die();
}

#-------------------------------------------------------------------------------
# Initialize extension                                                         #
# Sets up credit information, and hooks                                        #
#-------------------------------------------------------------------------------
if(isset($wgScriptPath))
{
$wgExtensionCredits["parserhook"][]=array(
  'name' => 'Rating Extension',
  'version' => '0.1',
  'url' => 'http://wiki.peacocktech.com/wiki/RatingExtension',
  'author' => '[http://about.peacocktech.com/trevorp/ Trevor Peacock]',
  'description' => 'Adds rating mechanism' );
  $wgHooks['OutputPageBeforeHTML'][] = 'InsertRating';
  $wgHooks['SkinTemplateSetupPageCss'][] = 'RatingCss';
}

#-------------------------------------------------------------------------------
# Insert rating to top of page                                                 #
#-------------------------------------------------------------------------------
function InsertRating($parserOutput, $text) {
  global $wgArticle;
  $oldid=getOldID($wgArticle);
  if($oldid)
    $text='<div id="ratingsection">'.
      getRatingHTML(getRating($oldid), $oldid).'</div>'.$text;
}



#-------------------------------------------------------------------------------
# Add CSS into skin for rating                                                 #
#-------------------------------------------------------------------------------
function RatingCss(&$css) {
  global $wgScriptPath;
  $css = "/*<![CDATA[*/".
  " @import \"$wgScriptPath/?file=rating.css\"; ".
  "/*]]>*/";
  return true;
}

################################################################################
# Supporting Functions                                                         #
################################################################################
# These functions support the core functions of the extension                  #
################################################################################

#-------------------------------------------------------------------------------
# Use the mediawiki engine to run the given sql code and return an object      #
# containing the first result of the query                                     #
#-------------------------------------------------------------------------------
#run sql code
function runQuery($sql)
{
  $dbr =& wfGetDB( DB_SLAVE );
  $res=wfQuery($sql, DB_SLAVE, "");
  return $dbr->fetchObject( $res );
}

#-------------------------------------------------------------------------------
# Return the oldid of the current page                                         #
# If oldid=0 (most current revision) take the latest oldid from the database   #
# for the current article                                                      #
#-------------------------------------------------------------------------------
function getOldID($article)
{
  $oldid=$article->getOldIDFromRequest();
  if($oldid!=0)
    return $oldid;
  $dbr =& wfGetDB( DB_SLAVE );
  $sql = "SELECT MAX(`rc_this_oldid`) AS `rc_this_oldid` FROM recentchanges '.
    'WHERE rc_cur_id=".$article->getID().";";
  $res=wfQuery($sql, DB_SLAVE, "");
  $row=$dbr->fetchObject( $res );
  if($row->rc_this_oldid)
    return $row->rc_this_oldid;
  return null;
}

#-------------------------------------------------------------------------------
# Performs a SQL query to fetch a rating for page oldid                        #
#-------------------------------------------------------------------------------
function getRatingData($oldid)
{
  $sql="SELECT COUNT(*) AS `count`, AVG(`page_rating`) AS `rating` '.
    'FROM ratings WHERE `page_oldid`=".$oldid." GROUP BY `page_oldid`;";
  return runQuery($sql);
}

#-------------------------------------------------------------------------------
# Fetch and calculate a rating for page oldid                                  #
# If there are not enough ratings for the current revivion, cycle              #
# older revisions to gather a minimum number of ratings                        #
#-------------------------------------------------------------------------------
function getRating($oldid)
{
  global $wgTitle;

  $countlimit=3;

  $ratingdata=getRatingData($oldid);
  $finalrating='?';
  $currentcount=number_format($ratingdata->count, 0);
  #If there are not enough ratings for the current revision
  if($rating->count<$countlimit)
  {
    $count=$ratingdata->count;
    $rating=$count*$ratingdata->rating;
    #cycle older revisions looking for more ratings
    while($oldid=$wgTitle->getPreviousRevisionID($oldid)) 
    {
      $ratingdata=getRatingData($oldid);
      #If still not enough ratings
      if($count+$ratingdata->count<$countlimit)
      {
        $count+=$ratingdata->count;
        $rating+=$ratingdata->count*$ratingdata->rating;
      }
      else #found enough ratings
      {
        $rating+=($countlimit-$count)*$ratingdata->rating;
        $count=$countlimit;
        $finalrating=$rating/$count;
        $oldid=false;
      }
    }
  }
  else
    $finalrating=$rating/$count;

  #format rating data
  if(is_numeric($finalrating))
    $finalrating=($finalrating-1)*1.25;
  $ratingarray=array('display'=>
      (is_numeric($finalrating)?number_format($finalrating, 2):$finalrating).
      " ($currentcount ratings)",
    'count'=>$currentcount,
    'rating'=>(is_numeric($finalrating)?$finalrating:0));
  return $ratingarray;
}

#-------------------------------------------------------------------------------
# Given the rating array and the page oldid, generate HTML code to be          #
# displayed                                                                    #
#-------------------------------------------------------------------------------
function getRatingHTML($rating, $oldid)
{
  global $wgTitle, $wgScriptPath;
  $countlimit=3;
  $html='';
  #generate stars
  for($x=0;$x<=4;$x++)
  {
    $html.='<a href="'.
      $wgTitle->getFullURL('oldid='.$oldid.'&rate='.($x+1)).'">'.
      '<img src="?file=star';
    if($rating['rating']>=$x+1) #larger than current star : filled
         $html.='4'.($rating['count']<$countlimit?'b':'');
    elseif($rating['rating']>$x+0.75) #3/4 current star : 3/4 filled
      $html.='3'.($rating['count']<$countlimit?'b':'');
    elseif($rating['rating']>$x+0.5) #1/2 current star : 1/2 filled
      $html.='2'.($rating['count']<$countlimit?'b':'');
    elseif($rating['rating']>$x+0.25) #1/4 current star : 1/4 filled
      $html.='1'.($rating['count']<$countlimit?'b':'');
    else #less than current star : empty
      $html.='0';
    $html.='.png" align=bottom/></a>'."\n";
  }
  #add text rating 
  $html.=' '.$rating['display'].'';
  $html=($rating['count']<$countlimit?'<b>'.$html.'</b>':$html);
  return $html;
}


#-------------------------------------------------------------------------------
# Return a file and exit.                                                      #
# File determined by ?file= GET parameter                                      #
#-------------------------------------------------------------------------------
function doFile()
{
  switch ($_GET['file'])
  {
    #Star .png files
    case "star0.png":
    case "star1.png":
    case "star1b.png":
    case "star2.png":
    case "star2b.png":
    case "star3.png":
    case "star3b.png":
    case "star4.png":
    case "star4b.png":
      header("Content-type: image/png");
      echo readFile('extensions/rating/'.$_GET['file']);
      die();
    #extension css styling
    case "rating.css":
      header("Content-type: text/css");
        ?>
#ratingsection {
  float: right;
  margin-top: -3.7em;
  padding: 3px;
}

#ratingsection b {
  color: red;
  padding: 4px;
}
<?php
      die();
  }
}

?>
Personal tools