DatabaseSession.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. /**
  3. * Database Session save handler. Allows saving session information into a model.
  4. *
  5. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  6. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice.
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  13. * @link https://cakephp.org CakePHP(tm) Project
  14. * @since 2.0.0
  15. * @license https://opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Network\Session;
  18. use Cake\ORM\Entity;
  19. use Cake\ORM\TableRegistry;
  20. use SessionHandlerInterface;
  21. /**
  22. * DatabaseSession provides methods to be used with Session.
  23. */
  24. class DatabaseSession implements SessionHandlerInterface
  25. {
  26. /**
  27. * Reference to the table handling the session data
  28. *
  29. * @var \Cake\ORM\Table
  30. */
  31. protected $_table;
  32. /**
  33. * Number of seconds to mark the session as expired
  34. *
  35. * @var int
  36. */
  37. protected $_timeout;
  38. /**
  39. * Constructor. Looks at Session configuration information and
  40. * sets up the session model.
  41. *
  42. * @param array $config The configuration for this engine. It requires the 'model'
  43. * key to be present corresponding to the Table to use for managing the sessions.
  44. */
  45. public function __construct(array $config = [])
  46. {
  47. $tableLocator = isset($config['tableLocator']) ? $config['tableLocator'] : TableRegistry::getTableLocator();
  48. if (empty($config['model'])) {
  49. $config = $tableLocator->exists('Sessions') ? [] : ['table' => 'sessions'];
  50. $this->_table = $tableLocator->get('Sessions', $config);
  51. } else {
  52. $this->_table = $tableLocator->get($config['model']);
  53. }
  54. $this->_timeout = ini_get('session.gc_maxlifetime');
  55. }
  56. /**
  57. * Set the timeout value for sessions.
  58. *
  59. * Primarily used in testing.
  60. *
  61. * @param int $timeout The timeout duration.
  62. * @return $this
  63. */
  64. public function setTimeout($timeout)
  65. {
  66. $this->_timeout = $timeout;
  67. return $this;
  68. }
  69. /**
  70. * Method called on open of a database session.
  71. *
  72. * @param string $savePath The path where to store/retrieve the session.
  73. * @param string $name The session name.
  74. * @return bool Success
  75. */
  76. public function open($savePath, $name)
  77. {
  78. return true;
  79. }
  80. /**
  81. * Method called on close of a database session.
  82. *
  83. * @return bool Success
  84. */
  85. public function close()
  86. {
  87. return true;
  88. }
  89. /**
  90. * Method used to read from a database session.
  91. *
  92. * @param string|int $id ID that uniquely identifies session in database.
  93. * @return string Session data or empty string if it does not exist.
  94. */
  95. public function read($id)
  96. {
  97. $result = $this->_table
  98. ->find('all')
  99. ->select(['data'])
  100. ->where([$this->_table->getPrimaryKey() => $id])
  101. ->enableHydration(false)
  102. ->first();
  103. if (empty($result)) {
  104. return '';
  105. }
  106. if (is_string($result['data'])) {
  107. return $result['data'];
  108. }
  109. $session = stream_get_contents($result['data']);
  110. if ($session === false) {
  111. return '';
  112. }
  113. return $session;
  114. }
  115. /**
  116. * Helper function called on write for database sessions.
  117. *
  118. * @param string|int $id ID that uniquely identifies session in database.
  119. * @param mixed $data The data to be saved.
  120. * @return bool True for successful write, false otherwise.
  121. */
  122. public function write($id, $data)
  123. {
  124. if (!$id) {
  125. return false;
  126. }
  127. $expires = time() + $this->_timeout;
  128. $record = compact('data', 'expires');
  129. $record[$this->_table->getPrimaryKey()] = $id;
  130. $result = $this->_table->save(new Entity($record));
  131. return (bool)$result;
  132. }
  133. /**
  134. * Method called on the destruction of a database session.
  135. *
  136. * @param string|int $id ID that uniquely identifies session in database.
  137. * @return bool True for successful delete, false otherwise.
  138. */
  139. public function destroy($id)
  140. {
  141. $this->_table->delete(new Entity(
  142. [$this->_table->getPrimaryKey() => $id],
  143. ['markNew' => false]
  144. ));
  145. return true;
  146. }
  147. /**
  148. * Helper function called on gc for database sessions.
  149. *
  150. * @param int $maxlifetime Sessions that have not updated for the last maxlifetime seconds will be removed.
  151. * @return bool True on success, false on failure.
  152. */
  153. public function gc($maxlifetime)
  154. {
  155. $this->_table->deleteAll(['expires <' => time() - $maxlifetime]);
  156. return true;
  157. }
  158. }