You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rcube_session_db.php 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. /**
  3. +-----------------------------------------------------------------------+
  4. | This file is part of the Roundcube Webmail client |
  5. | Copyright (C) 2005-2014, The Roundcube Dev Team |
  6. | Copyright (C) 2011, Kolab Systems AG |
  7. | |
  8. | Licensed under the GNU General Public License version 3 or |
  9. | any later version with exceptions for skins & plugins. |
  10. | See the README file for a full license statement. |
  11. | |
  12. | PURPOSE: |
  13. | Provide database supported session management |
  14. +-----------------------------------------------------------------------+
  15. | Author: Thomas Bruederli <roundcube@gmail.com> |
  16. | Author: Aleksander Machniak <alec@alec.pl> |
  17. | Author: Cor Bosman <cor@roundcu.be> |
  18. +-----------------------------------------------------------------------+
  19. */
  20. /**
  21. * Class to provide database session storage
  22. *
  23. * @package Framework
  24. * @subpackage Core
  25. * @author Thomas Bruederli <roundcube@gmail.com>
  26. * @author Aleksander Machniak <alec@alec.pl>
  27. * @author Cor Bosman <cor@roundcu.be>
  28. */
  29. class rcube_session_db extends rcube_session
  30. {
  31. private $db;
  32. private $table_name;
  33. /**
  34. * @param Object $config
  35. */
  36. public function __construct($config)
  37. {
  38. parent::__construct($config);
  39. // get db instance
  40. $this->db = rcube::get_instance()->get_dbh();
  41. // session table name
  42. $this->table_name = $this->db->table_name('session', true);
  43. // register sessions handler
  44. $this->register_session_handler();
  45. // register db gc handler
  46. $this->register_gc_handler(array($this, 'gc_db'));
  47. }
  48. /**
  49. * @param $save_path
  50. * @param $session_name
  51. * @return bool
  52. */
  53. public function open($save_path, $session_name)
  54. {
  55. return true;
  56. }
  57. /**
  58. * @return bool
  59. */
  60. public function close()
  61. {
  62. return true;
  63. }
  64. /**
  65. * Handler for session_destroy()
  66. *
  67. * @param $key
  68. * @return bool
  69. */
  70. public function destroy($key)
  71. {
  72. if ($key) {
  73. $this->db->query("DELETE FROM {$this->table_name} WHERE `sess_id` = ?", $key);
  74. }
  75. return true;
  76. }
  77. /**
  78. * Read session data from database
  79. *
  80. * @param string Session ID
  81. *
  82. * @return string Session vars
  83. */
  84. public function read($key)
  85. {
  86. $sql_result = $this->db->query(
  87. "SELECT `vars`, `ip`, `changed`, " . $this->db->now() . " AS ts"
  88. . " FROM {$this->table_name} WHERE `sess_id` = ?", $key);
  89. if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
  90. $this->time_diff = time() - strtotime($sql_arr['ts']);
  91. $this->changed = strtotime($sql_arr['changed']);
  92. $this->ip = $sql_arr['ip'];
  93. $this->vars = base64_decode($sql_arr['vars']);
  94. $this->key = $key;
  95. return !empty($this->vars) ? (string) $this->vars : '';
  96. }
  97. return '';
  98. }
  99. /**
  100. * insert new data into db session store
  101. *
  102. * @param $key
  103. * @param $vars
  104. * @return bool
  105. */
  106. public function write($key, $vars)
  107. {
  108. $now = $this->db->now();
  109. $this->db->query("INSERT INTO {$this->table_name}"
  110. . " (`sess_id`, `vars`, `ip`, `created`, `changed`)"
  111. . " VALUES (?, ?, ?, $now, $now)",
  112. $key, base64_encode($vars), (string)$this->ip);
  113. return true;
  114. }
  115. /**
  116. * update session data
  117. *
  118. * @param $key
  119. * @param $newvars
  120. * @param $oldvars
  121. *
  122. * @return bool
  123. */
  124. public function update($key, $newvars, $oldvars)
  125. {
  126. $now = $this->db->now();
  127. $ts = microtime(true);
  128. // if new and old data are not the same, update data
  129. // else update expire timestamp only when certain conditions are met
  130. if ($newvars !== $oldvars) {
  131. $this->db->query("UPDATE {$this->table_name} "
  132. . "SET `changed` = $now, `vars` = ? WHERE `sess_id` = ?",
  133. base64_encode($newvars), $key);
  134. }
  135. else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
  136. $this->db->query("UPDATE {$this->table_name} SET `changed` = $now"
  137. . " WHERE `sess_id` = ?", $key);
  138. }
  139. return true;
  140. }
  141. /**
  142. * Clean up db sessions.
  143. */
  144. public function gc_db()
  145. {
  146. // just clean all old sessions when this GC is called
  147. $this->db->query("DELETE FROM " . $this->db->table_name('session')
  148. . " WHERE changed < " . $this->db->now(-$this->gc_enabled));
  149. $this->log("Session GC (DB): remove records < "
  150. . date('Y-m-d H:i:s', time() - $this->gc_enabled)
  151. . '; rows = ' . intval($this->db->affected_rows()));
  152. }
  153. }