PluginProbe
ShiftController Employee Shift Scheduling / 4.9.24
ShiftController Employee Shift Scheduling v4.9.24
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / hc3 / session.php

session.php in ShiftController Employee Shift Scheduling 4.9.24, at hc3/session.php

567 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if (! defined('ABSPATH')) exit; // Exit if accessed directly
2 interface HC3_Session_
3 {
4 public function getFlashdata( $key );
5 public function setFlashdata( $key, $value, $append = FALSE );
6
7 public function getUserdata( $key );
8 public function setUserdata( $key, $value, $append = FALSE );
9 public function unsetUserdata( $key );
10 }
11
12 class HC3_Session implements HC3_Session_
13 {
14 protected $_started = FALSE;
15
16 protected $_prefix = 'hitcode_';
17 protected $request = NULL;
18 protected $encrypt = NULL;
19
20 protected $encryption_key = NULL;
21
22 protected $sess_encrypt_cookie = FALSE;
23 protected $sess_expiration = 7200;
24 protected $sess_expire_on_close = FALSE;
25 protected $sess_match_ip = FALSE;
26 protected $sess_match_useragent = FALSE;
27 protected $sess_cookie_name = 'hc3_session';
28 protected $cookie_prefix = '';
29 protected $cookie_path = '';
30 protected $cookie_domain = '';
31 protected $cookie_secure = FALSE;
32 protected $sess_time_to_update = 300;
33 protected $flashdata_key = 'flash';
34 protected $time_reference = 'time';
35 protected $userdata = array();
36 protected $now;
37
38 protected $builtin_props = array(
39 'session_id',
40 'ip_address',
41 'user_agent',
42 'last_activity',
43 'user_data'
44 );
45
46 /**
47 * Session Constructor
48 *
49 * The constructor runs the session routines automatically
50 * whenever the class is instantiated.
51 */
52
53 public static function instance()
54 {
55 static $ret = NULL;
56 if( NULL === $ret ){
57 $ret = new static;
58 }
59 return $ret;
60 }
61
62 public static function start()
63 {
64 if( session_id() == '' ){
65 // echo "<div style='margin-left: 14em;'>START SESSION</div>";
66 $sessionOptions = array();
67 // $sessionOptions = array( 'read_and_close' => TRUE );
68 @session_start( $sessionOptions );
69 }
70 }
71
72 public function __construct( $prefix = 'shiftcontroller4' )
73 {
74 // $this->request = $request;
75 $this->_prefix = $prefix;
76
77 $this->encryption_key = md5(__FILE__);
78
79 static::start();
80
81 // Set the "now" time. Can either be GMT or server time, based on the
82 // config prefs. We use this to set the "last activity" time
83 $this->now = $this->_get_time();
84
85 // Set the session length. If the session expiration is
86 // set to zero we'll set the expiration two years from now.
87 if ($this->sess_expiration == 0){
88 $this->sess_expiration = (60*60*24*365*2);
89 }
90
91 // Set the cookie name
92 // $this->sess_cookie_name = $this->cookie_prefix . $this->sess_cookie_name . '_' . $this->_prefix;
93 $this->sess_cookie_name = $this->cookie_prefix . $this->sess_cookie_name;
94
95 // Run the Session routine. If a session doesn't exist we'll
96 // create a new one. If it does, we'll update it.
97 if ( ! $this->sess_read()){
98 $this->sess_create();
99 }
100 else {
101 $this->sess_update();
102 }
103
104 // Delete 'old' flashdata (from last request)
105 $this->_flashdata_sweep();
106
107 // Mark all new flashdata as old (data will be deleted before next request)
108 $this->_flashdata_mark();
109 }
110
111 // --------------------------------------------------------------------
112
113 /**
114 * Fetch the current session data if it exists
115 *
116 * @access public
117 * @return bool
118 */
119 function sess_read()
120 {
121 // Fetch the cookie
122 $session = array_key_exists($this->sess_cookie_name, $_COOKIE) ? $_COOKIE[$this->sess_cookie_name] : FALSE;
123
124 // No cookie? Goodbye cruel world!...
125 if ($session === FALSE)
126 {
127 // log_message('debug', 'A session cookie was not found.');
128 return FALSE;
129 }
130
131 // Decrypt the cookie data
132 if( $this->encrypt ){
133 $session = $this->encrypt->decode($session);
134 }
135 else {
136 // encryption was not used, so we need to check the md5 hash
137 $hash = substr($session, strlen($session)-32); // get last 32 chars
138 $session = substr($session, 0, strlen($session)-32);
139
140 // Does the md5 hash match? This is to prevent manipulation of session data in userspace
141 if ($hash !== md5($session.$this->encryption_key)){
142 // echo 'The session cookie data did not match what was expected. This could be a possible malicious attempt.';
143 $this->sess_destroy();
144 return FALSE;
145 }
146 }
147
148 // Unserialize the session array
149 $session = $this->_unserialize($session);
150
151 // Is the session data we unserialized an array with the correct format?
152 if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity'])){
153 $this->sess_destroy();
154 return FALSE;
155 }
156
157 // Is the session current?
158 if (($session['last_activity'] + $this->sess_expiration) < $this->now){
159 $this->sess_destroy();
160 return FALSE;
161 }
162
163 // Session is valid!
164 $this->userdata = $session;
165 unset($session);
166
167 return TRUE;
168 }
169
170 // --------------------------------------------------------------------
171
172 /**
173 * Write the session data
174 *
175 * @access public
176 * @return void
177 */
178 function sess_write()
179 {
180 $this->_set_cookie();
181 }
182
183 // --------------------------------------------------------------------
184
185 /**
186 * Create a new session
187 *
188 * @access public
189 * @return void
190 */
191 function sess_create()
192 {
193 $sessid = '';
194 while (strlen($sessid) < 32){
195 $sessid .= mt_rand(0, mt_getrandmax());
196 }
197
198 // To make the session ID even more secure we'll combine it with the user's IP
199 // $sessid .= $this->request->getIpAddress();
200
201 $this->userdata = array(
202 'session_id' => md5(uniqid($sessid, TRUE)),
203 // 'ip_address' => $this->request->getIpAddress(),
204 // 'user_agent' => substr($this->request->getUserAgent(), 0, 120),
205 'last_activity' => $this->now,
206 'user_data' => ''
207 );
208
209 // Write the cookie
210 $this->_set_cookie();
211 }
212
213 // --------------------------------------------------------------------
214
215 /**
216 * Update an existing session
217 *
218 * @access public
219 * @return void
220 */
221 function sess_update()
222 {
223 // We only update the session every five minutes by default
224 if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
225 {
226 return;
227 }
228
229 // Save the old session id so we know which record to
230 // update in the database if we need it
231 $old_sessid = $this->userdata['session_id'];
232 $new_sessid = '';
233 while (strlen($new_sessid) < 32)
234 {
235 $new_sessid .= mt_rand(0, mt_getrandmax());
236 }
237
238 // To make the session ID even more secure we'll combine it with the user's IP
239 // $new_sessid .= $this->request->getIpAddress();
240
241 // Turn it into a hash
242 $new_sessid = md5(uniqid($new_sessid, TRUE));
243
244 // Update the session data in the session data array
245 $this->userdata['session_id'] = $new_sessid;
246 $this->userdata['last_activity'] = $this->now;
247
248 // _set_cookie() will handle this for us if we aren't using database sessions
249 // by pushing all userdata to the cookie.
250 $cookie_data = NULL;
251
252 // Write the cookie
253 $this->_set_cookie($cookie_data);
254 }
255
256 // --------------------------------------------------------------------
257
258 /**
259 * Destroy the current session
260 *
261 * @access public
262 * @return void
263 */
264 function sess_destroy()
265 {
266 // Kill the cookie
267 @setcookie(
268 $this->sess_cookie_name,
269 addslashes(serialize(array())),
270 ($this->now - 31500000),
271 $this->cookie_path,
272 $this->cookie_domain,
273 0
274 );
275
276 // Kill session data
277 $this->userdata = array();
278 }
279
280 public function getUserdata($item)
281 {
282 $my_key = $this->getPrefix() . $item;
283 if( isset($_SESSION[$my_key]) ){
284 return $_SESSION[$my_key];
285 }
286 return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];
287 }
288
289 // --------------------------------------------------------------------
290
291 /**
292 * Fetch all session data
293 *
294 * @access public
295 * @return array
296 */
297 function all_userdata()
298 {
299 $ret = array();
300 if( ! isset($_SESSION) ) return $ret;
301
302 $prefix = $this->getPrefix();
303
304 /* get flash data we store in _SESSION */
305 foreach( $_SESSION as $key => $v ){
306 if( ! (substr($key, 0, strlen($prefix)) == $prefix) )
307 continue;
308 $my_key = substr($key, strlen($prefix) );
309 $ret[ $my_key ] = $v;
310 }
311
312 $parent_ret = $this->userdata;
313 $ret = array_merge( $ret, $parent_ret );
314 return $ret;
315 }
316
317 public function getPrefix()
318 {
319 $ret = $this->_prefix;
320
321 $isWpAdmin = FALSE;
322
323 if( defined('WPINC') && is_admin() ){
324 $isWpAdmin = TRUE;
325 }
326 else {
327 if( isset($_GET['hca']) && ('admin' == substr($_GET['hca'], 0, strlen('admin'))) ){
328 $isWpAdmin = TRUE;
329 }
330 }
331
332 if( $isWpAdmin ){
333 $ret .= '_wpadmin_';
334 }
335
336 return $ret;
337 }
338
339 public function setUserdata( $key, $value, $append = FALSE )
340 {
341 // static::start();
342 $prefix = $this->getPrefix();
343
344 $newdata = array( $key => $value );
345
346 $parent_newdata = array();
347 if (count($newdata) > 0){
348 $parent_newdata = array();
349 foreach ($newdata as $key => $val){
350 if( ! in_array($key, $this->builtin_props) ){
351 $my_key = $prefix . $key;
352 if( $append ){
353 if( ! isset($_SESSION[$my_key]) )
354 $_SESSION[$my_key] = array();
355 if( ! is_array($_SESSION[$my_key]) )
356 $_SESSION[$my_key] = array( $_SESSION[$my_key] );
357 $_SESSION[$my_key][] = $val;
358 }
359 else {
360 $_SESSION[$my_key] = $val;
361 }
362 }
363 else {
364 $parent_newdata[ $key ] = $val;
365 }
366 }
367 }
368
369 if( $parent_newdata ){
370 if (count($parent_newdata) > 0){
371 foreach( $parent_newdata as $key => $val){
372 $this->userdata[$key] = $val;
373 }
374 }
375 $this->sess_write();
376 }
377
378 return $this;
379 }
380
381 // --------------------------------------------------------------------
382
383 /**
384 * Delete a session variable from the "userdata" array
385 *
386 * @access array
387 * @return void
388 */
389 public function unsetUserdata( $key )
390 {
391 static::start();
392 $parent_newdata = array();
393
394 if( ! in_array($key, $this->builtin_props) ){
395 $my_key = $this->getPrefix() . $key;
396 unset($_SESSION[$my_key]);
397 }
398 else {
399 $parent_newdata[ $key ] = $val;
400 }
401
402 if( $parent_newdata ){
403 foreach ($parent_newdata as $key => $val){
404 unset($this->userdata[$key]);
405 }
406 $this->sess_write();
407 }
408 return $this;
409 }
410
411 public function setFlashdata( $name, $value, $append = FALSE )
412 {
413 $newdata = array( $name => $value );
414
415 foreach( $newdata as $key => $val ){
416 $flashdata_key = $this->flashdata_key.':new:'.$key;
417 $this->setUserdata( $flashdata_key, $val, $append );
418 }
419
420 return $this;
421 }
422
423 function getFlashdata( $key )
424 {
425 $flashdata_key = $this->flashdata_key.':old:'.$key;
426 return $this->getUserdata($flashdata_key);
427 }
428
429 // ------------------------------------------------------------------------
430
431 /**
432 * Identifies flashdata as 'old' for removal
433 * when _flashdata_sweep() runs.
434 *
435 * @access private
436 * @return void
437 */
438 protected function _flashdata_mark()
439 {
440 $userdata = $this->all_userdata();
441 foreach ($userdata as $name => $value)
442 {
443 $parts = explode(':new:', $name);
444 if (is_array($parts) && count($parts) === 2)
445 {
446 $new_name = $this->flashdata_key.':old:'.$parts[1];
447 $this->setUserdata($new_name, $value);
448 $this->unsetUserdata($name);
449 }
450 }
451 }
452
453 // ------------------------------------------------------------------------
454
455 /**
456 * Removes all flashdata marked as 'old'
457 *
458 * @access private
459 * @return void
460 */
461
462 protected function _flashdata_sweep()
463 {
464 $userdata = $this->all_userdata();
465 foreach ($userdata as $key => $value){
466 if (strpos($key, ':old:')){
467 $this->unsetUserdata($key);
468 }
469 }
470 }
471
472 protected function _get_time()
473 {
474 if (strtolower($this->time_reference) == 'gmt'){
475 $now = time();
476 $time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));
477 }
478 else {
479 $time = time();
480 }
481
482 return $time;
483 }
484
485 // --------------------------------------------------------------------
486
487 /**
488 * Write the session cookie
489 *
490 * @access public
491 * @return void
492 */
493 function _set_cookie($cookie_data = NULL)
494 {
495 if (is_null($cookie_data)){
496 $cookie_data = $this->userdata;
497 }
498
499 // Serialize the userdata for the cookie
500 $cookie_data = $this->_serialize($cookie_data);
501
502 if( $this->encrypt ){
503 $cookie_data = $this->encrypt->encode($cookie_data);
504 }
505 else {
506 // if encryption is not used, we provide an md5 hash to prevent userside tampering
507 $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
508 }
509
510 $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
511 // Set the cookie
512 @setcookie(
513 $this->sess_cookie_name,
514 $cookie_data,
515 $expire,
516 $this->cookie_path,
517 $this->cookie_domain,
518 $this->cookie_secure
519 );
520 }
521
522 protected function _serialize($data)
523 {
524 if (is_array($data)){
525 foreach ($data as $key => $val){
526 if (is_string($val)){
527 $data[$key] = str_replace('\\', '{{slash}}', $val);
528 }
529 }
530 }
531 else {
532 if (is_string($data)){
533 $data = str_replace('\\', '{{slash}}', $data);
534 }
535 }
536 return serialize($data);
537 }
538
539 protected function _unserialize($data)
540 {
541 $data = @unserialize( $this->strip_slashes($data) );
542
543 if (is_array($data)){
544 foreach ($data as $key => $val){
545 if (is_string($val)){
546 $data[$key] = str_replace('{{slash}}', '\\', $val);
547 }
548 }
549 return $data;
550 }
551
552 return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data;
553 }
554
555 function strip_slashes($str)
556 {
557 if (is_array($str)){
558 foreach ($str as $key => $val){
559 $str[$key] = $this->strip_slashes($val);
560 }
561 }
562 else {
563 $str = stripslashes($str);
564 }
565 return $str;
566 }
567 }