<?php
/**
 * Vote class
 * 
 * Provides methods related to vote module
 * 
 * @package linea21\modules\vote
 * @author $Author$ - Simon Georget <simon@linea21.com>
 * @version $Id$ 
 * @access public
 * @license http://opensource.org/licenses/gpl-3.0.html
 * Content Management
 */

class vote {

	private $params = array();
	private $allowMultipleVotes = false; // change to debug or allow multiples votes
	private $deleteInterval = 30; // interval in seconds to allow user to delete own votes
	protected $dispatcher = null;


	public function __construct($a = array())
	{
		$this->dispatcher = $GLOBALS['dispatcher'];
		$this->params = $a;
	}

	public function __call($method, $arguments)
	{
		$event = $this->dispatcher->notifyUntil(new sfEvent($this, 'vote.extensible_function', array(
				'method'    => $method,
				'arguments' => $arguments
		)));
		if (!$event->isProcessed())
		{
			throw new Exception(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
		}

		return $event->getReturnValue();
	}


	public function has_already_voted($a, $sql_object) {
	    
	    global $l21auth;
	    
	    // Notify the call of the current method
	    $this->dispatcher->notify(new sfEvent($this, 'vote.has_already_voted', array('data' => $a)));
	    
	    // for developpement, allow multiple votes
	    if($this->allowMultipleVotes == true) return false;
	    
	    $a = array_map('sanitize_string', $a);
	    
	    $a=$sql_object->DBescape($a);
	    
	    $a['module'] = strip_input(trim($a['module']), false);
	    $a['module_id'] = strip_input(trim($a['module_id']), false);
	    $a['user_id'] = strip_input(trim($a['user_id']), false);
	    $a['user_ip'] = strip_input(trim($a['user_ip']), false);
	    
	    $q = "SELECT * from " . T_VOTE . " WHERE vote_module='" . $a['module'] . "' AND vote_module_id='" . $a['module_id'] . "' AND (vote_user_id ='". $a['user_id'] ."' OR vote_user_ip = '". $a['user_ip'] ."' );";
	    
	    $data = $sql_object->DBSelect ($q);
	    
	    // if a record is return, the user has already voted for the current item
	    if(isset($data[0]['vote_user_ip'])) return true;
	    // else it's ok
	    else return false;
	    
	}


	public function add($a, $sql_object) {

		global $l21auth;
		
		// Filter data event + return value
		$r = $this->dispatcher->filter(new sfEvent($this, 'vote.before_add', array('data' => $a)), $a);
		$a = $r->getReturnValue();
		
		$a = array_map('sanitize_string', $a);

		$a=$sql_object->DBescape($a);


		$a['module'] = strip_input(trim($a['module']), false);
		$a['module_id'] = strip_input(trim($a['module_id']), false);
		$a['user_id'] = strip_input(trim($a['user_id']), false);
		$a['user_ip'] = strip_input(trim($a['user_ip']), false);
		

		$q = "INSERT INTO " . T_VOTE . " (vote_module, vote_module_id, vote_user_id, vote_user_ip, vote_date_crea) VALUES('" . $a['module'] . "', '" . $a['module_id'] . "', '" . $a['user_id'] . "', '" . $a['user_ip'] . "', now());";

		$last_id = $sql_object->DBInsert ($q, 1);

		
		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'vote.after_add', array('data' => $a, 'id' => $last_id)));
		
		// we log add action
		if(is_numeric($last_id))	{
		    logfile(LOG_MAINFILE, array('[action] add vote', 'ID='.$last_id, 'by_id='.$a['user_login']));
		    return array ('id' => $last_id, 'counter' => $this->getVotesCount($a, $sql_object));
		} else return false;
		
	}


	public function getVotesCount($a, $sql_object) {

		// Notify the end of the current method
	    $this->dispatcher->notify(new sfEvent($this, 'vote.get_vote_item', array('data' => $a)));
		
	    $data = $sql_object->DBSelect(SQL_getVotesNumber($a));

		return $data[0]['nb'];
	}


	public function delete($id, $sql_object) {

		global $l21auth;
		
		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'vote.delete', array('id' => $id)));

		$id = $sql_object->DBEscape($id);
		$q = "DELETE FROM ". T_VOTE . " WHERE vote_id='".$id."' AND vote_user_ip = '" . i2c_realip() . "' AND now() < DATE_ADD(vote_date_crea, INTERVAL ".$this->deleteInterval." SECOND)";
		$r = $sql_object->DBQuery($q);
		
		// we check if row is affected
		if($sql_object->DBaffectedRow() > 0) {
		
    		if($l21auth->isAuthenticated()) $user_id = $l21auth->GetSessionElement('id');  else $user_id = 0;
    		if($l21auth->isAuthenticated()) $user_login = $l21auth->GetSessionElement('login');  else $user_login = 'NOT_AUTHENTICATED';
    		
    		// we log delete action
    		logfile(LOG_MAINFILE, array('[action] delete vote', 'ID='.$id, 'by_id='.$user_id, 'by_login='.$user_login));
    		return true;
		}

		return false;
	}

	public function getInterval() {
	    return $this->deleteInterval;
	}

}

?>