Merge "Improve wording and tense in some "page language" strings"
[lhc/web/wiklou.git] / includes / session / Session.php
1 <?php
2 /**
3 * MediaWiki session
4 *
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.
9 *
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.
14 *
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
19 *
20 * @file
21 * @ingroup Session
22 */
23
24 namespace MediaWiki\Session;
25
26 use User;
27 use WebRequest;
28
29 /**
30 * Manages data for an an authenticated session
31 *
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.
40 *
41 * The Session object also serves as a replacement for PHP's $_SESSION,
42 * managing access to per-session data.
43 *
44 * @todo Once we drop support for PHP 5.3.3, implementing ArrayAccess would be nice.
45 * @ingroup Session
46 * @since 1.27
47 */
48 final class Session implements \Countable, \Iterator {
49 /** @var SessionBackend Session backend */
50 private $backend;
51
52 /** @var int Session index */
53 private $index;
54
55 /**
56 * @param SessionBackend $backend
57 * @param int $index
58 */
59 public function __construct( SessionBackend $backend, $index ) {
60 $this->backend = $backend;
61 $this->index = $index;
62 }
63
64 public function __destruct() {
65 $this->backend->deregisterSession( $this->index );
66 }
67
68 /**
69 * Returns the session ID
70 * @return string
71 */
72 public function getId() {
73 return $this->backend->getId();
74 }
75
76 /**
77 * Returns the SessionId object
78 * @private For internal use by WebRequest
79 * @return SessionId
80 */
81 public function getSessionId() {
82 return $this->backend->getSessionId();
83 }
84
85 /**
86 * Changes the session ID
87 * @return string New ID (might be the same as the old)
88 */
89 public function resetId() {
90 return $this->backend->resetId();
91 }
92
93 /**
94 * Fetch the SessionProvider for this session
95 * @return SessionProviderInterface
96 */
97 public function getProvider() {
98 return $this->backend->getProvider();
99 }
100
101 /**
102 * Indicate whether this session is persisted across requests
103 *
104 * For example, if cookies are set.
105 *
106 * @return bool
107 */
108 public function isPersistent() {
109 return $this->backend->isPersistent();
110 }
111
112 /**
113 * Make this session persisted across requests
114 *
115 * If the session is already persistent, equivalent to calling
116 * $this->renew().
117 */
118 public function persist() {
119 $this->backend->persist();
120 }
121
122 /**
123 * Indicate whether the user should be remembered independently of the
124 * session ID.
125 * @return bool
126 */
127 public function shouldRememberUser() {
128 return $this->backend->shouldRememberUser();
129 }
130
131 /**
132 * Set whether the user should be remembered independently of the session
133 * ID.
134 * @param bool $remember
135 */
136 public function setRememberUser( $remember ) {
137 $this->backend->setRememberUser( $remember );
138 }
139
140 /**
141 * Returns the request associated with this session
142 * @return WebRequest
143 */
144 public function getRequest() {
145 return $this->backend->getRequest( $this->index );
146 }
147
148 /**
149 * Returns the authenticated user for this session
150 * @return User
151 */
152 public function getUser() {
153 return $this->backend->getUser();
154 }
155
156 /**
157 * Fetch the rights allowed the user when this session is active.
158 * @return null|string[] Allowed user rights, or null to allow all.
159 */
160 public function getAllowedUserRights() {
161 return $this->backend->getAllowedUserRights();
162 }
163
164 /**
165 * Indicate whether the session user info can be changed
166 * @return bool
167 */
168 public function canSetUser() {
169 return $this->backend->canSetUser();
170 }
171
172 /**
173 * Set a new user for this session
174 * @note This should only be called when the user has been authenticated
175 * @param User $user User to set on the session.
176 * This may become a "UserValue" in the future, or User may be refactored
177 * into such.
178 */
179 public function setUser( $user ) {
180 $this->backend->setUser( $user );
181 }
182
183 /**
184 * Get a suggested username for the login form
185 * @return string|null
186 */
187 public function suggestLoginUsername() {
188 return $this->backend->suggestLoginUsername( $this->index );
189 }
190
191 /**
192 * Whether HTTPS should be forced
193 * @return bool
194 */
195 public function shouldForceHTTPS() {
196 return $this->backend->shouldForceHTTPS();
197 }
198
199 /**
200 * Set whether HTTPS should be forced
201 * @param bool $force
202 */
203 public function setForceHTTPS( $force ) {
204 $this->backend->setForceHTTPS( $force );
205 }
206
207 /**
208 * Fetch the "logged out" timestamp
209 * @return int
210 */
211 public function getLoggedOutTimestamp() {
212 return $this->backend->getLoggedOutTimestamp();
213 }
214
215 /**
216 * Set the "logged out" timestamp
217 * @param int $ts
218 */
219 public function setLoggedOutTimestamp( $ts ) {
220 $this->backend->setLoggedOutTimestamp( $ts );
221 }
222
223 /**
224 * Fetch provider metadata
225 * @protected For use by SessionProvider subclasses only
226 * @return mixed
227 */
228 public function getProviderMetadata() {
229 return $this->backend->getProviderMetadata();
230 }
231
232 /**
233 * Delete all session data and clear the user (if possible)
234 */
235 public function clear() {
236 $data = &$this->backend->getData();
237 if ( $data ) {
238 $data = array();
239 $this->backend->dirty();
240 }
241 if ( $this->backend->canSetUser() ) {
242 $this->backend->setUser( new User );
243 }
244 $this->backend->save();
245 }
246
247 /**
248 * Renew the session
249 *
250 * Resets the TTL in the backend store if the session is near expiring, and
251 * re-persists the session to any active WebRequests if persistent.
252 */
253 public function renew() {
254 $this->backend->renew();
255 }
256
257 /**
258 * Fetch a copy of this session attached to an alternative WebRequest
259 *
260 * Actions on the copy will affect this session too, and vice versa.
261 *
262 * @param WebRequest $request Any existing session associated with this
263 * WebRequest object will be overwritten.
264 * @return Session
265 */
266 public function sessionWithRequest( WebRequest $request ) {
267 $request->setSessionId( $this->backend->getSessionId() );
268 return $this->backend->getSession( $request );
269 }
270
271 /**
272 * Fetch a value from the session
273 * @param string|int $key
274 * @param mixed $default
275 * @return mixed
276 */
277 public function get( $key, $default = null ) {
278 $data = &$this->backend->getData();
279 return array_key_exists( $key, $data ) ? $data[$key] : $default;
280 }
281
282 /**
283 * Test if a value exists in the session
284 * @param string|int $key
285 * @return bool
286 */
287 public function exists( $key ) {
288 $data = &$this->backend->getData();
289 return array_key_exists( $key, $data );
290 }
291
292 /**
293 * Set a value in the session
294 * @param string|int $key
295 * @param mixed $value
296 */
297 public function set( $key, $value ) {
298 $data = &$this->backend->getData();
299 if ( !array_key_exists( $key, $data ) || $data[$key] !== $value ) {
300 $data[$key] = $value;
301 $this->backend->dirty();
302 }
303 }
304
305 /**
306 * Remove a value from the session
307 * @param string|int $key
308 */
309 public function remove( $key ) {
310 $data = &$this->backend->getData();
311 if ( array_key_exists( $key, $data ) ) {
312 unset( $data[$key] );
313 $this->backend->dirty();
314 }
315 }
316
317 /**
318 * Delay automatic saving while multiple updates are being made
319 *
320 * Calls to save() or clear() will not be delayed.
321 *
322 * @return \ScopedCallback When this goes out of scope, a save will be triggered
323 */
324 public function delaySave() {
325 return $this->backend->delaySave();
326 }
327
328 /**
329 * Save the session
330 */
331 public function save() {
332 $this->backend->save();
333 }
334
335 /**
336 * @name Interface methods
337 * @{
338 */
339
340 public function count() {
341 $data = &$this->backend->getData();
342 return count( $data );
343 }
344
345 public function current() {
346 $data = &$this->backend->getData();
347 return current( $data );
348 }
349
350 public function key() {
351 $data = &$this->backend->getData();
352 return key( $data );
353 }
354
355 public function next() {
356 $data = &$this->backend->getData();
357 next( $data );
358 }
359
360 public function rewind() {
361 $data = &$this->backend->getData();
362 reset( $data );
363 }
364
365 public function valid() {
366 $data = &$this->backend->getData();
367 return key( $data ) !== null;
368 }
369
370 /**@}*/
371
372 }