Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | c2387f117808 |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
24 class NativeSessionStorage implements SessionStorageInterface | 24 class NativeSessionStorage implements SessionStorageInterface |
25 { | 25 { |
26 /** | 26 /** |
27 * @var SessionBagInterface[] | 27 * @var SessionBagInterface[] |
28 */ | 28 */ |
29 protected $bags = array(); | 29 protected $bags = []; |
30 | 30 |
31 /** | 31 /** |
32 * @var bool | 32 * @var bool |
33 */ | 33 */ |
34 protected $started = false; | 34 protected $started = false; |
96 * | 96 * |
97 * @param array $options Session configuration options | 97 * @param array $options Session configuration options |
98 * @param \SessionHandlerInterface|null $handler | 98 * @param \SessionHandlerInterface|null $handler |
99 * @param MetadataBag $metaBag MetadataBag | 99 * @param MetadataBag $metaBag MetadataBag |
100 */ | 100 */ |
101 public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) | 101 public function __construct(array $options = [], $handler = null, MetadataBag $metaBag = null) |
102 { | 102 { |
103 $options += array( | 103 $options += [ |
104 'cache_limiter' => '', | 104 'cache_limiter' => '', |
105 'cache_expire' => 0, | 105 'cache_expire' => 0, |
106 'use_cookies' => 1, | 106 'use_cookies' => 1, |
107 'lazy_write' => 1, | 107 'lazy_write' => 1, |
108 ); | 108 ]; |
109 | 109 |
110 session_register_shutdown(); | 110 session_register_shutdown(); |
111 | 111 |
112 $this->setMetadataBag($metaBag); | 112 $this->setMetadataBag($metaBag); |
113 $this->setOptions($options); | 113 $this->setOptions($options); |
135 | 135 |
136 if (\PHP_SESSION_ACTIVE === session_status()) { | 136 if (\PHP_SESSION_ACTIVE === session_status()) { |
137 throw new \RuntimeException('Failed to start the session: already started by PHP.'); | 137 throw new \RuntimeException('Failed to start the session: already started by PHP.'); |
138 } | 138 } |
139 | 139 |
140 if (ini_get('session.use_cookies') && headers_sent($file, $line)) { | 140 if (filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) { |
141 throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); | 141 throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); |
142 } | 142 } |
143 | 143 |
144 // ok to try and start the session | 144 // ok to try and start the session |
145 if (!session_start()) { | 145 if (!session_start()) { |
224 foreach ($this->bags as $bag) { | 224 foreach ($this->bags as $bag) { |
225 if (empty($_SESSION[$key = $bag->getStorageKey()])) { | 225 if (empty($_SESSION[$key = $bag->getStorageKey()])) { |
226 unset($_SESSION[$key]); | 226 unset($_SESSION[$key]); |
227 } | 227 } |
228 } | 228 } |
229 if (array($key = $this->metadataBag->getStorageKey()) === array_keys($_SESSION)) { | 229 if ([$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) { |
230 unset($_SESSION[$key]); | 230 unset($_SESSION[$key]); |
231 } | 231 } |
232 | 232 |
233 // Register custom error handler to catch a possible failure warning during session write | 233 // Register error handler to add information about the current save handler |
234 set_error_handler(function ($errno, $errstr, $errfile, $errline) { | 234 $previousHandler = set_error_handler(function ($type, $msg, $file, $line) use (&$previousHandler) { |
235 throw new \ErrorException($errstr, $errno, E_WARNING, $errfile, $errline); | 235 if (E_WARNING === $type && 0 === strpos($msg, 'session_write_close():')) { |
236 }, E_WARNING); | 236 $handler = $this->saveHandler instanceof SessionHandlerProxy ? $this->saveHandler->getHandler() : $this->saveHandler; |
237 $msg = sprintf('session_write_close(): Failed to write session data with "%s" handler', \get_class($handler)); | |
238 } | |
239 | |
240 return $previousHandler ? $previousHandler($type, $msg, $file, $line) : false; | |
241 }); | |
237 | 242 |
238 try { | 243 try { |
239 $e = null; | |
240 session_write_close(); | 244 session_write_close(); |
241 } catch (\ErrorException $e) { | |
242 } finally { | 245 } finally { |
243 restore_error_handler(); | 246 restore_error_handler(); |
244 $_SESSION = $session; | 247 $_SESSION = $session; |
245 } | 248 } |
246 if (null !== $e) { | |
247 // The default PHP error message is not very helpful, as it does not give any information on the current save handler. | |
248 // Therefore, we catch this error and trigger a warning with a better error message | |
249 $handler = $this->getSaveHandler(); | |
250 if ($handler instanceof SessionHandlerProxy) { | |
251 $handler = $handler->getHandler(); | |
252 } | |
253 | |
254 trigger_error(sprintf('session_write_close(): Failed to write session data with %s handler', get_class($handler)), E_USER_WARNING); | |
255 } | |
256 | 249 |
257 $this->closed = true; | 250 $this->closed = true; |
258 $this->started = false; | 251 $this->started = false; |
259 } | 252 } |
260 | 253 |
267 foreach ($this->bags as $bag) { | 260 foreach ($this->bags as $bag) { |
268 $bag->clear(); | 261 $bag->clear(); |
269 } | 262 } |
270 | 263 |
271 // clear out the session | 264 // clear out the session |
272 $_SESSION = array(); | 265 $_SESSION = []; |
273 | 266 |
274 // reconnect the bags to the session | 267 // reconnect the bags to the session |
275 $this->loadSession(); | 268 $this->loadSession(); |
276 } | 269 } |
277 | 270 |
336 * Sets session.* ini variables. | 329 * Sets session.* ini variables. |
337 * | 330 * |
338 * For convenience we omit 'session.' from the beginning of the keys. | 331 * For convenience we omit 'session.' from the beginning of the keys. |
339 * Explicitly ignores other ini keys. | 332 * Explicitly ignores other ini keys. |
340 * | 333 * |
341 * @param array $options Session ini directives array(key => value) | 334 * @param array $options Session ini directives [key => value] |
342 * | 335 * |
343 * @see http://php.net/session.configuration | 336 * @see http://php.net/session.configuration |
344 */ | 337 */ |
345 public function setOptions(array $options) | 338 public function setOptions(array $options) |
346 { | 339 { |
347 if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { | 340 if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { |
348 return; | 341 return; |
349 } | 342 } |
350 | 343 |
351 $validOptions = array_flip(array( | 344 $validOptions = array_flip([ |
352 'cache_expire', 'cache_limiter', 'cookie_domain', 'cookie_httponly', | 345 'cache_expire', 'cache_limiter', 'cookie_domain', 'cookie_httponly', |
353 'cookie_lifetime', 'cookie_path', 'cookie_secure', | 346 'cookie_lifetime', 'cookie_path', 'cookie_secure', |
354 'entropy_file', 'entropy_length', 'gc_divisor', | 347 'entropy_file', 'entropy_length', 'gc_divisor', |
355 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', | 348 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', |
356 'hash_function', 'lazy_write', 'name', 'referer_check', | 349 'hash_function', 'lazy_write', 'name', 'referer_check', |
357 'serialize_handler', 'use_strict_mode', 'use_cookies', | 350 'serialize_handler', 'use_strict_mode', 'use_cookies', |
358 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', | 351 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', |
359 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', | 352 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', |
360 'upload_progress.freq', 'upload_progress.min_freq', 'url_rewriter.tags', | 353 'upload_progress.freq', 'upload_progress.min_freq', 'url_rewriter.tags', |
361 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags', | 354 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags', |
362 )); | 355 ]); |
363 | 356 |
364 foreach ($options as $key => $value) { | 357 foreach ($options as $key => $value) { |
365 if (isset($validOptions[$key])) { | 358 if (isset($validOptions[$key])) { |
366 ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value); | 359 ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value); |
367 } | 360 } |
409 if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { | 402 if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { |
410 return; | 403 return; |
411 } | 404 } |
412 | 405 |
413 if ($this->saveHandler instanceof SessionHandlerProxy) { | 406 if ($this->saveHandler instanceof SessionHandlerProxy) { |
414 session_set_save_handler($this->saveHandler->getHandler(), false); | |
415 } elseif ($this->saveHandler instanceof \SessionHandlerInterface) { | |
416 session_set_save_handler($this->saveHandler, false); | 407 session_set_save_handler($this->saveHandler, false); |
417 } | 408 } |
418 } | 409 } |
419 | 410 |
420 /** | 411 /** |
429 { | 420 { |
430 if (null === $session) { | 421 if (null === $session) { |
431 $session = &$_SESSION; | 422 $session = &$_SESSION; |
432 } | 423 } |
433 | 424 |
434 $bags = array_merge($this->bags, array($this->metadataBag)); | 425 $bags = array_merge($this->bags, [$this->metadataBag]); |
435 | 426 |
436 foreach ($bags as $bag) { | 427 foreach ($bags as $bag) { |
437 $key = $bag->getStorageKey(); | 428 $key = $bag->getStorageKey(); |
438 $session[$key] = isset($session[$key]) ? $session[$key] : array(); | 429 $session[$key] = isset($session[$key]) ? $session[$key] : []; |
439 $bag->initialize($session[$key]); | 430 $bag->initialize($session[$key]); |
440 } | 431 } |
441 | 432 |
442 $this->started = true; | 433 $this->started = true; |
443 $this->closed = false; | 434 $this->closed = false; |