Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1092600
session.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Aug 10, 6:23 PM
Size
30 KB
Mime Type
text/x-php
Expires
Tue, Aug 12, 6:23 PM (16 h, 24 m)
Engine
blob
Format
Raw Data
Handle
707600
Attached To
rINP In-Portal
session.php
View Options
<?php
/**
* @version $Id: session.php 16826 2025-04-10 05:55:23Z 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!'
);
/*
The session works the following way:
1. When a visitor loads a page from the site the script checks if cookies_on varibale has been passed to it as a cookie.
2. If it has been passed, the script tries to get Session ID (SID) from the request:
3. Depending on session mode the script is getting SID differently.
The following modes are available:
- Session::smAUTO
Automatic mode: if cookies are on at the client side, the script relays only on cookies and
ignore all other methods of passing SID. If cookies are off at the client side, the script relays on SID
passed through query string and referal passed by the client. THIS METHOD IS NOT 100% SECURE, as long as
attacker may get SID and substitude referal to gain access to user' session. One of the faults of this method
is that the session is only created when the visitor clicks the first link on the site, so there
is NO session at the first load of the page. (Actually there is a session, but it gets lost after
the first click because we do not use SID in query string while we are not sure if we need it)
- Session::smCOOKIES_ONLY
Cookies only: in this mode the script relays solely on cookies passed from the browser and ignores
all other methods. In this mode there is no way to use sessions for clients without cookies support
or cookies support disabled. The cookies are stored with the full domain name and path to base-directory
of script installation.
- Session::smGET_ONLY
GET only: the script will not set any cookies and will use only SID passed in query string using GET,
it will also check referal. The script will set SID at the first load of the page
- Session::smCOOKIES_AND_GET
Combined mode: the script will use both cookies and GET right from the start. If client has cookies enabled,
the script will check SID stored in cookie and passed in query string, and will use this SID only if both
cookie and query string matches. However if cookies are disabled on the client side, the script will work
the same way as in GET_ONLY mode.
4. After the script has the SID it tries to load it from the Storage (default is database)
5. If such SID is found in the database, the script checks its expiration time. If session is not expired,
it updates its expiration, and resend the cookie (if applicable to session mode)
6. Then the script loads all the data (session variables) pertaining to the SID.
Usage:
$session = new Session(Session::smAUTO); //Session::smAUTO is default, you could just leave the brackets empty, or provide another mode
$session->SetCookieDomain('my.domain.com');
$session->SetCookiePath('/myscript');
$session->SetCookieName('my_sid_cookie');
$session->SetGETName('sid');
$session->InitSession();
...
//link output:
echo "<a href='index.php?'". ( $session->NeedQueryString() ? 'sid='.$session->SID : '' ) .">My Link</a>";
*/
class
Session
extends
kBase
{
const
smAUTO
=
1
;
const
smCOOKIES_ONLY
=
2
;
const
smGET_ONLY
=
3
;
const
smCOOKIES_AND_GET
=
4
;
const
PURPOSE_TRANSPORT
=
1
;
const
PURPOSE_STORAGE
=
2
;
const
PURPOSE_REFERENCE
=
3
;
const
SID_LENGTH
=
32
;
var
$Checkers
;
var
$Mode
;
var
$OriginalMode
=
null
;
var
$GETName
=
'sid'
;
var
$CookiesEnabled
=
true
;
var
$CookieName
=
'sid'
;
var
$CookieDomain
;
var
$CookiePath
;
var
$CookieSecure
=
0
;
var
$SessionTimeout
=
3600
;
var
$Expiration
;
var
$SID
;
var
$CachedSID
;
var
$SessionSet
=
false
;
/**
* Session ID is used from GET
*
* @var bool
*/
var
$_fromGet
=
false
;
/**
* Enter description here...
*
* @var SessionStorage
* @access protected
*/
protected
$Storage
;
var
$CachedNeedQueryString
=
null
;
/**
* Session Data array
*
* @var Params
*/
var
$Data
;
/**
* Names of optional session keys with their optional values (which does not need to be always stored)
*
* @var Array
*/
var
$OptionalData
=
Array
();
/**
* Session expiration mark
*
* @var bool
*/
var
$expired
=
false
;
/**
* Creates session
*
* @param int $mode
* @access public
*/
public
function
__construct
(
$mode
=
self
::
smAUTO
)
{
parent
::
__construct
();
$this
->
SetMode
(
$mode
);
}
function
SetMode
(
$mode
)
{
$this
->
Mode
=
$mode
;
$this
->
CachedNeedQueryString
=
null
;
$this
->
CachedSID
=
null
;
}
function
SetCookiePath
(
$path
)
{
$this
->
CookiePath
=
str_replace
(
' '
,
'%20'
,
$path
);
}
/**
* Setting cookie domain. Set false for local domains, because they don't contain dots in their names.
*
* @param string $domain
*/
function
SetCookieDomain
(
$domain
)
{
// 1. localhost or other like it without "." in domain name
if
(!
substr_count
(
$domain
,
'.'
))
{
// don't use cookie domain at all
$this
->
CookieDomain
=
false
;
return
;
}
// 2. match using predefined cookie domains from configuration
$cookie_domains
=
$this
->
Application
->
ConfigValue
(
'SessionCookieDomains'
);
if
(
$cookie_domains
)
{
$cookie_domains
=
array_map
(
'trim'
,
explode
(
"
\n
"
,
$cookie_domains
));
foreach
(
$cookie_domains
as
$cookie_domain
)
{
if
(
ltrim
(
$cookie_domain
,
'.'
)
==
$domain
)
{
$this
->
CookieDomain
=
$cookie_domain
;
// as defined in configuration
return
;
}
}
}
// 3. only will execute, when none of domains were matched at previous step
$this
->
CookieDomain
=
$this
->
_autoGuessDomain
(
$domain
);
}
/**
* Auto-guess cookie domain based on $_SERVER['HTTP_HOST']
*
* @param $domain
* @return string
*/
function
_autoGuessDomain
(
$domain
)
{
static
$cache
=
Array
();
if
(!
array_key_exists
(
$domain
,
$cache
))
{
switch
(
substr_count
(
$domain
,
'.'
)
)
{
case
2
:
// 3rd level domain (3 parts)
$cache
[
$domain
]
=
substr
(
$domain
,
strpos
(
$domain
,
'.'
));
// with leading "."
break
;
case
1
:
// 2rd level domain (2 parts)
$cache
[
$domain
]
=
'.'
.
$domain
;
// with leading "."
break
;
default
:
// more then 3rd level
$cache
[
$domain
]
=
ltrim
(
$domain
,
'.'
);
// without leading "."
break
;
}
}
return
$cache
[
$domain
];
}
function
SetGETName
(
$get_name
)
{
$this
->
GETName
=
$get_name
;
}
function
SetCookieName
(
$cookie_name
)
{
$this
->
CookieName
=
$cookie_name
;
}
function
InitStorage
(
$special
)
{
$this
->
Storage
=
$this
->
Application
->
recallObject
(
'SessionStorage.'
.
$special
);
$this
->
Storage
->
setSession
(
$this
);
}
public
function
Init
(
$prefix
,
$special
)
{
parent
::
Init
(
$prefix
,
$special
);
if
(
php_sapi_name
()
==
'cli'
)
{
$this
->
SetMode
(
self
::
smGET_ONLY
);
}
$this
->
CheckIfCookiesAreOn
();
if
(
$this
->
CookiesEnabled
)
$_COOKIE
[
'cookies_on'
]
=
1
;
$this
->
Checkers
=
Array
();
$this
->
InitStorage
(
$special
);
$this
->
Data
=
new
Params
();
$tmp_sid
=
$this
->
GetPassedSIDValue
();
$check
=
$this
->
Check
();
if
(
$this
->
Application
->
isAdmin
)
{
// 1. Front-End session may not be created (SID is present, but no data in database).
// Check expiration LATER from kApplication::Init, because template, used in session
// expiration redirect should be retrieved from mod-rewrite url first.
// 2. Admin sessions are always created, so case when SID is present,
// but session in database isn't is 100% session expired. Check expiration
// HERE because Session::SetSession will create missing session in database
// and when Session::ValidateExpired will be called later from kApplication::Init
// it won't consider such session as expired !!!
$this
->
ValidateExpired
();
}
if
(
$check
)
{
$this
->
SID
=
$this
->
GetPassedSIDValue
();
$this
->
Refresh
();
$this
->
LoadData
();
}
else
{
$this
->
SetSession
();
}
if
(!
is_null
(
$this
->
OriginalMode
))
$this
->
SetMode
(
$this
->
OriginalMode
);
}
function
ValidateExpired
()
{
if
(
defined
(
'IS_INSTALL'
)
&&
IS_INSTALL
)
{
return
;
}
// $this->DeleteExpired(); // called from u:OnDeleteExpiredSessions scheduled task now
if
(
$this
->
expired
||
(
$this
->
CachedSID
&&
!
$this
->
_fromGet
&&
!
$this
->
SessionSet
))
{
$this
->
RemoveSessionCookie
();
// true was here to force new session creation, but I (kostja) used
// RemoveCookie a line above, to avoid redirect loop with expired sid
// not being removed setSession with true was used before, to set NEW
// session cookie
$this
->
SetSession
();
// case #1: I've OR other site visitor expired my session
// case #2: I have no session in database, but SID is present
$this
->
expired
=
false
;
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'u:OnSessionExpire'
));
}
}
/**
* Helper method for detecting cookie availability
*
* @return bool
*/
function
_checkCookieReferer
()
{
// removing /admin for compatability with in-portal (in-link/admin/add_link.php)
$path
=
preg_replace
(
'/admin[
\/
]{0,1}$/'
,
''
,
$this
->
CookiePath
);
$reg
=
'#^'
.
preg_quote
(
PROTOCOL
.
ltrim
(
$this
->
CookieDomain
,
'.'
).
$path
).
'#'
;
return
preg_match
(
$reg
,
getArrayValue
(
$_SERVER
,
'HTTP_REFERER'
)
);
}
function
CheckIfCookiesAreOn
()
{
if
(
$this
->
Mode
==
self
::
smGET_ONLY
)
{
//we don't need to bother checking if we would not use it
$this
->
CookiesEnabled
=
false
;
return
false
;
}
/** @var kHTTPQuery $http_query */
$http_query
=
$this
->
Application
->
recallObject
(
'HTTPQuery'
);
$cookies_on
=
array_key_exists
(
'cookies_on'
,
$http_query
->
Cookie
);
// not good here
$get_sid
=
getArrayValue
(
$http_query
->
Get
,
$this
->
GETName
);
if
(
(
$this
->
Application
->
HttpQuery
->
IsHTTPSRedirect
()
&&
$get_sid
)
||
$this
->
getFlashSID
()
)
{
// Redirect from http to https on different domain OR flash uploader
$this
->
OriginalMode
=
$this
->
Mode
;
$this
->
SetMode
(
self
::
smGET_ONLY
);
}
if
(
!
$cookies_on
||
$this
->
Application
->
HttpQuery
->
IsHTTPSRedirect
()
||
$this
->
getFlashSID
()
)
{
//If referer is our server, but we don't have our cookies_on, it's definetly off
$is_install
=
defined
(
'IS_INSTALL'
)
&&
IS_INSTALL
;
if
(
!
$is_install
&&
$this
->
_checkCookieReferer
()
&&
!
$this
->
Application
->
GetVar
(
'admin'
)
&&
!
$this
->
Application
->
HttpQuery
->
IsHTTPSRedirect
()
)
{
$this
->
CookiesEnabled
=
false
;
}
else
{
//Otherwise we still suppose cookies are on, because may be it's the first time user visits the site
//So we send cookies on to get it next time (when referal will tell us if they are realy off
$this
->
SetCookie
(
'cookies_on'
,
1
,
adodb_mktime
()
+
31104000
);
//one year should be enough
}
}
else
{
$this
->
CookiesEnabled
=
true
;
}
return
$this
->
CookiesEnabled
;
}
/**
* Sets cookie for current site using path and domain
*
* @param string $name
* @param mixed $value
* @param int $expires
*/
function
SetCookie
(
$name
,
$value
,
$expires
=
null
)
{
if
(
isset
(
$expires
)
&&
$expires
<
adodb_mktime
())
{
unset
(
$this
->
Application
->
HttpQuery
->
Cookie
[
$name
]);
}
else
{
$this
->
Application
->
HttpQuery
->
Cookie
[
$name
]
=
$value
;
}
$old_style_domains
=
Array
(
// domain like in pre 5.1.0 versions
'.'
.
SERVER_NAME
,
// auto-guessed domain (when user specified other domain in configuration variable)
$this
->
_autoGuessDomain
(
SERVER_NAME
)
);
foreach
(
$old_style_domains
as
$old_style_domain
)
{
if
(
$this
->
CookieDomain
!=
$old_style_domain
)
{
// new style cookie domain -> delete old style cookie to prevent infinite redirect
setcookie
(
$name
,
$value
,
adodb_mktime
()
-
3600
,
$this
->
CookiePath
,
$old_style_domain
,
$this
->
CookieSecure
,
true
);
}
}
setcookie
(
$name
,
$value
,
$expires
,
$this
->
CookiePath
,
$this
->
CookieDomain
,
$this
->
CookieSecure
,
true
);
}
function
Check
()
{
// don't check referer here, because it doesn't provide any security option and can be easily falsified
$sid
=
$this
->
GetPassedSIDValue
();
if
(
empty
(
$sid
))
{
return
false
;
}
//try to load session by sid, if everything is fine
$result
=
$this
->
LoadSession
(
$sid
);
$this
->
SessionSet
=
$result
;
// fake front-end session will given "false" here
return
$result
;
}
function
LoadSession
(
$sid
)
{
if
(
$this
->
Storage
->
LocateSession
(
$sid
)
)
{
// if we have session with such SID - get its expiration
$this
->
Expiration
=
$this
->
Storage
->
GetExpiration
();
// If session has expired
if
(
$this
->
Expiration
<
adodb_mktime
())
{
// when expired session is loaded, then SID is
// not assigned, but used in Destroy method
$this
->
SID
=
$sid
;
$this
->
Destroy
();
$this
->
expired
=
true
;
// when Destory methods calls SetSession inside and new session get created
return
$this
->
SessionSet
;
}
// Otherwise it's ok
return
true
;
}
else
{
// fake or deleted due to expiration SID
if
(!
$this
->
_fromGet
)
{
$this
->
expired
=
true
;
}
return
false
;
}
}
function
getFlashSID
()
{
/** @var kHTTPQuery $http_query */
$http_query
=
$this
->
Application
->
recallObject
(
'HTTPQuery'
);
return
getArrayValue
(
$http_query
->
Post
,
'flashsid'
);
}
function
GetPassedSIDValue
(
$use_cache
=
1
)
{
if
(!
empty
(
$this
->
CachedSID
)
&&
$use_cache
)
{
return
$this
->
CachedSID
;
}
// flash sid overrides regular sid
$get_sid
=
$this
->
getFlashSID
();
if
(!
$get_sid
)
{
/** @var kHTTPQuery $http_query */
$http_query
=
$this
->
Application
->
recallObject
(
'HTTPQuery'
);
$get_sid
=
getArrayValue
(
$http_query
->
Get
,
$this
->
GETName
);
}
$sid_from_get
=
$get_sid
?
true
:
false
;
if
(
$this
->
Application
->
GetVar
(
'admin'
)
==
1
&&
$get_sid
)
{
$sid
=
$get_sid
;
}
else
{
switch
(
$this
->
Mode
)
{
case
self
::
smAUTO
:
//Cookies has the priority - we ignore everything else
$sid
=
$this
->
CookiesEnabled
?
$this
->
GetSessionCookie
()
:
$get_sid
;
if
(
$this
->
CookiesEnabled
)
{
$sid_from_get
=
false
;
}
break
;
case
self
::
smCOOKIES_ONLY
:
$sid
=
$this
->
GetSessionCookie
();
break
;
case
self
::
smGET_ONLY
:
$sid
=
$get_sid
;
break
;
case
self
::
smCOOKIES_AND_GET
:
$cookie_sid
=
$this
->
GetSessionCookie
();
//both sids should match if cookies are enabled
if
(!
$this
->
CookiesEnabled
||
(
$cookie_sid
==
$get_sid
))
{
$sid
=
$get_sid
;
//we use get here just in case cookies are disabled
}
else
{
$sid
=
''
;
$sid_from_get
=
false
;
}
break
;
}
}
$this
->
CachedSID
=
$sid
;
$this
->
_fromGet
=
$sid_from_get
;
return
$this
->
CachedSID
;
}
/**
* Returns session id
*
* @param integer $purpose Purpose.
*
* @return integer
* @throws RuntimeException When unknown purpose is given.
*/
public
function
GetID
(
$purpose
=
self
::
PURPOSE_TRANSPORT
)
{
if
(
$purpose
===
self
::
PURPOSE_TRANSPORT
)
{
return
$this
->
SID
;
}
if
(
$purpose
===
self
::
PURPOSE_STORAGE
)
{
return
$this
->
Storage
->
createSignatureFromSID
(
$this
->
SID
);
}
if
(
$purpose
===
self
::
PURPOSE_REFERENCE
)
{
return
$this
->
Storage
->
GetID
();
}
throw
new
RuntimeException
(
'The "'
.
$purpose
.
'" purpose is not supported.'
);
}
/**
* Generates new session id
*
* @return string
*/
protected
function
GenerateSID
()
{
// Generated byte-string is hex-encoded and therefore is twice the requested size.
$promise
=
SecurityGenerator
::
generateBytes
(
self
::
SID_LENGTH
/
2
);
$promise
->
asSignature
()->
resolveForPersisting
(
TABLE_PREFIX
.
'UserSessions'
,
'SessionKey'
);
$new_sid
=
$promise
->
asValue
()->
resolve
();
$this
->
setSID
(
$new_sid
);
return
$this
->
SID
;
}
/**
* Set's new session id
*
* @param int $new_sid
* @access private
*/
function
setSID
(
$new_sid
)
{
$this
->
SID
/*= $this->CachedSID*/
=
$new_sid
;
// don't set cached sid here
$this
->
Application
->
SetVar
(
$this
->
GETName
,
$new_sid
);
}
function
NeedSession
()
{
$data
=
$this
->
Data
->
GetParams
();
$data_keys
=
array_keys
(
$data
);
$optional_keys
=
array_keys
(
$this
->
OptionalData
);
$real_keys
=
array_diff
(
$data_keys
,
$optional_keys
);
return
$real_keys
?
true
:
false
;
}
function
SetSession
(
$force
=
false
)
{
if
(
$this
->
SessionSet
&&
!
$force
)
{
return
true
;
}
$this
->
Expiration
=
adodb_mktime
()
+
$this
->
SessionTimeout
;
if
(
!
$force
&&
/*!$this->Application->isAdmin &&*/
!
$this
->
Application
->
GetVar
(
'admin'
)
&&
!
$this
->
NeedSession
()
)
{
// don't create session (in db) on Front-End, when sid is present (GPC), but data in db isn't
if
(
$this
->
_fromGet
)
{
// set sid, that was given in GET
$this
->
setSID
(
$this
->
GetPassedSIDValue
());
}
else
{
// re-generate sid only, when cookies are used
$this
->
GenerateSID
();
}
$this
->
Storage
->
StoreSession
(
false
);
return
false
;
}
if
(
!
$this
->
SID
||
$force
)
{
$this
->
GenerateSID
();
}
switch
(
$this
->
Mode
)
{
case
self
::
smAUTO
:
if
(
$this
->
CookiesEnabled
)
{
$this
->
SetSessionCookie
();
}
break
;
case
self
::
smGET_ONLY
:
break
;
case
self
::
smCOOKIES_ONLY
:
case
self
::
smCOOKIES_AND_GET
:
$this
->
SetSessionCookie
();
break
;
}
$this
->
Storage
->
StoreSession
();
if
(
$this
->
Application
->
isAdmin
||
$this
->
Special
==
'admin'
)
{
$this
->
StoreVar
(
'admin'
,
1
);
}
$this
->
SessionSet
=
true
;
// should be called before SaveData, because SaveData will try to SetSession again
if
(
$this
->
Special
!=
''
)
{
// front-session called from admin or otherwise, then save it's data
$this
->
SaveData
();
}
$this
->
Application
->
resetCounters
(
'UserSessions'
);
return
true
;
}
/**
* Returns SID from cookie.
*
* Use 2 cookies to have 2 expiration:
* - 1. for normal expiration when browser is not closed (30 minutes by default), configurable
* - 2. for advanced expiration when browser is closed
*
* @return int
*/
function
GetSessionCookie
()
{
$keep_session_on_browser_close
=
$this
->
Application
->
ConfigValue
(
'KeepSessionOnBrowserClose'
);
if
(
isset
(
$this
->
Application
->
HttpQuery
->
Cookie
[
$this
->
CookieName
])
&&
(
$keep_session_on_browser_close
||
(
!
$keep_session_on_browser_close
&&
isset
(
$this
->
Application
->
HttpQuery
->
Cookie
[
$this
->
CookieName
.
'_live'
])
&&
$this
->
Application
->
HttpQuery
->
Cookie
[
$this
->
CookieName
]
==
$this
->
Application
->
HttpQuery
->
Cookie
[
$this
->
CookieName
.
'_live'
]
)
)
)
{
return
$this
->
Application
->
HttpQuery
->
Cookie
[
$this
->
CookieName
];
}
return
false
;
}
/**
* Updates SID in cookie with new value
*
*/
function
SetSessionCookie
()
{
$this
->
SetCookie
(
$this
->
CookieName
,
$this
->
SID
,
$this
->
Expiration
);
$this
->
SetCookie
(
$this
->
CookieName
.
'_live'
,
$this
->
SID
);
$_COOKIE
[
$this
->
CookieName
]
=
$this
->
SID
;
// for compatibility with in-portal
}
function
RemoveSessionCookie
()
{
$this
->
SetCookie
(
$this
->
CookieName
,
''
);
$this
->
SetCookie
(
$this
->
CookieName
.
'_live'
,
''
);
$_COOKIE
[
$this
->
CookieName
]
=
null
;
// for compatibility with in-portal
}
/**
* Refreshes session expiration time
*
* @access private
*/
function
Refresh
()
{
if
(
$this
->
Application
->
GetVar
(
'skip_session_refresh'
))
{
return
;
}
if
(
$this
->
CookiesEnabled
)
{
// we need to refresh the cookie
$this
->
SetSessionCookie
();
}
$this
->
Storage
->
UpdateSession
();
}
function
Destroy
()
{
$this
->
Storage
->
DeleteSession
();
$this
->
Data
=
new
Params
();
$this
->
SID
=
$this
->
CachedSID
=
''
;
$this
->
SessionSet
=
false
;
if
(
$this
->
CookiesEnabled
)
{
$this
->
SetSessionCookie
();
//will remove the cookie due to value (sid) is empty
}
$this
->
SetSession
(
true
);
//will create a new session, true to force
}
function
NeedQueryString
(
$use_cache
=
1
)
{
if
(
$this
->
CachedNeedQueryString
!==
null
&&
$use_cache
)
{
return
$this
->
CachedNeedQueryString
;
}
$result
=
false
;
switch
(
$this
->
Mode
)
{
case
self
::
smAUTO
:
if
(
!
$this
->
CookiesEnabled
&&
PHP_SAPI
!==
'cli'
)
{
$result
=
true
;
}
break
;
/*case self::smCOOKIES_ONLY:
break;*/
case
self
::
smGET_ONLY
:
case
self
::
smCOOKIES_AND_GET
:
if
(
PHP_SAPI
!==
'cli'
)
{
$result
=
true
;
}
break
;
}
$this
->
CachedNeedQueryString
=
$result
;
return
$result
;
}
function
LoadData
()
{
$this
->
Data
->
AddParams
(
$this
->
Storage
->
LoadData
()
);
}
/**
* Returns information about session contents
*
* @param bool $include_optional
* @return array
* @access public
*/
public
function
getSessionData
(
$include_optional
=
true
)
{
$session_data
=
$this
->
Data
->
GetParams
();
ksort
(
$session_data
);
foreach
(
$session_data
as
$session_key
=>
$session_value
)
{
if
(
kUtil
::
IsSerialized
(
$session_value
)
)
{
$session_data
[
$session_key
]
=
unserialize
(
$session_value
);
}
}
if
(
!
$include_optional
)
{
$optional_keys
=
array_keys
(
$this
->
OptionalData
);
foreach
(
$session_data
as
$session_key
=>
$session_value
)
{
if
(
in_array
(
$session_key
,
$optional_keys
)
)
{
unset
(
$session_data
[
$session_key
]);
}
}
}
return
$session_data
;
}
/**
* Returns real session data, that was saved
*
* @param Array $session_data
* @return Array
* @access protected
*/
protected
function
_getRealSessionData
(
$session_data
)
{
$data_keys
=
array_keys
(
$session_data
);
$optional_keys
=
array_keys
(
$this
->
OptionalData
);
$real_keys
=
array_diff
(
$data_keys
,
$optional_keys
);
if
(
!
$real_keys
)
{
return
Array
();
}
$ret
=
Array
();
foreach
(
$real_keys
as
$real_key
)
{
$ret
[
$real_key
]
=
$session_data
[
$real_key
];
}
return
$ret
;
}
function
PrintSession
(
$comment
=
''
)
{
if
(
defined
(
'DEBUG_MODE'
)
&&
$this
->
Application
->
isDebugMode
()
&&
kUtil
::
constOn
(
'DBG_SHOW_SESSIONDATA'
)
)
{
// dump session data
$this
->
Application
->
Debugger
->
appendHTML
(
'SessionStorage ['
.
(
$this
->
RecallVar
(
'admin'
)
==
1
?
'Admin'
:
'Front-End'
)
.
'] ('
.
$comment
.
'):'
);
$session_data
=
$this
->
getSessionData
();
$this
->
Application
->
Debugger
->
dumpVars
(
$session_data
);
if
(
!
$this
->
RecallVar
(
'admin'
)
)
{
// dump real keys (only for front-end)
$real_session_data
=
$this
->
_getRealSessionData
(
$session_data
);
if
(
$real_session_data
)
{
$this
->
Application
->
Debugger
->
appendHTML
(
'Real Keys:'
);
$this
->
Application
->
Debugger
->
dumpVars
(
$real_session_data
);
}
}
}
if
(
defined
(
'DEBUG_MODE'
)
&&
$this
->
Application
->
isDebugMode
()
&&
kUtil
::
constOn
(
'DBG_SHOW_PERSISTENTDATA'
)
)
{
// dump persistent session data
if
(
$this
->
Storage
->
PersistentVars
)
{
$this
->
Application
->
Debugger
->
appendHTML
(
'Persistant Session:'
);
$session_data
=
$this
->
Storage
->
PersistentVars
;
ksort
(
$session_data
);
foreach
(
$session_data
as
$session_key
=>
$session_value
)
{
if
(
kUtil
::
IsSerialized
(
$session_value
)
)
{
$session_data
[
$session_key
]
=
unserialize
(
$session_value
);
}
}
$this
->
Application
->
Debugger
->
dumpVars
(
$session_data
);
}
}
}
function
SaveData
(
$params
=
Array
())
{
if
(!
$this
->
SetSession
())
{
// call it here - it may be not set before, because there was no need; if there is a need, it will be set here
return
;
}
if
(!
$this
->
Application
->
GetVar
(
'skip_last_template'
)
&&
$this
->
Application
->
GetVar
(
'ajax'
)
!=
'yes'
)
{
$this
->
SaveLastTemplate
(
$this
->
Application
->
GetVar
(
't'
),
$params
);
}
$this
->
PrintSession
(
'after save'
);
$this
->
Storage
->
SaveData
();
}
/**
* Save last template
*
* @param string $t
* @param Array $params
*/
function
SaveLastTemplate
(
$t
,
$params
=
Array
())
{
$wid
=
$this
->
Application
->
GetVar
(
'm_wid'
);
$last_env
=
$this
->
getLastTemplateENV
(
$t
,
array
(
'm_opener'
=>
'u'
));
$last_template
=
basename
(
$_SERVER
[
'PHP_SELF'
])
.
'|'
.
$last_env
;
$this
->
StoreVar
(
rtrim
(
'last_template_'
.
$wid
,
'_'
),
$last_template
);
// prepare last_template for opener stack, module & session could be added later
$last_env
=
$this
->
getLastTemplateENV
(
$t
);
$last_template
=
basename
(
$_SERVER
[
'PHP_SELF'
])
.
'|'
.
$last_env
;
// save last_template in persistent session
if
(!
$wid
)
{
if
(
$this
->
Application
->
isAdmin
)
{
// only for main window, not popups, not login template, not temp mode (used in adm:MainFrameLink tag)
$temp_mode
=
false
;
$passed
=
explode
(
','
,
$this
->
Application
->
GetVar
(
'passed'
));
foreach
(
$passed
as
$passed_prefix
)
{
if
(
$this
->
Application
->
GetVar
(
$passed_prefix
.
'_mode'
))
{
$temp_mode
=
true
;
break
;
}
}
if
(!
$temp_mode
)
{
if
(
$this
->
Application
->
GetVarDirect
(
'section'
,
'Get'
)
!==
false
)
{
// check directly in GET, because LinkVar (session -> request) used on these vars
$last_template
.=
'§ion='
.
$this
->
Application
->
GetVar
(
'section'
).
'&module='
.
$this
->
Application
->
GetVar
(
'module'
);
}
$this
->
StorePersistentVar
(
'last_template_popup'
,
$last_template
);
}
}
elseif
(
$this
->
Application
->
GetVar
(
'admin'
))
{
// admin checking by session data to prevent recursive session save
static
$admin_saved
=
null
;
if
(!
$this
->
RecallVar
(
'admin'
)
&&
!
isset
(
$admin_saved
))
{
// bug: we get recursion in this place, when cookies are disabled in browser and we are browsing
// front-end in admin's frame (front-end session is initialized using admin's sid and they are
// mixed together)
$admin_saved
=
true
;
/** @var Session $admin_session */
$admin_session
=
$this
->
Application
->
recallObject
(
'Session.admin'
);
// save to admin last_template too, because when F5 is pressed in frameset Front-End frame should reload as well
$admin_session
->
StoreVar
(
'last_template_popup'
,
'../'
.
$last_template
);
$admin_session
->
StorePersistentVar
(
'last_template_popup'
,
'../'
.
$last_template
);
$admin_session
->
SaveData
(
Array
(
'save_last_template'
=>
false
)
);
}
else
{
// don't allow admin=1 & editing_mode=* to get in admin last_template
$last_template
=
preg_replace
(
'/&(admin|editing_mode)=[
\d
]/'
,
''
,
$last_template
);
}
}
}
// save other last... variables for mystical purposes (customizations may be)
$this
->
StoreVar
(
'last_url'
,
$_SERVER
[
'REQUEST_URI'
]);
// needed by ord:StoreContinueShoppingLink
$this
->
StoreVar
(
'last_env'
,
$last_env
);
$save_last_template
=
array_key_exists
(
'save_last_template'
,
$params
)
?
$params
[
'save_last_template'
]
:
true
;
if
(
$save_last_template
)
{
// save last template here, because section & module could be added before
$this
->
StoreVar
(
rtrim
(
'last_template_popup_'
.
$wid
,
'_'
),
$last_template
);
}
}
protected
function
getLastTemplateENV
(
$t
,
$params
=
null
)
{
if
(!
isset
(
$params
))
{
$params
=
Array
();
}
if
(
$this
->
Application
->
GetVar
(
'admin'
)
&&
!
array_key_exists
(
'admin'
,
$params
)
&&
!
defined
(
'EDITING_MODE'
))
{
$params
[
'editing_mode'
]
=
''
;
// used in kApplication::Run
}
$params
=
array_merge
(
$this
->
Application
->
getPassThroughVariables
(
$params
),
$params
);
return
$this
->
Application
->
BuildEnv
(
$t
,
$params
,
'all'
,
false
,
false
);
}
/**
* Stores variable $val in session under name $var
*
* Use this method to store variable in session. Later this variable could be recalled.
*
* @param string $name Variable name
* @param mixed $value Variable value
* @param bool $optional
* @return void
* @access public
* @see Session::RecallVar()
*/
public
function
StoreVar
(
$name
,
$value
,
$optional
=
false
)
{
$this
->
Data
->
Set
(
$name
,
$value
);
if
(
$optional
)
{
// make variable optional, also remember optional value
$this
->
OptionalData
[
$name
]
=
$value
;
}
elseif
(
!
$optional
&&
array_key_exists
(
$name
,
$this
->
OptionalData
)
)
{
if
(
$this
->
OptionalData
[
$name
]
==
$value
)
{
// same value as optional -> don't remove optional mark
return
;
}
// make variable non-optional
unset
(
$this
->
OptionalData
[
$name
]);
}
}
/**
* Stores variable to persistent session
*
* @param string $name
* @param mixed $value
* @param bool $optional
* @return void
* @access public
*/
public
function
StorePersistentVar
(
$name
,
$value
,
$optional
=
false
)
{
$this
->
Storage
->
StorePersistentVar
(
$name
,
$value
,
$optional
);
}
function
LoadPersistentVars
()
{
$this
->
Storage
->
LoadPersistentVars
();
}
/**
* Stores default value for session variable
*
* @param string $name
* @param string $value
* @param bool $optional
* @return void
* @access public
* @see Session::RecallVar()
* @see Session::StoreVar()
*/
public
function
StoreVarDefault
(
$name
,
$value
,
$optional
=
false
)
{
$tmp
=
$this
->
RecallVar
(
$name
);
if
(
$tmp
===
false
||
$tmp
==
''
)
{
$this
->
StoreVar
(
$name
,
$value
,
$optional
);
}
}
/**
* Returns session variable value
*
* Return value of $var variable stored in Session. An optional default value could be passed as second parameter.
*
* @param string $name Variable name
* @param mixed $default Default value to return if no $var variable found in session
* @return mixed
* @access public
*/
public
function
RecallVar
(
$name
,
$default
=
false
)
{
$ret
=
$this
->
Data
->
Get
(
$name
);
return
(
$ret
===
false
)
?
$default
:
$ret
;
}
/**
* Returns variable value from persistent session
*
* @param string $name
* @param mixed $default
* @return mixed
* @access public
*/
public
function
RecallPersistentVar
(
$name
,
$default
=
false
)
{
return
$this
->
Storage
->
RecallPersistentVar
(
$name
,
$default
);
}
/**
* Deletes Session variable
*
* @param string $var
* @return void
* @access public
*/
public
function
RemoveVar
(
$name
)
{
$this
->
Storage
->
RemoveFromData
(
$name
);
$this
->
Data
->
Remove
(
$name
);
}
/**
* Removes variable from persistent session
*
* @param string $name
* @return void
* @access public
*/
public
function
RemovePersistentVar
(
$name
)
{
$this
->
Storage
->
RemovePersistentVar
(
$name
);
}
/**
* Ignores session variable value set before
*
* @param string $name
* @return void
* @access public
*/
public
function
RestoreVar
(
$name
)
{
$value
=
$this
->
Storage
->
GetFromData
(
$name
,
'__missing__'
);
if
(
$value
===
'__missing__'
)
{
// there is nothing to restore (maybe session was not saved), look in optional variable values
$value
=
array_key_exists
(
$name
,
$this
->
OptionalData
)
?
$this
->
OptionalData
[
$name
]
:
false
;
}
$this
->
StoreVar
(
$name
,
$value
);
}
function
GetField
(
$var_name
,
$default
=
false
)
{
return
$this
->
Storage
->
GetField
(
$var_name
,
$default
);
}
function
SetField
(
$var_name
,
$value
)
{
$this
->
Storage
->
SetField
(
$var_name
,
$value
);
}
/**
* Deletes expired sessions
*
* @return Array expired sids if any
* @access private
*/
function
DeleteExpired
()
{
return
$this
->
Storage
->
DeleteExpired
();
}
/**
* Deletes given sessions
*
* @param $session_ids
* @param int $delete_reason
* @return void
*/
function
DeleteSessions
(
$session_ids
,
$delete_reason
=
SESSION_LOG_EXPIRED
)
{
$this
->
Storage
->
DeleteSessions
(
$session_ids
,
$delete_reason
);
}
/**
* Allows to check if user in this session is logged in or not
*
* @return bool
*/
function
LoggedIn
()
{
$user_id
=
$this
->
RecallVar
(
'user_id'
);
$ret
=
$user_id
>
0
;
if
((
$this
->
RecallVar
(
'admin'
)
==
1
||
defined
(
'ADMIN'
))
&&
(
$user_id
==
USER_ROOT
))
{
$ret
=
true
;
}
return
$ret
;
}
}
Event Timeline
Log In to Comment