Uri::getPort()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 0
1
<?php
2
3
namespace Saxulum\HttpMessage;
4
5
use Psr\Http\Message\UriInterface;
6
7
final class Uri implements UriInterface
8
{
9
    /**
10
     * @var string|null
11
     */
12
    private $scheme;
13
14
    /**
15
     * @var string|null
16
     */
17
    private $host;
18
19
    /**
20
     * @var int|null
21
     */
22
    private $port;
23
24
    const PORT_HTTP = 80;
25
    const PORT_HTTPS = 443;
26
27
    /**
28
     * @var string|null
29
     */
30
    private $user;
31
32
    /**
33
     * @var string|null
34
     */
35
    private $password;
36
37
    /**
38
     * @var string|null
39
     */
40
    private $path;
41
42
    /**
43
     * @var string|null
44
     */
45
    private $query;
46
47
    /**
48
     * @var string|null
49
     */
50
    private $fragment;
51
52
    /**
53
     * @var UriInterface|null
54
     */
55
    private $__previous;
56
57
    /**
58
     * @param string|null       $scheme
59
     * @param string|null       $host
60
     * @param int|null          $port
61
     * @param string|null       $user
62
     * @param string|null       $password
63
     * @param string|null       $path
64
     * @param string|null       $query
65
     * @param string|null       $fragment
66
     * @param UriInterface|null $__previous
67
     */
68
    public function __construct(
69
        string $scheme = null,
70
        string $host = null,
71
        int $port = null,
72
        string $user = null,
73
        string $password = null,
74
        string $path = null,
75
        string $query = null,
76
        string $fragment = null,
77
        UriInterface $__previous = null
78
    ) {
79
        $this->scheme = $scheme;
80
        $this->host = $host;
81
        $this->port = $port;
82
        $this->user = $user;
83
        $this->password = $password;
84
        $this->path = $path;
85
        $this->query = $query;
86
        $this->fragment = $fragment;
87
        $this->__previous = $__previous;
88
    }
89
90
    /**
91
     * @param string $uri
92
     *
93
     * @return UriInterface
94
     *
95
     * @throws \InvalidArgumentException
96
     */
97
    public static function create(string $uri)
98
    {
99
        $uriParts = parse_url($uri);
100
        if (false === $uriParts) {
101
            throw new \InvalidArgumentException(sprintf('Invalid uri format for parse_url: %s', $uri));
102
        }
103
104
        return new self(
105
            $uriParts['scheme'] ?? null,
106
            $uriParts['host'] ?? null,
107
            $uriParts['port'] ?? null,
108
            $uriParts['user'] ?? null,
109
            $uriParts['pass'] ?? null,
110
            $uriParts['path'] ?? null,
111
            $uriParts['query'] ?? null,
112
            $uriParts['fragment'] ?? null
113
        );
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function getScheme(): string
120
    {
121
        return strtolower((string) $this->scheme);
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function getAuthority(): string
128
    {
129
        if ('' === $host = $this->getHost()) {
130
            return '';
131
        }
132
133
        $authority = '';
134
135
        if ('' !== $userInfo = $this->getUserInfo()) {
136
            $authority .= $userInfo.'@';
137
        }
138
139
        $authority .= $host;
140
141
        if (null !== $port = $this->getPort()) {
142
            $authority .= ':'.$port;
143
        }
144
145
        return $authority;
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function getUserInfo(): string
152
    {
153
        if (null === $this->user) {
154
            return '';
155
        }
156
157
        if (null === $this->password) {
158
            return $this->user;
159
        }
160
161
        return $this->user.':'.$this->password;
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     */
167
    public function getHost(): string
168
    {
169
        return strtolower((string) $this->host);
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function getPort()
176
    {
177
        if (null === $this->port) {
178
            return null;
179
        }
180
181
        if ($this->port === $this->getPortForScheme($this->getScheme())) {
182
            return null;
183
        }
184
185
        return $this->port;
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191
    public function getPath(): string
192
    {
193
        return (string) $this->path;
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function getQuery(): string
200
    {
201
        return (string) $this->query;
202
    }
203
204
    /**
205
     * {@inheritdoc}
206
     */
207
    public function getFragment(): string
208
    {
209
        return (string) $this->fragment;
210
    }
211
212
    /**
213
     * {@inheritdoc}
214
     */
215
    public function withScheme($scheme): self
216
    {
217
        return $this->with(['scheme' => $scheme]);
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223
    public function withUserInfo($user, $password = null): self
224
    {
225
        return $this->with(['user' => $user, 'password' => $password]);
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231
    public function withHost($host): self
232
    {
233
        return $this->with(['host' => $host]);
234
    }
235
236
    /**
237
     * {@inheritdoc}
238
     */
239
    public function withPort($port): self
240
    {
241
        return $this->with(['port' => $port]);
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247
    public function withPath($path): self
248
    {
249
        return $this->with(['path' => $path]);
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255
    public function withQuery($query): self
256
    {
257
        return $this->with(['query' => $query]);
258
    }
259
260
    /**
261
     * {@inheritdoc}
262
     */
263
    public function withFragment($fragment): self
264
    {
265
        return $this->with(['fragment' => $fragment]);
266
    }
267
268
    /**
269
     * {@inheritdoc}
270
     */
271
    public function __toString(): string
272
    {
273
        $uri = '';
274
275
        if ('' !== $scheme = $this->getScheme()) {
276
            $uri .= $scheme.':';
277
        }
278
279
        if ('' !== $authority = $this->getAuthority()) {
280
            $uri .= '//'.$authority;
281
        }
282
283
        if ('' !== $path = $this->getPath()) {
284
            $uri .= $this->getPathForUri($authority, $path);
285
        }
286
287
        if ('' !== $query = $this->getQuery()) {
288
            $uri .= '?'.$query;
289
        }
290
291
        if ('' !== $fragment = $this->getFragment()) {
292
            $uri .= '#'.$fragment;
293
        }
294
295
        return $uri;
296
    }
297
298
    /**
299
     * @param string $scheme
300
     *
301
     * @return int|null
302
     */
303
    private function getPortForScheme(string $scheme)
304
    {
305
        $constantName = 'PORT_'.strtoupper($scheme);
306
        $reflection = new \ReflectionObject($this);
307
        if ($reflection->hasConstant($constantName)) {
308
            return $reflection->getConstant($constantName);
309
        }
310
311
        return null;
312
    }
313
314
    /**
315
     * @param string $authority
316
     * @param string $path
317
     *
318
     * @return string
319
     */
320
    private function getPathForUri(string $authority, string $path): string
321
    {
322
        if ('' !== $authority) {
323
            return $this->getPathForUriWithAuthority($path);
324
        }
325
326
        return $this->getPathForUriWithoutAuthority($path);
327
    }
328
329
    /**
330
     * @param string $path
331
     *
332
     * @return string
333
     */
334
    private function getPathForUriWithAuthority(string $path)
335
    {
336
        return '/' === $path[0] ? $path : '/'.$path;
337
    }
338
339
    /**
340
     * @param string $path
341
     *
342
     * @return string
343
     */
344
    private function getPathForUriWithoutAuthority(string $path)
345
    {
346
        $pathLength = strlen($path);
347
        for ($i = 0; $i < $pathLength; ++$i) {
348
            if ('/' !== $path[$i]) {
349
                break;
350
            }
351
        }
352
353
        return 0 === $i ? $path : '/'.substr($path, $i);
354
    }
355
356
    /**
357
     * @param array $parameters
358
     *
359
     * @return Uri
360
     */
361
    private function with(array $parameters): self
362
    {
363
        $defaults = [
364
            'scheme' => $this->scheme,
365
            'host' => $this->host,
366
            'port' => $this->port,
367
            'user' => $this->user,
368
            'password' => $this->password,
369
            'path' => $this->path,
370
            'query' => $this->query,
371
            'fragment' => $this->fragment,
372
        ];
373
374
        $arguments = array_values(array_replace($defaults, $parameters, ['__previous' => $this]));
375
376
        return new self(...$arguments);
0 ignored issues
show
Documentation introduced by
$arguments is of type array<integer,?>, but the function expects a null|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
377
    }
378
}
379