Uri::getPort()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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