<?php
/**
 * Tag class
 * 
 * Povides methods related to tag module
 * 
 * @package linea21\modules\tag
 * @author $Author$ - linea21 <info@linea21.com>
 * @version $Id$ 
 * @access public
 * @license http://opensource.org/licenses/gpl-3.0.html
 * Project Management
 */

class tag {
	
	/* @param
	 * */
	var $TDB_TAG = T_TAG; // nom de la table.
	var $ID;
	var $NAME;
	var $COMMENT;
	
	protected $dispatcher = null;

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

	public function __call($method, $arguments)
	{
		$event = $this->dispatcher->notifyUntil(new sfEvent($this, 'tag.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();
	}
	
	/**
	 * tag::checkDataIntegrity()
	 * Vérification intégrité des données
	 *
	 * @access public
	 * @param array $array : contient les composants du tag
	 * @return boolean true
	 * si verifié, sinon string 'message d'erreur'
	 */
	
	public function CheckDataIntegrity($array)
	{
	
		// Filter data event + return value
		$r = $this->dispatcher->filter(new sfEvent($this, 'tag.before_datacheck', array('data' => $array)), $array);
		$table = $r->getReturnValue();
	
		if (strlen($table[0]) < 2) return _t('tag','no_name');
	
		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'news.after_datacheck', array('data' => $array)));
	
		return true;
	}

