[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/joomla/session/src/Handler/ -> DatabaseHandler.php (source)

   1  <?php
   2  /**
   3   * Part of the Joomla Framework Session Package
   4   *
   5   * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
   6   * @license    GNU General Public License version 2 or later; see LICENSE
   7   */
   8  
   9  namespace Joomla\Session\Handler;
  10  
  11  use Joomla\Database\DatabaseDriver;
  12  use Joomla\Database\DatabaseInterface;
  13  use Joomla\Database\Exception\ExecutionFailureException;
  14  use Joomla\Database\ParameterType;
  15  use Joomla\Session\Exception\CreateSessionTableException;
  16  use Joomla\Session\Exception\UnsupportedDatabaseDriverException;
  17  use Joomla\Session\HandlerInterface;
  18  
  19  /**
  20   * Database session storage handler
  21   *
  22   * @since  2.0.0
  23   */
  24  class DatabaseHandler implements HandlerInterface
  25  {
  26      /**
  27       * Database connector
  28       *
  29       * @var    DatabaseInterface
  30       * @since  2.0.0
  31       */
  32      private $db;
  33  
  34      /**
  35       * Flag whether gc() has been called
  36       *
  37       * @var    boolean
  38       * @since  2.0.0
  39       */
  40      private $gcCalled = false;
  41  
  42      /**
  43       * Lifetime for garbage collection
  44       *
  45       * @var    integer
  46       * @since  2.0.0
  47       */
  48      private $gcLifetime;
  49  
  50      /**
  51       * Constructor
  52       *
  53       * @param   DatabaseInterface  $db  Database connector
  54       *
  55       * @since   2.0.0
  56       */
  57  	public function __construct(DatabaseInterface $db)
  58      {
  59          $this->db = $db;
  60      }
  61  
  62      /**
  63       * Close the session
  64       *
  65       * @return  boolean  True on success, false otherwise
  66       *
  67       * @since   2.0.0
  68       */
  69      #[\ReturnTypeWillChange]
  70  	public function close()
  71      {
  72          if ($this->gcCalled)
  73          {
  74              $query = $this->db->getQuery(true)
  75                  ->delete($this->db->quoteName('#__session'))
  76                  ->where($this->db->quoteName('time') . ' < ?')
  77                  ->bind(1, $this->gcLifetime, ParameterType::INTEGER);
  78  
  79              // Remove expired sessions from the database.
  80              $this->db->setQuery($query)->execute();
  81  
  82              $this->gcCalled   = false;
  83              $this->gcLifetime = null;
  84          }
  85  
  86          $this->db->disconnect();
  87  
  88          return true;
  89      }
  90  
  91      /**
  92       * Creates the session database table
  93       *
  94       * @return  boolean
  95       *
  96       * @since   2.0.0
  97       * @throws  CreateSessionTableException
  98       * @throws  UnsupportedDatabaseDriverException
  99       */
 100  	public function createDatabaseTable(): bool
 101      {
 102          switch ($this->db->getName())
 103          {
 104              case 'mysql':
 105              case 'mysqli':
 106                  $filename = 'mysql.sql';
 107  
 108                  break;
 109  
 110              case 'postgresql':
 111                  $filename = 'pgsql.sql';
 112  
 113                  break;
 114  
 115              case 'sqlsrv':
 116              case 'sqlazure':
 117                  $filename = 'sqlsrv.sql';
 118  
 119                  break;
 120  
 121              case 'sqlite':
 122                  $filename = 'sqlite.sql';
 123  
 124                  break;
 125  
 126              default:
 127                  throw new UnsupportedDatabaseDriverException(sprintf('The %s database driver is not supported.', $this->db->getName()));
 128          }
 129  
 130          $path = \dirname(__DIR__, 2) . '/meta/sql/' . $filename;
 131  
 132          if (!is_readable($path))
 133          {
 134              throw new CreateSessionTableException(
 135                  sprintf('Database schema could not be read from %s. Please ensure the file exists and is readable.', $path)
 136              );
 137          }
 138  
 139          $queries = DatabaseDriver::splitSql(file_get_contents($path));
 140  
 141          foreach ($queries as $query)
 142          {
 143              $query = trim($query);
 144  
 145              if ($query !== '')
 146              {
 147                  try
 148                  {
 149                      $this->db->setQuery($query)->execute();
 150                  }
 151                  catch (ExecutionFailureException $exception)
 152                  {
 153                      throw new CreateSessionTableException('Failed to create the session table.', 0, $exception);
 154                  }
 155              }
 156          }
 157  
 158          return true;
 159      }
 160  
 161      /**
 162       * Destroy a session
 163       *
 164       * @param   integer  $session_id  The session ID being destroyed
 165       *
 166       * @return  boolean  True on success, false otherwise
 167       *
 168       * @since   2.0.0
 169       */
 170  	public function destroy($session_id): bool
 171      {
 172          try
 173          {
 174              $query = $this->db->getQuery(true)
 175                  ->delete($this->db->quoteName('#__session'))
 176                  ->where($this->db->quoteName('session_id') . ' = ' . $this->db->quote($session_id));
 177  
 178              // Remove a session from the database.
 179              $this->db->setQuery($query)->execute();
 180  
 181              return true;
 182          }
 183          catch (\Exception $e)
 184          {
 185              return false;
 186          }
 187      }
 188  
 189      /**
 190       * Cleanup old sessions
 191       *
 192       * @param   integer  $maxlifetime  Sessions that have not updated for the last maxlifetime seconds will be removed
 193       *
 194       * @return  boolean  True on success, false otherwise
 195       *
 196       * @since   2.0.0
 197       */
 198      #[\ReturnTypeWillChange]
 199      public function gc($maxlifetime)
 200      {
 201          // We'll delay garbage collection until the session is closed to prevent potential issues mid-cycle
 202          $this->gcLifetime = time() - $maxlifetime;
 203          $this->gcCalled   = true;
 204  
 205          return true;
 206      }
 207  
 208      /**
 209       * Test to see if the HandlerInterface is available
 210       *
 211       * @return  boolean  True on success, false otherwise
 212       *
 213       * @since   2.0.0
 214       */
 215  	public static function isSupported(): bool
 216      {
 217          return interface_exists(DatabaseInterface::class);
 218      }
 219  
 220      /**
 221       * Initialize session
 222       *
 223       * @param   string  $save_path   The path where to store/retrieve the session
 224       * @param   string  $session_id  The session id
 225       *
 226       * @return  boolean  True on success, false otherwise
 227       *
 228       * @since   2.0.0
 229       */
 230      #[\ReturnTypeWillChange]
 231  	public function open($save_path, $session_id)
 232      {
 233          $this->db->connect();
 234  
 235          return true;
 236      }
 237  
 238      /**
 239       * Read session data
 240       *
 241       * @param   string  $session_id  The session id to read data for
 242       *
 243       * @return  string  The session data
 244       *
 245       * @since   2.0.0
 246       */
 247      #[\ReturnTypeWillChange]
 248  	public function read($session_id)
 249      {
 250          try
 251          {
 252              // Get the session data from the database table.
 253              $query = $this->db->getQuery(true)
 254                  ->select($this->db->quoteName('data'))
 255                  ->from($this->db->quoteName('#__session'))
 256                  ->where($this->db->quoteName('session_id') . ' = ?')
 257                  ->bind(1, $session_id);
 258  
 259              $this->db->setQuery($query);
 260  
 261              return (string) $this->db->loadResult();
 262          }
 263          catch (\Exception $e)
 264          {
 265              return '';
 266          }
 267      }
 268  
 269      /**
 270       * Write session data
 271       *
 272       * @param   string  $session_id    The session id
 273       * @param   string  $session_data  The encoded session data
 274       *
 275       * @return  boolean  True on success, false otherwise
 276       *
 277       * @since   2.0.0
 278       */
 279      #[\ReturnTypeWillChange]
 280  	public function write($session_id, $session_data)
 281      {
 282          try
 283          {
 284              // Figure out if a row exists for the session ID
 285              $query = $this->db->getQuery(true)
 286                  ->select($this->db->quoteName('session_id'))
 287                  ->from($this->db->quoteName('#__session'))
 288                  ->where($this->db->quoteName('session_id') . ' = ?')
 289                  ->bind(1, $session_id);
 290  
 291              $idExists = $this->db->setQuery($query)->loadResult();
 292  
 293              $query = $this->db->getQuery(true);
 294  
 295              $time = time();
 296  
 297              if ($idExists)
 298              {
 299                  $query->update($this->db->quoteName('#__session'))
 300                      ->set($this->db->quoteName('data') . ' = ?')
 301                      ->set($this->db->quoteName('time') . ' = ?')
 302                      ->where($this->db->quoteName('session_id') . ' = ?')
 303                      ->bind(1, $session_data)
 304                      ->bind(2, $time, ParameterType::INTEGER)
 305                      ->bind(3, $session_id);
 306              }
 307              else
 308              {
 309                  $query->insert($this->db->quoteName('#__session'))
 310                      ->columns([$this->db->quoteName('data'), $this->db->quoteName('time'), $this->db->quoteName('session_id')])
 311                      ->values('?, ?, ?')
 312                      ->bind(1, $session_data)
 313                      ->bind(2, $time, ParameterType::INTEGER)
 314                      ->bind(3, $session_id);
 315              }
 316  
 317              // Try to insert the session data in the database table.
 318              $this->db->setQuery($query)->execute();
 319  
 320              return true;
 321          }
 322          catch (\Exception $e)
 323          {
 324              return false;
 325          }
 326      }
 327  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer