<?php
/**
 * @package linea21.core
 * @subpackage user
 * @author linea21 <info@linea21.com>
 * @version $id SVN
 * @access public
 * @license http://opensource.org/licenses/gpl-3.0.html
 * User Management
 */

class user {
  /* @param
   * */
  var $TDB_USER = T_USER; // nom de la table.
  var $URI_INPUT = "library/userfiles/users/avatars/"; // dossier racine de stockage des photos
  var $NB_USERS = 30; // affichage par défaut du nombre d'utilisateurs
  var $UPLOAD_MAX_MO = 30720; // taille maximale d'upload des avatars en octets
  var $ID;
  var $LOGIN;
  var $PASSWORD;
  var $COMMUNITY = USER_COMMUNITY;
  var $CATEGORY;
  var $RIGHT;
  var $PROFILE;
  var $DATE_CREA;
  var $VALIDITY;
  var $LAST_MODIFY;

  var $R_ID;
  var $R_DASHBOARD;
  var $R_WORKSHOP;
  var $R_PROJECT;
  var $R_PUBLICATION;
  var $R_NEWS;
  var $R_YELLOWPAGES;
  var $R_THEME;
  var $R_SCALE;
  var $R_LEVEL;
  var $R_CATEGORY_USER;

  var $P_ID;
  var $P_EMAIL;
  var $P_EMAIL_DISPLAY;

  var $P_FIRSTNAME;
  var $P_LASTNAME;
  var $P_CITY;
  var $P_BIRTHDATE;
  var $P_LEISURES;
  var $P_JOB;
  var $P_AVATAR;
  var $P_QUOTATION;
  var $P_SIGNATURE;

  protected $dispatcher = null;

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

  public function __call($method, $arguments)
  {
    $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'user.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();
  }

  /**
   * user::CheckDataIntegrity()
   * Vérification intégrité des données
   *
   * @access public
   * @param array $table : contient les composants d'un user
   * @param object $sql_object
   * @return boolean si vrai renvoie true sinon message d'erreurs (string)
   */
  function CheckDataIntegrity($table, $sql_object = null, $logincheck = true)
  {
  	// Filter data event + return value
  	$r = $this->dispatcher->filter(new sfEvent($this, 'user.before_datacheck', array('data' => $table)), $table);
  	$table = $r->getReturnValue();
  	
    if ($logincheck) {
      $result = $this->_checkLoginValidity($table[0], $sql_object);
      if (is_string($result)) return $result;
    }
    $result = $this->_checkEmailValidity($table[1]);
    if (is_string($result)) return $result;
    
    // Notify the beginning of the current method
    $this->dispatcher->notify(new sfEvent($this, 'user.after_datacheck', array('data' => $table)));
    
    return true;
  }

  /**
   * user::_checkLoginValidity()
   * validation d'un login
   *
   * @access private
   * @param string $login : login rentré par l'utilisateur
   * @param object $sql_object
   * @return bool $result
   * si valide true sinon message d'erreur (string)
   */
  function _checkLoginValidity($login, $sql_object)
  {
  	// Notify the beginning of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.check_login_validity', array('login' => $login)));
  	
    $login = trim($login);
    if (!preg_match('|^[a-zA-Z0-9_\.\-]+$|', $login)) return _t('user','login_prohibited');
    if (strlen($login) < 5) return _t('user','login_tooshort');
    if (strlen($login) > 50) _t('user','login_toolong');
    $q = "SELECT user_id FROM " . $this->TDB_USER . " WHERE lower(user_login)= '" . strtolower($login) . "' AND user_validity='Y';";

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

    if (isset($result[0]['user_id'])) return _t('user','login_used');

    return true;
  }

  /**
   * user::checkPasswordValidity()
   * validation d'un password
   *
   * @access publi
   * @param string $password password rentre par l'utilisateur
   * @param string $pass2 (option)
   * @return bool si valide true sinon message d'erreur (string)
   */
  function checkPasswordValidity($password, $pass2 = -1)
  {
  	// Notify the beginning of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.check_password_validity', array('password' => $password, 'password2' => $pass2)));
  	
    if (strlen($password) < PASSWD_MINLENGTH) return sprintf(_t('user','pass_tooshort'), PASSWD_MINLENGTH);
    if (strlen($password) > 15) return _t('user','pass_toolong');
    if ($pass2 != -1 && $password != $pass2) return _t('user','pass_not_same');

    return true;
  }

