PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/fuel/core/classes/session/db.php

https://github.com/enygma/fuel
PHP | 260 lines | 133 code | 41 blank | 86 comment | 16 complexity | 83754a9400835534033f553e0c35949d MD5 | raw file
  1. <?php
  2. /**
  3. * Fuel
  4. *
  5. * Fuel is a fast, lightweight, community driven PHP5 framework.
  6. *
  7. * @package Fuel
  8. * @version 1.0
  9. * @author Harro "WanWizard" Verton
  10. * @license MIT License
  11. * @copyright 2010 Dan Horrigan
  12. * @link http://fuelphp.com
  13. */
  14. namespace Fuel\Core;
  15. // --------------------------------------------------------------------
  16. class Session_Db extends Session_Driver {
  17. /*
  18. * @var session database result object
  19. */
  20. protected $record = null;
  21. /**
  22. * array of driver config defaults
  23. */
  24. protected static $_defaults = array(
  25. 'cookie_name' => 'fueldid', // name of the session cookie for database based sessions
  26. 'table' => 'sessions', // name of the sessions table
  27. 'gc_probability' => 5 // probability % (between 0 and 100) for garbage collection
  28. );
  29. // --------------------------------------------------------------------
  30. public function __construct($config = array())
  31. {
  32. // merge the driver config with the global config
  33. $this->config = array_merge($config, is_array($config['db']) ? $config['db'] : static::$_defaults);
  34. $this->config = $this->_validate_config($this->config);
  35. }
  36. // --------------------------------------------------------------------
  37. /**
  38. * create a new session
  39. *
  40. * @access public
  41. * @return void
  42. */
  43. public function create()
  44. {
  45. // create a new session
  46. $this->keys['session_id'] = $this->_new_session_id();
  47. $this->keys['previous_id'] = $this->keys['session_id']; // prevents errors if previous_id has a unique index
  48. $this->keys['ip_address'] = \Input::real_ip();
  49. $this->keys['user_agent'] = \Input::user_agent();
  50. $this->keys['created'] = $this->time->get_timestamp();
  51. $this->keys['updated'] = $this->keys['created'];
  52. $this->keys['payload'] = '';
  53. // create the session record
  54. $result = \DB::insert($this->config['table'], array_keys($this->keys))->values($this->keys)->execute($this->config['database']);
  55. // and set the session cookie
  56. $this->_set_cookie();
  57. }
  58. // --------------------------------------------------------------------
  59. /**
  60. * read the session
  61. *
  62. * @access public
  63. * @param boolean, set to true if we want to force a new session to be created
  64. * @return void
  65. */
  66. public function read($force = false)
  67. {
  68. // get the session cookie
  69. $cookie = $this->_get_cookie();
  70. // if no session cookie was present, create it
  71. if ($cookie === false or $force)
  72. {
  73. $this->create();
  74. }
  75. // read the session record
  76. $this->record = \DB::select()->where('session_id', '=', $this->keys['session_id'])->from($this->config['table'])->execute($this->config['database']);
  77. // record found?
  78. if ($this->record->count())
  79. {
  80. $payload = $this->_unserialize($this->record->get('payload'));
  81. }
  82. else
  83. {
  84. // try to find the session on previous id
  85. $this->record = \DB::select()->where('previous_id', '=', $this->keys['session_id'])->from($this->config['table'])->execute($this->config['database']);
  86. // record found?
  87. if ($this->record->count())
  88. {
  89. $payload = $this->_unserialize($this->record->get('payload'));
  90. }
  91. else
  92. {
  93. // cookie present, but session record missing. force creation of a new session
  94. $this->read(true);
  95. return;
  96. }
  97. }
  98. if (isset($payload[0])) $this->data = $payload[0];
  99. if (isset($payload[1])) $this->flash = $payload[1];
  100. }
  101. // --------------------------------------------------------------------
  102. /**
  103. * write the current session
  104. *
  105. * @access public
  106. * @return void
  107. */
  108. public function write()
  109. {
  110. // do we have something to write?
  111. if ( ! empty($this->keys) and ! empty($this->record))
  112. {
  113. // rotate the session id if needed
  114. $this->rotate(false);
  115. // create the session record, and add the session payload
  116. $session = $this->keys;
  117. $session['payload'] = $this->_serialize(array($this->data, $this->flash));
  118. // update the database
  119. $result = \DB::update($this->config['table'])->set($session)->where('session_id', '=', $this->record->get('session_id'))->execute($this->config['database']);
  120. // update went well?
  121. if ($result)
  122. {
  123. // then update the cookie
  124. $this->_set_cookie();
  125. }
  126. else
  127. {
  128. logger(Fuel::L_ERROR, 'Session update failed, session record could not be found. Concurrency issue?');
  129. }
  130. // do some garbage collection
  131. if (mt_rand(0,100) < $this->config['gc_probability'])
  132. {
  133. $expired = $this->time->get_timestamp() - $this->config['expiration_time'];
  134. $result = \DB::delete($this->config['table'])->where('updated', '<', $expired)->execute($this->config['database']);
  135. }
  136. }
  137. }
  138. // --------------------------------------------------------------------
  139. /**
  140. * destroy the current session
  141. *
  142. * @access public
  143. * @return void
  144. */
  145. public function destroy()
  146. {
  147. // do we have something to destroy?
  148. if ( ! empty($this->keys) and ! empty($this->record))
  149. {
  150. // delete the session record
  151. $result = \DB::delete($this->config['table'])->where('session_id', '=', $this->keys['session_id'])->execute($this->config['database']);
  152. }
  153. // reset the stored session data
  154. $this->record = null;
  155. $this->keys = $this->flash = $this->data = array();
  156. }
  157. // --------------------------------------------------------------------
  158. /**
  159. * validate a driver config value
  160. *
  161. * @param array array with configuration values
  162. * @access public
  163. * @return array validated and consolidated config
  164. */
  165. public function _validate_config($config)
  166. {
  167. $validated = array();
  168. foreach ($config as $name => $item)
  169. {
  170. // filter out any driver config
  171. if (!is_array($item))
  172. {
  173. switch ($name)
  174. {
  175. case 'cookie_name':
  176. if ( empty($item) OR ! is_string($item))
  177. {
  178. $item = 'fueldid';
  179. }
  180. break;
  181. case 'database':
  182. // do we have a database?
  183. if ( empty($item) OR ! is_string($item))
  184. {
  185. \Config::load('db', true);
  186. $item = \Config::get('db.active', false);
  187. }
  188. if ($item === false)
  189. {
  190. throw new \Exception('You have specify a database to use database backed sessions.');
  191. }
  192. break;
  193. case 'table':
  194. // and a table name?
  195. if ( empty($item) OR ! is_string($item))
  196. {
  197. throw new \Exception('You have specify a database table name to use database backed sessions.');
  198. }
  199. break;
  200. case 'gc_probability':
  201. // do we have a path?
  202. if ( ! is_numeric($item) OR $item < 0 OR $item > 100)
  203. {
  204. // default value: 5%
  205. $item = 5;
  206. }
  207. break;
  208. default:
  209. break;
  210. }
  211. // global config, was validated in the driver
  212. $validated[$name] = $item;
  213. }
  214. }
  215. // validate all global settings as well
  216. return parent::_validate_config($validated);
  217. }
  218. }
  219. /* End of file db.php */