Fix a fatal bug in JSession and lay the groundwork for lazy sessions. #1236

Merged
merged 1 commit into from Jun 16, 2012
@@ -25,13 +25,13 @@ class JSession implements IteratorAggregate
{
/**
* Internal state.
- * One of 'active'|'expired'|'destroyed'|'error'
+ * One of 'inactive'|'active'|'expired'|'destroyed'|'error'
*
* @var string
* @see getState()
* @since 11.1
*/
- protected $_state = 'active';
+ protected $_state = 'inactive';
/**
* Maximum age of unused session in minutes
@@ -78,6 +78,14 @@ class JSession implements IteratorAggregate
protected static $instance;
/**
+ * Holds the JInput object
+ *
+ * @var JInput
+ * @since 12.2
+ */
+ private $_input = null;
+
+ /**
* Constructor
*
* @param string $store The type of storage for the session.
@@ -111,27 +119,8 @@ public function __construct($store = 'none', $options = array())
$this->_setCookieParams();
- // Load the session
- $this->_start();
-
- // Initialise the session
- $this->_setCounter();
- $this->_setTimers();
-
- $this->_state = 'active';
+ $this->_state = 'inactive';
- // Perform security checks
- $this->_validate();
- }
-
- /**
- * Session object destructor
- *
- * @since 11.1
- */
- public function __destruct()
- {
- $this->close();
}
/**
@@ -379,6 +368,18 @@ public static function getStores()
}
/**
+ * Shorthand to check if the session is active
+ *
+ * @return boolean
+ *
+ * @since 12.2
+ */
+ public function isActive()
+ {
+ return (bool) ($this->_state == 'active');
+ }
+
+ /**
* Check whether this session is currently created
*
* @return boolean True on success.
@@ -396,6 +397,20 @@ public function isNew()
}
/**
+ * Check whether this session is currently created
+ *
+ * @param JInput $input JInput object for the session to use.
+ *
+ * @return void.
+ *
+ * @since 12.2
+ */
+ public function initialise(JInput $input)
+ {
+ $this->input = $input;
+ }
@chdemko
chdemko Jun 6, 2012 Contributor

Why not returning $this for chaining ?

@realityking
realityking Jun 13, 2012 Member

Since the rest of JSession is not chainable (and not easily made so) wouldn't that cause more confusion that utility?

+
+ /**
* Get data from the session store
*
* @param string $name Name of a variable
@@ -517,6 +532,29 @@ public function clear($name, $namespace = 'default')
}
/**
+ * Start a session.
+ *
+ * @return boolean true on success
+ *
+ * @since 12.2
+ */
+ public function start()
+ {
+ $this->_start();
+
+ $this->_state = 'active';
+
+ // Initialise the session
+ $this->_setCounter();
+ $this->_setTimers();
+
+ // Perform security checks
+ $this->_validate();
+
+ return true;
@chdemko
chdemko Jun 6, 2012 Contributor

why not returning $this for chaining?

+ }
+
+ /**
* Start a session.
*
* Creates a session (or resumes the current one based on the state of the session)
@@ -536,15 +574,12 @@ protected function _start()
{
$session_name = session_name();
- // Get the JInput object
- $input = JFactory::getApplication()->input;
-
// Get the JInputCookie object
- $cookie = $input->cookie;
+ $cookie = $this->input->cookie;
if (is_null($cookie->get($session_name)))
{
- $session_clean = $input->get($session_name, false, 'string');
+ $session_clean = $this->input->get($session_name, false, 'string');
if ($session_clean)
{
@@ -555,9 +590,9 @@ protected function _start()
}
/**
- *Write and Close handlers are called after destructing objects since PHP 5.0.5.
- *Thus destructors can use sessions but session handler can't use objects.
- *So we are moving session closure before destructing objects.
+ * Write and Close handlers are called after destructing objects since PHP 5.0.5.
+ * Thus destructors can use sessions but session handler can't use objects.
+ * So we are moving session closure before destructing objects.
*/
register_shutdown_function('session_write_close');
@@ -754,7 +789,7 @@ protected function _setCookieParams()
{
$cookie['path'] = $config->get('cookie_path');
}
- session_set_cookie_params($cookie['lifetime'], $cookie['path'], $cookie['domain'], $cookie['secure']);
+ session_set_cookie_params($cookie['lifetime'], $cookie['path'], $cookie['domain'], $cookie['secure'], true);
}
/**
@@ -958,6 +958,8 @@ protected function _createSession($name)
}
$session = JFactory::getSession($options);
+ $session->initialise($this->input);
@chdemko
chdemko Jun 6, 2012 Contributor

if chaining is done this could be replaced by

$session->initialise($this->input)->start();
+ $session->start();
// TODO: At some point we need to get away from having session data always in the db.