  /**
   * user::_checkEmailValidity()
   * validation d'un email
   *
   * @access private
   * @param string $email email rentre par l'utilisateur
   * @return string $result
   * return 1 si valide sinon message d'erreur (string)
   */
  function _checkEmailValidity($email)
  {

  	// Notify the beginning of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.check_email_validity', array('email' => $email)));
  	
    $is_valid = validEmail($email);

    if(!$is_valid) {
      return _t('user','invalid_mail') . " :'" . $email . "'";
    } else {
      return true;
    }

  }

  /**
   * user::_setUserCategory()
   * determine automatique la categorie d'un utilisateur en fonction de ses droits
   * et renseigne l'objet
   *
   * @access private
   * @param array $table_right tableau des droits de l'utilisateur
   * @return bool $result
   */
  function _setUserCategory($table_right)
  {
  	// Notify the beginning of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.set_usercategory', array('data' => $table_right)));
  	
    if (isset($table_right['category_user']) && $table_right['category_user'] == 'A') $this->CATEGORY = 1;
    else {
      if(in_array('A', array_values($table_right))) $this->CATEGORY = 1;
      elseif ($table_right['dashboard'] == 'O' || $table_right['publication'] == 'O' || $table_right['news'] == 'O' || $table_right['workshop'] == 'O') $this->CATEGORY = 2;
      else $this->CATEGORY = 3;
    }

    return true;
  }

  /**
   * user::_AddProfile()
   * Ajout d'un profil
   *
   * @access private
   * @param integer id
   * @param object $sql_object
   * @return integer $last_id
   */
  function _AddProfile($id, $sql_object)
  {
  	// Notify the beginning of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.add_profile', array('id' => $id)));
  	
    $q = "INSERT INTO " . T_PROFILE . " (profile_id, profile_firstname, profile_lastname, profile_email, profile_email_display, profile_city, profile_birthdate, profile_leisures, profile_job, profile_avatar, profile_quotation, profile_signature, profile_date_crea) VALUES (".$id.", '" . $this->P_FIRSTNAME . "', '" . $this->P_LASTNAME . "', '" . $this->P_EMAIL . "', '" . $this->P_EMAIL_DISPLAY . "','', '0001-01-01', '', '', '', '', '', NOW());";
    $r = $sql_object->DBInsert ($q);
    
    return $r;
  }

  /**
   * user::_AddRight()
   * stockage des droits d' un utilisateur BDD
   *
   * @access private
   * @param integer id
   * @param array $table_right contient les droits
   * @param object $sql_object
   * @return integer $last_id
   */
  function _AddRight($id, $table_right, $sql_object)
  {

  	// Filter data event + return value
  	$r = $this->dispatcher->filter(new sfEvent($this, 'user.before_add_right', array('data' => $table_right,'id' => $id)), $table_right);
  	$table_right = $r->getReturnValue();
  	
    $this->R_DASHBOARD = $table_right['dashboard'];
    $this->R_WORKSHOP = $table_right['workshop'];
    $this->R_PROJECT = $table_right['project'];
    $this->R_PUBLICATION = $table_right['publication'];
    $this->R_NEWS = $table_right['news'];
    $this->R_YELLOWPAGES = $table_right['yellowpages'];
    $this->R_THEME = $table_right['theme'];
    $this->R_SCALE = $table_right['scale'];
    $this->R_LEVEL = $table_right['level'];
    $this->R_CATEGORY_USER = $table_right['category_user'];
    $q = "INSERT INTO " . T_RIGHT . " (rights_id, rights_dashboard, rights_workshop, rights_project, rights_publication, rights_news, rights_yellowpages, rights_theme, rights_scale, rights_level, rights_category_user, rights_date_crea)VALUES (".$id.", '" . $this->R_DASHBOARD . "', '" . $this->R_WORKSHOP . "', '" . $this->R_PROJECT . "', '" . $this->R_PUBLICATION . "', '" . $this->R_NEWS . "', '" . $this->R_YELLOWPAGES . "', '" . $this->R_THEME . "', '" . $this->R_SCALE . "', '" . $this->R_LEVEL . "', '" . $this->R_CATEGORY_USER . "', NOW());";
    $r = $sql_object->DBInsert ($q);
    
    // Notify the end of the current method
    $this->dispatcher->notify(new sfEvent($this, 'user.after_add_right', array('data' => $table_right, 'id' => $id)));
    
    return $r;
  }

