<?php

/**------------------------------------------------
*
* Rooty, 2018 <rooty@rooty.me>
*
*
* This software is protected by copyright, please
* read the file COPYRIGHT.
* This program is distributed in the hope that it
* will be useful, but without any warranty; without
* even the implied warranty of merchantability or
* fitness for a particular purpose. Please
* read the file LICENCE.
*
* Fichier UserSession.php
*
* Ce fichier contient la classe UserSession (Session Utilisateur)
*
* @author Initiance <www.initiance.com|olivier@initiance.com & Christophe HEURTAUX>
* @link www.rooty.me
* @since 2004/06/01
* @version 0.3
* @package system_data
* @subpackage UserSession
* @copyright Copyright &copy; 2009-2018, Rooty
*/

#####################################################################################################
################################# Parametrage
#####################################################################################################

/**
* déclaration du system... si cette variable n'est pas définie, les fichier inclus ne fonctionnent pas...
* cette variable est déclarée sur la page d'exécution du script.
* <p> if ( !defined('SYSTEM_IN') )
* {
* die("Hacking attempt");
* }</p>
*/
if ( !defined('SYSTEM_IN') )
{
 die("Hacking attempt");
}

/**
* Classe de gestion des sources de données des sessions
*/

/**
* Classe UserSession
*
* classe de gestion des sessions Utilisateurs
*
* @package system_data
* @subpackage UserSession
*/


class UserSession
{
/**
* @access private
*/

/**
* @var chaine
* @desc ID de session
*/
var $id	= null;

/**
* @var User
* @desc Objet user courant
*/
var $user;

/**
* @var userPreference
* @desc Objet user preference (préférences system de l'utilisateur)
*/
var $userPreference;

/**
* @var langue
* @desc Objet langue courant
*/
var $langue;

/**
* @var entier
* @desc identifiant de l'Arboresence courante
*/

var $entryNodeId;
/**
* @var entier
* @desc identifiant de l'Arboresence courante
*/
var $navigationNodeId;

/**
* @var entier
* @desc ip de la session
*/
var $ip;

/**
* @var entier
* @desc timestamp du début de la session
*/
var $begin;

/**
* @var entier
* @desc timestamp de la dernière page consultée
*/
var $lastAction;

/**
* @var booleen
* @desc nouvelle session
*/
var $isNew;

/**
* @var entier
* @desc url de la dernière page consultée
*/
var $url;

/**
* @var mixed
* @desc variables de sessions
*/
var $session_vars;

/**
* @var listUserGroup
* @desc objet objet contenant les associations utilisateur/groupe
*/
var $listUserGroup;

/**
* @var listUserNode
* @desc objet objet contenant les associations noeud/utilisateur (en fonction de ses groupes)
*/
var $listUserNode;

/**
* @var Permission
* @desc Objet de Permissions
*/
var $permission;

