1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the miBadger package. |
5
|
|
|
* |
6
|
|
|
* @author Michael Webbers <[email protected]> |
7
|
|
|
* @license http://opensource.org/licenses/Apache-2.0 Apache v2 License |
8
|
|
|
* @version 1.0.0 |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace miBadger\Http; |
12
|
|
|
|
13
|
|
|
use Psr\Http\Message\UriInterface; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* The URI class. |
17
|
|
|
* |
18
|
|
|
* @see http://tools.ietf.org/html/rfc3986 |
19
|
|
|
* @since 1.0.0 |
20
|
|
|
*/ |
21
|
|
|
class URI implements UriInterface |
22
|
|
|
{ |
23
|
|
|
const DELIMITER_SCHEME = ':'; |
24
|
|
|
const DELIMITER_AUTHORITY = '//'; |
25
|
|
|
const DELIMITER_USER = '@'; |
26
|
|
|
const DELIMITER_PASSWORD = ':'; |
27
|
|
|
const DELIMITER_PORT = ':'; |
28
|
|
|
const DELIMITER_PATH = '/'; |
29
|
|
|
const DELIMITER_QUERY = '?'; |
30
|
|
|
const DELIMITER_QUERY_PAIR = '&'; |
31
|
|
|
const DELIMITER_QUERY_KEY_VALUE = '='; |
32
|
|
|
const DELIMITER_FRAGMENT = '#'; |
33
|
|
|
|
34
|
|
|
const SCHEME = 'scheme'; |
35
|
|
|
const AUTHORITY = 'authority'; |
36
|
|
|
const USERNAME = 'user'; |
37
|
|
|
const PASSWORD = 'pass'; |
38
|
|
|
const HOST = 'host'; |
39
|
|
|
const PORT = 'port'; |
40
|
|
|
const PATH = 'path'; |
41
|
|
|
const DIRECTORY = 'directory'; |
42
|
|
|
const FILE = 'file'; |
43
|
|
|
const QUERY = 'query'; |
44
|
|
|
const FRAGMENT = 'fragment'; |
45
|
|
|
|
46
|
|
|
/** @var string The scheme. */ |
47
|
|
|
private $scheme; |
48
|
|
|
|
49
|
|
|
/** @var string The username. */ |
50
|
|
|
private $username; |
51
|
|
|
|
52
|
|
|
/** @var string|null The password. */ |
53
|
|
|
private $password; |
54
|
|
|
|
55
|
|
|
/** @var string The host. */ |
56
|
|
|
private $host; |
57
|
|
|
|
58
|
|
|
/** @var int|null The port. */ |
59
|
|
|
private $port; |
60
|
|
|
|
61
|
|
|
/** @var string The directory. */ |
62
|
|
|
private $directory; |
63
|
|
|
|
64
|
|
|
/** @var string The file. */ |
65
|
|
|
private $file; |
66
|
|
|
|
67
|
|
|
/** @var array The query. */ |
68
|
|
|
private $query; |
69
|
|
|
|
70
|
|
|
/** @var string The fragment. */ |
71
|
|
|
private $fragment; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Construct a URI object with the given URI. |
75
|
|
|
* |
76
|
|
|
* @param string $uri |
77
|
|
|
* @throws \UnexpectedValueException |
78
|
|
|
*/ |
79
|
51 |
|
public function __construct($uri) |
80
|
|
|
{ |
81
|
51 |
|
$component = parse_url($uri); |
82
|
|
|
|
83
|
51 |
|
if ($component === false) { |
84
|
1 |
|
throw new \UnexpectedValueException('Invalid uri'); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
// Replace with the null coalescing in PHP7. E.g. $component[scheme] ?? '' |
88
|
|
|
$component += [ |
89
|
51 |
|
static::SCHEME => '', |
90
|
51 |
|
static::USERNAME => '', |
91
|
51 |
|
static::PASSWORD => null, |
92
|
51 |
|
static::HOST => '', |
93
|
51 |
|
static::PORT => null, |
94
|
51 |
|
static::PATH => '', |
95
|
51 |
|
static::QUERY => '', |
96
|
51 |
|
static::FRAGMENT => '' |
97
|
51 |
|
]; |
98
|
|
|
|
99
|
51 |
|
$this->setScheme($component[static::SCHEME]); |
100
|
51 |
|
$this->setUserInfo($component[static::USERNAME], $component[static::PASSWORD]); |
101
|
51 |
|
$this->setHost($component[static::HOST]); |
102
|
51 |
|
$this->setPort($component[static::PORT]); |
103
|
51 |
|
$this->setPath($component[static::PATH]); |
104
|
51 |
|
$this->setQuery($component[static::QUERY]); |
105
|
51 |
|
$this->setFragment($component[static::FRAGMENT]); |
106
|
51 |
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Returns a string representation of the URI object. |
110
|
|
|
* |
111
|
|
|
* @return string a string representation of the URI object. |
112
|
|
|
*/ |
113
|
3 |
|
public function __toString() |
114
|
|
|
{ |
115
|
3 |
|
return $this->getUri(); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Returns the URI with the given start and stop component. |
120
|
|
|
* |
121
|
|
|
* @param string $start = self::SCHEME |
122
|
|
|
* @param string $end = self::FRAGMENT |
123
|
|
|
* @return string the URI. |
124
|
|
|
*/ |
125
|
6 |
|
public function getUri($start = self::SCHEME, $end = self::FRAGMENT) |
126
|
|
|
{ |
127
|
6 |
|
$result = ''; |
128
|
|
|
|
129
|
|
|
switch ($start) { |
130
|
6 |
|
default: |
131
|
6 |
|
case static::SCHEME: |
132
|
5 |
|
$scheme = $this->getScheme(); |
133
|
|
|
|
134
|
5 |
|
if ($scheme) { |
135
|
4 |
|
$result .= $scheme . static::DELIMITER_SCHEME; |
136
|
4 |
|
} |
137
|
|
|
|
138
|
5 |
|
if ($end === static::SCHEME) { |
139
|
1 |
|
break; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
// no break |
143
|
|
|
|
144
|
6 |
|
case static::AUTHORITY: |
145
|
6 |
View Code Duplication |
case static::USERNAME: |
|
|
|
|
146
|
6 |
|
$username = $this->getUserInfo(); |
147
|
|
|
|
148
|
6 |
|
if ($username && $this->getHost()) { |
149
|
5 |
|
$result .= static::DELIMITER_AUTHORITY . $username . static::DELIMITER_USER; |
150
|
5 |
|
} |
151
|
|
|
|
152
|
6 |
|
if ($end === static::USERNAME) { |
153
|
1 |
|
break; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
// no break |
157
|
|
|
|
158
|
6 |
|
case static::HOST: |
159
|
6 |
|
$host = $this->getHost(); |
160
|
|
|
|
161
|
6 |
|
if ($host && ($result === '' || !$this->getUserInfo())) { |
162
|
1 |
|
$result .= static::DELIMITER_AUTHORITY; |
163
|
1 |
|
} |
164
|
|
|
|
165
|
6 |
|
$result .= $host; |
166
|
|
|
|
167
|
6 |
|
if ($end === static::HOST) { |
168
|
1 |
|
break; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
// no break |
172
|
|
|
|
173
|
6 |
View Code Duplication |
case static::PORT: |
|
|
|
|
174
|
6 |
|
$port = $this->getPort(); |
175
|
|
|
|
176
|
6 |
|
if ($port !== null && $this->getHost()) { |
177
|
5 |
|
$result .= static::DELIMITER_PORT . $port; |
178
|
5 |
|
} |
179
|
|
|
|
180
|
6 |
|
if ($end === static::PORT || $end === static::AUTHORITY) { |
181
|
2 |
|
break; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
// no break |
185
|
|
|
|
186
|
5 |
|
case static::PATH: |
187
|
5 |
View Code Duplication |
case static::DIRECTORY: |
|
|
|
|
188
|
5 |
|
$directory = $this->getDirectory(); |
189
|
|
|
|
190
|
5 |
|
if ($result !== '' && $directory !== '' && substr($directory, 0, 1) !== static::DELIMITER_PATH) { |
191
|
1 |
|
$result .= static::DELIMITER_PATH; |
192
|
1 |
|
} |
193
|
|
|
|
194
|
5 |
|
$result .= $directory; |
195
|
|
|
|
196
|
5 |
|
if ($end === static::DIRECTORY) { |
197
|
1 |
|
break; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
// no break |
201
|
|
|
|
202
|
5 |
View Code Duplication |
case static::FILE: |
|
|
|
|
203
|
5 |
|
$file = $this->getFile(); |
204
|
|
|
|
205
|
5 |
|
if ($result !== '' && substr($result, -1) !== static::DELIMITER_PATH && $file !== '') { |
206
|
1 |
|
$result .= static::DELIMITER_PATH; |
207
|
1 |
|
} |
208
|
|
|
|
209
|
5 |
|
$result .= $this->getFile(); |
210
|
|
|
|
211
|
5 |
|
if ($end === static::FILE || $end === static::PATH) { |
212
|
1 |
|
break; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
// no break |
216
|
|
|
|
217
|
5 |
|
case static::QUERY: |
218
|
5 |
|
$query = $this->getQuery(); |
219
|
|
|
|
220
|
5 |
|
if ($query) { |
221
|
5 |
|
$result .= static::DELIMITER_QUERY . $query; |
222
|
5 |
|
} |
223
|
|
|
|
224
|
5 |
|
if ($end === static::QUERY) { |
225
|
1 |
|
break; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
// no break |
229
|
|
|
|
230
|
4 |
|
case static::FRAGMENT: |
231
|
4 |
|
$fragment = $this->getFragment(); |
232
|
|
|
|
233
|
4 |
|
if ($fragment) { |
234
|
3 |
|
$result .= static::DELIMITER_FRAGMENT . $fragment; |
235
|
3 |
|
} |
236
|
|
|
|
237
|
|
|
// no break |
238
|
4 |
|
} |
239
|
|
|
|
240
|
6 |
|
return $result; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* {@inheritdoc} |
245
|
|
|
*/ |
246
|
7 |
|
public function getScheme() |
247
|
|
|
{ |
248
|
7 |
|
return $this->scheme; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* Set the scheme. |
253
|
|
|
* |
254
|
|
|
* @param string $scheme |
255
|
|
|
* @return $this |
256
|
|
|
*/ |
257
|
51 |
|
private function setScheme($scheme) |
258
|
|
|
{ |
259
|
51 |
|
$this->scheme = strtolower($scheme); |
260
|
|
|
|
261
|
51 |
|
return $this; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* {@inheritdoc} |
266
|
|
|
*/ |
267
|
1 |
|
public function withScheme($scheme) |
268
|
|
|
{ |
269
|
1 |
|
$result = clone $this; |
270
|
|
|
|
271
|
1 |
|
return $result->setScheme($scheme); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* {@inheritdoc} |
276
|
|
|
*/ |
277
|
1 |
|
public function getAuthority() |
278
|
|
|
{ |
279
|
1 |
|
if (!$this->getHost()) { |
280
|
1 |
|
return ''; |
281
|
|
|
} |
282
|
|
|
|
283
|
1 |
|
return substr($this->getUri(self::USERNAME, self::PORT), 2); |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* {@inheritdoc} |
288
|
|
|
*/ |
289
|
8 |
|
public function getUserInfo() |
290
|
|
|
{ |
291
|
8 |
|
$result = $this->username; |
292
|
|
|
|
293
|
8 |
|
if ($this->password !== null) { |
294
|
7 |
|
$result .= static::DELIMITER_PASSWORD . $this->password; |
295
|
7 |
|
} |
296
|
|
|
|
297
|
8 |
|
return $result; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Set the user info. |
302
|
|
|
* |
303
|
|
|
* @param string $username |
304
|
|
|
* @param string|null $password = null |
305
|
|
|
* @return $this |
306
|
|
|
*/ |
307
|
51 |
|
private function setUserInfo($username, $password = null) |
308
|
|
|
{ |
309
|
51 |
|
$this->username = $username; |
310
|
51 |
|
$this->password = $password; |
311
|
|
|
|
312
|
51 |
|
return $this; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* {@inheritdoc} |
317
|
|
|
*/ |
318
|
1 |
|
public function withUserInfo($username, $password = null) |
319
|
|
|
{ |
320
|
1 |
|
$result = clone $this; |
321
|
|
|
|
322
|
1 |
|
return $result->setUserInfo($username, $password); |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* {@inheritdoc} |
327
|
|
|
*/ |
328
|
29 |
|
public function getHost() |
329
|
|
|
{ |
330
|
29 |
|
return $this->host; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* Set the host. |
335
|
|
|
* |
336
|
|
|
* @param string $host |
337
|
|
|
* @return $this |
338
|
|
|
*/ |
339
|
51 |
|
private function setHost($host) |
340
|
|
|
{ |
341
|
51 |
|
$this->host = strtolower($host); |
342
|
|
|
|
343
|
51 |
|
return $this; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* {@inheritdoc} |
348
|
|
|
*/ |
349
|
2 |
|
public function withHost($host) |
350
|
|
|
{ |
351
|
2 |
|
$result = clone $this; |
352
|
|
|
|
353
|
2 |
|
return $result->setHost($host); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* {@inheritdoc} |
358
|
|
|
*/ |
359
|
9 |
|
public function getPort() |
360
|
|
|
{ |
361
|
9 |
|
return $this->port; |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* Set the port. |
366
|
|
|
* |
367
|
|
|
* @param int|null $port |
368
|
|
|
* @return $this |
369
|
|
|
* @throws \InvalidArgumentException |
370
|
|
|
*/ |
371
|
51 |
|
private function setPort($port = null) |
372
|
|
|
{ |
373
|
51 |
|
if ($port !== null && (1 > $port || 0xffff < $port)) { |
374
|
1 |
|
throw new \InvalidArgumentException('Invalid port'); |
375
|
|
|
} |
376
|
|
|
|
377
|
51 |
|
$this->port = $port; |
378
|
|
|
|
379
|
51 |
|
return $this; |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
/** |
383
|
|
|
* {@inheritdoc} |
384
|
|
|
*/ |
385
|
2 |
|
public function withPort($port) |
386
|
|
|
{ |
387
|
2 |
|
$result = clone $this; |
388
|
|
|
|
389
|
2 |
|
return $result->setPort($port); |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
/** |
393
|
|
|
* {@inheritdoc} |
394
|
|
|
*/ |
395
|
5 |
|
public function getPath() |
396
|
|
|
{ |
397
|
5 |
|
$result = $this->getDirectory(); |
398
|
|
|
|
399
|
5 |
|
if ($result !== '' && substr($result, -1) !== static::DELIMITER_PATH && $this->getFile()) { |
400
|
1 |
|
$result .= static::DELIMITER_PATH; |
401
|
1 |
|
} |
402
|
|
|
|
403
|
5 |
|
return $result . $this->getFile(); |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
/** |
407
|
|
|
* Set the path. |
408
|
|
|
* |
409
|
|
|
* @param string $path |
410
|
|
|
* @return $this |
411
|
|
|
*/ |
412
|
51 |
|
private function setPath($path) |
413
|
|
|
{ |
414
|
51 |
|
$directory = dirname($path); |
415
|
51 |
|
$file = basename($path); |
416
|
|
|
|
417
|
|
|
// If dirname is '.'. Then remove it. |
418
|
51 |
|
if ($directory === '.') { |
419
|
1 |
|
$directory = ''; |
420
|
1 |
|
} |
421
|
|
|
|
422
|
|
|
// If the path ends with '/'. Then there is no file. |
423
|
51 |
|
if (substr($path, -1) === static::DELIMITER_PATH) { |
424
|
4 |
|
$directory = $path; |
425
|
4 |
|
$file = ''; |
426
|
4 |
|
} |
427
|
|
|
|
428
|
|
|
// If the dirname and basename are both set. Then add the missing '/'. |
429
|
51 |
|
if (substr($directory, -1) !== static::DELIMITER_PATH && $directory !== '' && $file !== '') { |
430
|
35 |
|
$directory .= static::DELIMITER_PATH; |
431
|
35 |
|
} |
432
|
|
|
|
433
|
51 |
|
$this->setDirectory($directory); |
434
|
51 |
|
$this->setFile($file); |
435
|
|
|
|
436
|
51 |
|
return $this; |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* {@inheritdoc} |
441
|
|
|
*/ |
442
|
3 |
|
public function withPath($path) |
443
|
|
|
{ |
444
|
3 |
|
$result = clone $this; |
445
|
|
|
|
446
|
3 |
|
return $result->setPath($path); |
447
|
|
|
} |
448
|
|
|
|
449
|
|
|
/** |
450
|
|
|
* Returns the URI segements |
451
|
|
|
* |
452
|
|
|
* @return string[] the URI segments |
453
|
|
|
*/ |
454
|
2 |
|
public function getSegments() |
455
|
|
|
{ |
456
|
|
|
// array_values reindexes the array and array_diff removes the empty elements. |
457
|
2 |
|
return array_values(array_diff(explode(static::DELIMITER_PATH, $this->getPath()), [''])); |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
/** |
461
|
|
|
* Returns the segment at the given index or null if the segment at the given index doesn't exists. |
462
|
|
|
* |
463
|
|
|
* @param int $index |
464
|
|
|
* @return string|null the segment at the given index or null if the segment at the given index doesn't exists |
465
|
|
|
*/ |
466
|
1 |
|
public function getSegment($index) |
467
|
|
|
{ |
468
|
1 |
|
$result = $this->getSegments(); |
469
|
|
|
|
470
|
1 |
|
return isset($result[$index]) ? $result[$index] : null; |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
/** |
474
|
|
|
* Returns the directory. |
475
|
|
|
* |
476
|
|
|
* @return string the directory. |
477
|
|
|
*/ |
478
|
11 |
|
public function getDirectory() |
479
|
|
|
{ |
480
|
11 |
|
return $this->directory; |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* Set the directory. |
485
|
|
|
* |
486
|
|
|
* @param string $directory |
487
|
|
|
* @return $this |
488
|
|
|
*/ |
489
|
51 |
|
private function setDirectory($directory) |
490
|
|
|
{ |
491
|
51 |
|
$this->directory = $directory; |
492
|
|
|
|
493
|
51 |
|
return $this; |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
/** |
497
|
|
|
* Return an instance with the specified directory. |
498
|
|
|
* |
499
|
|
|
* @param string $directory |
500
|
|
|
* @return self |
501
|
|
|
*/ |
502
|
3 |
|
public function withDirectory($directory) |
503
|
|
|
{ |
504
|
3 |
|
$result = clone $this; |
505
|
|
|
|
506
|
3 |
|
return $result->setDirectory($directory); |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
/** |
510
|
|
|
* Returns the file. |
511
|
|
|
* |
512
|
|
|
* @return string the file. |
513
|
|
|
*/ |
514
|
11 |
|
public function getFile() |
515
|
|
|
{ |
516
|
11 |
|
return $this->file; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
/** |
520
|
|
|
* Set the file. |
521
|
|
|
* |
522
|
|
|
* @param string $file |
523
|
|
|
* @return $this |
524
|
|
|
*/ |
525
|
51 |
|
private function setFile($file) |
526
|
|
|
{ |
527
|
51 |
|
$this->file = $file; |
528
|
|
|
|
529
|
51 |
|
return $this; |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* Return an instance with the specified file. |
534
|
|
|
* |
535
|
|
|
* @param string $file |
536
|
|
|
* @return self |
537
|
|
|
*/ |
538
|
1 |
|
public function withFile($file) |
539
|
|
|
{ |
540
|
1 |
|
$result = clone $this; |
541
|
|
|
|
542
|
1 |
|
return $result->setFile($file); |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
/** |
546
|
|
|
* {@inheritdoc} |
547
|
|
|
*/ |
548
|
7 |
|
public function getQuery() |
549
|
|
|
{ |
550
|
7 |
|
return http_build_query($this->query); |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* Set the query. |
555
|
|
|
* |
556
|
|
|
* @param string $query |
557
|
|
|
* @return $this |
558
|
|
|
*/ |
559
|
51 |
|
private function setQuery($query) |
560
|
|
|
{ |
561
|
51 |
|
$this->query = []; |
562
|
|
|
|
563
|
51 |
|
parse_str($query, $this->query); |
564
|
|
|
|
565
|
51 |
|
return $this; |
566
|
|
|
} |
567
|
|
|
|
568
|
|
|
/** |
569
|
|
|
* {@inheritdoc} |
570
|
|
|
*/ |
571
|
1 |
|
public function withQuery($query) |
572
|
|
|
{ |
573
|
1 |
|
$result = clone $this; |
574
|
|
|
|
575
|
1 |
|
return $result->setQuery($query); |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
/** |
579
|
|
|
* Returns the value to which the specified key is mapped, or null if the query map contains no mapping for the key. |
580
|
|
|
* |
581
|
|
|
* @param string $key |
582
|
|
|
* @return string the value to which the specified key is mapped, or null if the query map contains no mapping for the key. |
583
|
|
|
*/ |
584
|
2 |
|
public function getQueryValue($key) |
585
|
|
|
{ |
586
|
2 |
|
return isset($this->query[$key]) ? $this->query[$key] : null; |
587
|
|
|
} |
588
|
|
|
|
589
|
|
|
/** |
590
|
|
|
* Associates the specified value with the specified key in the query map. |
591
|
|
|
* |
592
|
|
|
* @param string $key |
593
|
|
|
* @param string $value |
594
|
|
|
* @return $this |
595
|
|
|
*/ |
596
|
1 |
|
private function setQueryValue($key, $value) |
597
|
|
|
{ |
598
|
1 |
|
$this->query[$key] = $value; |
599
|
|
|
|
600
|
1 |
|
return $this; |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* Return an instance with the specified query value. |
605
|
|
|
* |
606
|
|
|
* @param string $key |
607
|
|
|
* @param string $value |
608
|
|
|
* @return self |
609
|
|
|
*/ |
610
|
1 |
|
public function withQueryValue($key, $value) |
611
|
|
|
{ |
612
|
1 |
|
$result = clone $this; |
613
|
|
|
|
614
|
1 |
|
return $result->setQueryValue($key, $value); |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
/** |
618
|
|
|
* {@inheritdoc} |
619
|
|
|
*/ |
620
|
6 |
|
public function getFragment() |
621
|
|
|
{ |
622
|
6 |
|
return $this->fragment; |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
/** |
626
|
|
|
* Set the fragment. |
627
|
|
|
* |
628
|
|
|
* @param string $fragment |
629
|
|
|
* @return $this |
630
|
|
|
*/ |
631
|
51 |
|
private function setFragment($fragment) |
632
|
|
|
{ |
633
|
51 |
|
$this->fragment = $fragment; |
634
|
|
|
|
635
|
51 |
|
return $this; |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
/** |
639
|
|
|
* {@inheritdoc} |
640
|
|
|
*/ |
641
|
1 |
|
public function withFragment($fragment) |
642
|
|
|
{ |
643
|
1 |
|
$result = clone $this; |
644
|
|
|
|
645
|
1 |
|
return $result->setFragment($fragment); |
646
|
|
|
} |
647
|
|
|
|
648
|
|
|
/** |
649
|
|
|
* Returns an instance with the decoded URI. |
650
|
|
|
* |
651
|
|
|
* @return self |
652
|
|
|
*/ |
653
|
1 |
|
public function decode() |
654
|
|
|
{ |
655
|
1 |
|
return new URI(html_entity_decode($this)); |
656
|
|
|
} |
657
|
|
|
|
658
|
|
|
/** |
659
|
|
|
* Returns an instance with the encoded URI. |
660
|
|
|
* |
661
|
|
|
* @return self |
662
|
|
|
*/ |
663
|
1 |
|
public function encode() |
664
|
|
|
{ |
665
|
1 |
|
return new URI(htmlentities($this)); |
666
|
|
|
} |
667
|
|
|
} |
668
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.