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

Uri   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 196
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 90
dl 0
loc 196
rs 10
c 0
b 0
f 0
wmc 28
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Furious\Psr7;
6
7
use Furious\Psr7\Exception\InvalidArgumentException;
8
use Furious\Psr7\Exception\UnableToParseUriException;
9
use Furious\Psr7\Filter\UriFilter;
10
use Furious\Psr7\Builder\UriBuilder;
11
use Psr\Http\Message\UriInterface;
12
use function parse_url;
13
use function is_string;
14
15
final class Uri implements UriInterface
16
{
17
    private const PARTS_PATTERN = [
18
        'user' => '',
19
        'scheme' => '',
20
        'host' => '',
21
        'port' => null,
22
        'path' => '',
23
        'query' => '',
24
        'fragment' => '',
25
        'pass' => null
26
    ];
27
28
    private UriFilter $filter;
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...
29
    private string $scheme = '';
30
    private string $userInfo = '';
31
    private string $host = '';
32
    private ?int $port = null;
33
    private string $path = '';
34
    private string $query = '';
35
    private string $fragment = '';
36
37
    public function __construct(string $uri = '')
38
    {
39
        $this->filter = new UriFilter();
40
        if ('' !== $uri) {
41
            $parts = parse_url($uri);
42
            if (false === $parts) {
43
                throw new UnableToParseUriException($uri);
44
            }
45
46
            $parts = $parts + self::PARTS_PATTERN;
47
48
            $this->userInfo = $parts['user'];
49
            $this->scheme = mb_strtolower($parts['scheme']);
50
            $this->host = mb_strtolower($parts['host']);
51
            $this->port = $this->filter->filterPort($this->scheme, $parts['port']);
52
            $this->path = $this->filter->filterPath($parts['path']);
53
            $this->query = $this->filter->filterQuery($parts['query']);
54
            $this->fragment = $this->filter->filterFragment($parts['fragment']);
55
56
            if (isset($parts['pass'])) {
57
                $this->userInfo .= ':' . $parts['pass'];
58
            }
59
        }
60
    }
61
62
    public function __toString(): string
63
    {
64
        return
65
            (new UriBuilder())
66
            ->withScheme($this->scheme)
67
            ->withAuthority($this->getAuthority())
68
            ->withPath($this->getAuthority(), $this->path)
69
            ->withQuery($this->query)
70
            ->withFragment($this->fragment)
71
            ->getUri()
72
        ;
73
    }
74
75
    // Get
76
77
    public function getScheme(): string
78
    {
79
        return $this->scheme;
80
    }
81
82
    public function getAuthority(): string
83
    {
84
        if ('' === $this->host) {
85
            return '';
86
        }
87
88
        $authority = $this->host;
89
        if ('' !== $this->userInfo) {
90
            $authority = $this->userInfo . '@' . $authority;
91
        }
92
93
        if (null !== $this->port) {
94
            $authority .= ':' . $this->port;
95
        }
96
97
        return $authority;
98
    }
99
100
    public function getUserInfo(): string
101
    {
102
        return $this->userInfo;
103
    }
104
105
    public function getHost(): string
106
    {
107
        return $this->host;
108
    }
109
110
    public function getPort(): ?int
111
    {
112
        return $this->port;
113
    }
114
115
    public function getPath(): string
116
    {
117
        return $this->path;
118
    }
119
120
    public function getQuery(): string
121
    {
122
        return $this->query;
123
    }
124
125
    public function getFragment(): string
126
    {
127
        return $this->fragment;
128
    }
129
130
    // With
131
132
    public function withScheme($scheme): self
133
    {
134
        if (!is_string($scheme)) {
135
            throw new InvalidArgumentException('Scheme must be a string');
136
        }
137
138
        $scheme = mb_strtolower($scheme);
139
140
        $uri = clone $this;
141
        $uri->scheme = $scheme;
142
        $uri->port = $this->filter->filterPort($uri->scheme, $uri->port);
143
144
        return $uri;
145
    }
146
147
    public function withUserInfo($user, $password = null): self
148
    {
149
        $info = $user;
150
        if (null !== $password and '' !== $password) {
151
            $info .= ':' . $password;
152
        }
153
154
        $new = clone $this;
155
        $new->userInfo = $info;
156
157
        return $new;
158
    }
159
160
    public function withHost($host): self
161
    {
162
        if (!is_string($host)) {
163
            throw new InvalidArgumentException('Host must be a string.');
164
        }
165
166
        $host = mb_strtolower($host);
167
168
        $uri = clone $this;
169
        $uri->host = $host;
170
171
        return $uri;
172
    }
173
174
    public function withPort($port): self
175
    {
176
        $port = $this->filter->filterPort($this->scheme, $port ? (int) $port : null);
177
        $uri = clone $this;
178
        $uri->port = $port;
179
180
        return $uri;
181
    }
182
183
    public function withPath($path): self
184
    {
185
        $path = $this->filter->filterPath($path);
186
187
        $uri = clone $this;
188
        $uri->path = $path;
189
190
        return $uri;
191
    }
192
193
    public function withQuery($query): self
194
    {
195
        $query = $this->filter->filterQuery($query);
196
197
        $uri = clone $this;
198
        $uri->query = $query;
199
200
        return $uri;
201
    }
202
203
    public function withFragment($fragment): self
204
    {
205
        $fragment = $this->filter->filterFragment($fragment);
206
207
        $uri = clone $this;
208
        $uri->fragment = $fragment;
209
210
        return $uri;
211
    }
212
}