	//
	// Constructor
	//
/**
* Constructeur de la classe UserSession PHP5
*
*/
	function __construct()
	{
		global $SYSTEM_IP, $_SERVER, $CONF_COOKIE_ENABLE, $CONF_COOKIE_PATH, $CONF_COOKIE_DOMAIN, $CONF_COOKIE_SECURE;
		$init=true;

		/* Récupération de l'id en fonction du cookie et/ou du $GET */
		$ID=(isset($_GET['id']))?$_GET['id']:(((isset($_COOKIE['SessionId'])) && ($CONF_COOKIE_ENABLE==true))?$_COOKIE['SessionId']:NULL);

		// gestion d'un id unique en fonction de l'ip
		if (!is_null($ID))
		{
			/* Vérification des éléments */
			$i=48;
			$arrayTest=array();
			while ($i<122)
			{
				$arrayTest[]=chr($i);
				if ($i==57)$i=64;
				if ($i==90)$i=96;
				$i++;
			}
			for ($i=0; $i<strlen($ID); $i++)
			{
				if (!in_array($ID[$i],$arrayTest)!=0)
				{
					$init=false;
					break;
				}
			}
		}

		if ( ($init==true) && (strlen($ID)>24) ){
			$this->id=$ID;
		}else{
			$this->id=md5(uniqid($SYSTEM_IP));
			$this->session_vars['HTTP_USER_AGENT']=md5($_SERVER['HTTP_USER_AGENT']);
		}

		/* Gestion du cookie comme référence */
		if ($CONF_COOKIE_ENABLE)
		{
			if (!headers_sent()){
// 				setcookie ( string $name [, string $value = "" [, int $expires = 0 [, string $path = "" [, string $domain = "" [, bool $secure = FALSE [, bool $httponly = FALSE ]]]]]] ) : bool
				setcookie('SessionId', $this->id, time()+3600, $CONF_COOKIE_PATH, $CONF_COOKIE_DOMAIN, $CONF_COOKIE_SECURE);
			}else{
				addError(4, "User Session", "Impossible de créer le cookie correspondant...", __line__, __file__);
			}
		}

		$this->ip				= $SYSTEM_IP;
		$this->begin			= time();
		$this->lastAction		= time();
		$this->url				= urlencode($_SERVER["SCRIPT_NAME"].(isset($_SERVER["QUERY_STRING"])?"?".$_SERVER["QUERY_STRING"]:""));
		$this->session_vars		= "";
		$this->user 			= new User();
		$this->langue 			= new Language();
		$this->entryNodeId		= $GLOBALS["SYSTEM_DEFAULT_NODE"];
		$this->navigationNodeId	= $GLOBALS["SYSTEM_DEFAULT_NODE"];
		$this->listUserGroup	= new ListUserGroup();
		$this->listUserNode		= new ListUserNode();
		$this->permission		= new Permission();
		$this->isNew			= true;
	}

/**
* getDefaultNode : charge le noeud par défaut
*
* <p>Renvoi le Noeud par Défaut de l'utilisateur</p>
* @return booleen
*/
	function getDefaultNode()
	{
		if ($this->userPreference->isLoaded()==true)
		{
			return $this->userPreference->getEntryNodeId();
		}else{
			$tmp=$this->listUserNode->getConfiguredNodeId();
			/* on prend le premier noeud */
// 			var_dump("tmp count: ".count($tmp));
			if (count($tmp)==0)
			{
				/* retour à une session par defaut */
				$this->defaultSession();
				/* pas de noeuds configurés pour l'utilisateur?! */
				$systemError=1;
				addError($systemError, "User Session", "Utilisateur corrompu, pas de noeud configures", __line__, __file__);
				return $GLOBALS["SYSTEM_DEFAULT_NODE"];
			}else{
				return $tmp[0];
			}
		}
	}

/**
* defaultSession : Charge la session utilisateur
*
* <p>Affectation d'un utilisateur directement </p>
* @return booleen
*/
	function defaultSession()
	{
		$retour=$this->doLoadFromUserId($GLOBALS["SYSTEM_DEFAULT_USER_GUEST"]);
	}

/**
* doLoad : Charge la session utilisateur
*
* <p>Affectation d'un utilisateur directement </p>
* @return booleen
*/
	function doLoad($user, $userPreference, $langue, $ip, $entryNodeId, $navigationNodeId, $begin, $lastAction, $url, $session_vars="")
	{
		/* test si il s'agit bien du mm utilisateur ou non */
		$session_vars['HTTP_USER_AGENT']=(isset($session_vars['HTTP_USER_AGENT']))?$session_vars['HTTP_USER_AGENT']:(( isset($this->session_vars['HTTP_USER_AGENT']) )?$this->session_vars['HTTP_USER_AGENT']:null);

		if( ( isset($session_vars['HTTP_USER_AGENT'])) && ($session_vars['HTTP_USER_AGENT']==md5($_SERVER['HTTP_USER_AGENT'])) ){
			$this->user				=$user;
			$this->userPreference			=$userPreference;
			$this->langue				=$langue;
			$this->ip				=$ip;
			$this->entryNodeId			=$entryNodeId;
			$this->navigationNodeId			=$navigationNodeId;
			$this->begin				=$begin;
			//$this->lastAction			=$lastAction;
			$this->session_vars	= $session_vars;
			$this->session_vars['HTTP_USER_AGENT']=md5($_SERVER['HTTP_USER_AGENT']);
			$_SESSION = &$this->session_vars;
			/* dependance de l'utilisateur */
			$this->listUserGroup			=$GLOBALS["SYSTEM_MANAGER"]["LIST_USER_GROUP"]->createInstance($this->user->getId());
			$groupAvailable				=$this->listUserGroup->getFatherArray();

			/* chargement des noeuds */
			$this->listUserNode			=$GLOBALS["SYSTEM_MANAGER"]["LIST_USER_NODE"]->createInstance($this->user->getId(), $groupAvailable);
			$nodeAvailable				=array_merge($this->listUserNode->getSonArray(), $this->listUserNode->getConfiguredNodeId());

			$this->permission			=$GLOBALS["SYSTEM_MANAGER"]["PERMISSION"]->createInstance($this->user->getId(), $groupAvailable, $nodeAvailable);
		}else{
			/* On force ici l'authentification à l'utilisateur par defaut */
			$this->defaultSession();
		}
	}

/**
* sessionFromUserId : Charge la session utilisateur
*
* <p>Affectation d'un utilisateur directement </p>
* @todo possible optimisation sur le chargement de l'utilisateur notement pour la granisphere...
* @return booleen
*/
	function doLoadFromUserId($userId)
	{
		//$this->id			=isset($_GET['id'])?$_GET['id']:md5(uniqid($SYSTEM_IP)); # Soit le id si existant, Soit l'ip encrypt?e
		$this->user 			=$GLOBALS["SYSTEM_MANAGER"]["USER"]->createInstance($userId);
		$this->userPreference		=$GLOBALS["SYSTEM_MANAGER"]["USER_PREFERENCE"]->createInstance($userId);
		$this->langue 			=$GLOBALS["SYSTEM_MANAGER"]["LANGUAGE"]->createInstance($this->userPreference->getLangueId());
		/* dependance de l'utilisateur */
		$this->listUserGroup		=$GLOBALS["SYSTEM_MANAGER"]["LIST_USER_GROUP"]->createInstance($this->user->getId());
		$groupAvailable			=$this->listUserGroup->getFatherArray();
		/* chargement des noeuds */
		$this->listUserNode		=$GLOBALS["SYSTEM_MANAGER"]["LIST_USER_NODE"]->createInstance($this->user->getId(), $groupAvailable);
		$nodeAvailable			=array_merge($this->listUserNode->getSonArray(), $this->listUserNode->getConfiguredNodeId());
		$this->permission		=$GLOBALS["SYSTEM_MANAGER"]["PERMISSION"]->createInstance($this->user->getId(), $groupAvailable, $nodeAvailable);
		$this->session_vars = array();
		$this->session_vars['HTTP_USER_AGENT']=md5($_SERVER['HTTP_USER_AGENT']);

		$_SESSION = &$this->session_vars;
		/* parametrage par defaut */
		$defaultNode			=$this->getDefaultNode();
// 		$defaultNode			=104;
		$this->entryNodeId		=$defaultNode;
		$this->navigationNodeId		=$defaultNode;
	}

/**
* addIdToURL : Ajouter l'identifiant de session à une URL
*
* <p>Fonction a utiliser pour ajouter l'identifiant de session à une URL</p>
* <p>Celle-ci doit être incluse obligatoirement dans chaque lien et formulaire. <br>
* Elle permet de garder l'identité de l'internaute au cas où...
* retourne l'URL</p>
* @param chaine url à modifier
* @return chaine
*/
	function addIdToUrl($url, $non_html_amp = false)
	{
		if ( !empty($this->id) && !preg_match('#id=#', $url) )
		{
			$url .= ( ( strpos($url, '?') != false ) ?  ( ( $non_html_amp ) ? '&id=' : '&amp;id=' ) : '?id=' ) . $this->id;
		}
		return $url;
	}

/**
* defaultRight
*
* @return object objet droit par defaut/null pour aucun
*/
	function defaultRight()
	{
		$i=0;
		$tabNode=$this->getAllParentNodeForNavigation($this->navigationNodeId);
		$tab=$this->permission->getAllRightForNode($tabNode);
		$retour="";

		foreach($tab as $Right){
			if ( $this->navigationNodeId==$Right->getNodeId() )
			{
				if ($this->isRightOn($Right->getObjectId(), $Right->getClassName(), $Right->getMethodName()))
				{
					return $Right;
				}
			}
		}
		return $retour;
	}

/**
* getCurrentTemplate : récupère la template courante
* @return object objet droit par defaut/null pour aucun
*/
	function getCurrentTemplate()
	{
		return $this->listUserNode->getTemplateFromNode($this->entryNodeId, $this->navigationNodeId);
	}

/**
* getAllObjectId : droit par défaut dans une arborescence...
* @return object objet droit par défaut
*/
	function getAllObjectId()
	{
		return $this->permission->getAllObjectIdForNode($this->listUserNode->getNodeIdOnTreeId($this->entryNodeId, $this->navigationNodeId));
	}

/**
* getAllObjectId : droit par défaut dans une arborescence...
* @access public
* @return object objet droit par défaut
*/
	function getObjectIdByLabel($array)
	{
		return $this->permission->getObjectIdByLabel($array, $this->listUserNode->getNodeIdOnTreeId($this->entryNodeId, $this->navigationNodeId));
	}

/**
* isRightOn : droit par défaut dans une arborescence...
* @return booleen
*/
	function isRightOn($oid, $className, $methodName, $nodeId="")
	{
		if ($nodeId=="")
			$nodeId=$this->navigationNodeId;

		$retour=$this->permission->isRightOn($this->entryNodeId, $oid, $className, $methodName, $this->user->getId(), $this->listUserGroup->getFatherGroupId(), $this->getAllParentNodeForNavigation($nodeId));
		return $retour;
	}

/**
* getAllNodeForTreeId : récupère tous les nodes valides pour l'entrée de l'utilisateur
* @return array identifiant de noeud
*/
	function getAllNodeForTreeId($id)
	{
		return $this->listUserNode->getAllAllowedNode($id);
	}

/**
* getValidEntryNode : récupère tous les nodes valides pour l'entrée de l'utilisateur
* @return array identifiant de noeud
*/
	function getValidEntryNode()
	{
		return $this->listUserNode->getConfiguredNodeId();
	}

/**
* getValidNavigationNode : récupère tous les nodes valides pour l'entrée de l'utilisateur
* @return array identifiant de noeud
*/
	function getValidNavigationNode()
	{
		$tab=array_merge(array($this->entryNodeId),$this->listUserNode->getSonNodeIdOnTreeId($this->entryNodeId));
		return $tab;
	}

/**
* getSonOfNodeForEntryNode : récupère les fils d'un noeud depuis le noeud principal
* @return array identifiant de noeud
*/
	function getSonOfNodeForEntryNode($nodeId)
	{
		$tab=$this->listUserNode->getSon($this->entryNodeId, $nodeId);
		return $tab;
	}

/**
* getSonOfNodeIdForEntryNode : recupere les fils d'un noeud depuis le noeud principal
*/
	function getSonOfNodeIdForEntryNode($nodeId)
	{
		$tab=$this->listUserNode->getSonArray($this->entryNodeId, $nodeId);
		return $tab;
	}

/**
* recupere les fils d'un noeud depuis le noeud principal
*/
	function getNode($nodeId)
	{
		$tab=$this->listUserNode->getNode($this->entryNodeId, $nodeId);
		return $tab;
	}

/**
* retourne tous les péres pour l'identifiant de navigation actuel...
*/
	function getAllParentNodeForNavigation($nodeId)
	{
		$tab=$this->listUserNode->getAllIdForNavigationId($this->entryNodeId, $nodeId);
		return $tab;
	}

/**
* retourne tous les péres pour l'identifiant de navigation actuel...
*/
	function getSonOfNodeAllowed($nodeId)
	{
		return $this->listUserNode->getSonOfNodeAllowed($this->entryNodeId, $nodeId);
	}
}
?>
