Location: PHPKode > scripts > AJAX Star Rating > ajax-star-rating/RatingManager.inc.php
<?php
/**
 * Mysqli database wrapper class for start rating
 *@package AJAXRATING
 *@access public
 *@abstract Database
 *@author Sudhir Chauhan (hide@address.com, hide@address.com)
 *@return string
 *@version 1.0.0;
 */
//database host name or IP
define('DATABASEHOST','localhost');
//database user name
define('DATABASEUSERNAME','root');
// database user password
define('DATABASEPASSWORD','');
//database name
define('DATABASENAME','rating');
// single start width
define('STARWIDTH',20);
// total number of starts
// NOTE: This is not working complately. If you want to increase of decrease stars you have to modify css also
define('TOTALSTARS',5);

//mysqli extention must be loaded
// Abstact class for rating
abstract class Database {
	public $databaseHost = DATABASEHOST;
	public $databaseUser = DATABASEUSERNAME;
	public $databasePassword = DATABASEPASSWORD;
	public $databaseName = DATABASENAME;
	public $mysqli = 0; //  database connection
	protected $recordsSelected = 0;
	protected $recordsUpdated = 0;
	protected $databaseResults = Array();
	
	
	protected function connect() {
		$this->mysqli = new mysqli($this->databaseHost, $this->databaseUser, $this->databasePassword, $this->databaseName);
		if (mysqli_connect_errno()) {
			$this->mysqli = 0;
   			trigger_error(mysqli_connect_error());
		}
	}
	
	protected function querySelect($query) {
		
		if (strlen(trim($query)) < 0 ) {
			trigger_error("Database encountered empty query string in querySelect function",E_USER_ERROR);
			return false;
		}
		
		if ($this->mysqli === 0 ) {
			$this->connect();
		}
		if ($result = $this->mysqli->query($query)) {
			$this->recordsSelected = $result->num_rows;
			$this->databaseResults = $this->getData($result);
			$result->close();			
		}
		return $this->databaseResults;
	}
	
	protected function queryExecute($query) {
		
		if (strlen(trim($query)) < 0 ) {
			trigger_error("Database encountered empty query string in queryExecute function",E_ERROR);
		}
		if ($this->mysqli === 0 ) {
			$this->connect();
		}
		
		if($this->mysqli->query($query) === true) {
			$this->recordsUpdated = $this->mysqli->affected_rows;
		}
	}
	
	protected function getData($result) {
		$data = array();
		$i = 0;
		while ($row = $result->fetch_assoc()) {
			foreach ($row as $key => $value) {
				$data[$i][$key] = stripslashes($value);		
			}
			$i++;
		}
		return $data;
	}	
	
}

/**
 * Ajax start rating
 *@package AJAXRATING
 *@access public
 *@abstract Database
 *@author Sudhir Chauhan (hide@address.com, hide@address.com)
 *@return string
 *@version 1.0.0;
 * TODO:: 
 *	for optimisation we can get all values from rating table in the constructer
 * 	and avoid multiple select queries.
 * 	IP base check: restrict users how have already voted. (cookie or ip address0
 */
class RatingManager extends Database {
	public static $instance = 0;
	
	public function __construct() {
		if (!in_array('mysqli', get_loaded_extensions())) {
			trigger_error("mysqli extention is required for rating.",0);
			exit;
		}
	}
	
	public static function getInstance() {
		if (self::$instance == 0 ) {
			self::$instance = new RatingManager();
		}
		return self::$instance;
	}
	