	/**
	 * tag::modifyTags()
	 * Ajout d'un ou plusieurs tags au contenu
	 *
	 * @access public
	 * @param string $module nom du module
	 * @param int $module_id identifiant du module
	 * @param string $content tags séparés par des virgules
	 * @return integer $last_id
	 */
	public function modifyTags($module, $module_id, $content) {

		global $sql_object;

		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'tag.modify_all', array('id' => $module_id,'module' => $module, 'content' => $content)));

		$query = "DELETE FROM " . J_TAG . " WHERE jta_module ='".$module."' AND jta_module_id ='".$module_id."';";
		$result = $sql_object->DBQuery($query);
		 
		if(!empty($content)) {
			$result = $this->addTags($module, $module_id, $content);
		}

		return $result;
	}

	/**
	 * tag::addTags()
	 * Ajout d'un ou plusieurs tags au contenu
	 *
	 * @access public
	 * @param string $module_id nom du module
	 * @param int $module_id identifiant du module
	 * @param string $content tags séparés par des virgules
	 * @return integer $last_id
	 */
	public function addTags($module, $module_id, $content)
	{
		global $sql_object;
		 
		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'tag.add_all', array('id' => $module_id,'module' => $module, 'content' => $content)));

		// we remove latest comma
		if (substr($content, -1) == ',') {
			$content = substr($content, 0, -1);
		}
		// we explode string to array
		$array = @explode(',', $content);
		$array = array_map('trim', $array);
		$array = array_unique($array); // we finally remove double entries
		$array = $sql_object->DBEscape($array);
		
		for ($i = 0;$i < count($array);$i++) {
			// we check if tag already exists
			$q = "SELECT tag_id FROM " . T_TAG. " WHERE lower(tag_name) = '" . strtolower($array[$i]) . "';";
			$data = $sql_object->DBSelect($q);

			// if already exists, we retrieve id
			if(isset($data[0]['tag_id'])) {
				$tag_id = $data[0]['tag_id'];
			} else {
				// else we create it and retrieve id
				$q = "INSERT INTO " . T_TAG . " (tag_name, tag_comment, tag_date_crea) VALUES('" . $array[$i] . "', '', NOW());";
				$last_id = $sql_object->DBInsert ($q, 1);
				$tag_id = $last_id;
			}
			// finally we insert tuple in table
			$q = "INSERT INTO " . J_TAG . " (jta_module, jta_module_id, jta_tag_id) VALUES('" . $module . "', " . $module_id . ", " . $tag_id . ");";

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

		return $last_id;
	}
	
	/**
	 * tag::modifyTagById()
	 * Suppression d'un tag
	 *
	 * @access public
	 * @param int $id identifiant du tag
	 * @param array $a array container
	 * @return boolean
	 */
	public function modifyTagById($id, $a) {
			
		global $sql_object;
		
		// image 64 encoded conversion if enabled before escaping content
		$a[1] = convertBase64Images($a[1], 'tag-');
		
		$array = $sql_object->DBEscape($a);
			
		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'tag.modify_by_id', array('id' => $id)));
	
		$query = "UPDATE " . T_TAG . " SET tag_name='".$array[0]."', tag_comment='".$array[1]."' WHERE tag_id ='".$id."';";
		$r = $sql_object->DBQuery($query);
	
			
		return $r;
	}
	
	/**
	 * tag::deleteTagById()
	 * Suppression d'un tag
	 *
	 * @access public
	 * @param int $id identifiant du tag
	 * @return boolean
	 */
	public function deleteTagById($id) {
			
		global $sql_object;
			
		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'tag.delete_by_id', array('id' => $id)));
		
		$query = "DELETE FROM " . J_TAG . " WHERE jta_tag_id ='".$id."';";
		$r = $sql_object->DBQuery($query);
		
		if($r) {
			$query = "DELETE FROM " . T_TAG . " WHERE tag_id ='".$id."';";
			$r = $sql_object->DBQuery($query);
		}
			
		return $r;
	}
	
	/**
	 * tag::getTagById()
	 * Obtention des informations relatives à un tag
	 *
	 * @access public
	 * @param id identifiant du tag
	 * @return array
	 */
	public function getTagById($id) {
	    
	    global $sql_object;
	    
	    // Notify the beginning of the current method
	    $this->dispatcher->notify(new sfEvent($this, 'tag.get_tag_by_id', array('id' => $id)));
	    
	    $query = "SELECT * FROM " . T_TAG . " WHERE tag_id =".$id.";";
	    
	    $r = $sql_object->DBSelect($query);

	    if(!isset($r[0]['tag_id'])) return false;
	    
	    return array('id' => $r[0]['tag_id'], 'name' => $r[0]['tag_name']);
	}
	
	/**
	 * tag::deleteTagsByItem()
	 * Suppression des tags associés à un couple module/module_id
	 *
	 * @access public
	 * @param string $module nom du module
	 * @param int $module_id identifiant du module
	 * @return boolean
	 */
	public function deleteTagsByItem($module, $module_id) {
			
		global $sql_object;
			
		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'tag.delete_all', array('id' => $module_id,'module' => $module)));
			
		$query = "DELETE FROM " . J_TAG . " WHERE jta_module ='".$module."' AND jta_module_id ='".$module_id."';";
		$result = $sql_object->DBQuery($query);
			
		return $result;
	}
	
	/**
	 * tag::linkTags()
	 * return a list of tag or unique tag
	 *
	 * @access public
	 * @param $array - array containing tags
	 * @param $defaultlink - string containing link
	 * @param $remove - array / string pattern(s) to remove from tag names
	 * @return string
	 */
	public function linkTags($array, $defaultlink, $remove= '') {
		
		$str = '';
		if(is_string($remove)) $remove = array($remove);
		
		foreach ($array as &$el) {
			$defaultlink['id'] = $el['tag_id'];
			$defaultlink['name'] = $el['tag_name'];
			$link = HrefMaker($defaultlink);
			$str .= '<a href="'.$link.'" class="tag">'.str_replace($remove, '', $el['tag_name']).'</a>';
		}
		
		return $str;
	}
	
	/**
	 * tag::exists()
	 * Test if tags exists
	 *
	 * @access public
	 * @param $array - array containing values to search
	 * @param $tagso - array of tags to search in formatted as getTags() returned values
	 * @param $type - 'equals' or 'startsWith' values
	 * @param $return -  if 'first', return only one value else return all searched and found values
	 * @return array
	 */
	public function exists($array, $tagso, $type = 'equals', $return = 'first') {
	    
	    $found = array();
	    
	    if($type == 'equals') {
    	    foreach($array as $value) {
    	        
    	        foreach($tagso as $key => $val) {
    	            if($value == $val['tag_name']) array_push($found, array('tag_id' => $val['tag_id'], 'tag_name' => $val['tag_name']));
    	        }
    	    }
	    } elseif($type == 'startsWith') {
	        foreach($array as $value) {
	            
	            foreach($tagso as $key => $val) {
	                if(Stringy\Stringy::create($val['tag_name'], CHARSET)->startsWith($value)) array_push($found, array('tag_id' => $val['tag_id'], 'tag_name' => $val['tag_name']));
	            }
	        }
	    }
	    
	    if(count($found) == 0) return false;
	    if($return == 'first') return array($found[0]);
	    else return $found;
	    
	}
	
	
	public function getAssociatedContent() {
		
	}
	/**
	 * tag::getTags()
	 * @param string $module
	 * @param integer $module_id
	 * @param boolean $as_string
	 */
	public function getTags($module, $module_id = -1, $as_string = true, $separator = ',', $unique = false) {
		
		global $sql_object;
			
		// Notify the beginning of the current method
		$this->dispatcher->notify(new sfEvent($this, 'tag.get_all', array('id' => $module_id,'module' => $module)));
		
		if($module_id != -1)  $mask=" AND jta_module_id ='".$module_id."'";
		else $mask = '';
		
		$query = "SELECT tag_id, tag_name FROM " . J_TAG . " LEFT OUTER JOIN " . T_TAG . " ON jta_tag_id = tag_id WHERE jta_module ='%s' %s;";
		
		$query = sprintf($query, $module, $mask);
		
		$result = $sql_object->DBSelect($query);
		
			$stored = array();
			$array  			= array();
			$simple_array = array();
			
			if(isset($result[0]['tag_id'])) {
				for($i=0; $i <count($result); $i++) {
					if($unique === false) {
						$array[$i]['tag_name'] =  $result[$i]['tag_name'];
						$array[$i]['tag_id'] =  $result[$i]['tag_id'];
						array_push($simple_array, $result[$i]['tag_name']);
					} else {
						if(!in_array($result[$i]['tag_name'], $stored)) {
							array_push($stored, $result[$i]['tag_name']);
							$array[$i]['tag_name'] =  $result[$i]['tag_name'];
							$array[$i]['tag_id'] =  $result[$i]['tag_id'];
							array_push($simple_array, $result[$i]['tag_name']);
						}
					}	
				}
			}
			
			if($as_string) {
				
				return join($separator . ' ', $simple_array);
				
			} else {
				
				return $array;
				
			}
			
		return $result;
	}


}


?>