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

/storage/session/adapter/Php.php

http://github.com/UnionOfRAD/lithium
PHP | 262 lines | 130 code | 19 blank | 113 comment | 24 complexity | f74ca060b9e0ea2877370300bf535257 MD5 | raw file
  1. <?php
  2. /**
  3. * li₃: the most RAD framework for PHP (http://li3.me)
  4. *
  5. * Copyright 2009, Union of RAD. All rights reserved. This source
  6. * code is distributed under the terms of the BSD 3-Clause License.
  7. * The full license text can be found in the LICENSE.txt file.
  8. */
  9. namespace lithium\storage\session\adapter;
  10. use lithium\util\Set;
  11. use RuntimeException;
  12. use lithium\core\ConfigException;
  13. use lithium\core\Libraries;
  14. /**
  15. * A minimal adapter to interface with native PHP sessions.
  16. *
  17. * This adapter provides basic support for `write`, `read` and `delete`
  18. * session handling, as well as allowing these three methods to be filtered as
  19. * per the Lithium filtering system.
  20. */
  21. class Php extends \lithium\core\ObjectDeprecated {
  22. /**
  23. * Default ini settings for this session adapter. Will disabl cookie lifetime,
  24. * set cookies to HTTP only and the cache_limiter to `'nocache'`.
  25. *
  26. * @link http://php.net/session.configuration.php
  27. * @link http://php.net/session.configuration.php#ini.session.cookie-lifetime
  28. * @link http://php.net/session.configuration.php#ini.session.cookie-httponly
  29. * @link http://php.net/session.configuration.php#ini.session.cache-limiter
  30. * @var array Configuration options matching the pattern `'session.*'` are session
  31. * ini settings. Please consult the PHP documentation for further information.
  32. */
  33. protected $_defaults = [
  34. 'session.cookie_lifetime' => '0',
  35. 'session.cookie_httponly' => true,
  36. 'session.cache_limiter' => 'nocache'
  37. ];
  38. /**
  39. * Constructor. Takes care of setting appropriate configurations for this object. Also sets
  40. * session ini settings.
  41. *
  42. * @see lithium\storage\session\adapter\Php::$_defaults
  43. * @param array $config Configuration options matching the pattern `'session.*'` are interpreted
  44. * as session ini settings. Please consult the PHP documentation for further
  45. * information.
  46. * A few ini settings are set by default here and will overwrite those from
  47. * your php.ini. To disable sending a cache limiter set `'session.cache_limiter'`
  48. * to `false`.
  49. * @return void
  50. */
  51. public function __construct(array $config = []) {
  52. if (empty($config['session.name'])) {
  53. $config['session.name'] = basename(Libraries::get(true, 'path'));
  54. }
  55. parent::__construct($config + $this->_defaults);
  56. }
  57. /**
  58. * Initialization of the session.
  59. *
  60. * @todo Split up into an _initialize() and a _start().
  61. */
  62. protected function _init() {
  63. if ($this->isStarted()) {
  64. return true;
  65. }
  66. $config = $this->_config;
  67. unset($config['adapter'], $config['strategies'], $config['filters'], $config['init']);
  68. foreach ($config as $key => $value) {
  69. if (strpos($key, 'session.') === false) {
  70. continue;
  71. }
  72. if (ini_set($key, $value) === false) {
  73. throw new ConfigException('Could not initialize the session.');
  74. }
  75. }
  76. }
  77. /**
  78. * Starts the session.
  79. *
  80. * @return boolean `true` if session successfully started
  81. * (or has already been started), `false` otherwise.
  82. */
  83. protected function _start() {
  84. if ($this->isStarted()) {
  85. return true;
  86. }
  87. session_cache_limiter();
  88. return session_start();
  89. }
  90. /**
  91. * Obtain the status of the session.
  92. *
  93. * @return boolean True if a session is currently started, False otherwise. If PHP 5.4
  94. * then we know, if PHP 5.3 then we cannot tell for sure if a session
  95. * has been closed.
  96. */
  97. public function isStarted() {
  98. if (function_exists('session_status')) {
  99. return session_status() === PHP_SESSION_ACTIVE;
  100. }
  101. return isset($_SESSION) && session_id();
  102. }
  103. /**
  104. * Sets or obtains the session ID.
  105. *
  106. * @param string $key Optional. If specified, sets the session ID to the value of `$key`.
  107. * @return mixed Session ID, or `null` if the session has not been started.
  108. */
  109. public function key($key = null) {
  110. if ($key !== null) {
  111. return session_id($key);
  112. }
  113. return session_id() ?: null;
  114. }
  115. /**
  116. * Checks if a value has been set in the session.
  117. *
  118. * @param string $key Key of the entry to be checked.
  119. * @param array $options Options array. Not used for this adapter method.
  120. * @return \Closure Function returning boolean `true` if the key exists, `false` otherwise.
  121. */
  122. public function check($key, array $options = []) {
  123. if (!$this->isStarted() && !$this->_start()) {
  124. throw new RuntimeException('Could not start session.');
  125. }
  126. return function($params) {
  127. return Set::check($_SESSION, $params['key']);
  128. };
  129. }
  130. /**
  131. * Read a value from the session.
  132. *
  133. * @param null|string $key Key of the entry to be read. If no key is passed, all
  134. * current session data is returned.
  135. * @param array $options Options array. Not used for this adapter method.
  136. * @return \Closure Function returning data in the session if successful, `false` otherwise.
  137. */
  138. public function read($key = null, array $options = []) {
  139. if (!$this->isStarted() && !$this->_start()) {
  140. throw new RuntimeException('Could not start session.');
  141. }
  142. return function($params) {
  143. $key = $params['key'];
  144. if (!$key) {
  145. return $_SESSION;
  146. }
  147. if (strpos($key, '.') === false) {
  148. return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
  149. }
  150. $filter = function($keys, $data) use (&$filter) {
  151. $key = array_shift($keys);
  152. if (isset($data[$key])) {
  153. return (empty($keys)) ? $data[$key] : $filter($keys, $data[$key]);
  154. }
  155. };
  156. return $filter(explode('.', $key), $_SESSION);
  157. };
  158. }
  159. /**
  160. * Write a value to the session.
  161. *
  162. * @param string $key Key of the item to be stored.
  163. * @param mixed $value The value to be stored.
  164. * @param array $options Options array. Not used for this adapter method.
  165. * @return \Closure Function returning boolean `true` on successful write, `false` otherwise.
  166. */
  167. public function write($key, $value, array $options = []) {
  168. if (!$this->isStarted() && !$this->_start()) {
  169. throw new RuntimeException('Could not start session.');
  170. }
  171. return function($params) {
  172. return $this->overwrite(
  173. $_SESSION, Set::insert($_SESSION, $params['key'], $params['value'])
  174. );
  175. };
  176. }
  177. /**
  178. * Delete value from the session
  179. *
  180. * @param string $key The key to be deleted.
  181. * @param array $options Options array. Not used for this adapter method.
  182. * @return \Closure Function returning boolean `true` if the key no longer
  183. * exists in the session, `false` otherwise
  184. */
  185. public function delete($key, array $options = []) {
  186. if (!$this->isStarted() && !$this->_start()) {
  187. throw new RuntimeException('Could not start session.');
  188. }
  189. return function($params) {
  190. $key = $params['key'];
  191. $this->overwrite($_SESSION, Set::remove($_SESSION, $key));
  192. return !Set::check($_SESSION, $key);
  193. };
  194. }
  195. /**
  196. * Clears all keys from the session.
  197. *
  198. * @param array $options Options array. Not used for this adapter method.
  199. * @return \Closure Function returning boolean `true` on successful clear, `false` otherwise.
  200. */
  201. public function clear(array $options = []) {
  202. if (!$this->isStarted() && !$this->_start()) {
  203. throw new RuntimeException('Could not start session.');
  204. }
  205. return function($params) {
  206. return session_destroy();
  207. };
  208. }
  209. /**
  210. * Determines if PHP sessions are enabled.
  211. *
  212. * @return boolean Returns `true` if enabled (PHP session functionality
  213. * can be disabled completely), `false` otherwise.
  214. */
  215. public static function enabled() {
  216. if (function_exists('session_status')) {
  217. return session_status() !== PHP_SESSION_DISABLED;
  218. }
  219. return in_array('session', get_loaded_extensions());
  220. }
  221. /**
  222. * Overwrites session keys and values.
  223. *
  224. * @param array $old Reference to the array that needs to be
  225. * overwritten. Will usually be `$_SESSION`.
  226. * @param array $new The data that should overwrite the keys/values in `$old`.
  227. * @return boolean Always `true`.
  228. */
  229. public function overwrite(&$old, $new) {
  230. if (!empty($old)) {
  231. foreach ($old as $key => $value) {
  232. if (!isset($new[$key])) {
  233. unset($old[$key]);
  234. }
  235. }
  236. }
  237. foreach ($new as $key => $value) {
  238. $old[$key] = $value;
  239. }
  240. return true;
  241. }
  242. }
  243. ?>