• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / http / 13104062608

03 Feb 2025 12:37AM UTC coverage: 83.441%. Remained the same
13104062608

push

github

dg
Url, UrlImmutable: user & password are deprecated

907 of 1087 relevant lines covered (83.44%)

0.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.18
/src/Http/UrlImmutable.php
1
<?php
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Nette\Http;
11

12
use Nette;
13

14

15
/**
16
 * Immutable representation of a URL.
17
 *
18
 * <pre>
19
 * scheme  user  password  host  port      path        query    fragment
20
 *   |      |      |        |      |        |            |         |
21
 * /--\   /--\ /------\ /-------\ /--\/------------\ /--------\ /------\
22
 * http://john:x0y17575@nette.org:8042/en/manual.php?name=param#fragment  <-- absoluteUrl
23
 * \______\__________________________/
24
 *     |               |
25
 *  hostUrl        authority
26
 * </pre>
27
 *
28
 * @property-read string $scheme
29
 * @property-read string $user
30
 * @property-read string $password
31
 * @property-read string $host
32
 * @property-read int $port
33
 * @property-read string $path
34
 * @property-read string $query
35
 * @property-read string $fragment
36
 * @property-read string $absoluteUrl
37
 * @property-read string $authority
38
 * @property-read string $hostUrl
39
 * @property-read array $queryParameters
40
 */