	/**
	 * Draw stars
	 * TODO: add IP restriction check to avoid person to vote again
	 * COOKIE can also be used for this
	 */
	public function drawStars($id) {
		
		if (!is_numeric($id)) {
			trigger_error("RatingManager encountered problem in drawStars() parameter. Passed parameter must be numeric.");
			exit;
		}
		
		$query = "SELECT total_votes, total_value, used_ips FROM ratings WHERE id='".$id."'";
		$result = $this->querySelect($query);
		
		if (is_array($result) && count($result) > 0 ) {
			$totalVotes = $result[0]['total_votes'];	//how many total votes
			$totalValues = $result[0]['total_value'];  //total number of rating added together and stored
		}
		else {
			$totalVotes = 1;
			$totalValues = 0;
			
		}
		
		
		$ipAddress = $_SERVER['REMOTE_ADDR'];

		$currentRating = @number_format($totalValues / $totalVotes, 2) * STARWIDTH ;
		
		$ratingString = '<div id="unit_long'.$id.'">
							<ul class="unit-rating">
							<li class="current-rating" style="width:'.$currentRating.'px;">Currently '.$currentRating.'; ?>/ TOTALSTARS </li>';
		
			for ($ncount = 1; $ncount <= TOTALSTARS; $ncount++) { 
				$ratingString .= '<li><a href="javascript:void(0);" title="'.$ncount.' out of '.TOTALSTARS.'" class="r'.$ncount.'-unit" onclick="javascript:sndRequest(\''.$ncount.'\','.$id.',\''.$ipAddress.'\')">'.$ncount.'</a></li>';
			}

			$ncount = 0; // resets the count
			
			$ratingString .= '</ul>
							</div>';
			
		echo $ratingString;	
		
	}
	
	/**
	 * update votes for id
	 */
	public function updateVote($numberofVotesSent, $voteForWitchId, $userIPAddress) {
		ob_start();
		header("Cache-Control: no-cache");
		header("Pragma: nocache");
		
		$numberOfVotes = $numberofVotesSent;
		$voteForID = $voteForWitchId; 
		$ipAddress = $userIPAddress; 

		$query = "SELECT total_votes, total_value, used_ips FROM ratings WHERE id='".$voteForID."'";
		$result = $this->querySelect($query);
		
		$sum = 0;
		$oldIPAddress = Array();
		if (is_array($result) && count($result) > 0) {
			$totalVotes = $result[0]['total_votes'];			//how many votes total
			$totalValues = $result[0]['total_value'];  //total number of rating added together and stored
			$oldIPAddress = unserialize($result[0]['used_ips']);
			$sum = $numberOfVotes + $totalValues;		// add together current vote value and the total vote value
		}
		
		if ($sum == 0) {
			$addedVotes = 1; //checking to see if the first vote has been voted
			$sum = $numberOfVotes ;
		}
		else {
			$addedVotes = $totalVotes + 1;//increment the current number of votes
		}

		if (is_array($oldIPAddress)) {
			array_push($oldIPAddress, $ipAddress);//if it is an array i.e. already has entries the push in another value
		}
		else {
			$oldIPAddress = array($ipAddress);//for the first entry
		}
		
		$serializeIPList = serialize($oldIPAddress);
		
		//Check existing IDs
		$query = "SELECT count(*) as total FROM ratings WHERE id='".$voteForID."'";
		$result = $this->querySelect($query);
	
		
		if ($result[0]['total'] > 0 ) {
			$query = "UPDATE ratings SET total_votes = '".$addedVotes."', total_value='".$sum."', used_ips='".$serializeIPList."' WHERE id='".$voteForID."'";			
			$this->queryExecute($query);
		}
		else {
			$query = "INSERT INTO ratings (id, total_votes, total_value, used_ips) VALUES ($voteForID, $addedVotes, $sum, '".$serializeIPList."')";
			$this->queryExecute($query);
		}
		
		
		$currentRating = @number_format($sum / $addedVotes, 2) * STARWIDTH ;
		
		$ratingString = "<ul class=\"unit-rating\">\n" .
						"<li class=\"current-rating\" style=\"width:". $currentRating ."px;\">Currently $currentRating</li>\n";
			
			for ($ncount = 1; $ncount <= TOTALSTARS; $ncount++) { 
				$ratingString .= "<li class=\"r$ncount-unit\">$ncount</li>\n";
			}
			
		$ratingString .= "</ul>";//show the updated value of the vote
		
		//name of the div id to be updated | the html that needs to be changed
		$output = "unit_long$voteForID|$ratingString";
		echo $output;
	}
	
}

?>
Return current item: AJAX Star Rating