RatingExtension

From PeacockWiki

Revision as of 01:46, 8 August 2006; Trevorp (Talk | contribs)
(diff) ←Older revision | Current revision | Newer revision→ (diff)
Jump to: navigation, search

Contents

Details

  • Version 0.3.1
  • Date 8 Aug 2006
  • Tested on MediaWiki 1.7.1, PHP 5.0.5 (apache2handler)
  • Tested on MediaWiki 1.6.6, PHP 5.0.5 (apache2handler)

Features

  • Allows 5 star rating for each page in a wiki
  • With too few ratings it will use previous ratings
  • With too few ratings, rating will change color to draw attention to get ratings
  • NoFollow support
  • Tags to allow insertion of ratings into a page, or a list of "top 5" ratings etc.
  • Rating cache, to speed up <ratings> usage in large wikis.

Usage

Enabling the plugin will display star ratings above each page. 5 stars are displayed, which may be cliked by a user to indicate their opinion of the page. Stars are arranged left to right, with the first star having a value of 1, and the last a value of 5. Each user (identified by logon, or by IP address) may have one vote on any revision of a page, and may change their vote at any time.

The extension also enables the use of three new wiki tags:

  • <rating>
  • <ratingcount>
  • <ratings>

The rating and rating count tags display a numeric value, indicating the page rating, or the number of ratings for a selected page. The page is indicated by placing the name of the page between an opening and closing tag.

The ratings tag displays a list of pages, and their ratings or rating counts. The ratings tag supports the following parameters:

  • namespace - limit the namespaces of displayed pages (numeric value). May be included multiple times to indicate multiple namespaces. Defaults to all namespaces
  • sortby (rating, name or count) - select the index to sort the list on. defaults to rating.
  • sortby (ascending or descending) - sort in ascending or decending
  • displaycount (true or false) - show the number of ratings for each page. defaults false
  • displayrating (true or false) - show the rating for each page. defaults true
  • pattern - indicates the text to be returned for each result. supports four parameters: $1 => page_name, $2 => page name, $3 => rating, $4 => count, $5 => page revision id. overrides displaycount and displayrating.
  • limit - limits the maximum number of results. defaults to 10. 0 = unlimited

Examples

<rating>Main Page</rating>

displays

4.52

<ratingcount>Main Page</ratingcount>

displays

23

Most popular page: <ratings>
namespace=0
namespace=1
namespace=2
namespace=3
sortby=rating
sortby=descending
pattern=[[$1|$2]] with a rating of $3
limit=1
</ratings>

displays

Most Popular Page: Main Page with a rating of 4.52

Installation

Media

Download Media:Rating.tar.gz (Image:Rating.tar.gz) and extract to the 'extensions/' directory. (Extensions directory should now contain a 'rating' subdirectory containing several png files)

Database

Run the following sql code on your database to create the ratings table. Ensure you have selected the correct database using the USE command.