41
class UrlImmutable implements \JsonSerializable
42
{
43
        use Nette\SmartObject;
44

45
        private string $scheme = '';
46
        private string $user = '';
47
        private string $password = '';
48
        private string $host = '';
49
        private ?int $port = null;
50
        private string $path = '';
51
        private array $query = [];
52
        private string $fragment = '';
53
        private ?string $authority = null;
54

55

56
        /**
57
         * @throws Nette\InvalidArgumentException if URL is malformed
58
         */
59
        public function __construct(string|self|Url $url)
1✔
60
        {
61
                $url = is_string($url) ? new Url($url) : $url;
1✔
62
                [$this->scheme, $this->user, $this->password, $this->host, $this->port, $this->path, $this->query, $this->fragment] = $url->export();
1✔
63
        }
1✔
64

65

66
        public function withScheme(string $scheme): static
1✔
67
        {
68
                $dolly = clone $this;
1✔
69
                $dolly->scheme = $scheme;
1✔
70
                $dolly->authority = null;
1✔
71
                return $dolly;
1✔
72
        }
73

74

75
        public function getScheme(): string
76
        {
77
                return $this->scheme;
1✔
78
        }
79

80

81
        /** @deprecated */
82
        public function withUser(string $user): static
1✔
83
        {
84
                $dolly = clone $this;
1✔
85
                $dolly->user = $user;
1✔
86
                $dolly->authority = null;
1✔
87
                return $dolly;
1✔
88
        }
89

90

91
        /** @deprecated */
92
        public function getUser(): string
93
        {
94
                return $this->user;
1✔
95
        }
96

97

98
        /** @deprecated */
99
        public function withPassword(string $password): static
1✔
100
        {
101
                $dolly = clone $this;
1✔
102
                $dolly->password = $password;
1✔
103
                $dolly->authority = null;
1✔
104
                return $dolly;
1✔
105
        }
106

107

108
        /** @deprecated */
109
        public function getPassword(): string
110
        {
111
                return $this->password;
1✔
112
        }
113

114

115
        /** @deprecated */
116
        public function withoutUserInfo(): static
117
        {
118
                $dolly = clone $this;
1✔
119
                $dolly->user = $dolly->password = '';
1✔
120
                $dolly->authority = null;
1✔
121
                return $dolly;
1✔
122
        }
123

124

125
        public function withHost(string $host): static
1✔
126
        {
127
                $dolly = clone $this;
1✔
128
                $dolly->host = $host;
1✔
129
                $dolly->authority = null;
1✔
130
                return $dolly->setPath($dolly->path);
1✔
131
        }
132

133

134
        public function getHost(): string
135
        {
136
                return $this->host;
1✔
137
        }
138

139

140
        public function getDomain(int $level = 2): string
1✔
141
        {
142
                $parts = ip2long($this->host)
1✔
143
                        ? [$this->host]
×
144
                        : explode('.', $this->host);
1✔
145
                $parts = $level >= 0
1✔
146
                        ? array_slice($parts, -$level)
1✔
147
                        : array_slice($parts, 0, $level);
1✔
148
                return implode('.', $parts);
1✔
149
        }
150

151

152
        public function withPort(int $port): static
1✔
153
        {
154
                $dolly = clone $this;
1✔
155
                $dolly->port = $port;
1✔
156
                $dolly->authority = null;
1✔
157
                return $dolly;
1✔
158
        }
159

160

161
        public function getPort(): ?int
162
        {
163
                return $this->port ?: $this->getDefaultPort();
1✔
164
        }
165

166

167
        public function getDefaultPort(): ?int
168
        {
169
                return Url::$defaultPorts[$this->scheme] ?? null;
1✔
170
        }
171

172

173
        public function withPath(string $path): static
1✔
174
        {
175
                return (clone $this)->setPath($path);
1✔
176
        }
177

178

179
        private function setPath(string $path): static
1✔
180
        {
181
                $this->path = $this->host && !str_starts_with($path, '/') ? '/' . $path : $path;
1✔
182
                return $this;
1✔
183
        }
184

185

186
        public function getPath(): string
187
        {
188
                return $this->path;
1✔
189
        }
190

191

192
        public function withQuery(string|array $query): static
1✔
193
        {
194
                $dolly = clone $this;
1✔
195
                $dolly->query = is_array($query) ? $query : Url::parseQuery($query);
1✔
196
                return $dolly;
1✔
197
        }
198

199

200
        public function getQuery(): string
201
        {
202
                return http_build_query($this->query, '', '&', PHP_QUERY_RFC3986);
1✔
203
        }
204

205

206
        public function withQueryParameter(string $name, mixed $value): static
1✔
207
        {
208
                $dolly = clone $this;
1✔
209
                $dolly->query[$name] = $value;
1✔
210
                return $dolly;
1✔
211
        }
212

213

214
        public function getQueryParameters(): array
215
        {
216
                return $this->query;
1✔
217
        }
218

219

220
        public function getQueryParameter(string $name): array|string|null
1✔
221
        {
222
                return $this->query[$name] ?? null;
1✔
223
        }
224

225

226
        public function withFragment(string $fragment): static
1✔
227
        {
228
                $dolly = clone $this;
1✔
229
                $dolly->fragment = $fragment;
1✔
230
                return $dolly;
1✔
231
        }
232

233

234
        public function getFragment(): string
235
        {
236
                return $this->fragment;
1✔
237
        }
238

239

240
        /**
241
         * Returns the entire URI including query string and fragment.
242
         */
243
        public function getAbsoluteUrl(): string
244
        {
245
                return $this->getHostUrl() . $this->path
1✔
246
                        . (($tmp = $this->getQuery()) ? '?' . $tmp : '')
1✔
247
                        . ($this->fragment === '' ? '' : '#' . $this->fragment);
1✔
248
        }
249

250

251
        /**
252
         * Returns the [user[:pass]@]host[:port] part of URI.
253
         */
254
        public function getAuthority(): string
255
        {
256
                return $this->authority ??= $this->host === ''
1✔
257
                        ? ''
×
258
                        : ($this->user !== ''
1✔
259
                                ? rawurlencode($this->user) . ($this->password === '' ? '' : ':' . rawurlencode($this->password)) . '@'
1✔
260
                                : '')
1✔
261
                        . $this->host
1✔
262
                        . ($this->port && $this->port !== $this->getDefaultPort()
1✔
263
                                ? ':' . $this->port
1✔
264
                                : '');
1✔
265
        }
266

267

268
        /**
269
         * Returns the scheme and authority part of URI.
270
         */
271
        public function getHostUrl(): string
272
        {
273
                return ($this->scheme === '' ? '' : $this->scheme . ':')
1✔
274
                        . ($this->host === '' ? '' : '//' . $this->getAuthority());
1✔
275
        }
276

277

278
        public function __toString(): string
279
        {
280
                return $this->getAbsoluteUrl();
1✔
281
        }
282

283

284
        public function isEqual(string|Url|self $url): bool
1✔
285
        {
286
                return (new Url($this))->isEqual($url);
1✔
287
        }
288

289

290
        /**
291
         * Resolves relative URLs in the same way as browser. If path is relative, it is resolved against
292
         * base URL, if begins with /, it is resolved against the host root.
293
         */
294
        public function resolve(string $reference): self
1✔
295
        {
296
                $ref = new self($reference);
1✔
297
                if ($ref->scheme !== '') {
1✔
298
                        $ref->path = Url::removeDotSegments($ref->path);
1✔
299
                        return $ref;
1✔
300
                }
301

302
                $ref->scheme = $this->scheme;
1✔
303

304
                if ($ref->host !== '') {
1✔
305
                        $ref->path = Url::removeDotSegments($ref->path);
1✔
306
                        return $ref;
1✔
307
                }
308

309
                $ref->host = $this->host;
1✔
310
                $ref->port = $this->port;
1✔
311

312
                if ($ref->path === '') {
1✔
313
                        $ref->path = $this->path;
1✔
314
                        $ref->query = $ref->query ?: $this->query;
1✔
315
                } elseif (str_starts_with($ref->path, '/')) {
1✔
316
                        $ref->path = Url::removeDotSegments($ref->path);
1✔
317
                } else {
318
                        $ref->path = Url::removeDotSegments($this->mergePath($ref->path));
1✔
319
                }
320
                return $ref;
1✔
321
        }
322

323

324
        /** @internal */
325
        protected function mergePath(string $path): string
1✔
326
        {
327
                $pos = strrpos($this->path, '/');
1✔
328
                return $pos === false ? $path : substr($this->path, 0, $pos + 1) . $path;
1✔
329
        }
330

331

332
        public function jsonSerialize(): string
333
        {
334
                return $this->getAbsoluteUrl();
1✔
335
        }
336

337

338
        /** @internal */
339
        final public function export(): array
340
        {
341
                return [$this->scheme, $this->user, $this->password, $this->host, $this->port, $this->path, $this->query, $this->fragment];
1✔
342
        }
343
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc