10 defined(
'JPATH_PLATFORM') or die;
34 protected $_state =
'inactive';
42 protected $_expire = 15;
50 protected $_store = null;
63 protected $_security = array(
'fix_browser');
72 protected $_force_ssl =
false;
96 private $_input = null;
104 private $_dispatcher = null;
114 public function __construct($store =
'none', array $options = array())
124 ini_set(
'session.use_trans_sid',
'0');
127 ini_set(
'session.use_only_cookies',
'1');
132 $this->storeName = $store;
135 $this->_setOptions($options);
137 $this->_setCookieParams();
139 $this->_state =
'inactive';
151 public function __get($name)
153 if ($name ===
'storeName')
158 if ($name ===
'state' || $name ===
'expire')
160 $property =
'_' . $name;
161 return $this->$property;
176 public static function getInstance($handler, $options)
178 if (!is_object(self::$instance))
180 self::$instance =
new JSession($handler, $options);
183 return self::$instance;
193 public function getState()
195 return $this->_state;
205 public function getExpire()
207 return $this->_expire;
223 public function getToken($forceNew =
false)
225 $token = $this->
get(
'session.token');
228 if ($token === null || $forceNew)
230 $token = $this->_createToken(12);
231 $this->
set(
'session.token', $token);
248 public function hasToken($tCheck, $forceExpire =
true)
251 $tStored = $this->
get(
'session.token');
254 if (($tStored !== $tCheck))
258 $this->_state =
'expired';
275 public static function getFormToken($forceNew =
false)
281 if (is_callable(array(
'JApplication',
'getHash')))
300 public function getIterator()
302 return new ArrayIterator($_SESSION);
316 public static function checkToken($method =
'post')
318 $token = self::getFormToken();
321 if (!$app->input->$method->get($token,
'',
'alnum'))
324 if ($session->isNew())
327 $app->enqueueMessage(
JText::_(
'JLIB_ENVIRONMENT_SESSION_EXPIRED'),
'warning');
348 public function getName()
350 if ($this->_state ===
'destroyed')
355 return session_name();
365 public function getId()
367 if ($this->_state ===
'destroyed')
382 public static function getStores()
384 $connectors = array();
387 $iterator =
new DirectoryIterator(__DIR__ .
'/storage');
389 foreach ($iterator as $file)
391 $fileName = $file->getFilename();
395 if (!$file->isFile() || substr($fileName, strrpos($fileName,
'.') + 1) !=
'php')
401 $class = str_ireplace(
'.php',
'',
'JSessionStorage' . ucfirst(trim($fileName)));
404 if (!class_exists($class))
410 if ($class::isSupported())
413 $connectors[] = str_ireplace(
'.php',
'', $fileName);
427 public function isActive()
429 return (
bool) ($this->_state ==
'active');
439 public function isNew()
441 $counter = $this->
get(
'session.counter');
442 return (
bool) ($counter === 1);
457 $this->_input = $input;
458 $this->_dispatcher = $dispatcher;
472 public function get($name, $default = null, $namespace =
'default')
475 $namespace =
'__' . $namespace;
477 if ($this->_state !==
'active' && $this->_state !==
'expired')
484 if (isset($_SESSION[$namespace][$name]))
486 return $_SESSION[$namespace][$name];
502 public function set($name, $value = null, $namespace =
'default')
505 $namespace =
'__' . $namespace;
507 if ($this->_state !==
'active')
513 $old = isset($_SESSION[$namespace][$name]) ? $_SESSION[$namespace][$name] : null;
517 unset($_SESSION[$namespace][$name]);
521 $_SESSION[$namespace][$name] = $value;
537 public function has($name, $namespace =
'default')
540 $namespace =
'__' . $namespace;
542 if ($this->_state !==
'active')
548 return isset($_SESSION[$namespace][$name]);
561 public function clear($name, $namespace =
'default')
564 $namespace =
'__' . $namespace;
566 if ($this->_state !==
'active')
573 if (isset($_SESSION[$namespace][$name]))
575 $value = $_SESSION[$namespace][$name];
576 unset($_SESSION[$namespace][$name]);
589 public function start()
591 if ($this->_state ===
'active')
598 $this->_state =
'active';
601 $this->_setCounter();
609 $this->_dispatcher->trigger(
'onAfterSessionStart');
622 protected function _start()
625 if ($this->_state ===
'restart')
627 session_regenerate_id(
true);
631 $session_name = session_name();
634 $cookie = $this->_input->cookie;
636 if (is_null($cookie->get($session_name)))
638 $session_clean = $this->_input->get($session_name,
false,
'string');
642 session_id($session_clean);
643 $cookie->set($session_name,
'', time() - 3600);
655 register_shutdown_function(
'session_write_close');
657 session_cache_limiter(
'none');
676 public function destroy()
679 if ($this->_state ===
'destroyed')
689 if (isset($_COOKIE[session_name()]))
692 $cookie_domain = $config->get(
'cookie_domain',
'');
693 $cookie_path = $config->get(
'cookie_path',
'/');
694 setcookie(session_name(),
'', time() - 42000, $cookie_path, $cookie_domain);
700 $this->_state =
'destroyed';
712 public function restart()
715 if ($this->_state !==
'destroyed')
722 $this->_store->register();
724 $this->_state =
'restart';
727 session_regenerate_id(
true);
729 $this->_state =
'active';
732 $this->_setCounter();
744 public function fork()
746 if ($this->_state !==
'active')
753 $cookie = session_get_cookie_params();
759 $this->_store->register();
762 session_set_cookie_params($cookie[
'lifetime'], $cookie[
'path'], $cookie[
'domain'], $cookie[
'secure'],
true);
765 session_regenerate_id(
true);
787 public function close()
789 session_write_close();
799 protected function _setCookieParams()
801 $cookie = session_get_cookie_params();
802 if ($this->_force_ssl)
804 $cookie[
'secure'] =
true;
809 if ($config->get(
'cookie_domain',
'') !=
'')
811 $cookie[
'domain'] = $config->get(
'cookie_domain');
814 if ($config->get(
'cookie_path',
'') !=
'')
816 $cookie[
'path'] = $config->get(
'cookie_path');
818 session_set_cookie_params($cookie[
'lifetime'], $cookie[
'path'], $cookie[
'domain'], $cookie[
'secure'],
true);
830 protected function _createToken($length = 32)
832 static $chars =
'0123456789abcdef';
833 $max = strlen($chars) - 1;
835 $name = session_name();
836 for ($i = 0; $i < $length; ++$i)
838 $token .= $chars[(rand(0, $max))];
841 return md5($token . $name);
851 protected function _setCounter()
853 $counter = $this->
get(
'session.counter', 0);
856 $this->
set(
'session.counter', $counter);
867 protected function _setTimers()
869 if (!$this->has(
'session.timer.start'))
873 $this->
set(
'session.timer.start', $start);
874 $this->
set(
'session.timer.last', $start);
875 $this->
set(
'session.timer.now', $start);
878 $this->
set(
'session.timer.last', $this->
get(
'session.timer.now'));
879 $this->
set(
'session.timer.now', time());
893 protected function _setOptions(array $options)
896 if (isset($options[
'name']))
898 session_name(md5($options[
'name']));
902 if (isset($options[
'id']))
904 session_id($options[
'id']);
908 if (isset($options[
'expire']))
910 $this->_expire = $options[
'expire'];
914 if (isset($options[
'security']))
916 $this->_security = explode(
',', $options[
'security']);
919 if (isset($options[
'force_ssl']))
921 $this->_force_ssl = (bool) $options[
'force_ssl'];
925 ini_set(
'session.gc_maxlifetime', $this->_expire);
946 protected function _validate($restart =
false)
951 $this->_state =
'active';
953 $this->
set(
'session.client.address', null);
954 $this->
set(
'session.client.forwarded', null);
955 $this->
set(
'session.client.browser', null);
956 $this->
set(
'session.token', null);
962 $curTime = $this->
get(
'session.timer.now', 0);
963 $maxTime = $this->
get(
'session.timer.last', 0) + $this->_expire;
966 if ($maxTime < $curTime)
968 $this->_state =
'expired';
974 if (isset($_SERVER[
'HTTP_X_FORWARDED_FOR']))
976 $this->
set(
'session.client.forwarded', $_SERVER[
'HTTP_X_FORWARDED_FOR']);
980 if (in_array(
'fix_adress', $this->_security) && isset($_SERVER[
'REMOTE_ADDR']))
982 $ip = $this->
get(
'session.client.address');
986 $this->
set(
'session.client.address', $_SERVER[
'REMOTE_ADDR']);
988 elseif ($_SERVER[
'REMOTE_ADDR'] !== $ip)
990 $this->_state =
'error';
996 if (in_array(
'fix_browser', $this->_security) && isset($_SERVER[
'HTTP_USER_AGENT']))
998 $browser = $this->
get(
'session.client.browser');
1000 if ($browser === null)
1002 $this->
set(
'session.client.browser', $_SERVER[
'HTTP_USER_AGENT']);
1004 elseif ($_SERVER[
'HTTP_USER_AGENT'] !== $browser)