  /**
   * user::GetUserWorkshops()
   * Ajout d'un utilisateur à un ou plusieurs workshops
   *
   * @access public
   * @param int $user_id identifiant du workshop
   * @param array $workgroups workgroups ID
   * @param string $user_right droit confié a l'utilisateur sur le workshop
   * @param object $sql_object
   * @return integer $last_id
   */
  function GetUserWorkshops($user_id, $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.get_user_workshops', array('id' => $user_id)));
  	
    if (is_numeric($user_id)) {
      $this->ID = $user_id;
    } else return false;

    $q = "SELECT jwu_workshop_id, workshop_denomination, jwu_user_right FROM ".J_WORK_USERS."
      		LEFT OUTER JOIN " . T_WORK . " ON jwu_workshop_id=workshop_id
      		WHERE jwu_user_id=".$this->ID." AND jwu_user_right='U';";
    $r = $sql_object->DBSelect ($q);

    return $r;
  }
  
  /**
  * user::changeWorkshopsNotification()
  * Change workshops notification for a given user
  *
  * @access public
  * @param object $sql_object
  * @return integer $last_id
  */
  function changeWorkshopsNotification($user_id, $exceptions, $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.change_workshops_notification', array('id' => $id, 'data' => $exceptions)));
  
  	$q = "DELETE FROM " . T_WORK_NOTIFY . " WHERE user_id=" . $user_id. ";";
  	$r = $sql_object->DBQuery ($q);
  	
  	foreach($exceptions as $el) {
  	  list($type, $workgroup)= explode('-', $el);
  	  $q = "INSERT INTO " . T_WORK_NOTIFY . " (user_id, workshop_id, type) VALUES(".$user_id.", ".$workgroup.", '".$type."');";
  	  $r = $sql_object->DBInsert ($q);
  	}
  
  	return $r;
  }

  /**
   * user::DeleteWorkshops()
   * Remove all workshops for a given user
   *
   * @access public
   * @param object $sql_object
   * @return integer $last_id
   */
  function DeleteWorkshops($user_id, $user_right, $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.delete_workshops', array('id' => $user_id, 'user_rights' => $user_right)));
  	
    if (is_numeric($user_id)) {
      $this->ID = $user_id;
    } else return false;

    $q = "DELETE FROM " . J_WORK_USERS . " WHERE jwu_user_id=" . $this->ID . " AND jwu_user_right='".$user_right."';";
    $r = $sql_object->DBQuery ($q);

    return $r;
  }

  /**
   * user::AddWorkshops()
   * Ajout d'un utilisateur à un ou plusieurs workshops
   *
   * @access public
   * @param int $user_id identifiant du workshop
   * @param array $workgroups workgroups ID
   * @param string $user_right droit confié a l'utilisateur sur le workshop
   * @param object $sql_object
   * @return integer $last_id
   */
  function AddWorkshops($user_id, $workgroups, $user_right , $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.add_workshops', array('id' => $user_id, 'workgroups' => $workgroups, 'user_rights' => $user_right)));
  	
    if (is_numeric($user_id)) {
      $this->ID = $user_id;
    } else return false;

    if(count($workgroups)==0) return true;

    for ($i = 0;$i < count($workgroups);$i++) {

      // check if user already belong to the group
      $q = "SELECT COUNT(jwu_id) AS nb FROM " . J_WORK_USERS . " WHERE jwu_user_id=" . $this->ID . " AND jwu_workshop_id=" . $workgroups[$i] . ";";
      $data = $sql_object->DBSelect($q, 'OBJECT');

      // in case it is a pending user already in database
      if ($data[0]->nb == 1) {
      	$q = "UPDATE " . J_WORK_USERS . " SET jwu_user_right='" . $user_right . "' WHERE jwu_workshop_id=" . $workgroups[$i] . " AND jwu_user_id =" . $this->ID . ";";
      	$last_id = $sql_object->DBQuery ($q);
      }
      if ($data[0]->nb != 1) {
        $q = "INSERT INTO " . J_WORK_USERS . " (jwu_workshop_id, jwu_user_id, jwu_user_right) VALUES(" . $workgroups[$i] . ", " . $this->ID . ",'" . $user_right . "');";
        $last_id = $sql_object->DBInsert ($q, 1);
      }
      
    }

    return true;
  }
  
