Failed Conditions
Push — rbac ( be68b4...52c28b )
by Michael
03:11
created

WebRequest   F

Complexity

Total Complexity 71

Size/Duplication

Total Lines 518
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
wmc 71
eloc 144
c 5
b 1
f 0
dl 0
loc 518
ccs 0
cts 275
cp 0
rs 2.7199

32 Methods

Rating   Name   Duplication   Size   Complexity  
A origin() 0 9 2
A postInt() 0 14 3
A userAgent() 0 9 2
A forwardedAddress() 0 9 2
A setGlobalStateProvider() 0 3 1
A getBoolean() 0 17 4
A serverName() 0 9 2
A pathInfo() 0 12 2
A requestUri() 0 9 2
A setLoggedInUser() 0 6 1
A setPostLoginRedirect() 0 4 1
A getSessionAlertData() 0 8 2
A scriptName() 0 9 2
A remoteAddress() 0 9 2
A getPartialLogin() 0 5 2
A getString() 0 12 3
A getSessionUserId() 0 5 2
A method() 0 9 2
A wasPosted() 0 3 1
A setPartialLogin() 0 4 1
A postString() 0 12 3
A clearPostLoginRedirect() 0 11 2
A getSessionContext() 0 13 3
A setSessionTokenData() 0 4 1
A getSessionTokenData() 0 8 2
A setSessionContext() 0 9 2
A getInt() 0 14 3
A isHttps() 0 28 6
A postEmail() 0 14 3
A clearSessionAlertData() 0 5 2
A postBoolean() 0 17 4
A setSessionAlertData() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like WebRequest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WebRequest, and based on these observations, apply Extract Interface, too.

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca;
10
11
use Waca\DataObjects\User;
12
use Waca\Providers\GlobalState\IGlobalStateProvider;
13
14
/**
15
 * Holds helper functions regarding the current request.
16
 *
17
 * This is the only place where it is allowed to use super-globals, but even then access MUST be pushed through the
18
 * global state provider to allow for unit tests. It's strongly recommended to do sanitising of data here, especially
19
 * if extra logic is required to get a deterministic value, like isHttps().
20
 *
21
 * @package Waca
22
 */
