Skip to content

Commit

Permalink
Revert "Session interaction refactoring"
Browse files Browse the repository at this point in the history
  • Loading branch information
rdeutz committed Sep 21, 2016
1 parent c0afccb commit 27eda0e
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 315 deletions.
34 changes: 15 additions & 19 deletions installation/application/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,6 @@ public function __construct()
JUri::root(null, implode('/', $parts));
}

/**
* Event listener for the `onAfterSessionStart` event.
*
* @param JSession $session Session object
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function afterSessionStart(JSession $session)
{
if ($session->isNew())
{
$session->set('registry', new Registry('session'));
}
}

/**
* Method to display errors in language parsing.
*
Expand Down Expand Up @@ -535,12 +518,25 @@ public function loadSession(JSession $session = null)
'force_ssl' => $this->get('force_ssl'),
);

$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));

// Instantiate the session object.
$session = JSession::getInstance($handler, $options);
$session->initialise($this->input, $this->dispatcher);

if ($session->getState() == 'expired')
{
$session->restart();
}
else
{
$session->start();
}

if (!$session->get('registry') instanceof Registry)
{
// Registry has been corrupted somehow.
$session->set('registry', new Registry('session'));
}

// Set the session object.
$this->session = $session;

Expand Down
159 changes: 48 additions & 111 deletions libraries/cms/application/cms.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,33 +133,20 @@ public function __construct(JInput $input = null, Registry $config = null, JAppl
}

/**
* Event listener for the `onAfterSessionStart` event.
*
* @param JSession $session Session object
* After the session has been started we need to populate it with some default values.
*
* @return void
*
* @since 3.2
*/
public function afterSessionStart(JSession $session)
public function afterSessionStart()
{
parent::afterSessionStart($session);

// If not using the database store, register the cleanup function to run at the end of the application cycle
if ($session->storeName != 'database')
{
$this->registerEvent('onAfterRender', array($this, 'cleanupSessionMetadata'));
}
$session = JFactory::getSession();

/*
* Check for extra session metadata when:
*
* 1) The database handler is in use and the session is new
* 2) The database handler is not in use and the time is an even numbered second or the session is new
*/
if (($session->storeName != 'database' && (time() % 2 || $session->isNew())) || ($session->storeName == 'database' && $session->isNew()))
if ($session->isNew())
{
$this->checkSession($session);
$session->set('registry', new Registry('session'));
$session->set('user', new JUser);
}
}

Expand All @@ -169,64 +156,37 @@ public function afterSessionStart(JSession $session)
* If the session record doesn't exist, initialise it.
* If session is new, create session variables
*
* @param JSession $session The session to check.
*
* @return void
*
* @since 3.2
* @throws RuntimeException
*/
public function checkSession(JSession $session = null)
public function checkSession()
{
/*
* Prior to __DEPLOY_VERSION__ this method had no parameters; for B/C pull the session from JFactory.
* @deprecated 4.0 The $session parameter will be required
*/
if ($session === null)
{
JLog::add(
sprintf(
'As of __DEPLOY_VERSION__, %s() accepts an optional JSession instance as a parameter and this will be required as of 4.0',
__METHOD__
),
JLog::WARNING,
'deprecated'
);

$session = JFactory::getSession();
}

$db = JFactory::getDbo();
$db = JFactory::getDbo();
$session = JFactory::getSession();
$user = JFactory::getUser();

$query = $db->getQuery(true)
->select($db->quoteName('session_id'))
->from($db->quoteName('#__session'))
->where($db->quoteName('session_id') . ' = ' . $db->quote($session->getId()));

try
{
$exists = $db->setQuery($query, 0, 1)->loadResult();
}
catch (JDatabaseExceptionExecuting $e)
{
throw new RuntimeException(JText::_('JERROR_SESSION_STARTUP'), $e->getCode(), $e);
}
$db->setQuery($query, 0, 1);
$exists = $db->loadResult();

// If the session record doesn't exist initialise it.
if (!$exists)
{
$query->clear();

// Get the session handler from the configuration.
$handler = $session->storeName;

$time = $session->isNew() ? time() : $session->get('session.timer.start');

$columns = array(
$db->quoteName('session_id'),
$db->quoteName('client_id'),
$db->quoteName('guest'),
$db->quoteName('time'),
$db->quoteName('userid'),
$db->quoteName('username'),
);
Expand All @@ -235,71 +195,29 @@ public function checkSession(JSession $session = null)
$db->quote($session->getId()),
(int) $this->getClientId(),
(int) $user->guest,
$db->quote((int) $time),
(int) $user->id,
$db->quote($user->username),
);

// If the database session handler is not in use, append the time to the row
if ($handler != 'database')
{
$columns[] = $db->quoteName('time');
$values[] = $db->quote((int) time());
}
$query->insert($db->quoteName('#__session'))
->columns($columns)
->values(implode(', ', $values));

$db->setQuery($query);

// If the insert failed, exit the application.
try
{
$db->setQuery(
$db->getQuery(true)
->insert($db->quoteName('#__session'))
->columns($columns)
->values(implode(', ', $values))
)->execute();
$db->execute();
}
catch (JDatabaseExceptionExecuting $e)
catch (RuntimeException $e)
{
throw new RuntimeException(JText::_('JERROR_SESSION_STARTUP'), $e->getCode(), $e);
}
}
}

