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

class comment {

	private $params = array();
	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, 'comment.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();
	}


	/**
	 * comment::checkDataIntegrity()
	 * Vérification intégrité des données
	 *
	 * @access public
	 * @param array $a
	 * @return boolean true
	 * si verifié, sinon string 'message d'erreur'
	 */

	public function checkDataIntegrity($a)
	{
		// Filter data event + return value
		$r = $this->dispatcher->filter(new sfEvent($this, 'comment.before_datacheck', array('data' => $a)), $a);
		$a = $r->getReturnValue();

		// if not authenticated
		if(!isset($_SESSION['authenticated'])) {
			if (strlen($a['name']) < 3) return _t('comment','no_name');
			if (strlen($a['email']) < 3) return _t('comment','no_email');
			$result = $this->_checkEmailValidity($a['email']);
			if (is_string($result)) return $result;
		}

		if (strlen($a['body']) < 3) return _t('comment','no_body');

		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.after_datacheck', array('data' => $a)));

		return true;
	}

	/**
	 * comment::_checkEmailValidity()
	 * Email validation
	 *
	 * @access private
	 * @param string $email
	 * @return string $result
	 * return 1 si valide sinon message d'erreur (string)
	 */
	function _checkEmailValidity($email)
	{

		$is_valid = validEmail($email);

		if(!$is_valid) {
			return sprintf(_t('contact','email_error'), $email);
		} else {
			return true;
		}

	}

	public function add($a, $sql_object) {

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

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

		if ($a['name'] != '') {
			$a['name'] = strip_input(trim($a['name']), false);
		}
		if ($a['email'] != '') {
			$a['email'] = strip_input(trim($a['email']), false);
		}
		if ($a['url'] != '') {
			$a['url'] = strip_input(trim($a['url']), false);
		}

		if(COMMENT_MODERATION  == 1) {
			$a['status']='D';
			// if user is logged-in, do we moderate or not?
			if(!empty($a['user_id']) && COMMENT_MODERATE_REGISTERED  == 0) $a['status']='P';
		}
		else $a['status']='P';

		$q = "INSERT INTO " . T_COMM . " (comment_module, comment_module_id, comment_user_id, comment_name, comment_email, comment_url, comment_body, comment_notification, comment_status, comment_date_crea) VALUES('" . $a['module'] . "', '" . $a['module_id'] . "', '" . $a['user_id'] . "', '" . $a['name'] . "', '" . $a['email'] . "', '" . $a['url'] . "', '" . $a['body'] . "', '" . $a['notification'] . "', '" . $a['status']. "', now());";

		$last_id = $sql_object->DBInsert ($q, 1);
		
		// we log add action
		if(is_numeric($last_id))	logfile(LOG_MAINFILE, array('[action] add comment', 'ID='.$last_id, 'by_id='.$a['user_id']));

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.after_add', array('data' => $a, 'id' => $last_id)));

		return $last_id;
	}

	public function get($options, $sql_object) {

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.get', array('data' => $options)));

		$data = $sql_object->DBSelect(SQL_getComments($options));

		return $data;
	}

	public function getCommentItem($options, $sql_object) {

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.get_comment_item', array('data' => $options)));

		$data = $sql_object->DBSelect(SQL_getCommentItem($options));

		return $data;
	}

	public function getSubscribers($options, $sql_object) {

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.get_subscribers', array('data' => $options)));

		$data = array();

		$tmp = $sql_object->DBSelect(SQL_getRegisteredSubscribers($options, $sql_object));
		$tmp2 = $sql_object->DBSelect(SQL_getNonRegisteredSubscribers($options, $sql_object));
		if(!is_array($tmp)) $tmp = array();
		if(is_array($tmp2)) $tmp = array_merge($tmp, $tmp2);

		// we ensure there is no duplicate emails
		foreach($tmp as $el) {
			if(!in_array($el['user_email'], $data)) {
				array_push($data, $el['user_email']);
			}
		}

		return $data;
	}

	public function getByModule($options, $sql_object) {

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.get_by_module', array('data' => $options)));

		$data = $sql_object->DBSelect(SQL_getModuleComments($options));

		return $data;
	}

	/*
	 * get all comments awaiting for moderation
	*/
	public function getAllByModule($status, $sql_object, $limit = false, $sort = false) {

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.get_all_by_module', array('status' => $status, 'limit' => $limit, 'sort' => $sort)));

		$r = array();

		if(MOD_NEWS == 1) {
			$tmp = $this->getByModule(array('module' => 'news', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		if(MOD_PROJECT == 1) {
			$tmp = $this->getByModule(array('module' => 'project', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		if(MOD_WORKSHOP == 1) {
			$tmp = $this->getByModule(array('module' => 'workgroups', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		if(MOD_WORKSHOP == 1) {
			$tmp = $this->getByModule(array('module' => 'report', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		if(MOD_WORKSHOP == 1) {
			$tmp = $this->getByModule(array('module' => 'files', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		if(MOD_SDI == 1) {
			$tmp = $this->getByModule(array('module' => 'indicator', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		if(MOD_PUBLICATION == 1) {
			$tmp = $this->getByModule(array('module' => 'publication', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
			if(is_array($tmp)) $r = array_merge($r, $tmp);
		}
		$tmp = $this->getByModule(array('module' => 'contribute', 'status' => $status, 'limit' => $limit), $sql_object, 'module');
		if(is_array($tmp)) $r = array_merge($r, $tmp);

		if($sort == 'date') {
			// on obtient une liste de colonnes
			foreach ($r as $key => $row) {
				$date[$key]  = $row['comment_date_timestamp'];
			}

			// Tri des données par date décroissante
			// Ajoute $r en tant que dernier paramètre, pour trier par la clé commune
			if(isset($date) && is_array($date)) array_multisort($date, SORT_DESC, $r);
		}
		if($limit != false) {
			$r = array_slice($r, 0, $limit);
		}

		return $r;
	}


	public function modify_lite($id, $body, $sql_object) {
		
		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.modify_lite', array('id' => $id, 'body' => $body)));
		
		$body= $sql_object->DBEscape($body);
		$q = "UPDATE " . T_COMM . " SET comment_body = '" . $body. "' WHERE  comment_id = ".$id.";";

		$r = $sql_object->DBQuery($q);
		
		return $r;
	}
	

	public function isNew($id, $sql_object) {

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

		$id = $sql_object->DBEscape($id);
		$q = "SELECT comment_status FROM " . T_COMM . " WHERE  comment_id = '".$id."';";
		$r = $sql_object->DBSelect($q);

		if($r[0]['comment_status'] == 'D') {
			return true;
		} else {
			return false;
		}

	}



	public function unsubscribe($a, $sql_object) {

		// Notify the end of the current method
		$this->dispatcher->notify(new sfEvent($this, 'comment.unsubscribe', array('data' => $a)));

		// if registered user
		$a = $sql_object->DBEscape($a);
		$q = "SELECT U.user_id, P.profile_email FROM " . T_USER . " AS U LEFT OUTER JOIN " . T_PROFILE . " AS P ON P.profile_id = U.user_profile WHERE  P.profile_email = '".$a['email']."'";

		$data = $sql_object->DBSelect($q);

		if(count($data) > 0 && $data != 0) {
			// we loop because (in theory) a user can have several accounts associtaed with one unique email
			for($i=0; $i < count($data); $i++) {
				$q = "UPDATE ". T_COMM . " SET comment_notification = 'N' WHERE comment_module='".$a['module']."' AND comment_module_id='".$a['module_id']."' AND comment_status <> 'D' AND comment_user_id='".$data[$i]['user_id']."'";
				$r = $sql_object->DBQuery($q);
			}
		}

		// if not registered user
		$q = "UPDATE ". T_COMM . " SET comment_notification = 'N' WHERE comment_module='".$a['module']."' AND comment_module_id='".$a['module_id']."' AND comment_status <> 'D' AND comment_email='".$a['email']."'";
		$r = $sql_object->DBQuery($q);

		return $r;

	}

	public function delete($id, $sql_object) {

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

		$id = $sql_object->DBEscape($id);
		$q = "DELETE FROM ". T_COMM . " WHERE comment_id='".$id."'";
		$r = $sql_object->DBQuery($q);
		
		// we log delete action
		if($r)	logfile(LOG_MAINFILE, array('[action] delete comment', 'ID='.$id, 'by_id='.$l21auth->GetSessionElement('id'), 'by_login='.$l21auth->GetSessionElement('login')));

		return $r;
	}

	public function disapprove($id, $sql_object) {

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

		$id = $sql_object->DBEscape($id);
		$q = "UPDATE ". T_COMM . " SET comment_status = 'E' WHERE comment_id='".$id."'";
		$r = $sql_object->DBQuery($q);

		return $r;
	}

	public function approve($id, $sql_object) {

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

		$id = $sql_object->DBEscape($id);
		$q = "UPDATE ". T_COMM . " SET comment_status = 'P' WHERE comment_id='".$id."'";
		$r = $sql_object->DBQuery($q);

		return $r;

	}



}

?>