UriHelpers::filterUserInfo()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 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\Trait;
15
16
use Valkyrja\Http\Message\Constant\Port;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Http\Message\Constant\Port 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\Uri\Enum\Scheme;
18
use Valkyrja\Http\Message\Uri\Throwable\Exception\InvalidPathException;
19
use Valkyrja\Http\Message\Uri\Throwable\Exception\InvalidPortException;
20
use Valkyrja\Http\Message\Uri\Throwable\Exception\InvalidQueryException;
21
22
use function ltrim;
23
use function preg_replace;
24
use function str_starts_with;
25
use function strtolower;
26
27
/**
28
 * @property string   $host
29
 * @property int|null $port
30
 * @property Scheme   $scheme
31
 */
32
trait UriHelpers
33
{
34
    /**
35
     * Filter a scheme.
36
     *
37
     * @param string $scheme The scheme
38
     */
39
    protected static function filterScheme(string $scheme): Scheme
40
    {
41
        $scheme = strtolower($scheme);
42
        $scheme = (string) preg_replace('#:(//)?$#', '', $scheme);
43
44
        return Scheme::from($scheme);
45
    }
46
47
    /**
48
     * Retrieve the authority component of the URI.
49
     * If no authority information is present, this method MUST return an empty
50
     * string.
51
     * The authority syntax of the URI is:
52
     * <pre>
53
     * [user-info@]host[:port]
54
     * </pre>
55
     * If the port component is not set or is the standard port for the current
56
     * scheme, it SHOULD NOT be included.
57
     *
58
     * @see https://tools.ietf.org/html/rfc3986#section-3.2
59
     *
60
     * @return string The URI authority, in "[user-info@]host[:port]" format
61
     */
62
    abstract public function getAuthority(): string;
63
64
    /**
65
     * Validate a port.
66
     *
67
     * @param int|null $port The port
68
     *
69
     * @throws InvalidPortException
70
     */
71
    protected function validatePort(int|null $port = null): void
72
    {
73
        if (! Port::isValid($port)) {
74
            throw new InvalidPortException("Invalid port `%$port` specified; must be a valid TCP/UDP port");
75
        }
76
    }
77
78
    /**
79
     * Filter user info.
80
     */
81
    protected function filterUserInfo(string $userInfo): string
82
    {
83
        // TODO: Filter user info
84
85
        return $userInfo;
86
    }
87
88
    /**
89
     * Filter a path.
90
     *
91
     * @param string $path The path
92
     *
93
     * @throws InvalidPathException
94
     */
95
    protected function filterPath(string $path): string
96
    {
97
        $this->validatePath($path);
98
99
        // TODO: Filter path
100
101
        if (str_starts_with($path, '/')) {
102
            return '/' . ltrim($path, '/');
103
        }
104
105
        return $path;
106
    }
107
108
    /**
109
     * Validate a path.
110
     *
111
     * @param string $path The path
112
     *
113
     * @throws InvalidPathException
114
     */
115
    protected function validatePath(string $path): void
116
    {
117
        if (str_contains($path, '?')) {
118
            throw new InvalidPathException("Invalid path of `$path` provided; must not contain a query string");
119
        }
120
121
        if (str_contains($path, '#')) {
122
            throw new InvalidPathException("Invalid path of `$path` provided; must not contain a URI fragment");
123
        }
124
    }
125
126
    /**
127
     * Filter a query.
128
     *
129
     * @param string $query The query
130
     *
131
     * @throws InvalidQueryException
132
     */
133
    protected function filterQuery(string $query): string
134
    {
135
        $this->validateQuery($query);
136
137
        // TODO: Filter query
138
139
        return ltrim($query, '?');
140
    }
141
142
    /**
143
     * Validate a query.
144
     *
145
     * @param string $query The query
146
     *
147
     * @throws InvalidQueryException
148
     */
149
    protected function validateQuery(string $query): void
150
    {
151
        if (str_contains($query, '#')) {
152
            throw new InvalidQueryException(
153
                "Invalid query string of `$query` provided; must not contain a URI fragment"
154
            );
155
        }
156
    }
157
158
    /**
159
     * Filter a fragment.
160
     *
161
     * @param string $fragment The fragment
162
     */
163
    protected function filterFragment(string $fragment): string
164
    {
165
        $this->validateFragment($fragment);
166
167
        // TODO: Filter fragment
168
169
        return ltrim($fragment, '#');
170
    }
171
172
    /**
173
     * Validate a fragment.
174
     *
175
     * @param string $fragment The fragment
176
     */
177
    protected function validateFragment(string $fragment): void
0 ignored issues
show
Unused Code introduced by
The parameter $fragment is not used and could be removed. ( Ignorable by Annotation )

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

177
    protected function validateFragment(/** @scrutinizer ignore-unused */ string $fragment): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
178
    {
179
    }
180
181
    /**
182
     * Determine whether this uri is on a standard port for the scheme.
183
     */
184
    protected function isStandardPort(): bool
185
    {
186
        if ($this->scheme === Scheme::EMPTY) {
187
            return $this->host && $this->port === null;
188
        }
189
190
        if (! $this->host || $this->port === null) {
191
            return true;
192
        }
193
194
        return $this->isStandardUnsecurePort() || $this->isStandardSecurePort();
195
    }
196
197
    /**
198
     * Is standard HTTP port.
199
     */
200
    protected function isStandardUnsecurePort(): bool
201
    {
202
        return $this->scheme === Scheme::HTTP && $this->port === Port::HTTP;
203
    }
204
205
    /**
206
     * Is standard HTTPS port.
207
     */
208
    protected function isStandardSecurePort(): bool
209
    {
210
        return $this->scheme === Scheme::HTTPS && $this->port === Port::HTTPS;
211
    }
212
213
    /**
214
     * Add scheme to uri.
215
     *
216
     * @param string $uri The uri
217
     */
218
    protected function addSchemeToUri(string $uri): string
219
    {
220
        if (($scheme = $this->scheme) !== Scheme::EMPTY) {
221
            $uri .= $scheme->value . ':';
222
        }
223
224
        return $uri;
225
    }
226
227
    /**
228
     * Add authority to uri.
229
     *
230
     * @param string $uri The uri
231
     */
232
    protected function addAuthorityToUri(string $uri): string
233
    {
234
        if ($authority = $this->getAuthority()) {
235
            $uri .= '//' . $authority;
236
        }
237
238
        return $uri;
239
    }
240
241
    /**
242
     * Add path to uri.
243
     *
244
     * @param string $uri The uri
245
     */
246
    protected function addPathToUri(string $uri): string
247
    {
248
        if ($path = $this->path) {
249
            if ($path[0] !== '/') {
250
                $path = '/' . $path;
251
            }
252
253
            $uri .= $path;
254
        }
255
256
        return $uri;
257
    }
258
259
    /**
260
     * Add query to uri.
261
     *
262
     * @param string $uri The uri
263
     */
264
    protected function addQueryToUri(string $uri): string
265
    {
266
        if ($query = $this->query) {
267
            $uri .= '?' . $query;
268
        }
269
270
        return $uri;
271
    }
272
273
    /**
274
     * Add fragment to uri.
275
     *
276
     * @param string $uri The uri
277
     */
278
    protected function addFragmentToUri(string $uri): string
279
    {
280
        if ($fragment = $this->fragment) {
281
            $uri .= '#' . $fragment;
282
        }
283
284
        return $uri;
285
    }
286
}
287