/**
* Cleanup the session metadata
*
* This method is registered as an event listener for the `onAfterRender` system event and acts as a garbage handler
* for the extra session metadata when a non-database session store is used.
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function cleanupSessionMetadata()
{
$time = time();

// The modulus introduces a little entropy, making the flushing less accurate but fires the query less than half the time.
if ($time % 2)
{
$db = JFactory::getDbo();

$query = $db->getQuery(true)
->delete($db->quoteName('#__session'))
->where($db->quoteName('time') . ' < ' . $db->quote((int) $time));

try
{
$db->setQuery($query)->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
/*
* The database API logs errors on failures so we don't need to add any error handling mechanisms here.
* Since garbage collection does not result in a fatal error when run in the session API, we don't allow it here either.
*/
}
}
}

/**
* Enqueue a system message.
*
Expand Down Expand Up @@ -802,12 +720,8 @@ public function loadSession(JSession $session = null)
{
if ($session !== null)
{
// Set the session object.
$this->session = $session;

// Register the session with JFactory.
JFactory::$session = $session;

return $this;
}

Expand Down Expand Up @@ -844,18 +758,41 @@ public function loadSession(JSession $session = null)

$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));

// There's an internal coupling to the session object being present in JFactory, need to deal with this at some point
$session = JFactory::getSession($options);
$session->initialise($this->input, $this->dispatcher);
$session->start();

// TODO: At some point we need to get away from having session data always in the db.
$db = JFactory::getDbo();

// Remove expired sessions from the database.
$time = time();

if ($time % 2)
{
// The modulus introduces a little entropy, making the flushing less accurate
// but fires the query less than half the time.
$query = $db->getQuery(true)
->delete($db->quoteName('#__session'))
->where($db->quoteName('time') . ' < ' . $db->quote((int) ($time - $session->getExpire())));

$db->setQuery($query);
$db->execute();
}

// Get the session handler from the configuration.
$handler = $this->get('session_handler', 'none');

$session = JSession::getInstance($handler, $options, new JSessionHandlerJoomla($options));
$session->initialise($this->input, $this->dispatcher);
if (($handler != 'database' && ($time % 2 || $session->isNew()))
|| ($handler == 'database' && $session->isNew()))
{
$this->checkSession();
}

// Set the session object.
$this->session = $session;

// Register the session with JFactory.
JFactory::$session = $session;

return $this;
}

Expand Down
6 changes: 3 additions & 3 deletions libraries/joomla/application/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -1061,14 +1061,14 @@ public function loadSession(JSession $session = null)
/**
* After the session has been started we need to populate it with some default values.
*
* @param JSession $session Session object
*
* @return void
*
* @since 12.2
*/
public function afterSessionStart(JSession $session)
public function afterSessionStart()
{
$session = JFactory::getSession();

if ($session->isNew())
{
$session->set('registry', new Registry('session'));
Expand Down

0 comments on commit 27eda0e

Please sign in to comment.