Completed
Push — search ( 076ba7...2a5267 )
by Simon
16:36 queued 11:48
created

WebRequest   F

Complexity

Total Complexity 81

Size/Duplication

Total Lines 575
Duplicated Lines 0 %

Test Coverage

Coverage 51.92%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
wmc 81
eloc 164
c 5
b 1
f 0
dl 0
loc 575
ccs 108
cts 208
cp 0.5192
rs 2

37 Methods

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

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
/** @noinspection PhpPassByRefInspection - disable seemingly broken check in PhpStorm */
10
11
namespace Waca;
12
13
use Waca\DataObjects\User;
14
use Waca\Providers\GlobalState\IGlobalStateProvider;
15
16
/**
17
 * Holds helper functions regarding the current request.
18
 *
19
 * This is the only place where it is allowed to use super-globals, but even then access MUST be pushed through the
20
 * global state provider to allow for unit tests. It's strongly recommended to do sanitising of data here, especially
21
 * if extra logic is required to get a deterministic value, like isHttps().
22
 *
23
 * @package Waca
24
 */
25
class WebRequest
26
{
27
    /**
28
     * @var IGlobalStateProvider Provides access to the global state.
29
     */
30
    private static $globalStateProvider;
31
32
    /**
33
     * Returns a boolean value if the request was submitted with the HTTP POST method.
34
     * @return bool
35
     */
36 3
    public static function wasPosted()
37
    {
38 3
        return self::method() === 'POST';
39
    }
40
41
    /**
42
     * Gets the HTTP Method used
43
     * @return string|null
44
     */
45 3
    public static function method()
46
    {
47 3
        $server = &self::$globalStateProvider->getServerSuperGlobal();
48
49 3
        if (isset($server['REQUEST_METHOD'])) {
50 2
            return $server['REQUEST_METHOD'];
51
        }
52
53 1
        return null;
54
    }
55
56
    /**
57
     * Gets a boolean value stating whether the request was served over HTTPS or not.
58
     * @return bool
59
     */
60 7
    public static function isHttps()
61
    {
62 7
        $server = &self::$globalStateProvider->getServerSuperGlobal();
63
64 7
        if (isset($server['HTTP_X_FORWARDED_PROTO'])) {
65 3
            if ($server['HTTP_X_FORWARDED_PROTO'] === 'https') {
66
                // Client <=> Proxy is encrypted
67 2
                return true;
68
            }
69
            else {
70
                // Proxy <=> Server link unknown, Client <=> Proxy is not encrypted.
71 1
                return false;
72
            }
73
        }
74
75 4
        if (isset($server['HTTPS'])) {
76 3
            if ($server['HTTPS'] === 'off') {
77
                // ISAPI on IIS breaks the spec. :(
78 1
                return false;
79
            }
80
81 2
            if ($server['HTTPS'] !== '') {
82
                // Set to a non-empty value
83 2
                return true;
84
            }
85
        }
86
87 1
        return false;
88
    }
89
90
    /**
91
     * Gets the path info
92
     *
93
     * @return array Array of path info segments
94
     */
95 13
    public static function pathInfo()
96
    {
97 13
        $server = &self::$globalStateProvider->getServerSuperGlobal();
98 13
        if (!isset($server['PATH_INFO'])) {
99 1
            return array();
100
        }
101
102 12
        $exploded = explode('/', $server['PATH_INFO']);
103
104
        // filter out empty values, and reindex from zero. Notably, the first element is always zero, since it starts
105
        // with a /
106 12
        return array_values(array_filter($exploded));
107
    }
108
109
    /**
110
     * Gets the remote address of the web request
111
     * @return null|string
112
     */
113 2
    public static function remoteAddress()
114
    {
115 2
        $server = &self::$globalStateProvider->getServerSuperGlobal();
116
117 2
        if (isset($server['REMOTE_ADDR'])) {
118 1
            return $server['REMOTE_ADDR'];
119
        }
120
121 1
        return null;
122
    }
123
124
    /**
125
     * Gets the remote address of the web request
126
     * @return null|string
127
     */
128
    public static function httpHost()
129
    {
130
        $server = &self::$globalStateProvider->getServerSuperGlobal();
131
132
        if (isset($server['HTTP_HOST'])) {
133
            return $server['HTTP_HOST'];
134
        }
135
136
        return null;
137
    }
138
139
    /**
140
     * Gets the XFF header contents for the web request
141
     * @return null|string
142
     */
143 2
    public static function forwardedAddress()
144
    {
145 2
        $server = &self::$globalStateProvider->getServerSuperGlobal();
146
147 2
        if (isset($server['HTTP_X_FORWARDED_FOR'])) {
148 1
            return $server['HTTP_X_FORWARDED_FOR'];
149
        }
150
151 1
        return null;
152
    }
153
154
    /**
155
     * Sets the global state provider.
156
     *
157
     * Almost guaranteed this is not the method you want in production code.
158
     *
159
     * @param IGlobalStateProvider $globalState
160
     */
161 51
    public static function setGlobalStateProvider($globalState)
162
    {
163 51
        self::$globalStateProvider = $globalState;
164 51
    }
165
166
    #region POST variables
167
168
    /**
169
     * @param string $key
170
     *
171
     * @return null|string
172
     */
173 1
    public static function postString($key)
174
    {
175 1
        $post = &self::$globalStateProvider->getPostSuperGlobal();
176 1
        if (!array_key_exists($key, $post)) {
177
            return null;
178
        }
179
180 1
        if ($post[$key] === "") {
181 1
            return null;
182
        }
183
184 1
        return (string)$post[$key];
185
    }
186
187
    /**
188
     * @param string $key
189
     *
190
     * @return null|string
191
     */
192
    public static function postEmail($key)
193
    {
194
        $post = &self::$globalStateProvider->getPostSuperGlobal();
195
        if (!array_key_exists($key, $post)) {
196
            return null;
197
        }
198
199
        $filteredValue = filter_var($post[$key], FILTER_SANITIZE_EMAIL);
200
201
        if ($filteredValue === false) {
202
            return null;
203
        }
204
205
        return (string)$filteredValue;
206
    }
207
208
    /**
209
     * @param string $key
210
     *
211
     * @return int|null
212
     */
213 1
    public static function postInt($key)
214
    {
215 1
        $post = &self::$globalStateProvider->getPostSuperGlobal();
216 1
        if (!array_key_exists($key, $post)) {
217 1
            return null;
218
        }
219
220 1
        $filteredValue = filter_var($post[$key], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
221
222 1
        if ($filteredValue === null) {
223 1
            return null;
224
        }
225
226 1
        return (int)$filteredValue;
227
    }
228
229
    /**
230
     * @param string $key
231
     *
232
     * @return bool
233
     */
234 1
    public static function postBoolean($key)
235
    {
236 1
        $get = &self::$globalStateProvider->getPostSuperGlobal();
237 1
        if (!array_key_exists($key, $get)) {
238 1
            return false;
239
        }
240
241
        // presence of parameter only
242 1
        if ($get[$key] === "") {
243 1
            return true;
244
        }
245
246 1
        if (in_array($get[$key], array(false, 'no', 'off', 0, 'false'), true)) {
247 1
            return false;
248
        }
249
250 1
        return true;
251
    }
252
253
    #endregion
254
255
    #region GET variables
256
257
    /**
258
     * @param string $key
259
     *
260
     * @return bool
261
     */
262 1
    public static function getBoolean($key)
263
    {
264 1
        $get = &self::$globalStateProvider->getGetSuperGlobal();
265 1
        if (!array_key_exists($key, $get)) {
266 1
            return false;
267
        }
268
269
        // presence of parameter only
270 1
        if ($get[$key] === "") {
271 1
            return true;
272
        }
273
274 1
        if (in_array($get[$key], array(false, 'no', 'off', 0, 'false'), true)) {
275 1
            return false;
276
        }
277
278 1
        return true;
279
    }
280
281
    /**
282
     * @param string $key
283
     *
284
     * @return int|null
285
     */
286 1
    public static function getInt($key)
287
    {
288 1
        $get = &self::$globalStateProvider->getGetSuperGlobal();
289 1
        if (!array_key_exists($key, $get)) {
290 1
            return null;
291
        }
292
293 1
        $filteredValue = filter_var($get[$key], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
294
295 1
        if ($filteredValue === null) {
296 1
            return null;
297
        }
298
299 1
        return (int)$filteredValue;
300
    }
301
302
    /**
303
     * @param string $key
304
     *
305
     * @return null|string
306
     */
307 7
    public static function getString($key)
308
    {
309 7
        $get = &self::$globalStateProvider->getGetSuperGlobal();
310 7
        if (!array_key_exists($key, $get)) {
311 1
            return null;
312
        }
313
314 6
        if ($get[$key] === "") {
315 1
            return null;
316
        }
317
318 6
        return (string)$get[$key];
319
    }
320
321
    #endregion
322
323
    /**
324
     * Sets the logged-in user to the specified user.
325
     *
326
     * @param User $user
327
     */
328 1
    public static function setLoggedInUser(User $user)
329
    {
330 1
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
331
332 1
        $session['userID'] = $user->getId();
333 1
        unset($session['partialLogin']);
334 1
    }
335
336
    /**
337
     * Sets the post-login redirect
338
     *
339
     * @param string|null $uri The URI to redirect to
340
     */
341 2
    public static function setPostLoginRedirect($uri = null)
342
    {
343 2
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
344
345 2
        if ($uri === null) {
346 2
            $uri = self::requestUri();
347
        }
348
349 2
        $session['returnTo'] = $uri;
350 2
    }
351
352
    /**
353
     * @return string|null
354
     */
355 2
    public static function requestUri()
356
    {
357 2
        $server = &self::$globalStateProvider->getServerSuperGlobal();
358
359 2
        if (isset($server['REQUEST_URI'])) {
360 1
            return $server['REQUEST_URI'];
361
        }
362
363 1
        return null;
364
    }
365
366
    /**
367
     * Clears the post-login redirect
368
     * @return string
369
     */
370 2
    public static function clearPostLoginRedirect()
371
    {
372 2
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
373 2
        if (array_key_exists('returnTo', $session)) {
374 1
            $path = $session['returnTo'];
375 1
            unset($session['returnTo']);
376
377 1
            return $path;
378
        }
379
380 1
        return null;
381
    }
382
383
    /**
384
     * @return string|null
385
     */
386
    public static function serverName()
387
    {
388
        $server = &self::$globalStateProvider->getServerSuperGlobal();
389
390
        if (isset($server['SERVER_NAME'])) {
391
            return $server['SERVER_NAME'];
392
        }
393
394
        return null;
395
    }
396
397
    /**
398
     * You probably only want to deal with this through SessionAlert.
399
     * @return void
400
     */
401
    public static function clearSessionAlertData()
402
    {
403
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
404
        if (array_key_exists('alerts', $session)) {
405
            unset($session['alerts']);
406
        }
407
    }
408
409
    /**
410
     * You probably only want to deal with this through SessionAlert.
411
     *
412
     * @return string[]
413
     */
414
    public static function getSessionAlertData()
415
    {
416
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
417
        if (array_key_exists('alerts', $session)) {
418
            return $session['alerts'];
419
        }
420
421
        return array();
422
    }
423
424
    /**
425
     * You probably only want to deal with this through SessionAlert.
426
     *
427
     * @param string[] $data
428
     */
429
    public static function setSessionAlertData($data)
430
    {
431
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
432
        $session['alerts'] = $data;
433
    }
434
435
    /**
436
     * You probably only want to deal with this through TokenManager.
437
     *
438
     * @return string[]
439
     */
440
    public static function getSessionTokenData()
441
    {
442
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
443
        if (array_key_exists('tokens', $session)) {
444
            return $session['tokens'];
445
        }
446
447
        return array();
448
    }
449
450
    /**
451
     * You probably only want to deal with this through TokenManager.
452
     *
453
     * @param string[] $data
454
     */
455
    public static function setSessionTokenData($data)
456
    {
457
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
458
        $session['tokens'] = $data;
459
    }
460
461
    /**
462
     * @param string $key
463
     *
464
     * @return mixed
465
     */
466
    public static function getSessionContext($key)
467
    {
468
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
469
470
        if (!isset($session['context'])) {
471
            $session['context'] = array();
472
        }
473
474
        if (!isset($session['context'][$key])) {
475
            return null;
476
        }
477
478
        return $session['context'][$key];
479
    }
480
481
    /**
482
     * @param string $key
483
     * @param mixed  $data
484
     */
485
    public static function setSessionContext($key, $data)
486
    {
487
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
488
489
        if (!isset($session['context'])) {
490
            $session['context'] = array();
491
        }
492
493
        $session['context'][$key] = $data;
494
    }
495
496
    /**
497
     * @return int|null
498
     */
499
    public static function getSessionUserId()
500
    {
501
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
502
503
        return isset($session['userID']) ? (int)$session['userID'] : null;
504
    }
505
506
    /**
507
     * @param User $user
508
     */
509
    public static function setOAuthPartialLogin(User $user)
510
    {
511
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
512
        $session['oauthPartialLogin'] = $user->getId();
513
    }
514
515
    /**
516
     * @return int|null
517
     */
518
    public static function getOAuthPartialLogin()
519
    {
520
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
521
522
        return isset($session['oauthPartialLogin']) ? (int)$session['oauthPartialLogin'] : null;
523
    }
524
525
    public static function setAuthPartialLogin($userId, $stage)
526
    {
527
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
528
        $session['authPartialLoginId'] = $userId;
529
        $session['authPartialLoginStage'] = $stage;
530
    }
531
532
    public static function getAuthPartialLogin()
533
    {
534
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
535
536
        $userId = isset($session['authPartialLoginId']) ? (int)$session['authPartialLoginId'] : null;
537
        $stage = isset($session['authPartialLoginStage']) ? (int)$session['authPartialLoginStage'] : null;
538
539
        return array($userId, $stage);
540
    }
541
542
    public static function clearAuthPartialLogin()
543
    {
544
        $session = &self::$globalStateProvider->getSessionSuperGlobal();
545
        unset($session['authPartialLoginId']);
546
        unset($session['authPartialLoginStage']);
547
    }
548
549
    /**
550
     * @return null|string
551
     */
552
    public static function userAgent()
553
    {
554
        $server = &self::$globalStateProvider->getServerSuperGlobal();
555
556
        if (isset($server['HTTP_USER_AGENT'])) {
557
            return $server['HTTP_USER_AGENT'];
558
        }
559
560
        return null;
561
    }
562
563
    /**
564
     * @return null|string
565
     */
566
    public static function scriptName()
567
    {
568
        $server = &self::$globalStateProvider->getServerSuperGlobal();
569
570
        if (isset($server['SCRIPT_NAME'])) {
571
            return $server['SCRIPT_NAME'];
572
        }
573
574
        return null;
575
    }
576
577
    /**
578
     * @return null|string
579
     */
580
    public static function origin()
581
    {
582
        $server = &self::$globalStateProvider->getServerSuperGlobal();
583
584
        if (isset($server['HTTP_ORIGIN'])) {
585
            return $server['HTTP_ORIGIN'];
586
        }
587
588
        return null;
589
    }
590
591
    public static function testSiteNoticeCookieValue($expectedHash)
592
    {
593
        $cookie = &self::$globalStateProvider->getCookieSuperGlobal();
594
595
        if(isset($cookie['sitenotice'])) {
596
            return $cookie['sitenotice'] === $expectedHash;
597
        }
598
599
        return false;
600
    }
601
}
602