‪TYPO3CMS  11.5
DatabaseSessionBackend.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\Exception as DBALException;
23 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
28 
36 {
40  protected ‪$configuration = [];
41 
45  protected ‪$hasAnonymousSessions = false;
46 
54  public function ‪initialize(string $identifier, array ‪$configuration)
55  {
56  $this->hasAnonymousSessions = (bool)(‪$configuration['has_anonymous'] ?? false);
57  $this->configuration = ‪$configuration;
58  }
59 
67  public function ‪validateConfiguration(): bool
68  {
69  if (empty($this->configuration['table'])) {
70  throw new \InvalidArgumentException(
71  'The session backend "' . static::class . '" needs a "table" configuration.',
72  1442996707
73  );
74  }
75  return true;
76  }
77 
78  public function ‪hash(string $sessionId): string
79  {
80  // The sha1 hash ensures we have good length for the key.
81  $key = sha1(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . 'core-session-backend');
82  return hash_hmac('sha256', $sessionId, $key);
83  }
84 
92  public function get(string $sessionId): array
93  {
94  $query = $this->‪getQueryBuilder();
95  $query->select('*')
96  ->from($this->configuration['table'])
97  ->where($query->expr()->eq('ses_id', $query->createNamedParameter($this->hash($sessionId), ‪Connection::PARAM_STR)));
98  $result = $query->executeQuery()->fetchAssociative();
99  if (!is_array($result)) {
100  throw new ‪SessionNotFoundException(
101  'The session with identifier ' . $sessionId . ' was not found ',
102  1481885483
103  );
104  }
105  return $result;
106  }
107 
114  public function remove(string $sessionId): bool
115  {
116  $query = $this->‪getQueryBuilder();
117  $query->delete($this->configuration['table'])
118  ->where(
119  $query->expr()->orX(
120  $query->expr()->eq('ses_id', $query->createNamedParameter($this->hash($sessionId), ‪Connection::PARAM_STR)),
121  $query->expr()->eq('ses_id', $query->createNamedParameter($sessionId, ‪Connection::PARAM_STR))
122  )
123  );
124 
125  return (bool)$query->executeStatement();
126  }
127 
138  public function set(string $sessionId, array $sessionData): array
139  {
140  $sessionId = $this->‪hash($sessionId);
141  $sessionData['ses_id'] = $sessionId;
142  $sessionData['ses_tstamp'] = ‪$GLOBALS['EXEC_TIME'] ?? time();
143 
144  try {
145  $this->‪getConnection()->‪insert(
146  $this->configuration['table'],
147  $sessionData,
148  ['ses_data' => ‪Connection::PARAM_LOB]
149  );
150  } catch (DBALException $e) {
151  throw new SessionNotCreatedException(
152  'Session could not be written to database: ' . $e->getMessage(),
153  1481895005,
154  $e
155  );
156  }
157 
158  return $sessionData;
159  }
160 
171  public function ‪update(string $sessionId, array $sessionData): array
172  {
173  $hashedSessionId = $this->‪hash($sessionId);
174  $sessionData['ses_id'] = $hashedSessionId;
175  $sessionData['ses_tstamp'] = ‪$GLOBALS['EXEC_TIME'] ?? time();
176 
177  try {
178  // allow 0 records to be affected, happens when no columns where changed
179  $this->‪getConnection()->‪update(
180  $this->configuration['table'],
181  $sessionData,
182  ['ses_id' => $hashedSessionId],
183  ['ses_data' => ‪Connection::PARAM_LOB]
184  );
185  } catch (DBALException $e) {
186  throw new SessionNotUpdatedException(
187  'Session with id ' . $sessionId . ' could not be updated: ' . $e->getMessage(),
188  1481889220,
189  $e
190  );
191  }
192  return $sessionData;
193  }
194 
201  public function ‪collectGarbage(int $maximumLifetime, int $maximumAnonymousLifetime = 0)
202  {
203  $query = $this->‪getQueryBuilder();
204 
205  $query->delete($this->configuration['table'])
206  ->where($query->expr()->lt('ses_tstamp', (int)(‪$GLOBALS['EXEC_TIME'] - (int)$maximumLifetime)))
207  ->andWhere($this->hasAnonymousSessions ? $query->expr()->neq('ses_userid', 0) : ' 1 = 1');
208  $query->executeStatement();
209 
210  if ($maximumAnonymousLifetime > 0 && $this->hasAnonymousSessions) {
211  $query = $this->‪getQueryBuilder();
212  $query->delete($this->configuration['table'])
213  ->where($query->expr()->lt('ses_tstamp', (int)(‪$GLOBALS['EXEC_TIME'] - (int)$maximumAnonymousLifetime)))
214  ->andWhere($query->expr()->eq('ses_userid', 0));
215  $query->executeStatement();
216  }
217  }
218 
224  public function ‪getAll(): array
225  {
226  $query = $this->‪getQueryBuilder();
227  $query->select('*')->from($this->configuration['table']);
228  return $query->executeQuery()->fetchAllAssociative();
229  }
230 
234  protected function ‪getQueryBuilder(): QueryBuilder
235  {
236  return $this->‪getConnection()->‪createQueryBuilder();
237  }
238 
242  protected function ‪getConnection(): Connection
243  {
244  return GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->configuration['table']);
245  }
246 }
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\$configuration
‪array $configuration
Definition: DatabaseSessionBackend.php:39
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\validateConfiguration
‪bool validateConfiguration()
Definition: DatabaseSessionBackend.php:65
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\$hasAnonymousSessions
‪bool $hasAnonymousSessions
Definition: DatabaseSessionBackend.php:43
‪TYPO3\CMS\Core\Database\Connection\insert
‪int insert($tableName, array $data, array $types=[])
Definition: Connection.php:211
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\initialize
‪initialize(string $identifier, array $configuration)
Definition: DatabaseSessionBackend.php:52
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\getAll
‪array getAll()
Definition: DatabaseSessionBackend.php:222
‪TYPO3\CMS\Core\Session\Backend\HashableSessionBackendInterface
Definition: HashableSessionBackendInterface.php:21
‪TYPO3\CMS\Core\Session\Backend\Exception\SessionNotCreatedException
Definition: SessionNotCreatedException.php:23
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR
‪const PARAM_STR
Definition: Connection.php:54
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\update
‪array update(string $sessionId, array $sessionData)
Definition: DatabaseSessionBackend.php:169
‪TYPO3\CMS\Core\Database\Connection\update
‪int update($tableName, array $data, array $identifier, array $types=[])
Definition: Connection.php:302
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\getQueryBuilder
‪QueryBuilder getQueryBuilder()
Definition: DatabaseSessionBackend.php:232
‪TYPO3\CMS\Core\Session\Backend\SessionBackendInterface
Definition: SessionBackendInterface.php:28
‪TYPO3\CMS\Core\Session\Backend\Exception\SessionNotUpdatedException
Definition: SessionNotUpdatedException.php:23
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\hash
‪hash(string $sessionId)
Definition: DatabaseSessionBackend.php:76
‪TYPO3\CMS\Core\Session\Backend
Definition: DatabaseSessionBackend.php:18
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\getConnection
‪Connection getConnection()
Definition: DatabaseSessionBackend.php:240
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend
Definition: DatabaseSessionBackend.php:36
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend\collectGarbage
‪collectGarbage(int $maximumLifetime, int $maximumAnonymousLifetime=0)
Definition: DatabaseSessionBackend.php:199
‪TYPO3\CMS\Core\Database\Connection\createQueryBuilder
‪TYPO3 CMS Core Database Query QueryBuilder createQueryBuilder()
Definition: Connection.php:117
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Session\Backend\Exception\SessionNotFoundException
Definition: SessionNotFoundException.php:23
‪TYPO3\CMS\Core\Database\Connection\PARAM_LOB
‪const PARAM_LOB
Definition: Connection.php:59