Completed
Pull Request — newinternal (#285)
by Simon
07:17 queued 04:17
created

WebRequest::setGlobalStateProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
    }
38
39
    /**
40
     * Gets the HTTP Method used
41
     * @return string|null
42
     */
43 View Code Duplication
    public static function method()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
44
    {
45
        $server = &self::$globalStateProvider->getServerSuperGlobal();
46
47
        if (isset($server['REQUEST_METHOD'])) {
48
            return $server['REQUEST_METHOD'];
49
        }
50
51
        return null;
52
    }
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 View Code Duplication
        if (isset($server['HTTP_X_FORWARDED_PROTO'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
63
            if ($server['HTTP_X_FORWARDED_PROTO'] === 'https') {
0 ignored issues
show
Coding Style introduced by
The if-else statement can be simplified to return $server['HTTP_X_F...ED_PROTO'] === 'https';.
Loading history...
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 View Code Duplication
        if (isset($server['HTTPS'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    }
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
    }
106
107
    /**
108
     * Gets the remote address of the web request
109
     * @return null|string
110
     */
111 View Code Duplication
    public static function remoteAddress()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
    {
113
        $server = &self::$globalStateProvider->getServerSuperGlobal();
114
115
        if (isset($server['REMOTE_ADDR'])) {
116
            return $server['REMOTE_ADDR'];
117
        }
118
119
        return null;
120
    }
121
122
    /**
123
     * Gets the XFF header contents for the web request
124
     * @return null|string
125
     */
126 View Code Duplication
    public static function forwardedAddress()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    }
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
    }
148
149
    #region POST variables
150
151
    /**
152
     * @param string $key
153
     *
154
     * @return null|string
155
     */
156 View Code Duplication
    public static function postString($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
    {
158
        $post = &self::$globalStateProvider->getPostSuperGlobal();
159
        if (!array_key_exists($key, $post)) {
160
            return null;
161
        }
162
163
        if ($post[$key] === "") {
164
            return null;
165
        }
166
167
        return (string)$post[$key];
168
    }
169
170
    /**
171
     * @param string $key
172
     *
173
     * @return null|string
174
     */
175 View Code Duplication
    public static function postEmail($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    }
190
191
    /**
192
     * @param string $key
193
     *
194
     * @return int|null
195
     */
196 View Code Duplication
    public static function postInt($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    }
211
212
    /**
213
     * @param string $key
214
     *
215
     * @return bool
216
     */
217 View Code Duplication
    public static function postBoolean($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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] === "") {
226
            return true;
227
        }
228
229
        if (in_array($get[$key], array(false, 'no', 'off', 0, 'false'), true)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !in_array($get[$k...f', 0, 'false'), true);.
Loading history...
230
            return false;
231
        }
232
233
        return true;
234
    }
235
236
    #endregion
237
238
    #region GET variables
239
240
    /**
241
     * @param string $key
242
     *
243
     * @return bool
244
     */
245 View Code Duplication
    public static function getBoolean($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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] === "") {
254
            return true;
255
        }
256
257
        if (in_array($get[$key], array(false, 'no', 'off', 0, 'false'), true)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !in_array($get[$k...f', 0, 'false'), true);.
Loading history...
258
            return false;
259
        }
260
261
        return true;
262
    }
263
264
    /**
265
     * @param string $key
266
     *
267
     * @return int|null
268
     */
269 View Code Duplication
    public static function getInt($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    }
284
285
    /**
286
     * @param string $key
287
     *
288
     * @return null|string
289
     */
290 View Code Duplication
    public static function getString($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
291
    {
292
        $get = &self::$globalStateProvider->getGetSuperGlobal();
293
        if (!array_key_exists($key, $get)) {
294
            return null;
295
        }
296
297
        if ($get[$key] === "") {
298
            return null;
299
        }
300
301
        return (string)$get[$key];
302
    }
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
    }
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
    }
327
328
    /**
329
     * @return string|null
330
     */
331 View Code Duplication
    public static function requestUri()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
332
    {
333
        $server = &self::$globalStateProvider->getServerSuperGlobal();
334
335
        if (isset($server['REQUEST_URI'])) {
336
            return $server['REQUEST_URI'];
337
        }
338
339
        return null;
340
    }
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
    }
358
359
    /**
360
     * @return string|null
361
     */
362 View Code Duplication
    public static function serverName()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
363
    {
364
        $server = &self::$globalStateProvider->getServerSuperGlobal();
365
366
        if (isset($server['SERVER_NAME'])) {
367
            return $server['SERVER_NAME'];
368
        }
369
370
        return null;
371
    }
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
    }
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
    }
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
    }
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
    }
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
    }
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
    }
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
    }
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
    }
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
    }
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
    }
500
501
    /**
502
     * @return null|string
503
     */
504 View Code Duplication
    public static function userAgent()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    }
514
515
    /**
516
     * @return null|string
517
     */
518 View Code Duplication
    public static function scriptName()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
519
    {
520
        $server = &self::$globalStateProvider->getServerSuperGlobal();
521
522
        if (isset($server['SCRIPT_NAME'])) {
523
            return $server['SCRIPT_NAME'];
524
        }
525
526
        return null;
527
    }
528
529
    /**
530
     * @return null|string
531
     */
532 View Code Duplication
    public static function origin()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
533
    {
534
        $server = &self::$globalStateProvider->getServerSuperGlobal();
535
536
        if (isset($server['HTTP_ORIGIN'])) {
537
            return $server['HTTP_ORIGIN'];
538
        }
539
540
        return null;
541
    }
542
}