Test Failed
Branch master (f83914)
by Rasul
07:02
created

Request::__construct()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 10
nop 5
dl 0
loc 20
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Furious\Psr7;
6
7
use Furious\Psr7\Exception\InvalidArgumentException;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\UriInterface;
10
use function is_string;
11
use function preg_match;
12
13
class Request extends Message implements RequestInterface
14
{
15
    private const METHODS = [
16
        'GET', 'POST', 'PUT', 'PATCH', 'DELETE'
17
    ];
18
19
    private string $method;
1 ignored issue
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
20
    private ?string $requestTarget = null;
21
    private UriInterface $uri;
22
23
    public function  __construct(string $method, $uri, array $headers = [], $body = null, string $version = '1.1')
24
    {
25
        if (!($uri instanceof UriInterface)) {
26
            $uri = new Uri($uri);
27
        }
28
        if (!$this->isValidMethod($method)) {
29
            throw new InvalidArgumentException('Unsupported HTTP method');
30
        }
31
32
        $this->method = $method;
33
        $this->uri = $uri;
34
        $this->setHeaders($headers);
35
        $this->protocolVersion = $version;
36
37
        if (!$this->hasHeader('Host')) {
38
            $this->updateHostFromUri();
39
        }
40
41
        if ('' !== $body and null !== $body) {
42
            $this->stream = Stream::new($body);
43
        }
44
    }
45
46
    // Get
47
48
    public function getUri(): UriInterface
49
    {
50
        return $this->uri;
51
    }
52
53
    public function getMethod(): string
54
    {
55
        return $this->method;
56
    }
57
58
    public function getRequestTarget(): string
59
    {
60
        if (null !== $this->requestTarget) {
61
            return $this->requestTarget;
62
        }
63
64
        $target = $this->uri->getPath();
65
        if ('' === $target) {
66
            $target = '/';
67
        }
68
69
        if ('' !== $this->uri->getQuery()) {
70
            $target .= '?' . $this->uri->getQuery();
71
        }
72
73
        return $target;
74
    }
75
76
    // With
77
78
    public function withRequestTarget($requestTarget): self
79
    {
80
        if ($this->containWhitespace($requestTarget)) {
81
            throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
82
        }
83
84
        $request = clone $this;
85
        $request->requestTarget = $requestTarget;
86
87
        return $request;
88
    }
89
90
    public function withMethod($method): self
91
    {
92
        if (!is_string($method) or !$this->isValidMethod($method)) {
93
            throw new InvalidArgumentException('Unsupported HTTP method');
94
        }
95
96
        $request = clone $this;
97
        $request->method = $method;
98
99
        return $request;
100
    }
101
102
    public function withUri(UriInterface $uri, $preserveHost = false): self
103
    {
104
        $request = clone $this;
105
        $request->uri = $uri;
106
107
        if (!$preserveHost or !$this->hasHeader('Host')) {
108
            $request->updateHostFromUri();
109
        }
110
111
        return $request;
112
    }
113
114
    // Update
115
116
    private function updateHostFromUri(): void
117
    {
118
        if ('' === $host = $this->uri->getHost()) {
119
            return;
120
        }
121
122
        if (null !== ($port = $this->uri->getPort())) {
123
            $host .= ':' . $port;
124
        }
125
126
        if (isset($this->headerNames['host'])) {
127
            $header = $this->headerNames['host'];
128
        } else {
129
            $header = 'Host';
130
            $this->headerNames['host'] = $header;
131
        }
132
133
        $this->headers = [$header => [$host]] + $this->headers;
134
    }
135
136
    // Contain
137
138
    private function containWhitespace(string $requestTarget): bool
139
    {
140
        return boolval(preg_match('#\s#', $requestTarget));
141
    }
142
143
    private function isValidMethod(string $method): bool
144
    {
145
        return in_array($method, self::METHODS);
146
    }
147
}