  /**
   * user::changeLogin()
   * Modifie le login d'un utilisateur
   *
   * @access public
   * @param string $id
   * @param string $login
   * @param string $old_login
   * @param object $sql_object
   * @return string $password
   */
  function changeLogin($id, $login, $old_login, $sql_object)
  {
  	 $sep = ',';
  	 
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.change_login', array('id' => $id, 'login' => $login)));
  	 
  	$q = "UPDATE " . T_USER . " SET user_login = '".$login."', user_old_logins = CONCAT(user_old_logins,'". $sep . $old_login ."') WHERE user_id='" . $id . "';";
  
  	$data = $sql_object->DBQuery($q);

  	return true;
  
  }
  
  /**
   * user::deleteAvatar()
   * creation aleatoire d'un passkey
   *
   * @access public
   * @param string $user_id
   * @param object $sql_object
   * @return string $password
   */
  function deleteAvatar($id, $sql_object)
  {
  	
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.delete_avatar', array('id' => $id)));
  	
  	$q = "SELECT profile_avatar FROM " . T_PROFILE . " WHERE profile_id='" . $id . "';";

  	$data = $sql_object->DBSelect($q);
  	if(count($data) != 1 && $data[0]!=0) {
  		return false;
  	} else {
  		@unlink('../'.$r[0]['profile_avatar']);
  		$q = "UPDATE " . T_PROFILE . " SET profile_avatar='' WHERE profile_id='" . $id . "';";
  		$r = $sql_object->DBQuery($q);

  		return $r;
  	}

  }

  /**
   * user::ModifyWorkshops()
   * Update workgroups for a given user
   *
   * @access public
   * @param int $user_id identifiant du workshop
   * @param array $workgroups workgroups to add
   * @param string $user_right droit confié a l'utilisateur sur le workshop
   * @param object $sql_object
   * @return integer $r
   */
  function ModifyWorkshops($user_id, $workgroups, $user_right , $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.modify_workshops', array('id' => $user_id, 'workgroups' => $workgroups, 'user_rights' => $user_right)));
  	 
    if (is_numeric($user_id)) {
      $this->ID = $user_id;
    } else return false;

    if($this->DeleteWorkshops($this->ID, $user_right, $sql_object)) {
      $r = $this->AddWorkshops($this->ID, $workgroups, $user_right, $sql_object);
    }

    return $r;
  }

  /**
   * user::generateNewPasskey()
   * creation aleatoire d'un passkey
   *
   * @access public
   * @param string $user_id
   * @param object $sql_object
   * @return string $password
   */
  function generateNewPasskey($user_id, $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.generate_passkey', array('id' => $user_id)));
  	
    $this->PASSKEY = $this->GetNewPassword(30);
    $q = "UPDATE " . $this->TDB_USER . " SET user_forget_passkey='" . $this->PASSKEY . "' WHERE user_id='" . $user_id . "';";

    $r = $sql_object->DBQuery ($q);
    if($r) return $this->PASSKEY;
    else return false;
  }

  /**
   * user::resetPasskey()
   * creation aleatoire d'un passkey
   *
   * @access public
   * @param string $user_id
   * @param object $sql_object
   * @return string $password
   */
  function resetPasskey($user_id, $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.reset_passkey', array('id' => $user_id)));
  	
    $q = "UPDATE " . $this->TDB_USER . " SET user_forget_passkey='' WHERE user_id='" . $user_id . "';";

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

  /**
   * user::GetNewPassword()
   * creation aleatoire d'un password
   *
   * @access public
   * @param int $length taille du password
   * @return string $password
   */
  function GetNewPassword($length = PASSWD_MINLENGTH)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.get_new_password', array('length' => $length)));
  	
    $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $password = '';
    for ($i = 0; $i < $length; $i++) {
      $password .= substr($str, rand(0, strlen($str) - 1), 1);
    }
    return $password;
  }

