<?php
/**
* @version	$Id: rating_helper.php 13435 2010-04-27 10:27:11Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class RatingHelper extends kHelper {

		/**
		 * One star width/height in pixels
		 *
		 * @var int
		 */
		var $ratingUnitWidth = 25;
		var $ratingSmallUnitWidth = 20;

		/**
		 * Maximal star count
		 *
		 * @var int
		 */
		var $ratingMaximal = 5;

		var $_phrases = Array (
			'current_rating' => 'lu_CurrentRating',
			'vote_title' => 'lu_VoteTitle',
			'vote_count' => 'lu_VoteCount',
			'invalid_rating' => 'lu_InvalidRating',
			'already_voted' => 'lu_AlreadyVoted',
			'thanks_for_voting' => 'lu_ThanksForVoting',
		);

		/**
		 * Draws rating bar for a given category item
		 *
		 * @param kDBItem $object
		 * @param bool $show_div
		 * @param string $additional_msg
		 * @return string
		 */
		function ratingBar(&$object, $show_div = true, $additional_msg = '', $additional_style = '')
		{
			$perm_prefix = $this->Application->getUnitOption($object->Prefix, 'PermItemPrefix');
			$static = !$this->Application->CheckPermission($perm_prefix . '.RATE', 0, $object->GetDBField('CategoryId'));

			$total_votes = $object->GetDBField('CachedVotesQty');
			$total_rating = $object->GetDBField('CachedRating') * $total_votes;

			$spam_helper =& $this->Application->recallObject('SpamHelper');
			/* @var $spam_helper SpamHelper */

			$config_mapping = $this->Application->getUnitOption($object->Prefix, 'ConfigMapping');
			$review_settings = $config_mapping['RatingDelayValue'].':'.$config_mapping['RatingDelayInterval'];
			$spam_helper->InitHelper($object->GetDBField('ResourceId'), 'Rating', $review_settings, $object->GetCol('ResourceId'));

			$user_voted = $spam_helper->InSpamControl();

			// now draw the rating bar
			$unit_selected_width = $additional_style? $this->ratingSmallUnitWidth : $this->ratingUnitWidth;
			$rating_width = $total_votes ? @number_format($total_rating / $total_votes, 2) * $unit_selected_width : 0;
			$rating1 = $total_votes ? @number_format($total_rating / $total_votes, 1) : 0;
			$rating2 = $total_votes ? @number_format($total_rating / $total_votes, 2) : 0;

			$rater = '<span class="inline-rating">
						<ul class="star-rating '.$additional_style.'" style="width: ' . $unit_selected_width * $this->ratingMaximal . 'px;">
							<li class="current-rating" style="width: ' . $rating_width . 'px;">' . $this->_replaceInPhrase('current_rating', Array ('<strong>' . $rating2 . '</strong>', $this->ratingMaximal)) . '</li>'."\n";;

			if (!$static && !$user_voted) {
				// allow to set rating when not static and user not voted before
				for ($ncount = 1; $ncount <= $this->ratingMaximal; $ncount++) {
					$rater .= '<li><a href="#vote-' . $ncount . '" onclick="aRatingManager.makeVote(' . $ncount . ', \'' . $object->Prefix . '\', ' . $object->GetID() . ', \''.$additional_style.'\'); return false;" title="' . $this->_replaceInPhrase('vote_title', Array ($ncount, $this->ratingMaximal)) . '" class="r' . $ncount . '-unit rater" rel="nofollow">' . $ncount . '</a></li>'."\n";
				}
			}

			$msg_class = Array ();

			if ($static) {
				$msg_class[] = 'static';
			}

			if ($user_voted) {
				$msg_class[] = 'voted';
			}

			$rater .= '	</ul></span>';

			// this part is disabled for now, will be addressed once properly review
//			$rater .= '	<p class="' . implode(' ', $msg_class) . '">' .
							$this->_replaceInPhrase('vote_title', Array('<strong>'.$rating1.'</strong>', $this->ratingMaximal)) . ' ('. $this->_replaceInPhrase('vote_count', Array($total_votes)) . ') </p>';

			$rater .= '&nbsp;<span class="' . implode(' ', $msg_class) . '">'.$additional_msg.'</span>';

			if ($show_div) {
				// adds div around rating stars (when drawing rating first time)
				$rater = '<div class="inline-rating" id="page_rating_' . $object->GetID() . '">' . $rater . '</div>';
			}

			return $rater;
		}

		/**
		 * Saves user's vote, when allowed
		 *
		 * @param kDBItem $object
		 * @return string
		 */
		function makeVote(&$object)
		{
			$spam_helper =& $this->Application->recallObject('SpamHelper');
			/* @var $spam_helper SpamHelper */

			$config_mapping = $this->Application->getUnitOption($object->Prefix, 'ConfigMapping');
			$review_settings = $config_mapping['RatingDelayValue'].':'.$config_mapping['RatingDelayInterval'];
			$spam_helper->InitHelper($object->GetDBField('ResourceId'), 'Rating', $review_settings, $object->GetCol('ResourceId'));

			if (!$object->isLoaded() || $spam_helper->InSpamControl()) {
				return '@err:' . $this->_replaceInPhrase('already_voted');
			}

			$perm_prefix = $this->Application->getUnitOption($object->Prefix, 'PermItemPrefix');
			$can_rate = $this->Application->CheckPermission($perm_prefix . '.RATE', 0, $object->GetDBField('CategoryId'));
			$rating = (int)$this->Application->GetVar('rating'); // not numeric rating is from GoogleBot :(
			$additional_style = $this->Application->GetVar('size');

			if (($rating <= 0) || ($rating > $this->ratingMaximal) || !$can_rate) {
				return '@err:' . $this->_replaceInPhrase('invalid_rating');
			}

			// save current rating
			$fields_hash = Array (
				'ItemId'		=>	$object->GetID(),
				'RatingValue'	=>	$rating,
				'IPAddress'		=>	$_SERVER['REMOTE_ADDR'],
				'CreatedOn'		=>	adodb_mktime(),
			);
			$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'ItemRating');

			// recalculate average rating
			$votes_count = $object->GetDBField('CachedVotesQty');
			$avg_rating = $object->GetDBField('CachedRating');

			$avg_rating = round((($votes_count * $avg_rating) + $rating) / ($votes_count + 1), 2);
			$object->SetDBField('CachedRating', "$avg_rating");
			$object->Update();

			$sql = 'UPDATE '.$object->TableName.'
					SET CachedVotesQty = CachedVotesQty + 1
					WHERE '.$object->IDField.' = '.$object->GetID();
			$this->Conn->Query($sql);

			$object->SetDBField('CachedVotesQty', $object->GetDBField('CachedVotesQty') + 1); // for using in template

			// prevent user from voting too quickly
			$spam_helper->AddToSpamControl();

			return $this->ratingBar($object, false, '<span class="thanks">' . $this->_replaceInPhrase('thanks_for_voting') . '</span>', $additional_style);
		}

		/*function purgeVotes()
		{
			$expired = adodb_mktime() - 86400 * $this->Application->ConfigValue('Timeout_Rating'); // 3600

			$sql = 'DELETE FROM ' . TABLE_PREFIX . 'ItemRating
					WHERE CreatedOn < ' . $expired;
			$this->Conn->Query($sql);
		}*/

		/**
		 * Performs sprintf on phrase translation using given variables
		 *
		 * @param string $phrase
		 * @param Array $arguments
		 * @return string
		 */
		function _replaceInPhrase($phrase, $arguments = Array ())
		{
			$value = $this->Application->Phrase($this->_phrases[$phrase]);

			if ($arguments) {
				return vsprintf($value, $arguments);
			}

			return $value;
		}
	}