CREATE TABLE IF NOT EXISTS `ratings` (
  `page_oldid` int unsigned NOT NULL,
  `user_id` varchar(15) NOT NULL,
  `page_rating` int unsigned NOT NULL,
  PRIMARY KEY  (`page_oldid`, `user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

CREATE TABLE IF NOT EXISTS `ratings_cache` (
  `page_oldid` int unsigned NOT NULL,
  `page_rating` float unsigned NOT NULL,
  `page_rating_count` int unsigned NOT NULL,
  PRIMARY KEY  (`page_oldid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

Extension

Copy and paste the source code into a file named 'rating.php', and place it in the 'extensions/' directory of your mediawiki installation.

Insert the following line into the end of 'LocalSettings.php' (before the '?>')

require("extensions/rating.php");

Verification

To check to see if it is installed properly, visit your Version page, eg Special:Version.

You should see the following items:

  • Extensions:
  • Hooks:
    • OutputPageBeforeHTML: InsertRating
    • SkinTemplateSetupPageCss: RatingCss

Releases

Todo

  • Add ratings into search output

RoadMap

0.4 No Date

  • Add ratings into search output

History

0.3.1 - Date 8 Aug 2006

  • Ratings list shows link rather than image for Image namespace articles

0.3 - Date 2 Aug 2006

  • Add rating cache, to speed up <ratings> usage in large wikis.

0.2 - Date 31 July 2006

  • Fix sql injection possibilities
  • Add tags to allow insertion of ratings into a page, or a list of "top 5" ratings etc.
  • NoFollow support
  • rating tag
  • ratingcount tag
  • ratings tag

0.1 - Date 30 July 2006

  • Allows 5 star rating for each page in a wiki
  • With too few ratings it will use previous ratings
  • With too few ratings, rating will change color to draw attention to get ratings

Source Code

Authoritative version of source code available at RatingExtension/Source_Code.

<?php

################################################################################
# Setup                                                                        #
################################################################################
# This section defines parameters of the plugin                                #
################################################################################

#-------------------------------------------------------------------------------
# Sets the minimum number of ratings that can be returned in a ratings tag     #
# This helps keep performance for large wikis acceptable                       #
#-------------------------------------------------------------------------------
$renderLimit=100;

#-------------------------------------------------------------------------------
# Sets the minimum number of ratings required for the rating to be valid       #
# If the number of ratings are less, rating is 0 and bolded                    #
#-------------------------------------------------------------------------------
$countLimit=3;

#-------------------------------------------------------------------------------
# Defines namespaces for which ratings are enabled                             #
#-------------------------------------------------------------------------------
$allowedNamespaces=array(
  0=>true, //Default
  1=>true, //Talk
  2=>true, //User
  3=>true, //User_talk
  4=>true, //Project
  5=>true, //Project_talk
  6=>true, //Image
  7=>true, //Image_talk
#  8=>true, //MediaWiki
#  9=>true, //MediaWiki_talk
  10=>true, //Template
  11=>true, //Template_talk
  12=>true, //Help
  13=>true, //Help_talk
  14=>true, //Category
  15=>true //Category_talk 
);

################################################################################
# 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
  #----------------
  $dbr =& wfGetDB( DB_WRITE );
  $sql = "REPLACE INTO `ratings` (`page_oldid`, `user_id`, `page_rating`) ".
    "VALUES (".intval($_GET['oldid']).", '".
    ($wgUser->getID()?$wgUser->getID():$wgUser->getName()).
    "', ".intval($_GET['rate']).")";
  $res=wfQuery($sql, DB_WRITE, "");

  calculateRating($_GET['oldid']);
  
  #Return to refering page and exit
  #----------------
  $wgTitle->invalidateCache();
  $dbr->immediateCommit();
  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.3.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';
  $wgExtensionFunctions[] = "RatingExtension";
}

function RatingExtension()
{
  global $wgParser;
  $wgParser->setHook("rating", "renderRating");
  $wgParser->setHook("ratingcount", "renderRatingCount");
  $wgParser->setHook("ratings", "renderRatings");
}

#-------------------------------------------------------------------------------
# Render the <rating> tag                                                      #
# Shows the rating of the page specified by the text between the tags          #
#-------------------------------------------------------------------------------
function renderRating($input, $argv, &$parser)
{
  $rating=getRatingCache(getOldIDFromTitle(trim($input)));
  return number_format($rating['rating'], 2);
}

#-------------------------------------------------------------------------------
# Render the <rating> tag                                                      #
# Shows the number of ratings of the page specified by the text between        #
#  the tags                                                                    #
#-------------------------------------------------------------------------------
function renderRatingCount($input, $argv, &$parser)
{
  $rating=getRatingCache(getOldIDFromTitle(trim($input)));
  return number_format($rating['count'], 2);
}

#-------------------------------------------------------------------------------
# Displays a list of ratings based on the parameters given between the tags    #
#-------------------------------------------------------------------------------
function renderRatings($input, $argv, &$parser)
{
  $parameters=splitParameters($input);
  $sortdata=getSortData(isset($parameters['namespace'])?
    $parameters['namespace']:array());
  $ratings=getRatingList(isset($parameters['namespace'])?
    $parameters['namespace']:array(), $sortdata['column'], $sortdata['order'],
    isset($parameters['limit'])?$parameters['limit'][0]:10);
  $output='';
  $displayCount=(isset($parameters['displaycount'])?
    $parameters['displaycount'][0]:'false')!='false';
  $displayRating=(isset($parameters['displayrating'])?
    $parameters['displayrating'][0]:'true')!='false';
  $pattern=isset($parameters['pattern'])?$parameters['pattern'][0]:
    '[[$1|$2]]'.($displayRating?' ($3)':'').($displayCount?' ($4 ratings)':'');
  $limit=isset($parameters['limit'])?$parameters['limit'][0]:10;
  foreach($ratings as $rating)
  {
    $output.=str_replace(array('$1', '$2', '$3', '$4', '$5'), 
      array(($rating['namespace']==6?':':'').$rating['title'],
        strtr($rating['title'], '_', ' '), 
        number_format($rating['rating'], 2), 
        $rating['count'], $rating['oldid']), $pattern)."\n\n";
    if(--$limit==0) break;
  }
  return renderWikiText(trim($output), $parser);
}

#-------------------------------------------------------------------------------
# Insert rating to top of page                                                 #
#-------------------------------------------------------------------------------
function InsertRating($parserOutput, $text) {
  global $wgArticle, $allowedNamespaces;
  if(!$allowedNamespaces[$wgArticle->getTitle()->getNamespace()])
    return;
  $oldid=getOldID($wgArticle);
  if($oldid)
    $text='<div id="ratingsection">'.
      getRatingHTML(getRatingCache($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                  #
################################################################################

#-------------------------------------------------------------------------------
# Processes sortby parameters to determine how to sort ratings                 #
#-------------------------------------------------------------------------------
function getSortData($sort)
{
  $column='rating';
  $order=-1;
  foreach($sort as $item)
  {
    switch($item)
    {
      case 'rating':
        $column='rating'; break;
      case 'name':
        $column='title'; break;
      case 'count':
        $column='count'; break;
      case 'ascending':
        $order=SORT_ASC; break;
      case 'descending':
        $order=SORT_DESC; break;
    }
  }
  if($order==-1)
  {
    switch($column)
    {
      case 'rating':
        $order=SORT_DESC; break;
      case 'title':
        $order=SORT_ASC; break;
      case 'count':
        $order=SORT_DESC; break;
      default:
        $order=SORT_DESC;
    }
  }
  return array('column'=>$column, 'order'=>$order);
}

#-------------------------------------------------------------------------------
# Processes the given text using the mediawiki parser engine                   #
#-------------------------------------------------------------------------------
function renderWikiText($input, &$parser)
{
  return $parser->parse($input, $parser->mTitle, $parser->mOptions, 
    false, false)->getText();
}

#-------------------------------------------------------------------------------
# Returns the page rating given the pages string title                         #
#-------------------------------------------------------------------------------
function getOldIDFromTitle($title)
{
  $title=Title::newFromText($title);
  if($title==null)
  {
    echo "NoArticle";
    return 0;
  }
  $oldid=getOldID(new Article($title));
  if(!$oldid)
  {
    return "NoOldID";
    return 0;
  }
  return $oldid;
}

#-------------------------------------------------------------------------------
# Completes ratings_cache table for any revisions without ratings              #
#-------------------------------------------------------------------------------
function doFillCache()
{
  global $allowedNamespaces;
  $namespacestring='';
  foreach(array_keys($allowedNamespaces) as $space)
  {
    if(is_numeric($space))
    {
      $namespacestring.=', '.$space;
    }
  }
  $namespacestring=substr($namespacestring, 2);
  $sql="SELECT `page_latest` AS `oldid` FROM `page` WHERE".
    ' `page_namespace` IN ('.$namespacestring.') AND'.' `page_latest` NOT IN '.
    '(SELECT `page_oldid` FROM `ratings_cache`);';
  $articles=runQuery2($sql);
  foreach($articles as $article)
    getRating($article->oldid);
}

#-------------------------------------------------------------------------------
# Returns a list of pages in the specified namespaces                          #
# Optionally it may return sorting rating information for results              #
#-------------------------------------------------------------------------------
function getPageList($namespace=array(), $ratings=false, $sort='title',
    $order=SORT_ASC, $limit=100)
{
  global $renderLimit, $allowedNamespaces;
  $limit=($limit>$renderLimit?$renderLimit:$limit);
  $namespacestring='';
  $filterByNamespace=false;
  foreach($namespace as $space)
  {
    if(is_numeric($space) && isset($allowedNamespaces[$space]))
    {
      $namespacestring.=', '.$space;
      $filterByNamespace=true;
    }
  }
  if($filterByNamespace)
    $namespacestring=substr($namespacestring, 2);
  $sql="SELECT `page_title` AS `title`, `page_namespace` AS `namespace`, 
    `page_latest` AS `oldid` FROM `page`".($filterByNamespace?
    ' WHERE `page_namespace` IN ('.$namespacestring.')':"").';';
  if($ratings)
    $sql="SELECT `page_title` AS `title`, `page_namespace` AS `namespace`, ".
      "`page_latest` AS `oldid`, `page_oldid`, `page_rating` AS `rating`, ".
      "`page_rating_count` AS `count` FROM `page`, `ratings_cache` ".
      "WHERE `page_latest`=`page_oldid`".($filterByNamespace?
      ' AND `page_namespace` IN ('.$namespacestring.')':"").
      ' ORDER BY '.$sort.($order==SORT_ASC?'':'').
      ($order==SORT_DESC?' DESC':'').' LIMIT '.$limit.';';
  return runQuery2($sql);
}

#-------------------------------------------------------------------------------
# Returns a list of pages and their ratings for all pages in the specified     #
#  namespaces                                                                  #
#-------------------------------------------------------------------------------
function getRatingList($namespace=array(), $sort='title', $order=SORT_ASC,
    $limit=100)
{
  global $wgNamespaceNamesEn, $renderLimit;
  doFillCache();
  $limit=($limit>$renderLimit?$renderLimit:$limit);
  $articles=getPageList($namespace, true, $sort, $order, $limit);
  $ratings=array();
  foreach($articles as $article)
  {
    $rating=formatRating(array('count'=>$article->count,
      'rating'=>$article->rating));
    $ratings[]=array('title' => $wgNamespaceNamesEn[$article->namespace].
      ($article->namespace==0?'':':').$article->title, 
        'rating' => $rating['rating'], 'count' => $rating['count'],
        'oldid'=>$article->oldid, 'title_name'=>$article->title,
        'namespace_name'=>$wgNamespaceNamesEn[$article->namespace],
	'namespace'=>$article->namespace);
  }
  return $ratings;
}

#-------------------------------------------------------------------------------
# Splits parameters from the wikitext.                                         #
# Each parameter should be on its own line in the format  parameter = value    #
#-------------------------------------------------------------------------------
function splitParameters($input)
{
  $parameters=array();
  foreach(split("\n", $input) as $parameter)
  {
    $parameter=split('=', $parameter, 2);
    if(count($parameter)==2)
    {
      foreach($parameter as $key => $val)
        $parameter[$key]=trim($val);
      if(isset($parameters[$parameter[0]]))
        $parameters[$parameter[0]][]=$parameter[1];
      else
        $parameters[$parameter[0]]=array($parameter[1]);
    }
  }
  return $parameters;
}

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

function runQuery2($sql)
{
  $dbr =& wfGetDB( DB_SLAVE );
  $res=wfQuery($sql, DB_SLAVE, "");
  $array=array();
  while($item=$dbr->fetchObject( $res ))
    $array[]=$item;
  return $array;
}

#-------------------------------------------------------------------------------
# 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 `page_latest` AS `oldid` FROM `page` ".
    "WHERE `page_id`=".$article->getID().";";
  $res=wfQuery($sql, DB_SLAVE, "");
  $row=$dbr->fetchObject( $res );
  if($row->oldid)
    return $row->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`=".intval($oldid)." GROUP BY `page_oldid`;";
  return runQuery($sql);
}

#-------------------------------------------------------------------------------
# Returns the ID for the revision before $revision                             #
#-------------------------------------------------------------------------------
function getPreviousRevisionID( $revision ) {
	$dbr =& wfGetDB( DB_SLAVE );
	return $dbr->selectField( 'revision', 'rev_id',
		'rev_page=(SELECT `rev_page` from `revision` WHERE `rev_id`='.
		intval( $revision ).')'.' AND rev_id<' . intval( $revision ) . 
		' ORDER BY rev_id DESC' );
}

#-------------------------------------------------------------------------------
# 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                        #
# Updates cache table with calcaulated values                                  #
#-------------------------------------------------------------------------------
function calculateRating($oldid)
{
  global $wgTitle, $countLimit;
  $origid=$oldid;
  $ratingdata=getRatingData($oldid);
  $finalrating='?';
  $currentcount=number_format($ratingdata->count, 0);
  #If there are not enough ratings for the current revision
  if($ratingdata->count<$countLimit)
  {
    $count=$ratingdata->count;
    $rating=$count*$ratingdata->rating;
    #cycle older revisions looking for more ratings
    while($oldid=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=$ratingdata->rating;

  $dbr =& wfGetDB( DB_WRITE );
  $sql = "REPLACE INTO `ratings_cache` (`page_oldid`, `page_rating`, ".
    "`page_rating_count`) VALUES (".intval($origid).", ".
    (is_numeric($finalrating)?$finalrating:0).", ".$currentcount.")";
  $res=wfQuery($sql, DB_WRITE, "");
  
  return array('rating'=>$finalrating, 'count'=>$currentcount);
}

#-------------------------------------------------------------------------------
# Formats rating array for insertion to page rating section                    #
#-------------------------------------------------------------------------------
function formatRating($rating)
{
  $finalrating=$rating['rating'];
  $currentcount=$rating['count'];
  
  #format rating data
  if(is_numeric($finalrating) && $finalrating>0)
    $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;
}

#-------------------------------------------------------------------------------
# Calculates rating from database for specified revision                       #
# Updates rating cache table                                                   #
#-------------------------------------------------------------------------------
function getRating($oldid)
{
  return formatRating(calculateRating($oldid));
}

#-------------------------------------------------------------------------------
# Fetches the ratings from cache table                                         #
# Calculates rating if it is not found in cache                                #
#-------------------------------------------------------------------------------
function getRatingCache($oldid)
{
  $sql='SELECT * FROM `ratings_cache` WHERE `page_oldid`='.intval($oldid).';';
  $rating=runQuery($sql);
  $rating=array('rating'=>$rating->page_rating,
    'count'=>$rating->age_rating_count);
  if($rating->page_oldid==null)
    $rating=calculateRating($oldid);
  return formatRating($rating);
}

#-------------------------------------------------------------------------------
# Given the rating array and the page oldid, generate HTML code to be          #
# displayed                                                                    #
#-------------------------------------------------------------------------------
function getRatingHTML($rating, $oldid)
{
  global $wgTitle, $wgScriptPath, $countLimit;
  $html='';
  #generate stars
  for($x=0;$x<=4;$x++)
  {
    $html.='<a href="'.
      $wgTitle->getFullURL('oldid='.$oldid.'&rate='.($x+1)).'" rel="nofollow">'.
      '<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();
  }
}

?>

Development version

Personal tools