PageRenderTime 56ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

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

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