5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
24 namespace MediaWiki\Session
;
30 * Manages data for an an authenticated session
32 * A Session represents the fact that the current HTTP request is part of a
33 * session. There are two broad types of Sessions, based on whether they
34 * return true or false from self::canSetUser():
35 * * When true (mutable), the Session identifies multiple requests as part of
36 * a session generically, with no tie to a particular user.
37 * * When false (immutable), the Session identifies multiple requests as part
38 * of a session by identifying and authenticating the request itself as
39 * belonging to a particular user.
41 * The Session object also serves as a replacement for PHP's $_SESSION,
42 * managing access to per-session data.
44 * @todo Once we drop support for PHP 5.3.3, implementing ArrayAccess would be nice.
48 final class Session
implements \Countable
, \Iterator
{
49 /** @var SessionBackend Session backend */
52 /** @var int Session index */
56 * @param SessionBackend $backend
59 public function __construct( SessionBackend
$backend, $index ) {
60 $this->backend
= $backend;
61 $this->index
= $index;
64 public function __destruct() {
65 $this->backend
->deregisterSession( $this->index
);
69 * Returns the session ID
72 public function getId() {
73 return $this->backend
->getId();
77 * Returns the SessionId object
78 * @private For internal use by WebRequest
81 public function getSessionId() {
82 return $this->backend
->getSessionId();
86 * Changes the session ID
87 * @return string New ID (might be the same as the old)
89 public function resetId() {
90 return $this->backend
->resetId();
94 * Fetch the SessionProvider for this session
95 * @return SessionProviderInterface
97 public function getProvider() {
98 return $this->backend
->getProvider();
102 * Indicate whether this session is persisted across requests
104 * For example, if cookies are set.
108 public function isPersistent() {
109 return $this->backend
->isPersistent();
113 * Make this session persisted across requests
115 * If the session is already persistent, equivalent to calling
118 public function persist() {
119 $this->backend
->persist();
123 * Indicate whether the user should be remembered independently of the
127 public function shouldRememberUser() {
128 return $this->backend
->shouldRememberUser();
132 * Set whether the user should be remembered independently of the session
134 * @param bool $remember
136 public function setRememberUser( $remember ) {
137 $this->backend
->setRememberUser( $remember );
141 * Returns the request associated with this session
144 public function getRequest() {
145 return $this->backend
->getRequest( $this->index
);
149 * Returns the authenticated user for this session
152 public function getUser() {
153 return $this->backend
->getUser();
157 * Indicate whether the session user info can be changed
160 public function canSetUser() {
161 return $this->backend
->canSetUser();
165 * Set a new user for this session
166 * @note This should only be called when the user has been authenticated
167 * @param User $user User to set on the session.
168 * This may become a "UserValue" in the future, or User may be refactored
171 public function setUser( $user ) {
172 $this->backend
->setUser( $user );
176 * Get a suggested username for the login form
177 * @return string|null
179 public function suggestLoginUsername() {
180 return $this->backend
->suggestLoginUsername( $this->index
);
184 * Whether HTTPS should be forced
187 public function shouldForceHTTPS() {
188 return $this->backend
->shouldForceHTTPS();
192 * Set whether HTTPS should be forced
195 public function setForceHTTPS( $force ) {
196 $this->backend
->setForceHTTPS( $force );
200 * Fetch the "logged out" timestamp
203 public function getLoggedOutTimestamp() {
204 return $this->backend
->getLoggedOutTimestamp();
208 * Set the "logged out" timestamp
211 public function setLoggedOutTimestamp( $ts ) {
212 $this->backend
->setLoggedOutTimestamp( $ts );
216 * Fetch provider metadata
217 * @protected For use by SessionProvider subclasses only
220 public function getProviderMetadata() {
221 return $this->backend
->getProviderMetadata();
225 * Delete all session data and clear the user (if possible)
227 public function clear() {
228 $data = &$this->backend
->getData();
231 $this->backend
->dirty();
233 if ( $this->backend
->canSetUser() ) {
234 $this->backend
->setUser( new User
);
236 $this->backend
->save();
242 * Resets the TTL in the backend store if the session is near expiring, and
243 * re-persists the session to any active WebRequests if persistent.
245 public function renew() {
246 $this->backend
->renew();
250 * Fetch a copy of this session attached to an alternative WebRequest
252 * Actions on the copy will affect this session too, and vice versa.
254 * @param WebRequest $request Any existing session associated with this
255 * WebRequest object will be overwritten.
258 public function sessionWithRequest( WebRequest
$request ) {
259 $request->setSessionId( $this->backend
->getSessionId() );
260 return $this->backend
->getSession( $request );
264 * Fetch a value from the session
265 * @param string|int $key
266 * @param mixed $default
269 public function get( $key, $default = null ) {
270 $data = &$this->backend
->getData();
271 return array_key_exists( $key, $data ) ?
$data[$key] : $default;
275 * Test if a value exists in the session
276 * @param string|int $key
279 public function exists( $key ) {
280 $data = &$this->backend
->getData();
281 return array_key_exists( $key, $data );
285 * Set a value in the session
286 * @param string|int $key
287 * @param mixed $value
289 public function set( $key, $value ) {
290 $data = &$this->backend
->getData();
291 if ( !array_key_exists( $key, $data ) ||
$data[$key] !== $value ) {
292 $data[$key] = $value;
293 $this->backend
->dirty();
298 * Remove a value from the session
299 * @param string|int $key
301 public function remove( $key ) {
302 $data = &$this->backend
->getData();
303 if ( array_key_exists( $key, $data ) ) {
304 unset( $data[$key] );
305 $this->backend
->dirty();
310 * Delay automatic saving while multiple updates are being made
312 * Calls to save() or clear() will not be delayed.
314 * @return \ScopedCallback When this goes out of scope, a save will be triggered
316 public function delaySave() {
317 return $this->backend
->delaySave();
323 public function save() {
324 $this->backend
->save();
328 * @name Interface methods
332 public function count() {
333 $data = &$this->backend
->getData();
334 return count( $data );
337 public function current() {
338 $data = &$this->backend
->getData();
339 return current( $data );
342 public function key() {
343 $data = &$this->backend
->getData();
347 public function next() {
348 $data = &$this->backend
->getData();
352 public function rewind() {
353 $data = &$this->backend
->getData();
357 public function valid() {
358 $data = &$this->backend
->getData();
359 return key( $data ) !== null;