/libraries/src/Session/Storage/JoomlaStorage.php
https://github.com/Hackwar/joomla-cms · PHP · 313 lines · 137 code · 44 blank · 132 comment · 19 complexity · d0e0a3b2215f6bb899409252ac12e9ec MD5 · raw file
- <?php
- /**
- * Joomla! Content Management System
- *
- * @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
- * @license GNU General Public License version 2 or later; see LICENSE
- */
- namespace Joomla\CMS\Session\Storage;
- \defined('JPATH_PLATFORM') or die;
- use Joomla\CMS\Factory;
- use Joomla\Input\Input;
- use Joomla\Registry\Registry;
- use Joomla\Session\Storage\NativeStorage;
- /**
- * Service provider for the application's session dependency
- *
- * @since 4.0.0
- */
- class JoomlaStorage extends NativeStorage
- {
- /**
- * Internal data store for the session data
- *
- * @var Registry
- * @since 4.0.0
- */
- private $data;
- /**
- * Force cookies to be SSL only
- *
- * @var boolean
- * @since 4.0.0
- */
- private $forceSSL = false;
- /**
- * Input object
- *
- * @var Input
- * @since 4.0.0
- */
- private $input;
- /**
- * Constructor
- *
- * @param Input $input Input object
- * @param \SessionHandlerInterface $handler Session save handler
- * @param array $options Session options
- *
- * @since 4.0.0
- */
- public function __construct(Input $input, \SessionHandlerInterface $handler = null, array $options = [])
- {
- // Disable transparent sid support and default use cookies
- $options += [
- 'use_cookies' => 1,
- 'use_trans_sid' => 0,
- ];
- if (!headers_sent() && !$this->isActive())
- {
- session_cache_limiter('none');
- }
- $this->setOptions($options);
- $this->setHandler($handler);
- $this->setCookieParams();
- $this->data = new Registry;
- $this->input = $input;
- // Register our function as shutdown method, so we can manipulate it
- register_shutdown_function([$this, 'close']);
- }
- /**
- * Retrieves all variables from the session store
- *
- * @return array
- *
- * @since 4.0.0
- */
- public function all(): array
- {
- return $this->data->toArray();
- }
- /**
- * Clears all variables from the session store
- *
- * @return void
- *
- * @since 4.0.0
- */
- public function clear(): void
- {
- $session_name = $this->getName();
- /*
- * In order to kill the session altogether, such as to log the user out, the session id
- * must also be unset. If a cookie is used to propagate the session id (default behavior),
- * then the session cookie must be deleted.
- */
- if (isset($_COOKIE[$session_name]))
- {
- $app = Factory::getApplication();
- $cookie_domain = $app->get('cookie_domain', '');
- $cookie_path = $app->get('cookie_path', '/');
- $cookie = session_get_cookie_params();
- setcookie($session_name, '', time() - 42000, $cookie_path, $cookie_domain, $cookie['secure'], true);
- }
- $this->data = new Registry;
- }
- /**
- * Writes session data and ends session
- *
- * @return void
- *
- * @see session_write_close()
- * @since 4.0.0
- */
- public function close(): void
- {
- // Before storing data to the session, we serialize and encode the Registry
- $_SESSION['joomla'] = base64_encode(serialize(clone $this->data));
- parent::close();
- }
- /**
- * Get data from the session store
- *
- * @param string $name Name of a variable
- * @param mixed $default Default value of a variable if not set
- *
- * @return mixed Value of a variable
- *
- * @since 4.0.0
- */
- public function get(string $name, $default)
- {
- if (!$this->isStarted())
- {
- $this->start();
- }
- return $this->data->get($name, $default);
- }
- /**
- * Check whether data exists in the session store
- *
- * @param string $name Name of variable
- *
- * @return boolean True if the variable exists
- *
- * @since 4.0.0
- */
- public function has(string $name): bool
- {
- if (!$this->isStarted())
- {
- $this->start();
- }
- return $this->data->exists($name);
- }
- /**
- * Unset a variable from the session store
- *
- * @param string $name Name of variable
- *
- * @return mixed The value from session or NULL if not set
- *
- * @since 4.0.0
- */
- public function remove(string $name)
- {
- if (!$this->isStarted())
- {
- $this->start();
- }
- $old = $this->data->get($name);
- unset($this->data[$name]);
- return $old;
- }
- /**
- * Set data into the session store
- *
- * @param string $name Name of a variable.
- * @param mixed $value Value of a variable.
- *
- * @return mixed Old value of a variable.
- *
- * @since 4.0.0
- */
- public function set(string $name, $value = null)
- {
- if (!$this->isStarted())
- {
- $this->start();
- }
- $old = $this->data->get($name);
- $this->data->set($name, $value);
- return $old;
- }
- /**
- * Set session cookie parameters
- *
- * @return void
- *
- * @since 4.0.0
- */
- protected function setCookieParams(): void
- {
- if (headers_sent() || $this->isActive())
- {
- return;
- }
- $cookie = session_get_cookie_params();
- if ($this->forceSSL)
- {
- $cookie['secure'] = true;
- }
- $app = Factory::getApplication();
- if ($app->get('cookie_domain', '') != '')
- {
- $cookie['domain'] = $app->get('cookie_domain');
- }
- if ($app->get('cookie_path', '') != '')
- {
- $cookie['path'] = $app->get('cookie_path');
- }
- session_set_cookie_params($cookie['lifetime'], $cookie['path'], $cookie['domain'], $cookie['secure'], true);
- }
- /**
- * Sets session options
- *
- * @param array $options Session ini directives array(key => value).
- *
- * @return $this
- *
- * @see http://php.net/session.configuration
- * @since 4.0.0
- */
- public function setOptions(array $options): NativeStorage
- {
- if (isset($options['force_ssl']))
- {
- $this->forceSSL = (bool) $options['force_ssl'];
- }
- return parent::setOptions($options);
- }
- /**
- * Start a session
- *
- * @return void
- *
- * @since 4.0.0
- */
- public function start(): void
- {
- $session_name = $this->getName();
- // Get the cookie object
- $cookie = $this->input->cookie;
- if (\is_null($cookie->get($session_name)))
- {
- $session_clean = $this->input->getString($session_name);
- if ($session_clean)
- {
- $this->setId($session_clean);
- $cookie->set($session_name, '', time() - 3600);
- }
- }
- parent::start();
- // Try loading data from the session
- if (isset($_SESSION['joomla']) && !empty($_SESSION['joomla']))
- {
- $this->data = unserialize(base64_decode($_SESSION['joomla']));
- }
- }
- }