23
class WebRequest
24
{
25
    /**
26
     * @var \Waca\Providers\GlobalState\IGlobalStateProvider Provides access to the global state.
27
     */
28
    private static $globalStateProvider;
29
30
    /**
31
     * Returns a boolean value if the request was submitted with the HTTP POST method.
32
     * @return bool
33
     */
34
    public static function wasPosted()
35
    {
36
        return self::method() === 'POST';
37
    }
0 ignored issues
show
Coding Style introduced by
Expected //end wasPosted()
Loading history...
38
39
    /**
40
     * Gets the HTTP Method used
41
     * @return string|null
42
     */
43
    public static function method()
44
    {
45
        $server = &self::$globalStateProvider->getServerSuperGlobal();
46
47
        if (isset($server['REQUEST_METHOD'])) {
48
            return $server['REQUEST_METHOD'];
49
        }
50
51
        return null;
52
    }
0 ignored issues
show
Coding Style introduced by
Expected //end method()
Loading history...
53
54
    /**
55
     * Gets a boolean value stating whether the request was served over HTTPS or not.
56
     * @return bool
57
     */
58
    public static function isHttps()
59
    {
60
        $server = &self::$globalStateProvider->getServerSuperGlobal();
61
62
        if (isset($server['HTTP_X_FORWARDED_PROTO'])) {
63
            if ($server['HTTP_X_FORWARDED_PROTO'] === 'https') {
64
                // Client <=> Proxy is encrypted
65
                return true;
66
            }
67
            else {
68
                // Proxy <=> Server link unknown, Client <=> Proxy is not encrypted.
69
                return false;
70
            }
71
        }
72
73
        if (isset($server['HTTPS'])) {
74
            if ($server['HTTPS'] === 'off') {
75
                // ISAPI on IIS breaks the spec. :(
76
                return false;
77
            }
78
79
            if ($server['HTTPS'] !== '') {
80
                // Set to a non-empty value
81
                return true;
82
            }
83
        }
84
85
        return false;
86
    }
0 ignored issues
show
Coding Style introduced by
Expected //end isHttps()
Loading history...
87
88
    /**
89
     * Gets the path info
90
     *
91
     * @return array Array of path info segments
92
     */
93
    public static function pathInfo()
94
    {
95
        $server = &self::$globalStateProvider->getServerSuperGlobal();
96
        if (!isset($server['PATH_INFO'])) {
97
            return array();
98
        }
99
100
        $exploded = explode('/', $server['PATH_INFO']);
101
102
        // filter out empty values, and reindex from zero. Notably, the first element is always zero, since it starts
103
        // with a /
104
        return array_values(array_filter($exploded));
105
    }
0 ignored issues
show
Coding Style introduced by
Expected //end pathInfo()
Loading history...
106
107
    /**
108
     * Gets the remote address of the web request
109
     * @return null|string
110
     */
111
    public static function remoteAddress()
112
    {
113
        $server = &self::$globalStateProvider->getServerSuperGlobal();
114
115
        if (isset($server['REMOTE_ADDR'])) {
116
            return $server['REMOTE_ADDR'];
117
        }
118
119
        return null;
120
    }
0 ignored issues
show
Coding Style introduced by
Expected //end remoteAddress()
Loading history...
121
122
    /**
123
     * Gets the XFF header contents for the web request
124
     * @return null|string
125
     */
126
    public static function forwardedAddress()
127
    {
128
        $server = &self::$globalStateProvider->getServerSuperGlobal();
129
130
        if (isset($server['HTTP_X_FORWARDED_FOR'])) {
131
            return $server['HTTP_X_FORWARDED_FOR'];
132
        }
133
134
        return null;
135
    }
0 ignored issues
show
Coding Style introduced by
Expected //end forwardedAddress()
Loading history...
136
137
    /**
138
     * Sets the global state provider.
139
     *
140
     * Almost guaranteed this is not the method you want in production code.
141
     *
142
     * @param \Waca\Providers\GlobalState\IGlobalStateProvider $globalState
143
     */
144
    public static function setGlobalStateProvider($globalState)
145
    {
146
        self::$globalStateProvider = $globalState;
147
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setGlobalStateProvider()
Loading history...
148
149
    #region POST variables
150
151
    /**
152
     * @param string $key
153
     *
154
     * @return null|string
155
     */
156
    public static function postString($key)
157
    {
158
        $post = &self::$globalStateProvider->getPostSuperGlobal();
159
        if (!array_key_exists($key, $post)) {
160
            return null;
161
        }
162
163
        if ($post[$key] === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
164
            return null;
165
        }
166
167
        return (string)$post[$key];
168
    }
0 ignored issues
show
Coding Style introduced by
Expected //end postString()
Loading history...
169
170
    /**
171
     * @param string $key
172
     *
173
     * @return null|string
174
     */
175
    public static function postEmail($key)
176
    {
177
        $post = &self::$globalStateProvider->getPostSuperGlobal();
178
        if (!array_key_exists($key, $post)) {
179
            return null;
180
        }
181
182
        $filteredValue = filter_var($post[$key], FILTER_SANITIZE_EMAIL);
183
184
        if ($filteredValue === false) {
185
            return null;
186
        }
187
188
        return (string)$filteredValue;
189
    }
0 ignored issues
show
Coding Style introduced by
Expected //end postEmail()
Loading history...
190
191
    /**
192
     * @param string $key
193
     *
194
     * @return int|null
195
     */
196
    public static function postInt($key)
197
    {
198
        $post = &self::$globalStateProvider->getPostSuperGlobal();
199
        if (!array_key_exists($key, $post)) {
200
            return null;
201
        }
202
203
        $filteredValue = filter_var($post[$key], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
204
205
        if ($filteredValue === null) {
206
            return null;
207
        }
208
209
        return (int)$filteredValue;
210
    }
0 ignored issues
show
Coding Style introduced by
Expected //end postInt()
Loading history...
211
212
    /**
213
     * @param string $key
214
     *
215
     * @return bool
216
     */
217
    public static function postBoolean($key)
218
    {
219
        $get = &self::$globalStateProvider->getPostSuperGlobal();
220
        if (!array_key_exists($key, $get)) {
221
            return false;
222
        }
223
224
        // presence of parameter only
225
        if ($get[$key] === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
226
            return true;
227
        }
228
229
        if (in_array($get[$key], array(false, 'no', 'off', 0, 'false'), true)) {
230
            return false;
231
        }
232
233
        return true;
234
    }
0 ignored issues
show
Coding Style introduced by
Expected //end postBoolean()
Loading history...
235
236
    #endregion
237
238
    #region GET variables
239
240
    /**
241
     * @param string $key
242
     *
243
     * @return bool
244
     */
245
    public static function getBoolean($key)
246
    {
247
        $get = &self::$globalStateProvider->getGetSuperGlobal();
248
        if (!array_key_exists($key, $get)) {
249
            return false;
250
        }
251
252
        // presence of parameter only
253
        if ($get[$key] === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
254
            return true;
255
        }
256
257
        if (in_array($get[$key], array(false, 'no', 'off', 0, 'false'), true)) {
258
            return false;
259
        }
260
261
        return true;
262
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getBoolean()
Loading history...
263
264
    /**
265
     * @param string $key
266
     *
267
     * @return int|null
268
     */
269
    public static function getInt($key)
270
    {
271
        $get = &self::$globalStateProvider->getGetSuperGlobal();
272
        if (!array_key_exists($key, $get)) {
273
            return null;
274
        }
275
276
        $filteredValue = filter_var($get[$key], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
277
278
        if ($filteredValue === null) {
279
            return null;
280
        }
281
282
        return (int)$filteredValue;
283
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getInt()
Loading history...
284
285
    /**
286
     * @param string $key
287
     *
288
     * @return null|string
289
     */
290
    public static function getString($key)
291
    {
292
        $get = &self::$globalStateProvider->getGetSuperGlobal();
293
        if (!array_key_exists($key, $get)) {
294
            return null;
295
        }
296
297
        if ($get[$key] === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
298
            return null;
299
        }
300
301
        return (string)$get[$key];
302
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getString()
Loading history...
303
304
    #endregion
305
306
    /**
307
     * Sets the logged-in user to the specified user.
308
     *
309
     * @param User $user
310
     */
311
    public static function setLoggedInUser(User $user)
312
    {
313
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
314
315
        $session['userID'] = $user->getId();
316
        unset($session['partialLogin']);
317
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setLoggedInUser()
Loading history...
318
319
    /**
320
     * Sets the post-login redirect
321
     */
322
    public static function setPostLoginRedirect()
323
    {
324
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
325
        $session['returnTo'] = self::requestUri();
326
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setPostLoginRedirect()
Loading history...
327
328
    /**
329
     * @return string|null
330
     */
331
    public static function requestUri()
332
    {
333
        $server = &self::$globalStateProvider->getServerSuperGlobal();
334
335
        if (isset($server['REQUEST_URI'])) {
336
            return $server['REQUEST_URI'];
337
        }
338
339
        return null;
340
    }
0 ignored issues
show
Coding Style introduced by
Expected //end requestUri()
Loading history...
341
342
    /**
343
     * Clears the post-login redirect
344
     * @return string
345
     */
346
    public static function clearPostLoginRedirect()
347
    {
348
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
349
        if (array_key_exists('returnTo', $session)) {
350
            $path = $session['returnTo'];
351
            unset($session['returnTo']);
352
353
            return $path;
354
        }
355
356
        return null;
357
    }
0 ignored issues
show
Coding Style introduced by
Expected //end clearPostLoginRedirect()
Loading history...
358
359
    /**
360
     * @return string|null
361
     */
362
    public static function serverName()
363
    {
364
        $server = &self::$globalStateProvider->getServerSuperGlobal();
365
366
        if (isset($server['SERVER_NAME'])) {
367
            return $server['SERVER_NAME'];
368
        }
369
370
        return null;
371
    }
0 ignored issues
show
Coding Style introduced by
Expected //end serverName()
Loading history...
372
373
    /**
374
     * You probably only want to deal with this through SessionAlert.
375
     * @return void
376
     */
377
    public static function clearSessionAlertData()
378
    {
379
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
380
        if (array_key_exists('alerts', $session)) {
381
            unset($session['alerts']);
382
        }
383
    }
0 ignored issues
show
Coding Style introduced by
Expected //end clearSessionAlertData()
Loading history...
384
385
    /**
386
     * You probably only want to deal with this through SessionAlert.
387
     *
388
     * @return string[]
389
     */
390
    public static function getSessionAlertData()
391
    {
392
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
393
        if (array_key_exists('alerts', $session)) {
394
            return $session['alerts'];
395
        }
396
397
        return array();
398
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getSessionAlertData()
Loading history...
399
400
    /**
401
     * You probably only want to deal with this through SessionAlert.
402
     *
403
     * @param string[] $data
404
     */
405
    public static function setSessionAlertData($data)
406
    {
407
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
408
        $session['alerts'] = $data;
409
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setSessionAlertData()
Loading history...
410
411
    /**
412
     * You probably only want to deal with this through TokenManager.
413
     *
414
     * @return string[]
415
     */
416
    public static function getSessionTokenData()
417
    {
418
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
419
        if (array_key_exists('tokens', $session)) {
420
            return $session['tokens'];
421
        }
422
423
        return array();
424
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getSessionTokenData()
Loading history...
425
426
    /**
427
     * You probably only want to deal with this through TokenManager.
428
     *
429
     * @param string[] $data
430
     */
431
    public static function setSessionTokenData($data)
432
    {
433
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
434
        $session['tokens'] = $data;
435
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setSessionTokenData()
Loading history...
436
437
    /**
438
     * @param string $key
439
     *
440
     * @return mixed
441
     */
442
    public static function getSessionContext($key)
443
    {
444
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
445
446
        if (!isset($session['context'])) {
447
            $session['context'] = array();
448
        }
449
450
        if (!isset($session['context'][$key])) {
451
            return null;
452
        }
453
454
        return $session['context'][$key];
455
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getSessionContext()
Loading history...
456
457
    /**
458
     * @param string $key
459
     * @param mixed  $data
460
     */
461
    public static function setSessionContext($key, $data)
462
    {
463
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
464
465
        if (!isset($session['context'])) {
466
            $session['context'] = array();
467
        }
468
469
        $session['context'][$key] = $data;
470
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setSessionContext()
Loading history...
471
472
    /**
473
     * @return int|null
474
     */
475
    public static function getSessionUserId()
476
    {
477
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
478
479
        return isset($session['userID']) ? (int)$session['userID'] : null;
480
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getSessionUserId()
Loading history...
481
482
    /**
483
     * @param User $user
484
     */
485
    public static function setPartialLogin(User $user)
486
    {
487
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
488
        $session['partialLogin'] = $user->getId();
489
    }
0 ignored issues
show
Coding Style introduced by
Expected //end setPartialLogin()
Loading history...
490
491
    /**
492
     * @return int|null
493
     */
494
    public static function getPartialLogin()
495
    {
496
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
497
498
        return isset($session['partialLogin']) ? (int)$session['partialLogin'] : null;
499
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getPartialLogin()
Loading history...
500
501
    /**
502
     * @return null|string
503
     */
504
    public static function userAgent()
505
    {
506
        $server = &self::$globalStateProvider->getServerSuperGlobal();
507
508
        if (isset($server['HTTP_USER_AGENT'])) {
509
            return $server['HTTP_USER_AGENT'];
510
        }
511
512
        return null;
513
    }
0 ignored issues
show
Coding Style introduced by
Expected //end userAgent()
Loading history...
514
515
    /**
516
     * @return null|string
517
     */
518
    public static function scriptName()
519
    {
520
        $server = &self::$globalStateProvider->getServerSuperGlobal();
521
522
        if (isset($server['SCRIPT_NAME'])) {
523
            return $server['SCRIPT_NAME'];
524
        }
525
526
        return null;
527
    }
0 ignored issues
show
Coding Style introduced by
Expected //end scriptName()
Loading history...
528
529
    /**
530
     * @return null|string
531
     */
532
    public static function origin()
533
    {
534
        $server = &self::$globalStateProvider->getServerSuperGlobal();
535
536
        if (isset($server['HTTP_ORIGIN'])) {
537
            return $server['HTTP_ORIGIN'];
538
        }
539
540
        return null;
541
    }
0 ignored issues
show
Coding Style introduced by
Expected //end origin()
Loading history...
542
}
0 ignored issues
show
Coding Style introduced by
Expected //end class
Loading history...