Completed
Branch FET/conditional-update-queries (7f5e44)
by
unknown
20:59 queued 12:06
created

Request::filesParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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