<?php
/**
* @version	$Id: inp_session.php 14325 2011-05-20 08:10:28Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class InpSession extends Session
	{
		function Init($prefix, $special)
		{
			$this->SessionTimeout = $this->Application->ConfigValue('SessionTimeout');

			$path = (BASE_PATH == '') ? '/' : BASE_PATH;
			$this->SetCookiePath($path);

			$cookie_name = $this->Application->ConfigValue('SessionCookieName');
			if (!$cookie_name) {
				$cookie_name = 'sid';
			}

			$admin_session = ($this->Application->isAdmin && $special !== 'front') || ($special == 'admin');

			if ($admin_session) {
				$cookie_name = 'adm_' . $cookie_name;
			}

			$this->SetCookieName($cookie_name);

			$this->SetCookieDomain(SERVER_NAME);

			if ($admin_session) {
				$mode = smAUTO;
			}
			elseif (defined('IS_INSTALL') && IS_INSTALL) {
				$mode = smCOOKIES_ONLY;
			}
			else {
				$ses_mode = $this->Application->ConfigValue('CookieSessions');

				if ($ses_mode == 2) $mode = smAUTO;
				if ($ses_mode == 1) $mode = smCOOKIES_ONLY;
				if ($ses_mode == 0) $mode = smGET_ONLY;
			}

			$this->SetMode($mode);

			parent::Init($prefix, $special);

			if (!$this->Application->isAdmin && $this->GetField('PortalUserId') <= 0) {
				$group_list = $this->Application->ConfigValue('User_GuestGroup').','.$this->Application->ConfigValue('User_LoggedInGroup');
				$this->SetField('GroupId', $this->Application->ConfigValue('User_GuestGroup'));
				$this->SetField('GroupList', $group_list);
			}
		}

		function Destroy()
		{
			$this->Storage->DeleteSession($this);
			$this->Storage->DeleteEditTables();
			$this->Data = new Params();
			$this->SID = $this->CachedSID = '';

			if ($this->CookiesEnabled) {
				$this->SetSessionCookie(); //will remove the cookie due to value (sid) is empty
			}

			$this->SetSession(); //will create a new session
		}

	}

class InpSessionStorage extends SessionStorage {

	function Init($prefix,$special)
	{
		parent::Init($prefix,$special);
		$this->setTableName(TABLE_PREFIX.'UserSession');
		$this->SessionDataTable = TABLE_PREFIX.'SessionData';
		$this->setIDField('SessionKey');
		$this->TimestampField = 'LastAccessed';
		$this->DataValueField = 'VariableValue';
		$this->DataVarField = 'VariableName';
	}

	function LocateSession($sid)
	{
		$res = parent::LocateSession($sid);
		if ($res) {
			$this->Expiration +=  $this->SessionTimeout;
		}
		return $res;
	}

	function UpdateSession(&$session)
	{
		$time = adodb_mktime();
		// Update LastAccessed only if it's newer than 1/10 of session timeout - perfomance optimization to eliminate needless updates on every click
//		if ($time - $this->DirectVars['LastAccessed'] > $this->SessionTimeout/10) {
			$this->SetField($session, $this->TimestampField, $time + $this->SessionTimeout);
//		}
	}

	function GetSessionDefaults(&$session)
	{
		$fields_hash = Array (
			'PortalUserId'	=>	$this->Application->isAdmin ? 0 : USER_GUEST,
			'Language'		=>	$this->Application->GetDefaultLanguageId(true),
			'Theme'			=>	$this->Application->GetDefaultThemeId(),
			'GroupId'		=>	$this->Application->ConfigValue('User_GuestGroup'),
			'GroupList'		=>	$this->Application->ConfigValue('User_GuestGroup'),
		);

		if( isset($_SERVER['REMOTE_ADDR']) ) {
			$fields_hash['IpAddress'] = $_SERVER['REMOTE_ADDR']; // getenv('REMOTE_ADDR') won't work on IIS, so use $_SERVER instead
		}

		return array_merge($fields_hash, parent::GetSessionDefaults($session));
	}

	function GetExpiredSIDs()
	{
		$query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE  '.$this->TimestampField.' < '.(adodb_mktime());
		$ret = $this->Conn->GetCol($query);
		if($ret) {
			$this->DeleteEditTables();
		}
		return $ret;

	}

	function DeleteEditTables()
	{
		$tables = $this->Conn->GetCol('SHOW TABLES');
		$mask_edit_table = '/'.TABLE_PREFIX.'ses_(.*)_edit_(.*)/';
		$mask_search_table = '/'.TABLE_PREFIX.'ses_(.*?)_(.*)/';

		$sql='SELECT COUNT(*) FROM '.$this->TableName.' WHERE '.$this->IDField.' = \'%s\'';
		foreach($tables as $table)
		{
			if( preg_match($mask_edit_table,$table,$rets) || preg_match($mask_search_table,$table,$rets) )
			{
				$sid = preg_replace('/(.*)_(.*)/', '\\1', $rets[1]); // remove popup's wid from sid
				$is_alive = $this->Conn->GetOne( sprintf($sql,$sid) );
				if(!$is_alive) $this->Conn->Query('DROP TABLE IF EXISTS '.$table);
			}
		}
	}
}