GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( ac3740...a48291 )
by Patrique
01:31
created

ServerRequest::getAttributes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Patoui\Router;
6
7
use InvalidArgumentException;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Message\StreamInterface;
10
use Psr\Http\Message\UriInterface;
11
12
class ServerRequest implements ServerRequestInterface
13
{
14
    /**
15
     * @var string Represent the HTTP version number (e.g., "1.1", "1.0")
16
     */
17
    private $version;
18
19
    /**
20
     * @var array Contains header by key and array.
21
     * e.g. ['content-type' => ['application/json']]
22
     */
23
    private $headers;
24
25
    /** @var StreamInterface */
26
    private $body;
27
28
    /** @var string */
29
    private $requestTarget;
30
31
    /** @var string */
32
    private $method;
33
34
    public function __construct(
35
        string $version,
36
        array $headers,
37
        StreamInterface $body,
38
        string $requestTarget,
39
        string $method
40
    ) {
41
        $this->validateProtocolVersion($version);
42
        $this->validateHeaders($headers);
43
        $this->validateMethod($method);
44
45
        $this->version = $version;
46
        $this->headers = $headers;
47
        $this->body = $body;
48
        $this->requestTarget = $requestTarget;
49
        $this->method = $method;
50
    }
51
52
    /**
53
     * Retrieves the HTTP protocol version as a string.
54
     *
55
     * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
56
     *
57
     * @return string HTTP protocol version.
58
     */
59
    public function getProtocolVersion()
60
    {
61
        return $this->version;
62
    }
63
64
    /**
65
     * Return an instance with the specified HTTP protocol version.
66
     *
67
     * The version string MUST contain only the HTTP version number (e.g.,
68
     * "1.1", "1.0").
69
     *
70
     * This method MUST be implemented in such a way as to retain the
71
     * immutability of the message, and MUST return an instance that has the
72
     * new protocol version.
73
     *
74
     * @param  string  $version  HTTP protocol version
75
     * @return static
76
     */
77
    public function withProtocolVersion($version) : self
78
    {
79
        $this->validateProtocolVersion($version);
80
81
        return new static(
0 ignored issues
show
Bug introduced by
The call to ServerRequest::__construct() misses some required arguments starting with $requestTarget.
Loading history...
82
            $version,
83
            $this->getHeaders(),
84
            $this->getBody()
85
        );
86
    }
87
88
    /**
89
     * Verifies the protocol version.
90
     *
91
     * @throws InvalidArgumentException
92
     * @param  string  $version The version string MUST contain only the HTTP
93
     * version number (e.g., "1.1", "1.0").
94
     */
95
    private function validateProtocolVersion(string $version) : void
96
    {
97
        if (! in_array($version, ['1.1', '2.0'])) {
98
            throw new InvalidArgumentException("Invalid HTTP version: {$version}");
99
        }
100
    }
101
102
    /**
103
     * Retrieves all message header values.
104
     *
105
     * The keys represent the header name as it will be sent over the wire, and
106
     * each value is an array of strings associated with the header.
107
     *
108
     *     // Represent the headers as a string
109
     *     foreach ($message->getHeaders() as $name => $values) {
110
     *         echo $name . ": " . implode(", ", $values);
111
     *     }
112
     *
113
     *     // Emit headers iteratively:
114
     *     foreach ($message->getHeaders() as $name => $values) {
115
     *         foreach ($values as $value) {
116
     *             header(sprintf('%s: %s', $name, $value), false);
117
     *         }
118
     *     }
119
     *
120
     * While header names are not case-sensitive, getHeaders() will preserve the
121
     * exact case in which headers were originally specified.
122
     *
123
     * @return string[][] Returns an associative array of the message's headers. Each
124
     *     key MUST be a header name, and each value MUST be an array of strings
125
     *     for that header.
126
     */
127
    public function getHeaders()
128
    {
129
        return $this->headers;
130
    }
131
132
    /**
133
     * Checks if a header exists by the given case-insensitive name.
134
     *
135
     * @param  string  $name  Case-insensitive header field name.
136
     * @return bool Returns true if any header names match the given header
137
     *     name using a case-insensitive string comparison. Returns false if
138
     *     no matching header name is found in the message.
139
     */
140
    public function hasHeader($name)
141
    {
142
        return array_key_exists(
143
            mb_strtoupper($name),
144
            array_change_key_case($this->headers, CASE_UPPER)
145
        );
146
    }
147
148
    /**
149
     * Retrieves a message header value by the given case-insensitive name.
150
     *
151
     * This method returns an array of all the header values of the given
152
     * case-insensitive header name.
153
     *
154
     * If the header does not appear in the message, this method MUST return an
155
     * empty array.
156
     *
157
     * @param  string  $name  Case-insensitive header field name.
158
     * @return string[] An array of string values as provided for the given
159
     *    header. If the header does not appear in the message, this method MUST
160
     *    return an empty array.
161
     */
162
    public function getHeader($name)
163
    {
164
        $name = mb_strtoupper($name);
165
        $headers = array_change_key_case($this->headers, CASE_UPPER);
166
167
        if (array_key_exists($name, $headers) === false) {
168
            return [];
169
        }
170
171
        return $headers[$name];
172
    }
173
174
    /**
175
     * Retrieves a comma-separated string of the values for a single header.
176
     *
177
     * This method returns all of the header values of the given
178
     * case-insensitive header name as a string concatenated together using
179
     * a comma.
180
     *
181
     * NOTE: Not all header values may be appropriately represented using
182
     * comma concatenation. For such headers, use getHeader() instead
183
     * and supply your own delimiter when concatenating.
184
     *
185
     * If the header does not appear in the message, this method MUST return
186
     * an empty string.
187
     *
188
     * @param  string  $name  Case-insensitive header field name.
189
     * @return string A string of values as provided for the given header
190
     *    concatenated together using a comma. If the header does not appear in
191
     *    the message, this method MUST return an empty string.
192
     */
193
    public function getHeaderLine($name)
194
    {
195
        return implode(',', $this->getHeader($name));
196
    }
197
198
    /**
199
     * Return an instance with the provided value replacing the specified header.
200
     *
201
     * While header names are case-insensitive, the casing of the header will
202
     * be preserved by this function, and returned from getHeaders().
203
     *
204
     * This method MUST be implemented in such a way as to retain the
205
     * immutability of the message, and MUST return an instance that has the
206
     * new and/or updated header and value.
207
     *
208
     * @param  string  $name  Case-insensitive header field name.
209
     * @param  string|string[]  $value  Header value(s).
210
     * @return static
211
     * @throws \InvalidArgumentException for invalid header names or values.
212
     */
213
    public function withHeader($name, $value)
214
    {
215
        $newHeaders = array_merge($this->getHeaders(), [$name => [$value]]);
216
217
        return new static(
0 ignored issues
show
Bug introduced by
The call to ServerRequest::__construct() misses some required arguments starting with $requestTarget.
Loading history...
218
            $this->getProtocolVersion(),
219
            $newHeaders,
220
            $this->getBody()
221
        );
222
    }
223
224
    /**
225
     * Return an instance with the specified header appended with the given value.
226
     *
227
     * Existing values for the specified header will be maintained. The new
228
     * value(s) will be appended to the existing list. If the header did not
229
     * exist previously, it will be added.
230
     *
231
     * This method MUST be implemented in such a way as to retain the
232
     * immutability of the message, and MUST return an instance that has the
233
     * new header and/or value.
234
     *
235
     * @param  string  $name  Case-insensitive header field name to add.
236
     * @param  string|string[]  $value  Header value(s).
237
     * @return static
238
     * @throws \InvalidArgumentException for invalid header names or values.
239
     */
240
    public function withAddedHeader($name, $value)
241
    {
242
        $newHeaders = $this->getHeaders();
243
        $headerToUpdate = $this->getHeader($name);
244
        $headerToUpdate[] = $value;
245
        $newHeaders[$name] = $headerToUpdate;
246
247
        return new static(
0 ignored issues
show
Bug introduced by
The call to ServerRequest::__construct() misses some required arguments starting with $requestTarget.
Loading history...
248
            $this->getProtocolVersion(),
249
            $newHeaders,
250
            $this->getBody()
251
        );
252
    }
253
254
    /**
255
     * Return an instance without the specified header.
256
     *
257
     * Header resolution MUST be done without case-sensitivity.
258
     *
259
     * This method MUST be implemented in such a way as to retain the
260
     * immutability of the message, and MUST return an instance that removes
261
     * the named header.
262
     *
263
     * @param  string  $name  Case-insensitive header field name to remove.
264
     * @return static
265
     */
266
    public function withoutHeader($name)
267
    {
268
        $newHeaders = $this->getHeaders();
269
        unset($newHeaders[$name]);
270
271
        return new static(
0 ignored issues
show
Bug introduced by
The call to ServerRequest::__construct() misses some required arguments starting with $requestTarget.
Loading history...
272
            $this->getProtocolVersion(),
273
            $newHeaders,
274
            $this->getBody()
275
        );
276
    }
277
278
    /**
279
     * Verifies the headers are valid.
280
     *
281
     * @throws InvalidArgumentException
282
     * @param  array  $headers Headers for the incoming request
283
     */
284
    private function validateHeaders(array $headers) : void
285
    {
286
        $exceptionMessage = 'Invalid headers: '.json_encode($headers);
287
288
        if (empty($headers)) {
289
            return;
290
        }
291
292
        $headersWithArraysOnly = array_filter($headers, function ($header) {
293
            return is_array($header);
294
        });
295
296
        if (count($headers) !== count($headersWithArraysOnly)) {
297
            throw new InvalidArgumentException($exceptionMessage);
298
        }
299
300
        foreach ($headers as $key => $header) {
301
            $headerWithStringValuesOnly = array_filter($header, function ($headerValue) {
302
                return is_string($headerValue);
303
            });
304
305
            if (count($header) !== count($headerWithStringValuesOnly)) {
306
                throw new InvalidArgumentException($exceptionMessage);
307
            }
308
        }
309
    }
310
311
    /**
312
     * Gets the body of the message.
313
     *
314
     * @return StreamInterface Returns the body as a stream.
315
     */
316
    public function getBody()
317
    {
318
        return $this->body;
319
    }
320
321
    /**
322
     * Return an instance with the specified message body.
323
     *
324
     * The body MUST be a StreamInterface object.
325
     *
326
     * This method MUST be implemented in such a way as to retain the
327
     * immutability of the message, and MUST return a new instance that has the
328
     * new body stream.
329
     *
330
     * @param  StreamInterface  $body  Body.
331
     * @return static
332
     * @throws \InvalidArgumentException When the body is not valid.
333
     */
334
    public function withBody(StreamInterface $body)
335
    {
336
        return new static(
0 ignored issues
show
Bug introduced by
The call to ServerRequest::__construct() misses some required arguments starting with $requestTarget.
Loading history...
337
            $this->getProtocolVersion(),
338
            $this->getHeaders(),
339
            $body
340
        );
341
    }
342
343
    /**
344
     * Retrieves the message's request target.
345
     *
346
     * Retrieves the message's request-target either as it will appear (for
347
     * clients), as it appeared at request (for servers), or as it was
348
     * specified for the instance (see withRequestTarget()).
349
     *
350
     * In most cases, this will be the origin-form of the composed URI,
351
     * unless a value was provided to the concrete implementation (see
352
     * withRequestTarget() below).
353
     *
354
     * If no URI is available, and no request-target has been specifically
355
     * provided, this method MUST return the string "/".
356
     *
357
     * @return string
358
     */
359
    public function getRequestTarget()
360
    {
361
        return $this->requestTarget;
362
    }
363
364
    /**
365
     * Return an instance with the specific request-target.
366
     *
367
     * If the request needs a non-origin-form request-target — e.g., for
368
     * specifying an absolute-form, authority-form, or asterisk-form —
369
     * this method may be used to create an instance with the specified
370
     * request-target, verbatim.
371
     *
372
     * This method MUST be implemented in such a way as to retain the
373
     * immutability of the message, and MUST return an instance that has the
374
     * changed request target.
375
     *
376
     * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
377
     *     request-target forms allowed in request messages)
378
     * @param  mixed  $requestTarget
379
     * @return static
380
     */
381
    public function withRequestTarget($requestTarget)
382
    {
383
        return new static(
384
            $this->getProtocolVersion(),
385
            $this->getHeaders(),
386
            $this->getBody(),
387
            $requestTarget,
388
            $this->getMethod()
389
        );
390
    }
391
392
    /**
393
     * Verifies the HTTP method is valid.
394
     *
395
     * @throws InvalidArgumentException
396
     * @param  string  $method HTTP method for the incoming request
397
     */
398
    private function validateMethod(string $method) : void
399
    {
400
        if (! in_array(strtoupper($method), ['POST', 'GET', 'OPTIONS'])) {
401
            throw new InvalidArgumentException("Invalid HTTP method: {$method}");
402
        }
403
    }
404
405
    /**
406
     * Retrieves the HTTP method of the request.
407
     *
408
     * @return string Returns the request method.
409
     */
410
    public function getMethod()
411
    {
412
        return $this->method;
413
    }
414
415
    /**
416
     * Return an instance with the provided HTTP method.
417
     *
418
     * While HTTP method names are typically all uppercase characters, HTTP
419
     * method names are case-sensitive and thus implementations SHOULD NOT
420
     * modify the given string.
421
     *
422
     * This method MUST be implemented in such a way as to retain the
423
     * immutability of the message, and MUST return an instance that has the
424
     * changed request method.
425
     *
426
     * @param  string  $method  Case-sensitive method.
427
     * @return static
428
     * @throws \InvalidArgumentException for invalid HTTP methods.
429
     */
430
    public function withMethod($method)
431
    {
432
        // TODO: Implement withMethod() method.
433
    }
434
435
    /**
436
     * Retrieves the URI instance.
437
     *
438
     * This method MUST return a UriInterface instance.
439
     *
440
     * @link http://tools.ietf.org/html/rfc3986#section-4.3
441
     * @return UriInterface Returns a UriInterface instance
442
     *     representing the URI of the request.
443
     */
444
    public function getUri()
445
    {
446
        // TODO: Implement getUri() method.
447
    }
448
449
    /**
450
     * Returns an instance with the provided URI.
451
     *
452
     * This method MUST update the Host header of the returned request by
453
     * default if the URI contains a host component. If the URI does not
454
     * contain a host component, any pre-existing Host header MUST be carried
455
     * over to the returned request.
456
     *
457
     * You can opt-in to preserving the original state of the Host header by
458
     * setting `$preserveHost` to `true`. When `$preserveHost` is set to
459
     * `true`, this method interacts with the Host header in the following ways:
460
     *
461
     * - If the Host header is missing or empty, and the new URI contains
462
     *   a host component, this method MUST update the Host header in the returned
463
     *   request.
464
     * - If the Host header is missing or empty, and the new URI does not contain a
465
     *   host component, this method MUST NOT update the Host header in the returned
466
     *   request.
467
     * - If a Host header is present and non-empty, this method MUST NOT update
468
     *   the Host header in the returned request.
469
     *
470
     * This method MUST be implemented in such a way as to retain the
471
     * immutability of the message, and MUST return an instance that has the
472
     * new UriInterface instance.
473
     *
474
     * @link http://tools.ietf.org/html/rfc3986#section-4.3
475
     * @param  UriInterface  $uri  New request URI to use.
476
     * @param  bool  $preserveHost  Preserve the original state of the Host header.
477
     * @return static
478
     */
479
    public function withUri(UriInterface $uri, $preserveHost = false)
480
    {
481
        // TODO: Implement withUri() method.
482
    }
483
484
    /**
485
     * Retrieve server parameters.
486
     *
487
     * Retrieves data related to the incoming request environment,
488
     * typically derived from PHP's $_SERVER superglobal. The data IS NOT
489
     * REQUIRED to originate from $_SERVER.
490
     *
491
     * @return array
492
     */
493
    public function getServerParams()
494
    {
495
        // TODO: Implement getServerParams() method.
496
    }
497
498
    /**
499
     * Retrieve cookies.
500
     *
501
     * Retrieves cookies sent by the client to the server.
502
     *
503
     * The data MUST be compatible with the structure of the $_COOKIE
504
     * superglobal.
505
     *
506
     * @return array
507
     */
508
    public function getCookieParams()
509
    {
510
        // TODO: Implement getCookieParams() method.
511
    }
512
513
    /**
514
     * Return an instance with the specified cookies.
515
     *
516
     * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
517
     * be compatible with the structure of $_COOKIE. Typically, this data will
518
     * be injected at instantiation.
519
     *
520
     * This method MUST NOT update the related Cookie header of the request
521
     * instance, nor related values in the server params.
522
     *
523
     * This method MUST be implemented in such a way as to retain the
524
     * immutability of the message, and MUST return an instance that has the
525
     * updated cookie values.
526
     *
527
     * @param  array  $cookies  Array of key/value pairs representing cookies.
528
     * @return static
529
     */
530
    public function withCookieParams(array $cookies)
531
    {
532
        // TODO: Implement withCookieParams() method.
533
    }
534
535
    /**
536
     * Retrieve query string arguments.
537
     *
538
     * Retrieves the deserialized query string arguments, if any.
539
     *
540
     * Note: the query params might not be in sync with the URI or server
541
     * params. If you need to ensure you are only getting the original
542
     * values, you may need to parse the query string from `getUri()->getQuery()`
543
     * or from the `QUERY_STRING` server param.
544
     *
545
     * @return array
546
     */
547
    public function getQueryParams()
548
    {
549
        // TODO: Implement getQueryParams() method.
550
    }
551
552
    /**
553
     * Return an instance with the specified query string arguments.
554
     *
555
     * These values SHOULD remain immutable over the course of the incoming
556
     * request. They MAY be injected during instantiation, such as from PHP's
557
     * $_GET superglobal, or MAY be derived from some other value such as the
558
     * URI. In cases where the arguments are parsed from the URI, the data
559
     * MUST be compatible with what PHP's parse_str() would return for
560
     * purposes of how duplicate query parameters are handled, and how nested
561
     * sets are handled.
562
     *
563
     * Setting query string arguments MUST NOT change the URI stored by the
564
     * request, nor the values in the server params.
565
     *
566
     * This method MUST be implemented in such a way as to retain the
567
     * immutability of the message, and MUST return an instance that has the
568
     * updated query string arguments.
569
     *
570
     * @param  array  $query  Array of query string arguments, typically from
571
     *     $_GET.
572
     * @return static
573
     */
574
    public function withQueryParams(array $query)
575
    {
576
        // TODO: Implement withQueryParams() method.
577
    }
578
579
    /**
580
     * Retrieve normalized file upload data.
581
     *
582
     * This method returns upload metadata in a normalized tree, with each leaf
583
     * an instance of Psr\Http\Message\UploadedFileInterface.
584
     *
585
     * These values MAY be prepared from $_FILES or the message body during
586
     * instantiation, or MAY be injected via withUploadedFiles().
587
     *
588
     * @return array An array tree of UploadedFileInterface instances; an empty
589
     *     array MUST be returned if no data is present.
590
     */
591
    public function getUploadedFiles()
592
    {
593
        // TODO: Implement getUploadedFiles() method.
594
    }
595
596
    /**
597
     * Create a new instance with the specified uploaded files.
598
     *
599
     * This method MUST be implemented in such a way as to retain the
600
     * immutability of the message, and MUST return an instance that has the
601
     * updated body parameters.
602
     *
603
     * @param  array  $uploadedFiles  An array tree of UploadedFileInterface instances.
604
     * @return static
605
     * @throws \InvalidArgumentException if an invalid structure is provided.
606
     */
607
    public function withUploadedFiles(array $uploadedFiles)
608
    {
609
        // TODO: Implement withUploadedFiles() method.
610
    }
611
612
    /**
613
     * Retrieve any parameters provided in the request body.
614
     *
615
     * If the request Content-Type is either application/x-www-form-urlencoded
616
     * or multipart/form-data, and the request method is POST, this method MUST
617
     * return the contents of $_POST.
618
     *
619
     * Otherwise, this method may return any results of deserializing
620
     * the request body content; as parsing returns structured content, the
621
     * potential types MUST be arrays or objects only. A null value indicates
622
     * the absence of body content.
623
     *
624
     * @return null|array|object The deserialized body parameters, if any.
625
     *     These will typically be an array or object.
626
     */
627
    public function getParsedBody()
628
    {
629
        // TODO: Implement getParsedBody() method.
630
    }
631
632
    /**
633
     * Return an instance with the specified body parameters.
634
     *
635
     * These MAY be injected during instantiation.
636
     *
637
     * If the request Content-Type is either application/x-www-form-urlencoded
638
     * or multipart/form-data, and the request method is POST, use this method
639
     * ONLY to inject the contents of $_POST.
640
     *
641
     * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
642
     * deserializing the request body content. Deserialization/parsing returns
643
     * structured data, and, as such, this method ONLY accepts arrays or objects,
644
     * or a null value if nothing was available to parse.
645
     *
646
     * As an example, if content negotiation determines that the request data
647
     * is a JSON payload, this method could be used to create a request
648
     * instance with the deserialized parameters.
649
     *
650
     * This method MUST be implemented in such a way as to retain the
651
     * immutability of the message, and MUST return an instance that has the
652
     * updated body parameters.
653
     *
654
     * @param  null|array|object  $data  The deserialized body data. This will
655
     *     typically be in an array or object.
656
     * @return static
657
     * @throws \InvalidArgumentException if an unsupported argument type is
658
     *     provided.
659
     */
660
    public function withParsedBody($data)
661
    {
662
        // TODO: Implement withParsedBody() method.
663
    }
664
665
    /**
666
     * Retrieve attributes derived from the request.
667
     *
668
     * The request "attributes" may be used to allow injection of any
669
     * parameters derived from the request: e.g., the results of path
670
     * match operations; the results of decrypting cookies; the results of
671
     * deserializing non-form-encoded message bodies; etc. Attributes
672
     * will be application and request specific, and CAN be mutable.
673
     *
674
     * @return array Attributes derived from the request.
675
     */
676
    public function getAttributes()
677
    {
678
        // TODO: Implement getAttributes() method.
679
    }
680
681
    /**
682
     * Retrieve a single derived request attribute.
683
     *
684
     * Retrieves a single derived request attribute as described in
685
     * getAttributes(). If the attribute has not been previously set, returns
686
     * the default value as provided.
687
     *
688
     * This method obviates the need for a hasAttribute() method, as it allows
689
     * specifying a default value to return if the attribute is not found.
690
     *
691
     * @param  string  $name  The attribute name.
692
     * @param  mixed  $default  Default value to return if the attribute does not exist.
693
     * @return mixed
694
     * @see getAttributes()
695
     */
696
    public function getAttribute($name, $default = null)
697
    {
698
        // TODO: Implement getAttribute() method.
699
    }
700
701
    /**
702
     * Return an instance with the specified derived request attribute.
703
     *
704
     * This method allows setting a single derived request attribute as
705
     * described in getAttributes().
706
     *
707
     * This method MUST be implemented in such a way as to retain the
708
     * immutability of the message, and MUST return an instance that has the
709
     * updated attribute.
710
     *
711
     * @param  string  $name  The attribute name.
712
     * @param  mixed  $value  The value of the attribute.
713
     * @return static
714
     * @see getAttributes()
715
     */
716
    public function withAttribute($name, $value)
717
    {
718
        // TODO: Implement withAttribute() method.
719
    }
720
721
    /**
722
     * Return an instance that removes the specified derived request attribute.
723
     *
724
     * This method allows removing a single derived request attribute as
725
     * described in getAttributes().
726
     *
727
     * This method MUST be implemented in such a way as to retain the
728
     * immutability of the message, and MUST return an instance that removes
729
     * the attribute.
730
     *
731
     * @param  string  $name  The attribute name.
732
     * @return static
733
     * @see getAttributes()
734
     */
735
    public function withoutAttribute($name)
736
    {
737
        // TODO: Implement withoutAttribute() method.
738
    }
739
}
740