[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |