Completed
Branch BUG/11475/decode-site-title-fo... (bbd86e)
by
unknown
13:39 queued 25s
created

Request::userAgent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\services\request;
4
5
use EventEspresso\core\domain\services\contexts\RequestTypeContextCheckerInterface;
6
use EventEspresso\core\interfaces\InterminableInterface;
7
8
defined('EVENT_ESPRESSO_VERSION') || exit;
9
10
11
12
/**
13
 * Class Request
14
 * Representation of an incoming, server-side HTTP request
15
 *
16
 * @package EventEspresso\core\services\request
17
 * @author  Brent Christensen
18
 * @since   4.9.53
19
 */
20
class Request implements InterminableInterface, RequestInterface
21
{
22
23
    /**
24
     * $_GET parameters
25
     *
26
     * @var array $get
27
     */
28
    private $get;
29
30
    /**
31
     * $_POST parameters
32
     *
33
     * @var array $post
34
     */
35
    private $post;
36
37
    /**
38
     * $_COOKIE parameters
39
     *
40
     * @var array $cookie
41
     */
42
    private $cookie;
43
44
    /**
45
     * $_SERVER parameters
46
     *
47
     * @var array $server
48
     */
49
    private $server;
50
51
    /**
52
     * $_REQUEST parameters
53
     *
54
     * @var array $request
55
     */
56
    private $request;
57
58
    /**
59
     * @var RequestTypeContextCheckerInterface
60
     */
61
    private $request_type;
62
63
    /**
64
     * IP address for request
65
     *
66
     * @var string $ip_address
67
     */
68
    private $ip_address;
69
70
    /**
71
     * @var string $user_agent
72
     */
73
    private $user_agent;
74
75
    /**
76
     * true if current user appears to be some kind of bot
77
     *
78
     * @var bool $is_bot
79
     */
80
    private $is_bot;
81
82
83
84
    /**
85
     * @param array                              $get
86
     * @param array                              $post
87
     * @param array                              $cookie
88
     * @param array                              $server
89
     */
90
    public function __construct(array $get, array $post, array $cookie, array $server)
91
    {
92
        // grab request vars
93
        $this->get        = $get;
94
        $this->post       = $post;
95
        $this->cookie     = $cookie;
96
        $this->server     = $server;
97
        $this->request    = array_merge($this->get, $this->post);
98
        $this->ip_address = $this->visitorIp();
99
    }
100
101
102
    /**
103
     * @param RequestTypeContextCheckerInterface $type
104
     */
105
    public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type)
106
    {
107
        $this->request_type = $type;
108
    }
109
110
111
112
    /**
113
     * @return array
114
     */
115
    public function getParams()
116
    {
117
        return $this->get;
118
    }
119
120
121
122
    /**
123
     * @return array
124
     */
125
    public function postParams()
126
    {
127
        return $this->post;
128
    }
129
130
131
132
    /**
133
     * @return array
134
     */
135
    public function cookieParams()
136
    {
137
        return $this->cookie;
138
    }
139
140
141
    /**
142
     * @return array
143
     */
144
    public function serverParams()
145
    {
146
        return $this->server;
147
    }
148
149
150
151
    /**
152
     * returns contents of $_REQUEST
153
     *
154
     * @return array
155
     */
156
    public function requestParams()
157
    {
158
        return $this->request;
159
    }
160
161
162
163
    /**
164
     * @param      $key
165
     * @param      $value
166
     * @param bool $override_ee
167
     * @return    void
168
     */
169
    public function setRequestParam($key, $value, $override_ee = false)
170
    {
171
        // don't allow "ee" to be overwritten unless explicitly instructed to do so
172
        if (
173
            $key !== 'ee'
174
            || ($key === 'ee' && empty($this->request['ee']))
175
            || ($key === 'ee' && ! empty($this->request['ee']) && $override_ee)
176
        ) {
177
            $this->request[ $key ] = $value;
178
        }
179
    }
180
181
182
183
    /**
184
     * returns   the value for a request param if the given key exists
185
     *
186
     * @param       $key
187
     * @param null  $default
188
     * @return mixed
189
     */
190
    public function getRequestParam($key, $default = null)
191
    {
192
        return $this->requestParameterDrillDown($key, $default, 'get');
193
    }
194
195
196
197
    /**
198
     * check if param exists
199
     *
200
     * @param       $key
201
     * @return bool
202
     */
203
    public function requestParamIsSet($key)
204
    {
205
        return $this->requestParameterDrillDown($key);
206
    }
207
208
209
    /**
210
     * check if a request parameter exists whose key that matches the supplied wildcard pattern
211
     * and return the value for the first match found
212
     * wildcards can be either of the following:
213
     *      ? to represent a single character of any type
214
     *      * to represent one or more characters of any type
215
     *
216
     * @param string     $pattern
217
     * @param null|mixed $default
218
     * @return false|int
219
     */
220
    public function getMatch($pattern, $default = null)
221
    {
222
        return $this->requestParameterDrillDown($pattern, $default, 'match');
223
    }
224
225
226
    /**
227
     * check if a request parameter exists whose key matches the supplied wildcard pattern
228
     * wildcards can be either of the following:
229
     *      ? to represent a single character of any type
230
     *      * to represent one or more characters of any type
231
     * returns true if a match is found or false if not
232
     *
233
     * @param string $pattern
234
     * @return false|int
235
     */
236
    public function matches($pattern)
237
    {
238
        return $this->requestParameterDrillDown($pattern, null, 'match') !== null;
239
    }
240
241
242
    /**
243
     * @see https://stackoverflow.com/questions/6163055/php-string-matching-with-wildcard
244
     * @param string $pattern               A string including wildcards to be converted to a regex pattern
245
     *                                      and used to search through the current request's parameter keys
246
     * @param array  $request_params        The array of request parameters to search through
247
     * @param mixed  $default               [optional] The value to be returned if no match is found.
248
     *                                      Default is null
249
     * @param string $return                [optional] Controls what kind of value is returned.
250
     *                                      Options are:
251
     *                                      'bool' will return true or false if match is found or not
252
     *                                      'key' will return the first key found that matches the supplied pattern
253
     *                                      'value' will return the value for the first request parameter
254
     *                                      whose key matches the supplied pattern
255
     *                                      Default is 'value'
256
     * @return boolean|string
257
     */
258
    private function match($pattern, array $request_params, $default = null, $return = 'value')
259
    {
260
        $return = in_array($return, array('bool', 'key', 'value'), true)
261
            ? $return
262
            : 'is_set';
263
        // replace wildcard chars with regex chars
264
        $pattern = str_replace(
265
            array("\*", "\?"),
266
            array('.*', '.'),
267
            preg_quote($pattern, '/')
268
        );
269
        foreach ($request_params as $key => $request_param) {
270
            if (preg_match('/^' . $pattern . '$/is', $key)) {
271
                // return value for request param
272
                if ($return === 'value') {
273
                    return $request_params[ $key ];
274
                }
275
                // or actual key or true just to indicate it was found
276
                return $return === 'key' ? $key : true;
277
            }
278
        }
279
        // match not found so return default value or false
280
        return $return === 'value' ? $default : false;
281
    }
282
283
284
    /**
285
     * the supplied key can be a simple string to represent a "top-level" request parameter
286
     * or represent a key for a request parameter that is nested deeper within the request parameter array,
287
     * by using square brackets to surround keys for deeper array elements.
288
     * For example :
289
     * if the supplied $key was: "first[second][third]"
290
     * then this will attempt to drill down into the request parameter array to find a value.
291
     * Given the following request parameters:
292
     *  array(
293
     *      'first' => array(
294
     *          'second' => array(
295
     *              'third' => 'has a value'
296
     *          )
297
     *      )
298
     *  )
299
     * would return true if default parameters were set
300
     *
301
     * @param string $callback
302
     * @param        $key
303
     * @param null   $default
304
     * @param array  $request_params
305
     * @return bool|mixed|null
306
     */
307
    private function requestParameterDrillDown(
308
        $key,
309
        $default = null,
310
        $callback = 'is_set',
311
        array $request_params = array()
312
    ) {
313
        $callback       = in_array($callback, array('is_set', 'get', 'match'), true)
314
            ? $callback
315
            : 'is_set';
316
        $request_params = ! empty($request_params)
317
            ? $request_params
318
            : $this->request;
319
        // does incoming key represent an array like 'first[second][third]'  ?
320
        if (strpos($key, '[') !== false) {
321
            // turn it into an actual array
322
            $key  = str_replace(']', '', $key);
323
            $keys = explode('[', $key);
324
            $key  = array_shift($keys);
325
            if ($callback === 'match') {
326
                $real_key = $this->match($key, $request_params, $default, 'key');
327
                $key      = $real_key ? $real_key : $key;
328
            }
329
            // check if top level key exists
330
            if (isset($request_params[ $key ])) {
331
                // build a new key to pass along like: 'second[third]'
332
                // or just 'second' depending on depth of keys
333
                $key_string = array_shift($keys);
334
                if (! empty($keys)) {
335
                    $key_string .= '[' . implode('][', $keys) . ']';
336
                }
337
                return $this->requestParameterDrillDown(
338
                    $key_string,
339
                    $default,
340
                    $callback,
341
                    $request_params[ $key ]
342
                );
343
            }
344
        }
345
        if ($callback === 'is_set') {
346
            return isset($request_params[ $key ]);
347
        }
348
        if ($callback === 'match') {
349
            return $this->match($key, $request_params, $default);
350
        }
351
        return isset($request_params[ $key ])
352
            ? $request_params[ $key ]
353
            : $default;
354
    }
355
356
357
    /**
358
     * remove param
359
     *
360
     * @param      $key
361
     * @param bool $unset_from_global_too
362
     */
363
    public function unSetRequestParam($key, $unset_from_global_too = false)
364
    {
365
        unset($this->request[ $key ]);
366
        if ($unset_from_global_too) {
367
            unset($_REQUEST[ $key ]);
368
        }
369
    }
370
371
372
373
    /**
374
     * @return string
375
     */
376
    public function ipAddress()
377
    {
378
        return $this->ip_address;
379
    }
