<?php
/****************************************************************************
* DRBRatings
* http://www.dbscripts.net/ratings/
*
* Copyright (c) 2007-2010 Don B
****************************************************************************/
$CHECK_FOR_DUPLICATE_RATINGS = TRUE;
$CREDIT_LINK_REMOVAL_LICENSE = FALSE;
include_once(dirname(__FILE__) . '/config.php');
$rating_fp = NULL;
function show_ratings_control($id) {
global $MAX_STARS;
global $RATING_STRING;
global $NUMBER_OF_RATINGS_STRING;
global $CURRENT_RATING_STRING;
// Validate parameters
if(!is_valid_id($id)) {
rating_die('ERROR: An invalid rating ID was submitted.');
}
// Lock
rating_lock($id, LOCK_SH);
// Get the current rating and rating count
$summarylist = rating_summary_list($id);
$ratingCount = get_rating_count($summarylist);
$rating = get_current_rating($summarylist);
// Unlock
rating_unlock();
// Initialize the display messages for the rating control
$ratingString = sprintf($RATING_STRING, $rating, $MAX_STARS);
$numberOfRatingsString = sprintf($NUMBER_OF_RATINGS_STRING, $ratingCount);
// Output rating control
echo("<div class=\"ratingsContainer\">\r\n");
echo("\t<div class=\"currentRating\">" . htmlspecialchars($CURRENT_RATING_STRING) . "</div>\r\n");
echo("\t<div class=\"rating\">\r\n");
show_stars($rating);
echo("\t\t" . htmlspecialchars($ratingString) . "\r\n\t</div>\r\n");
echo("\t<div class=\"numberOfRatings\">" . htmlspecialchars($numberOfRatingsString) . "</div>\r\n");
show_rate_form($id);
the_credits();
echo("</div>\r\n");
}
function show_rate_form($id) {
global $RATE_THIS_STRING;
global $MAX_STARS;
global $SUBMIT_BUTTON_STRING;
global $RATING_LABELS;
global $RATING_LIST_DEFAULT_LABEL;
global $RATINGS_URL;
global $RATING_ID_PARAM_NAME;
global $RATING_PARAM_NAME;
echo("\t<form class=\"rateIt\" method=\"post\" action=\"" . $RATINGS_URL . "rate.php\">\r\n");
echo("\t\t" . htmlspecialchars($RATE_THIS_STRING) . "\r\n");
echo("\t\t<select name=\"" . htmlspecialchars($RATING_PARAM_NAME) . "\">\r\n");
echo("\t\t\t<option value=\"\">" . htmlspecialchars($RATING_LIST_DEFAULT_LABEL) . "</option>\r\n");
for($i = 1; $i <= $MAX_STARS; $i++) {
echo("\t\t\t<option value=\"" . $i . "\">" . $i);
if(!empty($RATING_LABELS) && isset($RATING_LABELS[$i])) {
echo(" - " . htmlspecialchars($RATING_LABELS[$i]));
}
echo("</option>\r\n");
}
echo("\t\t</select>\r\n");
echo("\t\t<input type=\"hidden\" name=\"" . htmlspecialchars($RATING_ID_PARAM_NAME) . "\" value=\"" . htmlspecialchars($id) . "\" />\r\n");
echo("\t\t<input type=\"submit\" value=\"" . htmlspecialchars($SUBMIT_BUTTON_STRING) . "\" class=\"submit\" />\r\n");
echo("\t</form>\r\n");
}
function show_stars($rating) {
global $IMAGE_STAR_EMPTY;
global $IMAGE_STAR_HALF;
global $IMAGE_STAR_FILLED;
global $MAX_STARS;
// Iterate through the stars, and show the correct type of star image
// based on the rating.
for($i = 1; $i <= $MAX_STARS; $i++) {
if($rating > $i - .5) {
show_ratings_image($IMAGE_STAR_FILLED, "*");
} else if($rating > $i - 1) {
show_ratings_image($IMAGE_STAR_HALF, "1/2");
} else {
show_ratings_image($IMAGE_STAR_EMPTY, "");
}
}
}
function show_ratings_image($filename, $alt) {
global $RATINGS_URL;
echo("\t\t<img src=\"" . $RATINGS_URL . urlencode($filename) . "\" alt=\"" . htmlspecialchars($alt) . "\" />\r\n");
}
function smarter_is_int($val) {
return (is_numeric($val)?intval($val)==$val:FALSE);
}
function is_valid_id($id) {
global $VALID_RATING_IDS;
return (!empty($id) && preg_match('/^[a-zA-Z0-9]+$/D', $id) === 1 && in_array($id, $VALID_RATING_IDS, TRUE));
}
function is_valid_rating($rating) {
global $MAX_STARS;
return (!empty($rating) && preg_match('/^[1-9][0-9]*$/D', $rating) === 1 && smarter_is_int($rating) && $rating >= 1 && $rating <= $MAX_STARS);
}
function get_rating_count($summarylist) {
// Get rating count from summary
if($summarylist === FALSE || count($summarylist) < 1) {
return 0;
} else {
return $summarylist[0];
}
}
function get_current_rating($summarylist) {
global $MAX_STARS;
// Get total count
$totalCount = get_rating_count($summarylist);
if($totalCount == 0) return 0; // Prevent divide by zero
// Calculate total ratings
$totalRatings = 0;
if($summarylist !== FALSE) {
for($i = 1; $i <= $MAX_STARS; $i++) {
if($i < count($summarylist)) {
$totalRatings += $summarylist[$i] * $i;
}
}
}
// Return average
global $RATINGS_PRECISION;
return round($totalRatings / $totalCount, $RATINGS_PRECISION);
}
function add_new_rating($id, $rating) {
global $rating_error_message;
// Make sure rating wasn't left blank
if(empty($rating)) {
global $NO_RATING_SELECTED_ERROR_MSG;
$rating_error_message = $NO_RATING_SELECTED_ERROR_MSG;
return FALSE;
}
// Validate parameters
if(!is_valid_id($id)) {
rating_die('ERROR: An invalid rating ID was submitted.');
}
if(!is_valid_rating($rating) ) {
rating_die('ERROR: An invalid rating was submitted.');
}
// Convert to integer value
$rating = intval($rating);
// Lock
rating_lock($id, LOCK_EX);
// Check for duplicate rating attempt
global $CHECK_FOR_DUPLICATE_RATINGS;
if($CHECK_FOR_DUPLICATE_RATINGS === TRUE) {
$ipaddress = $_SERVER['REMOTE_ADDR'];
if(has_rated($id, $ipaddress)) {
global $DUPLICATE_RATE_ERROR_MSG;
$rating_error_message = $DUPLICATE_RATE_ERROR_MSG;
rating_unlock(); // Unlock
return FALSE;
}
}
// Add rating
rating_history_add($id, $ipaddress, $rating);
rating_summary_add($id, $rating);
// Unlock
rating_unlock();
return TRUE;
}
function rating_summary_file_path($id) {
return dirname(__FILE__) . '/data/summary_' . $id . '.dat';
}
function rating_history_file_path($id) {
return dirname(__FILE__) . '/data/history_' . $id . '.dat';
}
function rating_lock_file_path($id) {
return dirname(__FILE__) . '/data/lock_' . $id . '.dat';
}
function rating_summary_list($id) {
// Load existing
$summarylist = @file(rating_summary_file_path($id));
if($summarylist !== FALSE) {
$summarylist = array_map("trim", $summarylist);
}
return $summarylist;
}
function rating_summary_add($id, $rating) {
// Get existing ratings
$summarylist = rating_summary_list($id);
// Open/create summary file
$summary_fp = @fopen(rating_summary_file_path($id), "w");
if($summary_fp === FALSE) {
rating_die("Unable to open summary file for writing");
}
// Update total rating count
if($summarylist === FALSE || count($summarylist) < 1) {
$count = 1;
} else {
$count = $summarylist[0] + 1;
}
fputs($summary_fp, $count . "\n");
// Add rating to history
global $MAX_STARS;
for($i = 1; $i <= $MAX_STARS; $i++) {
if($summarylist === FALSE || $i > count($summarylist) + 1) {
// This is the first rating for this number
if($i == $rating) {
$out = 1;
} else {
$out = 0;
}
} else {
// Add to existing rating count for this number
if($i == $rating) {
$out = ($summarylist[$i] + 1);
} else {
$out = $summarylist[$i];
}
}
// Write out new rating count for this number
fputs($summary_fp, $out . "\n");
}
fclose($summary_fp);
}
function rating_history_add($id, $ipaddress, $rating) {
// Open/create history file
$history_fp = @fopen(rating_history_file_path($id), "a");
if($history_fp === FALSE) {
rating_die("Unable to open history file for writing");
}
// Add IP address and rating to history
fputs($history_fp, $ipaddress . "|" . $rating . "\n");
fclose($history_fp);
}
function explode_history($line) {
return array_map("trim", explode("|", $line));
}
function rating_history_list($id) {
// Load existing rating history
$summarylist = @file(rating_history_file_path($id));
if($summarylist !== FALSE) {
$summarylist = array_map("explode_history", $summarylist);
}
return $summarylist;
}
function has_rated($id, $ipaddress) {
// Find rating history
$rating_history_list = rating_history_list($id);
if($rating_history_list !== FALSE) {
return( find_rating_history(trim($ipaddress), $rating_history_list) !== FALSE );
} else {
return FALSE;
}
}
function find_rating_history($ipaddress, $list) {
// Search rating history for this IP address
if(!empty($list)) {
for($i = 0; $i < count($list); $i++) {
if($list[$i][0] == $ipaddress) return $list[$i];
}
}
return FALSE;
}
function rating_die($msg) {
rating_unlock();
die($msg);
}
function rating_lock($poll_id, $operation) {
global $rating_fp;
if($rating_fp !== NULL) {
rating_die("Already locked for rating");
}
$rating_fp = @fopen(rating_lock_file_path($poll_id), 'a');
if($rating_fp === FALSE) die("Unable to open lock file");
if(@flock($rating_fp, $operation) === FALSE) {
@fclose($rating_fp);
die("Unable to lock for rating");
}
return;
}
function rating_unlock() {
global $rating_fp;
if($rating_fp !== NULL) {
@flock($rating_fp, LOCK_UN);
@fclose($rating_fp);
$rating_fp = NULL;
}
}
/* DO NOT REMOVE OR HIDE THE CREDIT BELOW, PER LICENSE! */
function the_credits() {
global $CREDIT_LINK_REMOVAL_LICENSE;
if($CREDIT_LINK_REMOVAL_LICENSE !== TRUE) {
$line = "PGRpdiBjbGFzcz0iY3JlZGl0IiBzdHlsZT0iZm9udC1zaXplOiA4cHQ7Ij5Qb3dlc"
. "mVkIGJ5IERSQlJhdGluZ3MgJm1pZGRvdDsgPGEgaHJlZj0iaHR0cDovL3d3dy5kYnNjcmlw"
. "dHMubmV0L2hvc3RpbmcvIj5QSFAgSG9zdGluZzwvYT48L2Rpdj4=";
echo(base64_decode($line) . "\n");
}
}
/* END CREDIT */
?>