Uri::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
c 0
b 0
f 0
nc 2
nop 8
dl 0
loc 23
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Http\Message\Uri;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\Http\Message\Exception\InvalidArgumentException;
18
use Valkyrja\Http\Message\Uri\Contract\Uri as Contract;
19
use Valkyrja\Http\Message\Uri\Enum\Scheme;
20
use Valkyrja\Http\Message\Uri\Exception\InvalidPathException;
21
use Valkyrja\Http\Message\Uri\Exception\InvalidPortException;
22
use Valkyrja\Http\Message\Uri\Exception\InvalidQueryException;
23
24
use function parse_url;
25
use function str_starts_with;
26
use function strtolower;
27
28
/**
29
 * Class Uri.
30
 *
31
 * @author Melech Mizrachi
32
 */
33
class Uri implements Contract
34
{
35
    use UriHelpers;
0 ignored issues
show
Bug introduced by
The trait Valkyrja\Http\Message\Uri\UriHelpers requires the property $value which is not provided by Valkyrja\Http\Message\Uri\Uri.
Loading history...
36
37
    /**
38
     * @var string
39
     */
40
    protected string $userInfo;
41
42
    /**
43
     * The URI as a string.
44
     *
45
     * @var string|null
46
     */
47
    private string|null $uriString = null;
48
49
    /**
50
     * UriImpl constructor.
51
     *
52
     * @param Scheme   $scheme   [optional] The scheme
53
     * @param string   $username [optional] The username
54
     * @param string   $password [optional] The user password
55
     * @param string   $host     [optional] The host
56
     * @param int|null $port     [optional] The port
57
     * @param string   $path     [optional] The path
58
     * @param string   $query    [optional] The query
59
     * @param string   $fragment [optional] The fragment
60
     *
61
     * @throws InvalidPathException
62
     * @throws InvalidPortException
63
     * @throws InvalidQueryException
64
     */
65
    public function __construct(
66
        protected Scheme $scheme = Scheme::EMPTY,
67
        protected string $username = '',
68
        protected string $password = '',
69
        protected string $host = '',
70
        protected int|null $port = null,
71
        protected string $path = '',
72
        protected string $query = '',
73
        protected string $fragment = ''
74
    ) {
75
        $userInfo = $username;
76
77
        if ($password !== '') {
78
            $userInfo .= ':' . $password;
79
        }
80
81
        $this->validatePort($port);
82
83
        $this->userInfo = $this->filterUserInfo($userInfo);
84
        $this->host     = strtolower($host);
85
        $this->path     = $this->filterPath($path);
86
        $this->query    = $this->filterQuery($query);
87
        $this->fragment = $this->filterFragment($fragment);
88
    }
89
90
    /**
91
     * @inheritDoc
92
     */
93
    #[Override]
94
    public static function fromString(string $uri): static
95
    {
96
        if (
97
            $uri !== ''
98
            && ! str_starts_with($uri, '/')
99
            && ! str_starts_with($uri, Scheme::HTTP->value)
100
            && ! str_starts_with($uri, Scheme::HTTPS->value)
101
        ) {
102
            $uri = '//' . $uri;
103
        }
104
105
        $parts = parse_url($uri);
106
107
        if ($parts === false) {
108
            throw new InvalidArgumentException("Invalid uri `$uri` provided");
109
        }
110
111
        return new static(
112
            scheme: static::filterScheme($parts['scheme'] ?? ''),
113
            username: $parts['user'] ?? '',
114
            password: $parts['pass'] ?? '',
115
            host: $parts['host'] ?? '',
116
            port: $parts['port'] ?? null,
117
            path: $parts['path'] ?? '',
118
            query: $parts['query'] ?? '',
119
            fragment: $parts['fragment'] ?? ''
120
        );
121
    }
122
123
    /**
124
     * @inheritDoc
125
     */
126
    #[Override]
127
    public function isSecure(): bool
128
    {
129
        return $this->scheme === Scheme::HTTPS;
130
    }
131
132
    /**
133
     * @inheritDoc
134
     */
135
    #[Override]
136
    public function getScheme(): Scheme
137
    {
138
        return $this->scheme;
139
    }
140
141
    /**
142
     * @inheritDoc
143
     */
144
    #[Override]
145
    public function getAuthority(): string
146
    {
147
        if (empty($this->host)) {
148
            return '';
149
        }
150
151
        $authority = $this->host;
152
153
        if (! empty($this->userInfo)) {
154
            $authority = $this->userInfo . '@' . $authority;
155
        }
156
157
        if (! $this->isStandardPort()) {
158
            $authority .= ':' . ((string) $this->port);
159
        }
160
161
        return $authority;
162
    }
163
164
    /**
165
     * @inheritDoc
166
     */
167
    #[Override]
168
    public function getUsername(): string
169
    {
170
        return $this->username;
171
    }
172
173
    /**
174
     * @inheritDoc
175
     */
176
    #[Override]
177
    public function getPassword(): string
178
    {
179
        return $this->password;
180
    }
181
182
    /**
183
     * @inheritDoc
184
     */
185
    #[Override]
186
    public function getUserInfo(): string
187
    {
188
        return $this->userInfo;
189
    }
190
191
    /**
192
     * @inheritDoc
193
     */
194
    #[Override]
195
    public function getHost(): string
196
    {
197
        return $this->host;
198
    }
199
200
    /**
201
     * @inheritDoc
202
     */
203
    #[Override]
204
    public function getPort(): int|null
205
    {
206
        return $this->isStandardPort() ? null : $this->port;
207
    }
208
209
    /**
210
     * @inheritDoc
211
     */
212
    #[Override]
213
    public function getHostPort(): string
214
    {
215
        $host = $this->host;
216
217
        if ($host !== '' && ($port = $this->port) !== null) {
218
            $host .= ':' . ((string) $port);
219
        }
220
221
        return $host;
222
    }
223
224
    /**
225
     * @inheritDoc
226
     */
227
    #[Override]
228
    public function getSchemeHostPort(): string
229
    {
230
        $hostPort = $this->getHostPort();
231
        $scheme   = $this->scheme;
232
233
        return $hostPort && $scheme !== Scheme::EMPTY ? $scheme->value . '://' . $hostPort : $hostPort;
234
    }
235
236
    /**
237
     * @inheritDoc
238
     */
239
    #[Override]
240
    public function getPath(): string
241
    {
242
        return $this->path;
243
    }
244
245
    /**
246
     * @inheritDoc
247
     */
248
    #[Override]
249
    public function getQuery(): string
250
    {
251
        return $this->query;
252
    }
253
254
    /**
255
     * @inheritDoc
256
     */
257
    #[Override]
258
    public function getFragment(): string
259
    {
260
        return $this->fragment;
261
    }
262
263
    /**
264
     * @inheritDoc
265
     */
266
    #[Override]
267
    public function withScheme(Scheme $scheme): static
268
    {
269
        $new = clone $this;
270
271
        $new->scheme = $scheme;
272
273
        return $new;
274
    }
275
276
    /**
277
     * @inheritDoc
278
     */
279
    #[Override]
280
    public function withUsername(string $username): static
281
    {
282
        return $this->withUserInfo($username, $this->password);
283
    }
284
285
    /**
286
     * @inheritDoc
287
     */
288
    #[Override]
289
    public function withPassword(string $password): static
290
    {
291
        return $this->withUserInfo($this->username, $password);
292
    }
293
294
    /**
295
     * @inheritDoc
296
     */
297
    #[Override]
298
    public function withUserInfo(string $user, string|null $password = null): static
299
    {
300
        $info = $user;
301
302
        if (empty($user)) {
303
            $password = null;
304
        }
305
306
        if ($password !== null) {
307
            $info .= ':' . $password;
308
        }
309
310
        $new = clone $this;
311
312
        $new->userInfo = $info;
313
        $new->username = $user;
314
        $new->password = $password ?? '';
315
316
        return $new;
317
    }
318
319
    /**
320
     * @inheritDoc
321
     */
322
    #[Override]
323
    public function withHost(string $host): static
324
    {
325
        $new = clone $this;
326
327
        $new->host = $host;
328
329
        return $new;
330
    }
331
332
    /**
333
     * @inheritDoc
334
     */
335
    #[Override]
336
    public function withPort(int|null $port = null): static
337
    {
338
        $this->validatePort($port);
339
340
        $new = clone $this;
341
342
        $new->port = $port;
343
344
        return $new;
345
    }
346
347
    /**
348
     * @inheritDoc
349
     */
350
    #[Override]
351
    public function withPath(string $path): static
352
    {
353
        $path = $this->filterPath($path);
354
355
        $new = clone $this;
356
357
        $new->path = $path;
358
359
        return $new;
360
    }
361
362
    /**
363
     * @inheritDoc
364
     */
365
    #[Override]
366
    public function withQuery(string $query): static
367
    {
368
        $query = $this->filterQuery($query);
369
370
        $new = clone $this;
371
372
        $new->query = $query;
373
374
        return $new;
375
    }
376
377
    /**
378
     * @inheritDoc
379
     */
380
    #[Override]
381
    public function withFragment(string $fragment): static
382
    {
383
        $fragment = $this->filterFragment($fragment);
384
385
        $new = clone $this;
386
387
        $new->fragment = $fragment;
388
389
        return $new;
390
    }
391
392
    /**
393
     * @inheritDoc
394
     */
395
    public function __toString(): string
396
    {
397
        if ($this->uriString !== null) {
398
            return $this->uriString;
399
        }
400
401
        $uri = '';
402
403
        $uri = $this->addSchemeToUri($uri);
404
        $uri = $this->addAuthorityToUri($uri);
405
        $uri = $this->addPathToUri($uri);
406
        $uri = $this->addQueryToUri($uri);
407
        $uri = $this->addFragmentToUri($uri);
408
409
        return $this->uriString = $uri;
410
    }
411
412
    public function __clone()
413
    {
414
        $this->uriString = null;
415
    }
416
}
417