380
381
382
    /**
383
     * attempt to get IP address of current visitor from server
384
     * plz see: http://stackoverflow.com/a/2031935/1475279
385
     *
386
     * @access public
387
     * @return string
388
     */
389
    private function visitorIp()
390
    {
391
        $visitor_ip  = '0.0.0.0';
392
        $server_keys = array(
393
            'HTTP_CLIENT_IP',
394
            'HTTP_X_FORWARDED_FOR',
395
            'HTTP_X_FORWARDED',
396
            'HTTP_X_CLUSTER_CLIENT_IP',
397
            'HTTP_FORWARDED_FOR',
398
            'HTTP_FORWARDED',
399
            'REMOTE_ADDR',
400
        );
401
        foreach ($server_keys as $key) {
402
            if (isset($this->server[ $key ])) {
403
                foreach (array_map('trim', explode(',', $this->server[ $key ])) as $ip) {
404
                    if ($ip === '127.0.0.1' || filter_var($ip, FILTER_VALIDATE_IP) !== false) {
405
                        $visitor_ip = $ip;
406
                    }
407
                }
408
            }
409
        }
410
        return $visitor_ip;
411
    }
412
413
414
    /**
415
     * @return string
416
     */
417
    public function requestUri()
418
    {
419
        $request_uri = filter_input(
420
            INPUT_SERVER,
421
            'REQUEST_URI',
422
            FILTER_SANITIZE_URL,
423
            FILTER_NULL_ON_FAILURE
424
        );
425
        if (empty($request_uri)) {
426
            // fallback sanitization if the above fails
427
            $request_uri = wp_sanitize_redirect($this->server['REQUEST_URI']);
428
        }
429
        return $request_uri;
430
    }
431
432
433
    /**
434
     * @return string
435
     */
436
    public function userAgent()
437
    {
438
        return $this->user_agent;
439
    }
440
441
442
    /**
443
     * @param string $user_agent
444
     */
445
    public function setUserAgent($user_agent = '')
446
    {
447
        if ($user_agent === '' || ! is_string($user_agent)) {
448
            $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? (string) esc_attr($_SERVER['HTTP_USER_AGENT']) : '';
449
        }
450
        $this->user_agent = $user_agent;
451
    }
452
453
454
    /**
455
     * @return bool
456
     */
457
    public function isBot()
458
    {
459
        return $this->is_bot;
460
    }
461
462
463
    /**
464
     * @param bool $is_bot
465
     */
466
    public function setIsBot($is_bot)
467
    {
468
        $this->is_bot = filter_var($is_bot, FILTER_VALIDATE_BOOLEAN);
469
    }
470
471
472
    /**
473
     * @return bool
474
     */
475
    public function isActivation()
476
    {
477
        return $this->request_type->isActivation();
478
    }
479
480
481
    /**
482
     * @param $is_activation
483
     * @return bool
484
     */
485
    public function setIsActivation($is_activation)
486
    {
487
        return $this->request_type->setIsActivation($is_activation);
488
    }
489
490
491
    /**
492
     * @return bool
493
     */
494
    public function isAdmin()
495
    {
496
        return $this->request_type->isAdmin();
497
    }
498
499
500
    /**
501
     * @return bool
502
     */
503
    public function isAdminAjax()
504
    {
505
        return $this->request_type->isAdminAjax();
506
    }
507
508
509
    /**
510
     * @return bool
511
     */
512
    public function isAjax()
513
    {
514
        return $this->request_type->isAjax();
515
    }
516
517
518
    /**
519
     * @return bool
520
     */
521
    public function isEeAjax()
522
    {
523
        return $this->request_type->isEeAjax();
524
    }
525
526
527
    /**
528
     * @return bool
529
     */
530
    public function isOtherAjax()
531
    {
532
        return $this->request_type->isOtherAjax();
533
    }
534
535
536
    /**
537
     * @return bool
538
     */
539
    public function isApi()
540
    {
541
        return $this->request_type->isApi();
542
    }
543
544
545
    /**
546
     * @return bool
547
     */
548
    public function isCli()
549
    {
550
        return $this->request_type->isCli();
551
    }
552
553
554
    /**
555
     * @return bool
556
     */
557
    public function isCron()
558
    {
559
        return $this->request_type->isCron();
560
    }
561
562
563
    /**
564
     * @return bool
565
     */
566
    public function isFeed()
567
    {
568
        return $this->request_type->isFeed();
569
    }
570
571
572
    /**
573
     * @return bool
574
     */
575
    public function isFrontend()
576
    {
577
        return $this->request_type->isFrontend();
578
    }
579
580
581
    /**
582
     * @return bool
583
     */
584
    public function isFrontAjax()
585
    {
586
        return $this->request_type->isFrontAjax();
587
    }
588
589
590
591
    /**
592
     * @return bool
593
     */
594
    public function isIframe()
595
    {
596
        return $this->request_type->isIframe();
597
    }
598
599
600
    /**
601
     * @return string
602
     */
603
    public function slug()
604
    {
605
        return $this->request_type->slug();
606
    }
607
608
609
}
610
// Location: Request.php
611