Passed
Push — solr-auth-refactor ( 3bee90 )
by Ilia
15:04
created

crawler_user::__call()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 9
ccs 0
cts 7
cp 0
crap 12
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
use Symfony\Component\HttpFoundation\Session\SessionInterface;
4
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
5
use Symfony\Component\HttpFoundation\Session\Session;
6
7
/**
8
 * Elgg Session Management
9
 *
10
 * Reserved keys: last_forward_from, msg, sticky_forms, user, guid, id, code, name, username
11
 * Deprecated keys: user, id, name, username
12
 * 
13
 * \ArrayAccess was deprecated in Elgg 1.9. This means you should use 
14
 * $session->get('foo') rather than $session['foo'].
15
 * Warning: You can not access multidimensional arrays through \ArrayAccess like
16
 * this $session['foo']['bar']
17
 *
18
 * @package    Elgg.Core
19
 * @subpackage Session
20
 * @see        elgg_get_session()
21
 */
22
class ElggSession implements \ArrayAccess {
23
24
	/**
25
	 * @var SessionInterface
26
	 */
27
	protected $storage;
28
29
	/**
30
	 * @var \ElggUser|null
31
	 */
32
	protected $logged_in_user;
33
34
	/**
35
	 * @var bool
36
	 */
37
	protected $ignore_access = false;
38
39
	/**
40
	 * Constructor
41
	 *
42
	 * @param SessionInterface $storage The underlying Session implementation
43
	 * @access private Use elgg_get_session()
44
	 */
45 79
	public function __construct(SessionInterface $storage) {
46 79
		$this->storage = $storage;
47 79
	}
48
49
	/**
50
	 * Start the session
51
	 *
52
	 * @return boolean
53
	 * @throws RuntimeException If session fails to start.
54
	 * @since 1.9
55
	 */
56 4
	public function start() {
57 4
		$result = $this->storage->start();
58 3
		$this->generateSessionToken();
59 3
		return $result;
60
	}
61
62
	/**
63
	 * Migrates the session to a new session id while maintaining session attributes
64
	 *
65
	 * @param boolean $destroy Whether to delete the session or let gc handle clean up
66
	 * @return boolean
67
	 * @since 1.9
68
	 */
69 2
	public function migrate($destroy = false) {
70 2
		return $this->storage->migrate($destroy);
71
	}
72
73
	/**
74
	 * Invalidates the session
75
	 *
76
	 * Deletes session data and session persistence. Starts a new session.
77
	 *
78
	 * @return boolean
79
	 * @since 1.9
80
	 */
81 1
	public function invalidate() {
82 1
		$this->storage->clear();
83 1
		$this->logged_in_user = null;
84 1
		$result = $this->migrate(true);
85 1
		$this->generateSessionToken();
86 1
		return $result;
87
	}
88
89
	/**
90
	 * Has the session been started
91
	 *
92
	 * @return boolean
93
	 * @since 1.9
94
	 */
95
	public function isStarted() {
96
		return $this->storage->isStarted();
97
	}
98
99
	/**
100
	 * Get the session ID
101
	 *
102
	 * @return string
103
	 * @since 1.9
104
	 */
105 2
	public function getId() {
106 2
		return $this->storage->getId();
107
	}
108
109
	/**
110
	 * Set the session ID
111
	 *
112
	 * @param string $id Session ID
113
	 * @return void
114
	 * @since 1.9
115
	 */
116
	public function setId($id) {
117
		$this->storage->setId($id);
118
	}
119
120
	/**
121
	 * Get the session name
122
	 *
123
	 * @return string
124
	 * @since 1.9
125
	 */
126
	public function getName() {
127
		return $this->storage->getName();
128
	}
129
130
	/**
131
	 * Set the session name
132
	 *
133
	 * @param string $name Session name
134
	 * @return void
135
	 * @since 1.9
136
	 */
137
	public function setName($name) {
138
		$this->storage->setName($name);
139
	}
140
141
	/**
142
	 * Get an attribute of the session
143
	 *
144
	 * @param string $name    Name of the attribute to get
145
	 * @param mixed  $default Value to return if attribute is not set (default is null)
146
	 * @return mixed
147
	 */
148 13
	public function get($name, $default = null) {
149 13
		return $this->storage->get($name, $default);
150
	}
151
152
	/**
153
	 * Set an attribute
154
	 *
155
	 * @param string $name  Name of the attribute to set
156
	 * @param mixed  $value Value to be set
157
	 * @return void
158
	 */
159 11
	public function set($name, $value) {
160 11
		$this->storage->set($name, $value);
161 11
	}
162
163
	/**
164
	 * Remove an attribute
165
	 *
166
	 * @param string $name The name of the attribute to remove
167
	 * @return mixed The removed attribute
168
	 * @since 1.9
169
	 */
170 2
	public function remove($name) {
171 2
		return $this->storage->remove($name);
172
	}
173
174
	/**
175
	 * Alias to offsetUnset()
176
	 *
177
	 * @param string $key Name
178
	 * @return void
179
	 * @deprecated 1.9 Use remove()
180
	 */
181
	public function del($key) {
182
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
183
		$this->remove($key);
184
	}
185
186
	/**
187
	 * Has the attribute been defined
188
	 *
189
	 * @param string $name Name of the attribute
190
	 * @return bool
191
	 * @since 1.9
192
	 */
193 3
	public function has($name) {
194 3
		return $this->storage->has($name);
195
	}
196
197
	/**
198
	 * Sets the logged in user
199
	 * 
200
	 * @param \ElggUser $user The user who is logged in
201
	 * @return void
202
	 * @since 1.9
203
	 */
204
	public function setLoggedInUser(\ElggUser $user) {
205
		$this->set('guid', $user->guid);
206
		$this->logged_in_user = $user;
207
	}
208
209
	/**
210
	 * Gets the logged in user
211
	 * 
212
	 * @return \ElggUser
213
	 * @since 1.9
214
	 */
215 37
	public function getLoggedInUser() {
216 37
		return $this->logged_in_user;
217
	}
218
219
	/**
220
	 * Return the current logged in user by guid.
221
	 *
222
	 * @see elgg_get_logged_in_user_entity()
223
	 * @return int
224
	 */
225 32
	public function getLoggedInUserGuid() {
226 32
		$user = $this->getLoggedInUser();
227 32
		return $user ? $user->guid : 0;
228
	}
229
	
230
	/**
231
	 * Returns whether or not the viewer is currently logged in and an admin user.
232
	 *
233
	 * @return bool
234
	 */
235
	public function isAdminLoggedIn() {
236
		$user = $this->getLoggedInUser();
237
	
238
		return $user && $user->isAdmin();
239
	}
240
	
241
	/**
242
	 * Returns whether or not the user is currently logged in
243
	 *
244
	 * @return bool
245
	 */
246
	public function isLoggedIn() {
0 ignored issues
show
Coding Style introduced by
isLoggedIn uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
247
		if (getenv('SOLR_CRAWLER') != '' && $_SERVER['HTTP_USER_AGENT'] === getenv('SOLR_CRAWLER')) return true;
248
		return (bool)$this->getLoggedInUser();
249
	}
250
251
	/**
252
	 * Remove the logged in user
253
	 * 
254
	 * @return void
255
	 * @since 1.9
256
	 */
257
	public function removeLoggedInUser() {
258
		$this->logged_in_user = null;
259
		$this->remove('guid');
260
	}
261
262
	/**
263
	 * Get current ignore access setting.
264
	 *
265
	 * @return bool
266
	 */
267
	public function getIgnoreAccess() {
268
		return $this->ignore_access;
269
	}
270
271
	/**
272
	 * Set ignore access.
273
	 *
274
	 * @param bool $ignore Ignore access
275
	 *
276
	 * @return bool Previous setting
277
	 */
278 3
	public function setIgnoreAccess($ignore = true) {
279 3
		_elgg_services()->accessCache->clear();
280
281 3
		$prev = $this->ignore_access;
282 3
		$this->ignore_access = $ignore;
283
284 3
		return $prev;
285
	}
286
287
	// @codingStandardsIgnoreStart
288
	/**
289
	 * Alias of getIgnoreAccess()
290
	 *
291
	 * @todo remove with elgg_get_access_object()
292
	 *
293
	 * @return bool
294
	 * @deprecated 1.8 Use elgg_get_ignore_access()
295
	 */
296
	public function get_ignore_access() {
297
		return $this->getIgnoreAccess();
298
	}
299
	// @codingStandardsIgnoreEnd
300
301
	// @codingStandardsIgnoreStart
302
	/**
303
	 * Alias of setIgnoreAccess()
304
	 *
305
	 * @todo remove with elgg_get_access_object()
306
	 *
307
	 * @param bool $ignore Ignore access
308
	 *
309
	 * @return bool Previous setting
310
	 *
311
	 * @deprecated 1.8 Use elgg_set_ignore_access()
312
	 */
313
	public function set_ignore_access($ignore = true) {
314
		return $this->setIgnoreAccess($ignore);
315
	}
316
	// @codingStandardsIgnoreEnd
317
318
	/**
319
	 * Adds a token to the session
320
	 * 
321
	 * This is used in creation of CSRF token, and is passed to the client to allow validating tokens
322
	 * later, even if the PHP session was destroyed.
323
	 * 
324
	 * @return void
325
	 */
326 3
	protected function generateSessionToken() {
327
		// Generate a simple token that we store server side
328 3
		if (!$this->has('__elgg_session')) {
329 3
			$this->set('__elgg_session', _elgg_services()->crypto->getRandomString(22));
330 3
		}
331 3
	}
332
333
	/**
334
	 * Test if property is set either as an attribute or metadata.
335
	 *
336
	 * @param string $key The name of the attribute or metadata.
337
	 *
338
	 * @return bool
339
	 * @deprecated 1.9 Use has()
340
	 */
341
	public function __isset($key) {
342
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
343
		// Note: We use offsetExists() for BC
344
		return $this->offsetExists($key);
0 ignored issues
show
Deprecated Code introduced by
The method ElggSession::offsetExists() has been deprecated with message: 1.9 Use has()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
345
	}
346
347
	/**
348
	 * Set a value, go straight to session.
349
	 *
350
	 * @param string $key   Name
351
	 * @param mixed  $value Value
352
	 *
353
	 * @return void
354
	 * @deprecated 1.9 Use set()
355
	 */
356
	public function offsetSet($key, $value) {
357
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
358
		$this->set($key, $value);
359
	}
360
361
	/**
362
	 * Get a variable from either the session, or if its not in the session
363
	 * attempt to get it from an api call.
364
	 *
365
	 * @see \ArrayAccess::offsetGet()
366
	 *
367
	 * @param mixed $key Name
368
	 *
369
	 * @return mixed
370
	 * @deprecated 1.9 Use get()
371
	 */
372
	public function offsetGet($key) {
373
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
374
375
		if (in_array($key, array('user', 'id', 'name', 'username'))) {
376
			elgg_deprecated_notice("Only 'guid' is stored in session for user now", 1.9);
377
			if ($this->logged_in_user) {
378
				switch ($key) {
379
					case 'user':
380
						return $this->logged_in_user;
381
						break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
382
					case 'id':
383
						return $this->logged_in_user->guid;
384
						break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
385
					case 'name':
386
					case 'username':
387
						return $this->logged_in_user->$key;
388
						break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
389
				}
390
			} else {
391
				return null;
392
			}
393
		}
394
395
		if ($this->has($key)) {
396
			return $this->get($key);
397
		}
398
399
		$orig_value = null;
400
		$value = _elgg_services()->hooks->trigger('session:get', $key, null, $orig_value);
401
		if ($orig_value !== $value) {
402
			elgg_deprecated_notice("Plugin hook session:get has been deprecated.", 1.9);
403
		}
404
405
		$this->set($key, $value);
406
		return $value;
407
	}
408
409
	/**
410
	 * Unset a value from the cache and the session.
411
	 *
412
	 * @see \ArrayAccess::offsetUnset()
413
	 *
414
	 * @param mixed $key Name
415
	 *
416
	 * @return void
417
	 * @deprecated 1.9 Use remove()
418
	 */
419
	public function offsetUnset($key) {
420
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
421
		$this->remove($key);
422
	}
423
424
	/**
425
	 * Return whether the value is set in either the session or the cache.
426
	 *
427
	 * @see \ArrayAccess::offsetExists()
428
	 *
429
	 * @param int $offset Offset
430
	 *
431
	 * @return bool
432
	 * @deprecated 1.9 Use has()
433
	 */
434
	public function offsetExists($offset) {
435
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
436
437
		if (in_array($offset, array('user', 'id', 'name', 'username'))) {
438
			elgg_deprecated_notice("Only 'guid' is stored in session for user now", 1.9);
439
			return (bool)$this->logged_in_user;
440
		}
441
442
		if ($this->has($offset)) {
443
			return true;
444
		}
445
446
		// Note: We use offsetGet() for BC
447
		if ($this->offsetGet($offset)) {
0 ignored issues
show
Deprecated Code introduced by
The method ElggSession::offsetGet() has been deprecated with message: 1.9 Use get()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
448
			return true;
449
		}
450
451
		return false;
452
	}
453
454
	/**
455
	 * Get an isolated ElggSession that does not persist between requests
456
	 *
457
	 * @return self
458
	 */
459 79
	public static function getMock() {
460 79
		$storage = new MockArraySessionStorage();
461 79
		$session = new Session($storage);
462 79
		return new self($session);
463
	}
464
}
465