-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSession.php
153 lines (129 loc) · 4.87 KB
/
Session.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
namespace PhpPlatform\WebSession;
use PhpPlatform\Session\Session as ISession;
use PhpPlatform\JSONCache\Cache;
use PhpPlatform\Config\Settings;
use PhpPlatform\Errors\Exceptions\Application\ProgrammingError;
class Session extends Cache implements ISession{
static private $_lasAccessKey = "php-platform.web-session.last-access";
private $id = null;
private static $session = null;
private $isValid = false;
protected function __construct(){
// check if session cokiee is present in the request
$sessionCookieName = Settings::getSettings(Package::Name,"name");
$sessionFilePrefix = Settings::getSettings(Package::Name,'sessionFilePrefix');
$sessionTimeOut = Settings::getSettings(Package::Name,'timeout');
$sessionSalt = Settings::getSettings(Package::Name,'salt');
$sessionPath = Settings::getSettings(Package::Name,'path');
$sessionSecurity = Settings::getSettings(Package::Name,'secure');
$validSession = false;
if(array_key_exists($sessionCookieName, $_COOKIE)){
// cookie is set
$sessionCookie = $_COOKIE[$sessionCookieName];
$sessionLastAccessTime = Cache::getInstance()->getData(self::$_lasAccessKey.'.'.$sessionCookie);
if(isset($sessionLastAccessTime) && time() - $sessionLastAccessTime < $sessionTimeOut){
// session not expired
$sessionFileName = md5($sessionSalt.$sessionCookie);
$this->cacheFileName = $sessionFilePrefix.$sessionFileName;
$validSession = true;
}
}
if(!$validSession){
// cookie is not set OR session is expired OR cookie is invalid
// generate new session
$sessionLastAccessTime = time();
while(isset($sessionLastAccessTime)){
// generate a non-colliding session cokiee
$sessionCookie = md5(microtime().$_SERVER['REMOTE_ADDR'].rand(1,1000));
$sessionLastAccessTime = Cache::getInstance()->getData(self::$_lasAccessKey.'.'.$sessionCookie);
}
$sessionFileName = md5($sessionSalt.$sessionCookie);
$this->cacheFileName = $sessionFilePrefix.$sessionFileName;
}
parent::__construct();
// set session id
$this->id = $sessionCookie;
// update session last access time
$this->setLastAccessTime(time());
// set cookie
$this->removeSessionSetCookieHeader($sessionCookieName);
setcookie($sessionCookieName,$sessionCookie,time()+$sessionTimeOut,$sessionPath,"",$sessionSecurity,true);
$this->isValid = true;
}
/**
* @return Session
*/
public static function getInstance() {
if(self::$session == null){
self::$session = new Session();
}
return self::$session;
}
public function getId() {
if(!$this->isValid){
throw new ProgrammingError('Invalid session instance, get a new instance from PHPPlatform\Session\Factory::getSession()');
}
return $this->id;
}
public function get($key) {
if(!$this->isValid){
throw new ProgrammingError('Invalid session instance, get a new instance from PHPPlatform\Session\Factory::getSession()');
}
return parent::getData($key);
}
public function set($key, $value) {
if(!$this->isValid){
throw new ProgrammingError('Invalid session instance, get a new instance from PHPPlatform\Session\Factory::getSession()');
}
return parent::setData(array($key=>$value));
}
public function clear() {
if(!$this->isValid){
throw new ProgrammingError('Invalid session instance, get a new instance from PHPPlatform\Session\Factory::getSession()');
}
return parent::reset();
}
public function reset($flag = 0) {
if(!$this->isValid){
throw new ProgrammingError('Invalid session instance, get a new instance from PHPPlatform\Session\Factory::getSession()');
}
// create a new Session
$sessionCookieName = Settings::getSettings(Package::Name,"name");
unset($_COOKIE[$sessionCookieName]);
self::$session = new Session();
if($flag & self::RESET_COPY_OLD){
self::$session->setData($this->getData(""));
}
if($flag & self::RESET_DELETE_OLD){
$this->clear();
}
$this->setLastAccessTime(0);
$this->isValid = false;
}
private function setLastAccessTime($time){
$lastAccessTime = array($this->id=>$time);
$cachePaths = array_reverse(explode(".", self::$_lasAccessKey));
foreach ($cachePaths as $cachePath){
$lastAccessTime = array($cachePath=>$lastAccessTime);
}
Cache::getInstance()->setData($lastAccessTime);
}
private function removeSessionSetCookieHeader($sessionName){
$headers = headers_list();
$cookiesToBeRestored = array();
foreach ($headers as $header){
if(strpos($header, "Set-Cookie:") === 0){
// SetCookie Header
if(strpos($header, "Set-Cookie: $sessionName=") !== 0){
// not a session SetCookie header
$cookiesToBeRestored[] = $header;
}
}
}
header_remove("Set-Cookie");
foreach ($cookiesToBeRestored as $header){
header($header,false);
}
}
}