Mercurial > hg > isophonics-drupal-site
diff vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 7a779792577d |
children | c2387f117808 |
line wrap: on
line diff
--- a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php Mon Apr 23 09:33:26 2018 +0100 +++ b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php Mon Apr 23 09:46:53 2018 +0100 @@ -12,7 +12,7 @@ namespace Symfony\Component\HttpFoundation\Session\Storage; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; -use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; @@ -24,11 +24,9 @@ class NativeSessionStorage implements SessionStorageInterface { /** - * Array of SessionBagInterface. - * * @var SessionBagInterface[] */ - protected $bags; + protected $bags = array(); /** * @var bool @@ -41,7 +39,7 @@ protected $closed = false; /** - * @var AbstractProxy + * @var AbstractProxy|\SessionHandlerInterface */ protected $saveHandler; @@ -51,8 +49,6 @@ protected $metadataBag; /** - * Constructor. - * * Depending on how you want the storage driver to behave you probably * want to override this constructor entirely. * @@ -65,6 +61,7 @@ * PHP starts to execute user-land code. Setting during runtime has no effect). * * cache_limiter, "" (use "0" to prevent headers from being sent entirely). + * cache_expire, "0" * cookie_domain, "" * cookie_httponly, "" * cookie_lifetime, "0" @@ -77,6 +74,7 @@ * gc_probability, "1" * hash_bits_per_character, "4" * hash_function, "0" + * lazy_write, "1" * name, "PHPSESSID" * referer_check, "" * serialize_handler, "php" @@ -96,14 +94,18 @@ * trans_sid_hosts, $_SERVER['HTTP_HOST'] * trans_sid_tags, "a=href,area=href,frame=src,form=" * - * @param array $options Session configuration options - * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler - * @param MetadataBag $metaBag MetadataBag + * @param array $options Session configuration options + * @param \SessionHandlerInterface|null $handler + * @param MetadataBag $metaBag MetadataBag */ public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) { - session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used) - ini_set('session.use_cookies', 1); + $options += array( + 'cache_limiter' => '', + 'cache_expire' => 0, + 'use_cookies' => 1, + 'lazy_write' => 1, + ); session_register_shutdown(); @@ -115,7 +117,7 @@ /** * Gets the save handler instance. * - * @return AbstractProxy + * @return AbstractProxy|\SessionHandlerInterface */ public function getSaveHandler() { @@ -191,6 +193,10 @@ return false; } + if (headers_sent()) { + return false; + } + if (null !== $lifetime) { ini_set('session.cookie_lifetime', $lifetime); } @@ -213,7 +219,40 @@ */ public function save() { - session_write_close(); + $session = $_SESSION; + + foreach ($this->bags as $bag) { + if (empty($_SESSION[$key = $bag->getStorageKey()])) { + unset($_SESSION[$key]); + } + } + if (array($key = $this->metadataBag->getStorageKey()) === array_keys($_SESSION)) { + unset($_SESSION[$key]); + } + + // Register custom error handler to catch a possible failure warning during session write + set_error_handler(function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, $errno, E_WARNING, $errfile, $errline); + }, E_WARNING); + + try { + $e = null; + session_write_close(); + } catch (\ErrorException $e) { + } finally { + restore_error_handler(); + $_SESSION = $session; + } + if (null !== $e) { + // The default PHP error message is not very helpful, as it does not give any information on the current save handler. + // Therefore, we catch this error and trigger a warning with a better error message + $handler = $this->getSaveHandler(); + if ($handler instanceof SessionHandlerProxy) { + $handler = $handler->getHandler(); + } + + trigger_error(sprintf('session_write_close(): Failed to write session data with %s handler', get_class($handler)), E_USER_WARNING); + } $this->closed = true; $this->started = false; @@ -257,7 +296,7 @@ throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); } - if ($this->saveHandler->isActive() && !$this->started) { + if (!$this->started && $this->saveHandler->isActive()) { $this->loadSession(); } elseif (!$this->started) { $this->start(); @@ -266,11 +305,6 @@ return $this->bags[$name]; } - /** - * Sets the MetadataBag. - * - * @param MetadataBag $metaBag - */ public function setMetadataBag(MetadataBag $metaBag = null) { if (null === $metaBag) { @@ -310,12 +344,16 @@ */ public function setOptions(array $options) { + if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { + return; + } + $validOptions = array_flip(array( - 'cache_limiter', 'cookie_domain', 'cookie_httponly', + 'cache_limiter', 'cache_expire', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', - 'hash_function', 'name', 'referer_check', + 'hash_function', 'lazy_write', 'name', 'referer_check', 'serialize_handler', 'use_strict_mode', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', @@ -339,7 +377,7 @@ * ini_set('session.save_handler', 'files'); * ini_set('session.save_path', '/tmp'); * - * or pass in a NativeSessionHandler instance which configures session.save_handler in the + * or pass in a \SessionHandler instance which configures session.save_handler in the * constructor, for a template see NativeFileSessionHandler or use handlers in * composer package drak/native-session * @@ -348,28 +386,33 @@ * @see http://php.net/sessionhandler * @see http://github.com/drak/NativeSession * - * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler + * @param \SessionHandlerInterface|null $saveHandler * * @throws \InvalidArgumentException */ public function setSaveHandler($saveHandler = null) { if (!$saveHandler instanceof AbstractProxy && - !$saveHandler instanceof NativeSessionHandler && !$saveHandler instanceof \SessionHandlerInterface && null !== $saveHandler) { - throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); + throw new \InvalidArgumentException('Must be instance of AbstractProxy; implement \SessionHandlerInterface; or be null.'); } // Wrap $saveHandler in proxy and prevent double wrapping of proxy if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); } elseif (!$saveHandler instanceof AbstractProxy) { - $saveHandler = new SessionHandlerProxy(new \SessionHandler()); + $saveHandler = new SessionHandlerProxy(new StrictSessionHandler(new \SessionHandler())); } $this->saveHandler = $saveHandler; - if ($this->saveHandler instanceof \SessionHandlerInterface) { + if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { + return; + } + + if ($this->saveHandler instanceof SessionHandlerProxy) { + session_set_save_handler($this->saveHandler->getHandler(), false); + } elseif ($this->saveHandler instanceof \SessionHandlerInterface) { session_set_save_handler($this->saveHandler, false); } } @@ -381,8 +424,6 @@ * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()). * PHP takes the return value from the read() handler, unserializes it * and populates $_SESSION with the result automatically. - * - * @param array|null $session */ protected function loadSession(array &$session = null) {