X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fsession%2FSession.php;h=96e8d50445987dfc16890d8b7a85a11e7e338d3f;hb=43420a0506b3115833d4b5d11b9e56579a967cdd;hp=4ad69ae802d6a819285f014541e9719cd578182e;hpb=4b63ca7113ee48b8c33ad19abc5b89d452b3590e;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/session/Session.php b/includes/session/Session.php index 4ad69ae802..96e8d50445 100644 --- a/includes/session/Session.php +++ b/includes/session/Session.php @@ -23,6 +23,7 @@ namespace MediaWiki\Session; +use Psr\Log\LoggerInterface; use User; use WebRequest; @@ -41,24 +42,28 @@ use WebRequest; * The Session object also serves as a replacement for PHP's $_SESSION, * managing access to per-session data. * - * @todo Once we drop support for PHP 5.3.3, implementing ArrayAccess would be nice. * @ingroup Session * @since 1.27 */ -final class Session implements \Countable, \Iterator { +final class Session implements \Countable, \Iterator, \ArrayAccess { /** @var SessionBackend Session backend */ private $backend; /** @var int Session index */ private $index; + /** @var LoggerInterface */ + private $logger; + /** * @param SessionBackend $backend * @param int $index + * @param LoggerInterface $logger */ - public function __construct( SessionBackend $backend, $index ) { + public function __construct( SessionBackend $backend, $index, LoggerInterface $logger ) { $this->backend = $backend; $this->index = $index; + $this->logger = $logger; } public function __destruct() { @@ -235,7 +240,7 @@ final class Session implements \Countable, \Iterator { public function clear() { $data = &$this->backend->getData(); if ( $data ) { - $data = array(); + $data = []; $this->backend->dirty(); } if ( $this->backend->canSetUser() ) { @@ -271,7 +276,7 @@ final class Session implements \Countable, \Iterator { /** * Fetch a value from the session * @param string|int $key - * @param mixed $default + * @param mixed $default Returned if $this->exists( $key ) would be false * @return mixed */ public function get( $key, $default = null ) { @@ -281,6 +286,7 @@ final class Session implements \Countable, \Iterator { /** * Test if a value exists in the session + * @note Unlike isset(), null values are considered to exist. * @param string|int $key * @return bool */ @@ -328,7 +334,7 @@ final class Session implements \Countable, \Iterator { $new = false; $secrets = $this->get( 'wsTokenSecrets' ); if ( !is_array( $secrets ) ) { - $secrets = array(); + $secrets = []; } if ( isset( $secrets[$key] ) && is_string( $secrets[$key] ) ) { $secret = $secrets[$key]; @@ -419,6 +425,39 @@ final class Session implements \Countable, \Iterator { return key( $data ) !== null; } + /** + * @note Despite the name, this seems to be intended to implement isset() + * rather than array_key_exists(). So do that. + */ + public function offsetExists( $offset ) { + $data = &$this->backend->getData(); + return isset( $data[$offset] ); + } + + /** + * @note This supports indirect modifications but can't mark the session + * dirty when those happen. SessionBackend::save() checks the hash of the + * data to detect such changes. + * @note Accessing a nonexistent key via this mechanism causes that key to + * be created with a null value, and does not raise a PHP warning. + */ + public function &offsetGet( $offset ) { + $data = &$this->backend->getData(); + if ( !array_key_exists( $offset, $data ) ) { + $ex = new \Exception( "Undefined index (auto-adds to session with a null value): $offset" ); + $this->logger->debug( $ex->getMessage(), [ 'exception' => $ex ] ); + } + return $data[$offset]; + } + + public function offsetSet( $offset, $value ) { + $this->set( $offset, $value ); + } + + public function offsetUnset( $offset ) { + $this->remove( $offset ); + } + /**@}*/ }