ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilSession.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once('Services/Authentication/classes/class.ilSessionControl.php');
5require_once('Services/Authentication/classes/class.ilSessionStatistics.php');
6require_once('Services/Authentication/classes/class.ilSessionIStorage.php');
7
16{
25
34
40 const SESSION_CLOSE_USER = 1; // manual logout
41 const SESSION_CLOSE_EXPIRE = 2; // has expired
42 const SESSION_CLOSE_FIRST = 3; // kicked by session control (first abidencer)
43 const SESSION_CLOSE_IDLE = 4; // kickey by session control (ilde time)
44 const SESSION_CLOSE_LIMIT = 5; // kicked by session control (limit reached)
45 const SESSION_CLOSE_LOGIN = 6; // anonymous => login
46 const SESSION_CLOSE_PUBLIC = 7; // => anonymous
47 const SESSION_CLOSE_TIME = 8; // account time limit reached
48 const SESSION_CLOSE_IP = 9; // wrong ip
49 const SESSION_CLOSE_SIMUL = 10; // simultaneous login
50 const SESSION_CLOSE_INACTIVE = 11; // inactive account
51 const SESSION_CLOSE_CAPTCHA = 12; // invalid captcha
52
53 private static $closing_context = null;
54
58 protected static $enable_web_access_without_session = false;
59
69 public static function _getData($a_session_id)
70 {
71 if (!$a_session_id) {
72 // fix for php #70520
73 return '';
74 }
75 global $DIC;
76
77 $ilDB = $DIC['ilDB'];
78
79 $q = "SELECT data FROM usr_session WHERE session_id = " .
80 $ilDB->quote($a_session_id, "text");
81 $set = $ilDB->query($q);
82 $rec = $ilDB->fetchAssoc($set);
83
84 // fix for php #70520
85 return (string) $rec["data"];
86 }
87
94 public static function lookupExpireTime($a_session_id)
95 {
96 global $DIC;
97
98 $ilDB = $DIC['ilDB'];
99
100 $query = 'SELECT expires FROM usr_session WHERE session_id = ' .
101 $ilDB->quote($a_session_id, 'text');
102 $res = $ilDB->query($query);
103 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
104 return (int) $row->expires;
105 }
106 return 0;
107 }
108
109
116 public static function _writeData($a_session_id, $a_data)
117 {
118 global $DIC;
119
120 $ilDB = $DIC['ilDB'];
121 $ilClientIniFile = $DIC['ilClientIniFile'];
122
123 if (self::isWebAccessWithoutSessionEnabled()) {
124 // Prevent session data written for web access checker
125 // when no cookie was sent (e.g. for pdf files linking others).
126 // This would result in new session records for each request.
127 return true;
128 }
129
130 if (!$a_session_id) {
131 return true;
132 }
133
134 $now = time();
135
136 // prepare session data
137 $fields = array(
138 "user_id" => array("integer", (int) $_SESSION['_authsession_user_id']),
139 "expires" => array("integer", self::getExpireValue()),
140 "data" => array("clob", $a_data),
141 "ctime" => array("integer", $now),
142 "type" => array("integer", (int) $_SESSION["SessionType"])
143 );
144 if ($ilClientIniFile->readVariable("session", "save_ip")) {
145 $fields["remote_addr"] = array("text", $_SERVER["REMOTE_ADDR"]);
146 }
147
148 if (ilSession::_exists($a_session_id)) {
149 // note that we do this only when inserting the new record
150 // updating may get us other contexts for the same session, especially ilContextWAC, which we do not want
151 if (class_exists("ilContext")) {
153 $fields["context"] = array("text", ilContext::getType());
154 }
155 }
156
157 $ilDB->update(
158 "usr_session",
159 $fields,
160 array("session_id" => array("text", $a_session_id))
161 );
162 } else {
163 $fields["session_id"] = array("text", $a_session_id);
164 $fields["createtime"] = array("integer", $now);
165
166 // note that we do this only when inserting the new record
167 // updating may get us other contexts for the same session, especially ilContextWAC, which we do not want
168 if (class_exists("ilContext")) {
169 $fields["context"] = array("text", ilContext::getType());
170 }
171
172 $ilDB->insert("usr_session", $fields);
173
174 // check type against session control
175 $type = $fields["type"][1];
178 $fields["session_id"][1],
179 $type,
180 $fields["createtime"][1],
181 $fields["user_id"][1]
182 );
183 }
184 }
185
186 // finally delete deprecated sessions
187 $random = new \ilRandom();
188 if ($random->int(0, 50) == 2) {
189 // get time _before_ destroying expired sessions
192 }
193
194 return true;
195 }
196
197
198
205 public static function _exists($a_session_id)
206 {
207 if (!$a_session_id) {
208 return false;
209 }
210 global $DIC;
211
212 $ilDB = $DIC['ilDB'];
213
214 $q = "SELECT 1 FROM usr_session WHERE session_id = " . $ilDB->quote($a_session_id, "text");
215 $set = $ilDB->query($q);
216
217 return $ilDB->numRows($set) > 0;
218 }
219
227 public static function _destroy($a_session_id, $a_closing_context = null, $a_expired_at = null)
228 {
229 global $DIC;
230
231 $ilDB = $DIC['ilDB'];
232
233 if (!$a_closing_context) {
234 $a_closing_context = self::$closing_context;
235 }
236
237 ilSessionStatistics::closeRawEntry($a_session_id, $a_closing_context, $a_expired_at);
238
239
240 if (!is_array($a_session_id)) {
241 $q = "DELETE FROM usr_session WHERE session_id = " .
242 $ilDB->quote($a_session_id, "text");
243 } else {
244 // array: id => timestamp - so we get rid of timestamps
245 if ($a_expired_at) {
246 $a_session_id = array_keys($a_session_id);
247 }
248 $q = "DELETE FROM usr_session WHERE " .
249 $ilDB->in("session_id", $a_session_id, "", "text");
250 }
251
253
254 $ilDB->manipulate($q);
255
256 try {
257 // only delete session cookie if it is set in the current request
258 if (isset($_COOKIE[session_name()]) && $_COOKIE[session_name()] === $a_session_id) {
259 \ilUtil::setCookie(session_name(), '', false, true);
260 }
261 } catch (\Throwable $e) {
262 // ignore
263 // this is needed for "header already" sent errors when the random cleanup of expired sessions is triggered
264 }
265
266 return true;
267 }
268
274 public static function _destroyByUserId($a_user_id)
275 {
276 global $DIC;
277
278 $ilDB = $DIC['ilDB'];
279
280 $q = "DELETE FROM usr_session WHERE user_id = " .
281 $ilDB->quote($a_user_id, "integer");
282 $ilDB->manipulate($q);
283
284 return true;
285 }
286
290 public static function _destroyExpiredSessions()
291 {
292 global $DIC;
293
294 $ilDB = $DIC['ilDB'];
295
296 $q = "SELECT session_id,expires FROM usr_session WHERE expires < " .
297 $ilDB->quote(time(), "integer");
298 $res = $ilDB->query($q);
299 $ids = array();
300 while ($row = $ilDB->fetchAssoc($res)) {
301 $ids[$row["session_id"]] = $row["expires"];
302 }
303 if (sizeof($ids)) {
304 self::_destroy($ids, self::SESSION_CLOSE_EXPIRE, true);
305 }
306
307 return true;
308 }
309
316 public static function _duplicate($a_session_id)
317 {
318 global $DIC;
319
320 $ilDB = $DIC['ilDB'];
321
322 // Create new session id
323 $new_session = $a_session_id;
324 do {
325 $new_session = md5($new_session);
326 $q = "SELECT * FROM usr_session WHERE " .
327 "session_id = " . $ilDB->quote($new_session, "text");
328 $res = $ilDB->query($q);
329 } while ($ilDB->fetchAssoc($res));
330
331 $query = "SELECT * FROM usr_session " .
332 "WHERE session_id = " . $ilDB->quote($a_session_id, "text");
333 $res = $ilDB->query($query);
334
335 while ($row = $ilDB->fetchObject($res)) {
336 ilSession::_writeData($new_session, $row->data);
337 return $new_session;
338 }
339 return false;
340 }
341
352 public static function getExpireValue($fixedMode = false)
353 {
354 global $DIC;
355
356 if ($fixedMode) {
357 // fixed session
358 return time() + self::getIdleValue($fixedMode);
359 }
360
361 $ilSetting = $DIC['ilSetting'];
362 if ($ilSetting->get('session_handling_type', self::SESSION_HANDLING_FIXED) == self::SESSION_HANDLING_FIXED) {
363 return time() + self::getIdleValue($fixedMode);
364 } elseif ($ilSetting->get('session_handling_type', self::SESSION_HANDLING_FIXED) == self::SESSION_HANDLING_LOAD_DEPENDENT) {
365 // load dependent session settings
366 return time() + (int) ($ilSetting->get('session_max_idle', ilSessionControl::DEFAULT_MAX_IDLE) * 60);
367 }
368 }
369
380 public static function getIdleValue($fixedMode = false)
381 {
382 global $DIC;
383
384 $ilSetting = $DIC['ilSetting'];
385 $ilClientIniFile = $DIC['ilClientIniFile'];
386
387 if ($fixedMode || $ilSetting->get('session_handling_type', self::SESSION_HANDLING_FIXED) == self::SESSION_HANDLING_FIXED) {
388 // fixed session
389 return $ilClientIniFile->readVariable('session', 'expire');
390 } elseif ($ilSetting->get('session_handling_type', self::SESSION_HANDLING_FIXED) == self::SESSION_HANDLING_LOAD_DEPENDENT) {
391 // load dependent session settings
392 return (int) ($ilSetting->get('session_max_idle', ilSessionControl::DEFAULT_MAX_IDLE) * 60);
393 }
394 }
395
405 public static function getSessionExpireValue()
406 {
407 return self::getIdleValue(true);
408 }
409
416 public static function _getUsersWithIp($a_ip)
417 {
418 global $DIC;
419
420 $ilDB = $DIC['ilDB'];
421
422 $query = "SELECT DISTINCT user_id FROM usr_session"
423 . " WHERE remote_addr = " . $ilDB->quote($a_ip, "text")
424 . " AND user_id > 0";
425 $result = $ilDB->query($query);
426
427 $users = array();
428 while ($row = $ilDB->fetchObject($result)) {
429 $users[] = $row->user_id;
430 }
431 return $users;
432 }
433
440 public static function set($a_var, $a_val)
441 {
442 $_SESSION[$a_var] = $a_val;
443 }
444
451 public static function get($a_var)
452 {
453 return $_SESSION[$a_var];
454 }
455
462 public static function clear($a_var)
463 {
464 unset($_SESSION[$a_var]);
465 }
466
472 public static function setClosingContext($a_context)
473 {
474 self::$closing_context = (int) $a_context;
475 }
476
482 public static function getClosingContext()
483 {
485 }
486
487
488
492 public static function isWebAccessWithoutSessionEnabled()
493 {
495 }
496
501 {
502 self::$enable_web_access_without_session = (bool) $enable_web_access_without_session;
503 }
504}
$result
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
static isSessionMainContext()
Context that are not only temporary in a session (e.g.
static getType()
Get context type.
static destroySession($a_session_id)
Destroy session(s).
static closeRawEntry($a_session_id, $a_context=null, $a_expired_at=null)
Close raw data entry.
static createRawEntry($a_session_id, $a_session_type, $a_timestamp, $a_user_id)
Create raw data entry.
static aggretateRaw($a_now)
Aggregate raw session data (older than given time)
static _exists($a_session_id)
Check whether session exists.
const SESSION_HANDLING_LOAD_DEPENDENT
const SESSION_CLOSE_USER
const SESSION_CLOSE_CAPTCHA
const SESSION_CLOSE_IP
static setClosingContext($a_context)
set closing context (for statistics)
const SESSION_HANDLING_FIXED
static getIdleValue($fixedMode=false)
Returns the idle time in seconds.
static getClosingContext()
get closing context (for statistics)
static _getUsersWithIp($a_ip)
Get the active users with a specific remote ip address.
static isWebAccessWithoutSessionEnabled()
const SESSION_CLOSE_LOGIN
const SESSION_CLOSE_TIME
static _writeData($a_session_id, $a_data)
Write session data.
static _destroyExpiredSessions()
Destroy expired sessions.
static _destroy($a_session_id, $a_closing_context=null, $a_expired_at=null)
Destroy session.
static _destroyByUserId($a_user_id)
Destroy session.
static _getData($a_session_id)
Get session data from table.
static clear($a_var)
Unset a value.
const SESSION_CLOSE_SIMUL
static enableWebAccessWithoutSession($enable_web_access_without_session)
static _duplicate($a_session_id)
Duplicate session.
const SESSION_CLOSE_FIRST
static lookupExpireTime($a_session_id)
Lookup expire time for a specific session @global ilDB $ilDB.
static $closing_context
const SESSION_CLOSE_INACTIVE
const SESSION_CLOSE_IDLE
const SESSION_CLOSE_PUBLIC
static getSessionExpireValue()
Returns the session expiration value.
static $enable_web_access_without_session
const SESSION_CLOSE_LIMIT
const SESSION_CLOSE_EXPIRE
static getExpireValue($fixedMode=false)
Returns the expiration timestamp in seconds.
static setCookie($a_cookie_name, $a_cookie_value='', $a_also_set_super_global=true, $a_set_cookie_invalid=false)
global $DIC
Definition: goto.php:24
global $ilSetting
Definition: privfeed.php:17
$query
$type
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
foreach($_POST as $key=> $value) $res
global $ilDB
$_COOKIE[session_name()]
Definition: xapitoken.php:37