  /**
   * user::InitUserRight()
   * formatage du tableau de droit suivant profil prédeterminé
   *
   * @access public
   * @param string $type niveau utilisateur : SIMPLE_USER ou ADMIN_USER
   * @return array $table_right : tableau des droits de l'utilisateur
   */
  function InitUserRight($type = 'SIMPLE_USER')
  {

    $table_user = array ("dashboard" => 'U', "workshop" => 'U', "publication" => 'U', "project" => 'U',
            "news" => 'U', "yellowpages" => 'U', "theme" => 'U',
            "scale" => 'U', "level" => 'U', "category_user" => 'U');

    switch ($type) {
      case 'SIMPLE_USER':
        $table_right = $table_user;
        break;
      case 'ADMIN_USER':
        $table_right = array ("dashboard" => 'A', "workshop" => 'A', "publication" => 'A',
                    "project" => 'A', "news" => 'A', "yellowpages" => 'A',
                    "theme" => 'A', "scale" => 'A', "level" => 'A',
                    "category_user" => 'A');
        break;
      default:
        $table_right = $table_user;
        break;
    }
    
    // Filter data event + return value
    $r = $this->dispatcher->filter(new sfEvent($this, 'user.init_user_right', array('data' => $table_right)), $table_right);
    $table_right = $r->getReturnValue();

    return $table_right;
  }


  /**
   * user::UpdateUserPassword()
   * changement de password (mise à jour) dans la bdd
   *
   * @access public
   * @param int $ID identifiant utilisateur
   * @param string $pass nouveau password non crypté
   * @param object $sql_object
   * @return bool $result
   */
  function UpdateUserPassword($ID, $pass, $sql_object)
  {
  	// Notify the end of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.update_password', array('id' => $ID, 'password' => $pass)));
  	
    if (is_numeric($ID)) {
      $this->ID = $ID;
    } else exit($ID);
    $this->PASSWORD = crypt($pass, SALT_CRYPT);
    $q = "UPDATE " . $this->TDB_USER . " SET user_password='" . $this->PASSWORD . "' WHERE user_id='" . $this->ID . "';";
    $result = $sql_object->DBQuery ($q);

    return $result;
  }

  /**
   * user::AddUser()
   * Ajout d'un utilisateur
   *
   * @access public
   * @param array $table_user contient les composants de l'utilisateur
   * @param array $table_right contient les droits attribués au nouvel utilisateur
   * @param object $sql_object
   * @return integer $last_id
   * renvoie un message d'erreur ou un numerique id de l'insertion
   */
  function AddUser($table_user, $table_right, $sql_object, $donotcrypt = false)
  {
  	// Filter data event + return value
  	$r = $this->dispatcher->filter(new sfEvent($this, 'user.before_add', array('data' => $table_user, 'user_rights' => $table_right)), $table_user);
  	$table_user = $r->getReturnValue();
  	
    $table_user=$sql_object->DBescape($table_user);

    $this->LOGIN = strip_input(trim($table_user[0]));
    $this->P_EMAIL = strtolower($table_user[1]);
    $this->P_EMAIL_DISPLAY = $table_user[2];
    $this->P_FIRSTNAME = strip_input(trim($table_user[3]));
    $this->P_LASTNAME = strip_input(trim($table_user[4]));
    if($donotcrypt) {
    	$this->PASSWORD = $table_user[5];
    } else {
    	$this->PASSWORD = crypt($table_user[5], SALT_CRYPT);
    }
    $this->_SetUserCategory($table_right);
    
    $q = "INSERT INTO " . $this->TDB_USER . " (user_login, user_password, user_community, user_category, user_date_crea) VALUES ('" . $this->LOGIN . "', '" . $this->PASSWORD . "', " . $this->COMMUNITY . ", " . $this->CATEGORY . ", NOW());";

    $this->ID = $sql_object->DBInsert ($q, 1);
    
    $this->_AddProfile($this->ID, $sql_object);
    $this->_AddRight($this->ID, $table_right, $sql_object);

    $q = "UPDATE " . $this->TDB_USER . " SET user_rights=".$this->ID.", user_profile=".$this->ID." WHERE user_id=".$this->ID.";";

    $res = $sql_object->DBQuery($q);
    
    if($res && (defined('NEWSLETTER_AUTO_SUB') && NEWSLETTER_AUTO_SUB == 1)) {
      include_once('../class/class.newsletter.php');
      $newsletter = new newsletter;
      $newsletter->AddEmail($this->P_EMAIL, $sql_object);
    }

    // Notify the end of the current method
    $this->dispatcher->notify(new sfEvent($this, 'user.after_add', array('data' => $table_user, 'user_rights' => $table_right, 'id' => $this->ID)));
    
    return $this->ID;
  }

