Uri   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Test Coverage

Coverage 98.2%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 93
c 6
b 0
f 0
dl 0
loc 244
ccs 109
cts 111
cp 0.982
rs 9.44
wmc 37

27 Methods

Rating   Name   Duplication   Size   Complexity  
A getQuery() 0 3 1
A getPassword() 0 3 1
A withUserInfo() 0 6 1
A getFragment() 0 3 1
A concatPrefix() 0 6 2
A setQuery() 0 4 1
A getUserInfo() 0 4 2
A getQueryPart() 0 3 1
A getHost() 0 3 1
A getPath() 0 3 1
A getUsername() 0 3 1
A getScheme() 0 3 1
A concatSuffix() 0 6 2
A withQueryKeyValue() 0 5 2
A withPath() 0 5 1
A getPort() 0 3 1
A withScheme() 0 5 1
A withFragment() 0 5 1
A withQuery() 0 5 1
A withHost() 0 5 1
A getInstanceFromUri() 0 3 1
A getInstanceFromString() 0 3 1
A __construct() 0 32 4
A __toString() 0 8 1
A getAuthority() 0 6 1
A withPort() 0 5 2
A getFromArray() 0 7 3
1
<?php
2
3
namespace ByJG\Util;
4
5
use Psr\Http\Message\UriInterface;
6
7
/**
8
 * Class Uri
9
 */
10
class Uri implements UriInterface, CustomUriInterface
11
{
12
13
14
    private $scheme = "";
15
16 3
    public function withScheme(string $value): UriInterface
17
    {
18 3
        $clone = clone $this;
19 3
        $clone->scheme = strtolower($value);
20 3
        return $clone;
21
    }
22
23 67
    public function getScheme(): string
24
    {
25 67
        return $this->scheme;
26
    }
27
28
    private $username = "";
29
    private $password = "";
30
31 4
    public function withUserInfo(string $user, string $password = null): UriInterface
32
    {
33 4
        $clone = clone $this;
34 4
        $clone->username = $user;
35 4
        $clone->password = $password;
36 4
        return $clone;
37
    }
38
39 98
    public function getUserInfo(): string
40
    {
41 98
        return $this->username
42 98
            . (!empty($this->password) ? ':' . rawurlencode($this->password) : '' );
43
    }
44
45
    /**
46
     * @return mixed
47
     */
48 31
    public function getUsername()
49
    {
50 31
        return $this->username;
51
    }
52
53
    /**
54
     * @return mixed
55
     */
56 31
    public function getPassword()
57
    {
58 31
        return $this->password;
59
    }
60
61
    private $host = "";
62
63 4
    public function withHost(string $value): UriInterface
64
    {
65 4
        $clone = clone $this;
66 4
        $clone->host = $value;
67 4
        return $clone;
68
    }
69
70 97
    public function getHost(): string
71
    {
72 97
        return $this->host;
73
    }
74
75
    private $port;
76
77
    /**
78
     * @param int|string|null $value
79
     * @return $this
80
     */
81 2
    public function withPort(?int $value): UriInterface
82
    {
83 2
        $clone = clone $this;
84 2
        $clone->port = is_numeric($value) ? intval($value) : null;
85 2
        return $clone;
86
    }
87
88 97
    public function getPort(): ?int
89
    {
90 97
        return $this->port;
91
    }
92
93
    private $path = "";
94
95 2
    public function withPath(string $value): UriInterface
96
    {
97 2
        $clone = clone $this;
98 2
        $clone->path = $value;
99 2
        return $clone;
100
    }
101
102 67
    public function getPath(): string
103
    {
104 67
        return $this->path;
105
    }
106
107
    private $query = [];
108
109 1
    public function withQuery(string $query): UriInterface
110
    {
111 1
        $clone = clone $this;
112 1
        $clone->setQuery($query);
113 1
        return $clone;
114
    }
115
116 338
    protected function setQuery($query)
117
    {
118 338
        parse_str($query, $this->query);
119 338
        return $this;
120
    }
121
122
123 69
    public function getQuery(): string
124
    {
125 69
        return http_build_query($this->query, "", "&", PHP_QUERY_RFC3986);
126
    }
127
128
    /**
129
     * @param string $key
130
     * @param string|array $value
131
     * @param bool $isEncoded
132
     * @return $this
133
     */
134 2
    public function withQueryKeyValue($key, $value, $isEncoded = false)
135
    {
136 2
        $clone = clone $this;
137 2
        $clone->query[$key] = ($isEncoded ? rawurldecode($value) : $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $string of rawurldecode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

137
        $clone->query[$key] = ($isEncoded ? rawurldecode(/** @scrutinizer ignore-type */ $value) : $value);
Loading history...
138 2
        return $clone;
139
    }
140
141
    /**
142
     * Not from UriInterface
143
     *
144
     * @param $key
145
     * @return string
146
     */
147
    public function getQueryPart($key)
148
    {
149
        return $this->getFromArray($this->query, $key, null);
150
    }
151
152 337
    private function getFromArray($array, $key, $default)
153
    {
154 337
        if (isset($array[$key])) {
155 337
            return empty($array[$key]) ? $default : $array[$key];
156
        }
157
158 245
        return $default;
159
    }
160
161
    private $fragment = "";
162
163 67
    public function getFragment(): string
164
    {
165 67
        return $this->fragment;
166
    }
167
168 1
    public function withFragment(string $fragment): UriInterface
169
    {
170 1
        $clone = clone $this;
171 1
        $clone->fragment = $fragment;
172 1
        return $clone;
173
    }
174
175 66
    public function getAuthority(): string
176
    {
177 66
        return
178 66
            $this->concatSuffix($this->getUserInfo(), "@")
179 66
            . $this->getHost()
180 66
            . $this->concatPrefix(':', $this->getPort());
181
    }
182
183 36
    public function __toString(): string
184
    {
185 36
        return
186 36
            $this->concatSuffix($this->getScheme(), '://')
187 36
            . $this->getAuthority()
188 36
            . $this->getPath()
189 36
            . $this->concatPrefix('?', $this->getQuery())
190 36
            . $this->concatPrefix('#', $this->getFragment());
191
    }
192
193 66
    private function concatSuffix($str, $suffix)
194
    {
195 66
        if (!empty($str)) {
196 46
            $str = $str . $suffix;
197
        }
198 66
        return $str;
199
    }
200
201 66
    private function concatPrefix($prefix, $str)
202
    {
203 66
        if (!empty($str)) {
204 38
            $str = $prefix . $str;
205
        }
206 66
        return $str;
207
    }
208
209
    /**
210
     * @param string $uri
211
     */
212 339
    public function __construct($uri = null)
213
    {
214 339
        if (empty($uri)) {
215 2
            return;
216
        }
217
218 337
        $pattern = "/^"
219 337
            . "(?:(?P<scheme>\w+):\/\/)?"
220 337
            . "(?:(?P<user>\S+?):(?P<pass>\S+)@)?"
221 337
            . "(?:(?P<user2>\S+)@)?"
222 337
            . "(?:(?P<host>(?![A-Za-z]:)[\w\d\-]+(?:\.[\w\d\-]+)*))?"
223 337
            . "(?::(?P<port>[\d]+))?"
224 337
            . "(?P<path>([A-Za-z]:)?[^?#]+)?"
225 337
            . "(?:\?(?P<query>[^#]+))?"
226 337
            . "(?:#(?P<fragment>.*))?"
227 337
            . "$/";
228 337
        preg_match($pattern, $uri, $parsed);
229
230 337
        $user = $this->getFromArray($parsed, 'user', null);
231 337
        if (empty($user)) {
232 237
            $user = $this->getFromArray($parsed, 'user2', null);
233
        }
234
235 337
        $this->scheme = $this->getFromArray($parsed, 'scheme', "");
236 337
        $this->host = $this->getFromArray($parsed, 'host', "");
237 337
        $this->port = $this->getFromArray($parsed, 'port', null);
238 337
        $this->username = $user;
239 337
        $this->password = rawurldecode($this->getFromArray($parsed, 'pass', ""));
240 337
        $this->path = preg_replace('~^//~', '', $this->getFromArray($parsed, 'path', ""));
241 337
        $this->path = empty($this->path) ? "" : $this->path;
242 337
        $this->setQuery($this->getFromArray($parsed, 'query', ""));
243 337
        $this->fragment = $this->getFromArray($parsed, 'fragment', "");
244
    }
245
246 6
    public static function getInstanceFromString($uriString = null)
247
    {
248 6
        return new Uri($uriString);
249
    }
250
251 2
    public static function getInstanceFromUri(UriInterface $uri)
252
    {
253 2
        return self::getInstanceFromString((string)$uri);
254
    }
255
}
256