  /**
   * user::DeleteUser()
   * suppression d'un utilisateur
   *
   * @access public
   * @param int $ID identifiant de l'utilisateur
   * @param object $sql_object
   * @return bool $result
   */
  function DeleteUser($ID, $sql_object)
  {
  	// Notify the beginning of the current method
  	$this->dispatcher->notify(new sfEvent($this, 'user.delete', array('id' => $ID)));
  	
    if (is_numeric($ID)) {
      $this->ID = $ID;
    } else return false;
    $q = "UPDATE " . $this->TDB_USER . " SET user_validity='N' WHERE user_id=" . $this->ID . ";";
    $result = $sql_object->DBQuery ($q);
    $q = "DELETE FROM " . J_WORK_USERS . " WHERE jwu_user_id=" . $this->ID . ";";
    $res = $sql_object->DBQuery ($q);

    return $res;
  }

  /**
   * user::ModifyProfile()
   * modification d'un profil utilisateur
   *
   * @access public
   * @param int $id identifiant d'un profil
   * @param object $sql_object
   * @param array $table_profile contient les composants d'un profil
   * @return bool $result
   */
  function ModifyProfile($ID, $table_profile, $sql_object)
  {
  	// Filter data event + return value
  	$r = $this->dispatcher->filter(new sfEvent($this, 'user.before_modify_profile', array('data' => $table_profile, 'id' => $ID)), $table_profile);
  	$table_profile = $r->getReturnValue();
  	
    $table_profile=$sql_object->DBescape($table_profile);

    if (is_numeric($ID)) {
      $this->ID = $ID;
    } else return false;

    $this->P_EMAIL = strtolower($table_profile[0]);

    $q = "UPDATE " . $this->TDB_USER . " SET user_last_modify=NOW() WHERE user_id='" . $this->ID . "';";
    $result = $sql_object->DBQuery($q);

    $q = "SELECT user_profile FROM " . $this->TDB_USER . " WHERE user_id='" . $this->ID . "' LIMIT 1;";
    $data = $sql_object->DBSelect ($q, 'OBJECT');
    if ($data!=0 && count($data) == 1) {
      $this->P_ID = $data[0]->user_profile;
    } else return false;
    $this->P_EMAIL_DISPLAY = strtoupper($table_profile[1]);
    $this->P_CITY = strip_input(ucfirst(trim($table_profile[2])));
    $this->P_BIRTHDATE = ($table_profile[3]=='--') ? '0001-01-01' : formatDate($table_profile[3], true);
    $this->P_LEISURES = strip_input(trim($table_profile[4]));
    $this->P_JOB = strip_input(trim($table_profile[5]));
    $this->P_QUOTATION = strip_input(trim($table_profile[6]));
    $this->P_SIGNATURE = strip_input(trim($table_profile[7]));
    $this->P_FIRSTNAME = strip_input(trim($table_profile[8]));
    $this->P_LASTNAME = strip_input(trim($table_profile[9]));
    $this->P_AVATAR = strip_input($table_profile[10]);

    $q = "UPDATE " . T_PROFILE . " SET profile_firstname='" . $this->P_FIRSTNAME . "', profile_lastname='" . $this->P_LASTNAME . "', profile_email='" . $this->P_EMAIL . "', profile_email_display='" . $this->P_EMAIL_DISPLAY . "', profile_city='" . $this->P_CITY . "', profile_birthdate='" . $this->P_BIRTHDATE . "', profile_leisures='" . $this->P_LEISURES . "', profile_job='" . $this->P_JOB . "', profile_quotation='" . $this->P_QUOTATION . "', profile_signature='" . $this->P_SIGNATURE . "', profile_avatar='" . $this->P_AVATAR . "' WHERE profile_id='" . $this->P_ID . "';";

    $result = $sql_object->DBQuery ($q);
    
    // Notify the end of the current method
    $this->dispatcher->notify(new sfEvent($this, 'user.after_modify_profile', array('data' => $table_profile, 'id' => $ID)));
    

    return $result;
  }

  /**
   * user::ModifyRight()
   * modification des droits d'un utilisateur
   *
   * @access public
   * @param int $ID identifiant de l'utilisateur
   * @param object $sql_object
   * @param array $table_right contient un tableau associatif de droit
   * @return bool $result
   */
  function ModifyRight($ID, $table_right, $sql_object)
  {
  	// Filter data event + return value
  	$r = $this->dispatcher->filter(new sfEvent($this, 'user.before_modify_right', array('data' => $table_right, 'id' => $ID)), $table_right);
  	$table_right = $r->getReturnValue();
  	
    if (is_numeric($ID)) {
      $this->ID = $ID;
    } else return false;

    $update = '';
    $sep = ', ';
    if (isset($table_right['dashboard'])) {
      $this->R_DASHBOARD = $table_right['dashboard'];
      $update .= "rights_dashboard='" . $this->R_DASHBOARD . "'";
    }
    if (isset($table_right['project'])) {
      $this->R_PROJECT = $table_right['project'];
      $update .= $sep . "rights_project='" . $this->R_PROJECT . "'";
    }
    if (isset($table_right['publication'])) {
      $this->R_PUBLICATION = $table_right['publication'];
      $update .= $sep . "rights_publication='" . $this->R_PUBLICATION . "'";
    }
    if (isset($table_right['workshop'])) {
      $this->R_WORKSHOP = $table_right['workshop'];
      $update .= $sep . "rights_workshop='" . $this->R_WORKSHOP . "'";
    }
    if (isset($table_right['news'])) {
      $this->R_NEWS = $table_right['news'];
      $update .= $sep . "rights_news='" . $this->R_NEWS . "'";
    }
    if (isset($table_right['yellowpages'])) {
      $this->R_YELLOWPAGES = $table_right['yellowpages'];
      $update .= $sep . "rights_yellowpages='" . $this->R_YELLOWPAGES . "'";
    }
    if (isset($table_right['theme'])) {
      $this->R_THEME = $table_right['theme'];
      $update .= $sep . "rights_theme='" . $this->R_THEME . "'";
    }
    if (isset($table_right['scale'])) {
      $this->R_SCALE = $table_right['scale'];
      $update .= $sep . "rights_scale='" . $this->R_SCALE . "'";
    }
    if (isset($table_right['level'])) {
      $this->R_LEVEL = $table_right['level'];
      $update .= $sep . "rights_level='" . $this->R_LEVEL . "'";
    }
    if (isset($table_right['category_user'])) {
      $this->R_CATEGORY_USER = $table_right['category_user'];
      $update .= $sep . "rights_category_user='" . $this->R_CATEGORY_USER . "'";
    }

    $q = "UPDATE " . $this->TDB_USER . " SET user_last_modify=NOW() WHERE user_id='" . $this->ID . "';";
    $result = $sql_object->DBSelect ($q);
    $q = "SELECT user_rights FROM " . $this->TDB_USER . " WHERE user_id='" . $this->ID . "';";
    $result = $sql_object->DBSelect ($q);

    if ($result == 0) return false;
    if (count($result) == 1) {
      $this->R_ID = $result[0]['user_rights'];
    } else return false;
    $q = "UPDATE " . T_RIGHT . " SET " . $update . " WHERE rights_id='" . $this->R_ID . "';";
    $result = $sql_object->DBQuery ($q);

    if ($result) {
      $this->_SetUserCategory($table_right);
      $q = "UPDATE " . $this->TDB_USER . " SET user_category='" . $this->CATEGORY . "' WHERE user_id='" . $this->ID . "';";

      $result = $sql_object->DBQuery ($q);
    }
    
    // Notify the end of the current method
    $this->dispatcher->notify(new sfEvent($this, 'user.after_modify_right', array('data' => $table_right, 'id' => $ID)));
    return $result;
  }


}

?>