Total Complexity | 106 |
Total Lines | 1074 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 1 | Features | 0 |
Complex classes like Uri often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Uri, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class Uri implements UriInterface |
||
27 | { |
||
28 | /** |
||
29 | * Uri::$scheme |
||
30 | * |
||
31 | * @var string |
||
32 | */ |
||
33 | protected $scheme; |
||
34 | |||
35 | /** |
||
36 | * Uri::$segments |
||
37 | * |
||
38 | * @var \O2System\Kernel\Http\Message\Uri\Segments |
||
39 | */ |
||
40 | public $segments; |
||
41 | |||
42 | /** |
||
43 | * Uri::$suffix |
||
44 | * |
||
45 | * @var string |
||
46 | */ |
||
47 | protected $suffix; |
||
48 | |||
49 | /** |
||
50 | * Uri::$host |
||
51 | * |
||
52 | * The host subcomponent of authority is identified by an IP literal |
||
53 | * encapsulated within square brackets, an IPv4 address in dotted-decimal form, |
||
54 | * or a registered name. |
||
55 | * |
||
56 | * @see https://tools.ietf.org/html/rfc3986 |
||
57 | * |
||
58 | * @var string IP-literal / IPv4address / registered-name |
||
59 | */ |
||
60 | protected $host; |
||
61 | |||
62 | /** |
||
63 | * Uri::$port |
||
64 | * |
||
65 | * @var int |
||
66 | */ |
||
67 | protected $port = 80; |
||
68 | |||
69 | /** |
||
70 | * Uri::$username |
||
71 | * |
||
72 | * @var string |
||
73 | */ |
||
74 | protected $username; |
||
75 | |||
76 | /** |
||
77 | * Uri::$password |
||
78 | * |
||
79 | * @var string |
||
80 | */ |
||
81 | protected $password; |
||
82 | |||
83 | /** |
||
84 | * Uri::$path |
||
85 | * |
||
86 | * @var string |
||
87 | */ |
||
88 | protected $path; |
||
89 | |||
90 | /** |
||
91 | * Uri::$query |
||
92 | * |
||
93 | * @var string |
||
94 | */ |
||
95 | protected $query; |
||
96 | |||
97 | /** |
||
98 | * Uri::$fragment |
||
99 | * |
||
100 | * @var string |
||
101 | */ |
||
102 | protected $fragment; |
||
103 | |||
104 | /** |
||
105 | * Uri::$attribute |
||
106 | * |
||
107 | * @var string |
||
108 | */ |
||
109 | protected $attribute; |
||
110 | |||
111 | /** |
||
112 | * Uri::$subDomain |
||
113 | * |
||
114 | * @var string |
||
115 | */ |
||
116 | protected $subDomain; |
||
117 | |||
118 | /** |
||
119 | * Uri::$subDomains |
||
120 | * |
||
121 | * List of Uri SubDomains |
||
122 | * |
||
123 | * @var array |
||
124 | */ |
||
125 | protected $subDomains = []; |
||
126 | |||
127 | /** |
||
128 | * Uri::$tld |
||
129 | * |
||
130 | * Uri Top Level Domain |
||
131 | * |
||
132 | * @var string |
||
133 | */ |
||
134 | protected $tld; |
||
135 | |||
136 | /** |
||
137 | * Uri::$tlds |
||
138 | * |
||
139 | * List of Uri Top Level Domains |
||
140 | * |
||
141 | * @var array |
||
142 | */ |
||
143 | protected $tlds = []; |
||
144 | |||
145 | // ------------------------------------------------------------------------ |
||
146 | |||
147 | /** |
||
148 | * Uri::__construct |
||
149 | * |
||
150 | * @param string|null $httpStringRequest |
||
151 | */ |
||
152 | public function __construct($httpStringRequest = null) |
||
153 | { |
||
154 | if (isset($httpStringRequest)) { |
||
155 | $this->segments = new Segments(''); |
||
156 | $httpStringRequest = ltrim($httpStringRequest, '//'); |
||
157 | |||
158 | if (strpos($httpStringRequest, 'http://') === false) { |
||
159 | if (strpos($httpStringRequest, 'https://') === false) { |
||
160 | $httpStringRequest = 'http://' . $httpStringRequest; |
||
161 | } |
||
162 | } |
||
163 | |||
164 | $httpStringRequest = trim($httpStringRequest, '/'); |
||
165 | $parseUrl = parse_url($httpStringRequest); |
||
166 | |||
167 | $this->host = isset($parseUrl[ 'host' ]) ? $parseUrl[ 'host' ] : null; |
||
168 | |||
169 | $this->scheme = isset($parseUrl[ 'scheme' ]) ? $parseUrl[ 'scheme' ] : (is_https() ? 'https' : 'http'); |
||
170 | |||
171 | /** |
||
172 | * Define Uri Port |
||
173 | */ |
||
174 | if (strpos($this->scheme, 'https') !== false) { |
||
175 | $this->port = 443; |
||
176 | } |
||
177 | |||
178 | if (isset($parseUrl[ 'path' ])) { |
||
179 | $xRequest = explode('/', $parseUrl[ 'path' ]); |
||
180 | $this->path = implode('/', array_slice($xRequest, 1)); |
||
181 | } |
||
182 | |||
183 | if (strpos($this->path, '.php') !== false) { |
||
184 | $xPath = explode('.php', $this->path); |
||
185 | $xPath = explode('/', trim($xPath[ 0 ], '/')); |
||
186 | array_pop($xPath); |
||
187 | |||
188 | $this->path = empty($xPath) ? null : implode('/', $xPath); |
||
189 | } |
||
190 | |||
191 | $this->query = isset($parseUrl[ 'query' ]) ? $parseUrl[ 'query' ] : null; |
||
192 | $this->username = isset($parseUrl[ 'user' ]) ? $parseUrl[ 'user' ] : null; |
||
193 | $this->password = isset($parseUrl[ 'pass' ]) ? $parseUrl[ 'pass' ] : null; |
||
194 | $this->port = isset($parseUrl[ 'port' ]) ? $parseUrl[ 'port' ] : 80; |
||
195 | $this->fragment = isset($parseUrl[ 'fragment' ]) ? $parseUrl[ 'fragment' ] : null; |
||
196 | } else { |
||
197 | $this->segments = new Segments(); |
||
198 | |||
199 | /** |
||
200 | * Define Uri Host |
||
201 | */ |
||
202 | $this->host = isset($_SERVER[ 'HTTP_HOST' ]) |
||
203 | ? str_replace('www.', '', $_SERVER[ 'HTTP_HOST' ]) |
||
204 | : str_replace('www.', '', $_SERVER[ 'SERVER_NAME' ]); |
||
205 | |||
206 | /** |
||
207 | * Define Uri Scheme |
||
208 | */ |
||
209 | $this->scheme = is_https() ? 'https' : 'http'; |
||
210 | |||
211 | /** |
||
212 | * Define Uri Attribute |
||
213 | */ |
||
214 | if (strpos($_SERVER[ 'PHP_SELF' ], '/@') !== false) { |
||
215 | $xPhpSelf = explode('/@', $_SERVER[ 'PHP_SELF' ]); |
||
216 | |||
217 | $this->attribute = '@' . $xPhpSelf[ 1 ]; |
||
218 | |||
219 | if (strpos($this->attribute, '/') !== false) { |
||
220 | $xAttribute = explode('/', $this->attribute); |
||
221 | |||
222 | $this->attribute = $xAttribute[ 0 ]; |
||
223 | } |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * Define Uri User and Password |
||
228 | */ |
||
229 | if (preg_match("/[a-zA-Z0-9]+[@][a-zA-Z0-9]+/", $_SERVER[ 'PHP_SELF' ], $usernamePassword)) { |
||
230 | $xUsernamePassword = explode('@', $usernamePassword[ 0 ]); |
||
231 | $this->username = $xUsernamePassword[ 0 ]; |
||
232 | $this->password = $xUsernamePassword[ 1 ]; |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * Define Uri Port |
||
237 | */ |
||
238 | $this->port = is_https() ? 443 : 80; |
||
239 | |||
240 | if (strpos($this->host, ':') !== false) { |
||
241 | $xHost = explode(':', $this->host); |
||
242 | $this->host = reset($xHost); |
||
243 | $this->port = end($xHost); |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * Define Uri Path |
||
248 | */ |
||
249 | $xPath = explode('.php', $_SERVER[ 'PHP_SELF' ]); |
||
250 | $xPath = explode('/', trim($xPath[ 0 ], '/')); |
||
251 | array_pop($xPath); |
||
252 | |||
253 | $this->path = empty($xPath) ? null : implode('/', $xPath) . '/'; |
||
254 | |||
255 | $this->query = isset($_SERVER[ 'QUERY_STRING' ]) ? $_SERVER[ 'QUERY_STRING' ] : null; |
||
256 | |||
257 | } |
||
258 | |||
259 | if (filter_var($this->host, FILTER_VALIDATE_IP) !== false OR strpos($this->host, '.') === false) { |
||
260 | $xHost = [$this->host]; |
||
261 | } else { |
||
262 | $xHost = explode('.', str_replace('www.', '', $this->host)); |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * Define Uri Tld |
||
267 | */ |
||
268 | if ($xHostNum = count($xHost)) { |
||
|
|||
269 | $this->tlds[] = end($xHost); |
||
270 | array_pop($xHost); |
||
271 | |||
272 | if (count($xHost) >= 2) { |
||
273 | $this->subDomains[] = $this->subDomain = reset($xHost); |
||
274 | array_shift($xHost); |
||
275 | |||
276 | if (count($xHost)) { |
||
277 | if (strlen($tld = end($xHost)) <= 3) { |
||
278 | array_unshift($this->tlds, $tld); |
||
279 | array_pop($xHost); |
||
280 | } |
||
281 | } |
||
282 | } |
||
283 | |||
284 | if (count($xHost)) { |
||
285 | $this->host = implode('.', $xHost) . '.' . implode('.', $this->tlds); |
||
286 | } |
||
287 | |||
288 | $this->tld = '.' . implode('.', $this->tlds); |
||
289 | } |
||
290 | |||
291 | $xHost = explode('.', $this->host); |
||
292 | $xHostNum = count($xHost); |
||
293 | $tldsNum = count($this->tlds); |
||
294 | |||
295 | // Convert Keys to Ordinal |
||
296 | $this->setOrdinalKeys($this->subDomains, ($tldsNum + $xHostNum) - 1); |
||
297 | $this->setOrdinalKeys($this->tlds, $tldsNum); |
||
298 | |||
299 | if (services()->has('config')) { |
||
300 | if (config()->offsetExists('uri')) { |
||
301 | $this->setSuffix(config('uri')->offsetGet('suffix')); |
||
302 | } |
||
303 | } |
||
304 | } |
||
305 | |||
306 | // ------------------------------------------------------------------------ |
||
307 | |||
308 | /** |
||
309 | * Uri::setOrdinalKeys |
||
310 | * |
||
311 | * @param array $elements |
||
312 | * @param int $startNumber |
||
313 | */ |
||
314 | protected function setOrdinalKeys(array &$elements, $startNumber = 0) |
||
330 | } |
||
331 | } |
||
332 | |||
333 | // ------------------------------------------------------------------------ |
||
334 | |||
335 | /** |
||
336 | * Uri::getSegments |
||
337 | * |
||
338 | * @return Segments |
||
339 | */ |
||
340 | public function &getSegments() |
||
341 | { |
||
342 | return $this->segments; |
||
343 | } |
||
344 | |||
345 | // ------------------------------------------------------------------------ |
||
346 | |||
347 | /** |
||
348 | * Uri::withSegments |
||
349 | * |
||
350 | * @param Segments $segments |
||
351 | * |
||
352 | * @return Uri |
||
353 | */ |
||
354 | public function withSegments(Segments $segments) |
||
360 | } |
||
361 | |||
362 | // ------------------------------------------------------------------------ |
||
363 | |||
364 | /** |
||
365 | * Uri::addSegments |
||
366 | * |
||
367 | * @param Segments|string|array $segments |
||
368 | * |
||
369 | * @return \O2System\Kernel\Http\Message\Uri |
||
370 | * @throws \O2System\Spl\Exceptions\RuntimeException |
||
371 | */ |
||
372 | public function addSegments($segments) |
||
373 | { |
||
374 | if ( ! $segments instanceof Segments) { |
||
375 | $segments = new Segments($segments); |
||
376 | } |
||
377 | |||
378 | $currentSegments = $this->segments->getArrayCopy(); |
||
379 | $addSegments = $segments->getArrayCopy(); |
||
380 | |||
381 | $uri = clone $this; |
||
382 | $uri->segments = new Segments(array_merge($currentSegments, $addSegments)); |
||
383 | |||
384 | return $uri; |
||
385 | } |
||
386 | |||
387 | // ------------------------------------------------------------------------ |
||
388 | |||
389 | /** |
||
390 | * Uri::getScheme |
||
391 | * |
||
392 | * Retrieve the scheme component of the URI. |
||
393 | * |
||
394 | * If no scheme is present, this method MUST return an empty string. |
||
395 | * |
||
396 | * The value returned MUST be normalized to lowercase, per RFC 3986 |
||
397 | * Section 3.1. |
||
398 | * |
||
399 | * The trailing ":" character is not part of the scheme and MUST NOT be |
||
400 | * added. |
||
401 | * |
||
402 | * @see https://tools.ietf.org/html/rfc3986#section-3.1 |
||
403 | * @return string The URI scheme. |
||
404 | */ |
||
405 | public function getScheme() |
||
406 | { |
||
407 | return $this->scheme; |
||
408 | } |
||
409 | |||
410 | // ------------------------------------------------------------------------ |
||
411 | |||
412 | /** |
||
413 | * Uri::getAuthority |
||
414 | * |
||
415 | * Retrieve the authority component of the URI. |
||
416 | * |
||
417 | * If no authority information is present, this method MUST return an empty |
||
418 | * string. |
||
419 | * |
||
420 | * The authority syntax of the URI is: |
||
421 | * |
||
422 | * <pre> |
||
423 | * [user-info@]host[:port] |
||
424 | * </pre> |
||
425 | * |
||
426 | * If the port component is not set or is the standard port for the current |
||
427 | * scheme, it SHOULD NOT be included. |
||
428 | * |
||
429 | * @see https://tools.ietf.org/html/rfc3986#section-3.2 |
||
430 | * @return string The URI authority, in "[user-info@]host[:port]" format. |
||
431 | */ |
||
432 | public function getAuthority() |
||
433 | { |
||
434 | if (empty($this->host)) { |
||
435 | return null; |
||
436 | } |
||
437 | |||
438 | $authority = $this->host; |
||
439 | |||
440 | if ( ! empty($this->getUserInfo())) { |
||
441 | $authority = $this->getUserInfo() . '@' . $authority; |
||
442 | } |
||
443 | |||
444 | if ( ! empty($this->port)) { |
||
445 | if ($this->port != 80) { |
||
446 | $authority .= ':' . $this->port; |
||
447 | } |
||
448 | } |
||
449 | |||
450 | return $authority; |
||
451 | } |
||
452 | |||
453 | // ------------------------------------------------------------------------ |
||
454 | |||
455 | /** |
||
456 | * Uri::getUserInfo |
||
457 | * |
||
458 | * Retrieve the user information component of the URI. |
||
459 | * |
||
460 | * If no user information is present, this method MUST return an empty |
||
461 | * string. |
||
462 | * |
||
463 | * If a user is present in the URI, this will return that value; |
||
464 | * additionally, if the password is also present, it will be appended to the |
||
465 | * user value, with a colon (":") separating the values. |
||
466 | * |
||
467 | * The trailing "@" character is not part of the user information and MUST |
||
468 | * NOT be added. |
||
469 | * |
||
470 | * @return string The URI user information, in "username[:password]" format. |
||
471 | */ |
||
472 | public function getUserInfo() |
||
473 | { |
||
474 | $userInfo = $this->username; |
||
475 | |||
476 | if ( ! empty($this->password)) { |
||
477 | $userInfo .= ':' . $this->password; |
||
478 | } |
||
479 | |||
480 | return $userInfo; |
||
481 | } |
||
482 | |||
483 | // ------------------------------------------------------------------------ |
||
484 | |||
485 | /** |
||
486 | * Uri::getHost |
||
487 | * |
||
488 | * Retrieve the host component of the URI. |
||
489 | * |
||
490 | * If no host is present, this method MUST return an empty string. |
||
491 | * |
||
492 | * The value returned MUST be normalized to lowercase, per RFC 3986 |
||
493 | * Section 3.2.2. |
||
494 | * |
||
495 | * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 |
||
496 | * @return string The URI host. |
||
497 | */ |
||
498 | public function getHost() |
||
499 | { |
||
500 | return $this->host; |
||
501 | } |
||
502 | |||
503 | // ------------------------------------------------------------------------ |
||
504 | |||
505 | /** |
||
506 | * Uri::getPort |
||
507 | * |
||
508 | * Retrieve the port component of the URI. |
||
509 | * |
||
510 | * If a port is present, and it is non-standard for the current scheme, |
||
511 | * this method MUST return it as an integer. If the port is the standard port |
||
512 | * used with the current scheme, this method SHOULD return null. |
||
513 | * |
||
514 | * If no port is present, and no scheme is present, this method MUST return |
||
515 | * a null value. |
||
516 | * |
||
517 | * If no port is present, but a scheme is present, this method MAY return |
||
518 | * the standard port for that scheme, but SHOULD return null. |
||
519 | * |
||
520 | * @return null|int The URI port. |
||
521 | */ |
||
522 | public function getPort() |
||
525 | } |
||
526 | |||
527 | // ------------------------------------------------------------------------ |
||
528 | |||
529 | /** |
||
530 | * Uri::getPath |
||
531 | * |
||
532 | * Retrieve the path component of the URI. |
||
533 | * |
||
534 | * The path can either be empty or absolute (starting with a slash) or |
||
535 | * rootless (not starting with a slash). Implementations MUST support all |
||
536 | * three syntaxes. |
||
537 | * |
||
538 | * Normally, the empty path "" and absolute path "/" are considered equal as |
||
539 | * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically |
||
540 | * do this normalization because in contexts with a trimmed base path, e.g. |
||
541 | * the front controller, this difference becomes significant. It's the task |
||
542 | * of the user to handle both "" and "/". |
||
543 | * |
||
544 | * The value returned MUST be percent-encoded, but MUST NOT double-encode |
||
545 | * any characters. To determine what characters to encode, please refer to |
||
546 | * RFC 3986, Sections 2 and 3.3. |
||
547 | * |
||
548 | * As an example, if the value should include a slash ("/") not intended as |
||
549 | * delimiter between path segments, that value MUST be passed in encoded |
||
550 | * form (e.g., "%2F") to the instance. |
||
551 | * |
||
552 | * @see https://tools.ietf.org/html/rfc3986#section-2 |
||
553 | * @see https://tools.ietf.org/html/rfc3986#section-3.3 |
||
554 | * @return string The URI path. |
||
555 | */ |
||
556 | public function &getPath() |
||
557 | { |
||
558 | return $this->path; |
||
559 | } |
||
560 | |||
561 | // ------------------------------------------------------------------------ |
||
562 | |||
563 | /** |
||
564 | * Uri::getQuery |
||
565 | * |
||
566 | * Retrieve the query string of the URI. |
||
567 | * |
||
568 | * If no query string is present, this method MUST return an empty string. |
||
569 | * |
||
570 | * The leading "?" character is not part of the query and MUST NOT be |
||
571 | * added. |
||
572 | * |
||
573 | * The value returned MUST be percent-encoded, but MUST NOT double-encode |
||
574 | * any characters. To determine what characters to encode, please refer to |
||
575 | * RFC 3986, Sections 2 and 3.4. |
||
576 | * |
||
577 | * As an example, if a value in a key/value pair of the query string should |
||
578 | * include an ampersand ("&") not intended as a delimiter between values, |
||
579 | * that value MUST be passed in encoded form (e.g., "%26") to the instance. |
||
580 | * |
||
581 | * @see https://tools.ietf.org/html/rfc3986#section-2 |
||
582 | * @see https://tools.ietf.org/html/rfc3986#section-3.4 |
||
583 | * @return string The URI query string. |
||
584 | */ |
||
585 | public function getQuery() |
||
586 | { |
||
587 | return $this->query; |
||
588 | } |
||
589 | |||
590 | // ------------------------------------------------------------------------ |
||
591 | |||
592 | /** |
||
593 | * Uri::getFragment |
||
594 | * |
||
595 | * Retrieve the fragment component of the URI. |
||
596 | * |
||
597 | * If no fragment is present, this method MUST return an empty string. |
||
598 | * |
||
599 | * The leading "#" character is not part of the fragment and MUST NOT be |
||
600 | * added. |
||
601 | * |
||
602 | * The value returned MUST be percent-encoded, but MUST NOT double-encode |
||
603 | * any characters. To determine what characters to encode, please refer to |
||
604 | * RFC 3986, Sections 2 and 3.5. |
||
605 | * |
||
606 | * @see https://tools.ietf.org/html/rfc3986#section-2 |
||
607 | * @see https://tools.ietf.org/html/rfc3986#section-3.5 |
||
608 | * @return string The URI fragment. |
||
609 | */ |
||
610 | public function getFragment() |
||
611 | { |
||
612 | return $this->fragment; |
||
613 | } |
||
614 | |||
615 | // ------------------------------------------------------------------------ |
||
616 | |||
617 | /** |
||
618 | * Uri::getSubDomain |
||
619 | * |
||
620 | * @param string $level |
||
621 | * |
||
622 | * @return bool|mixed |
||
623 | */ |
||
624 | public function getSubDomain($level = 'AUTO') |
||
625 | { |
||
626 | if ($level === 'AUTO') { |
||
627 | return reset($this->subDomains); |
||
628 | } elseif (isset($this->subDomains[ $level ])) { |
||
629 | return $this->subDomains[ $level ]; |
||
630 | } |
||
631 | |||
632 | return false; |
||
633 | } |
||
634 | |||
635 | // ------------------------------------------------------------------------ |
||
636 | |||
637 | /** |
||
638 | * Uri::addSubDomain |
||
639 | * |
||
640 | * @param string|array|null $subDomain |
||
641 | * |
||
642 | * @return \O2System\Kernel\Http\Message\Uri |
||
643 | */ |
||
644 | public function addSubDomain($subDomain) |
||
645 | { |
||
646 | $uri = clone $this; |
||
647 | |||
648 | if (is_null($subDomain)) { |
||
649 | $uri->subDomain = null; |
||
650 | $uri->subDomains = []; |
||
651 | } elseif (is_string($subDomain)) { |
||
652 | $uri->subDomain = $subDomain; |
||
653 | array_unshift($uri->subDomains, $subDomain); |
||
654 | } elseif (is_array($subDomain)) { |
||
655 | $uri->subDomain = reset($subDomain); |
||
656 | $uri->subDomains = array_merge($uri->subDomains, $subDomain); |
||
657 | } |
||
658 | |||
659 | $uri->subDomains = array_unique($uri->subDomains); |
||
660 | $this->setOrdinalKeys($uri->subDomains, count($uri->subDomains) + 2); |
||
661 | |||
662 | return $uri; |
||
663 | } |
||
664 | |||
665 | // ------------------------------------------------------------------------ |
||
666 | |||
667 | /** |
||
668 | * Uri::withSubDomain |
||
669 | * |
||
670 | * @param string|array|null $subDomain |
||
671 | * |
||
672 | * @return \O2System\Kernel\Http\Message\Uri |
||
673 | */ |
||
674 | public function withSubDomain($subDomain) |
||
675 | { |
||
676 | $uri = clone $this; |
||
677 | |||
678 | if (is_null($subDomain)) { |
||
679 | $uri->subDomain = null; |
||
680 | $uri->subDomains = []; |
||
681 | } elseif (is_string($subDomain)) { |
||
682 | $uri->subDomain = $subDomain; |
||
683 | $uri->subDomains = [$subDomain]; |
||
684 | } elseif (is_array($subDomain)) { |
||
685 | $uri->subDomain = reset($subDomain); |
||
686 | $uri->subDomains = $subDomain; |
||
687 | } |
||
688 | |||
689 | $uri->subDomains = array_unique($uri->subDomains); |
||
690 | $this->setOrdinalKeys($uri->subDomains, count($uri->subDomains) + 2); |
||
691 | |||
692 | return $uri; |
||
693 | } |
||
694 | |||
695 | // ------------------------------------------------------------------------ |
||
696 | |||
697 | /** |
||
698 | * Uri::getSubDomains |
||
699 | * |
||
700 | * @return array |
||
701 | */ |
||
702 | public function getSubDomains() |
||
703 | { |
||
704 | return $this->subDomains; |
||
705 | } |
||
706 | |||
707 | // ------------------------------------------------------------------------ |
||
708 | |||
709 | /** |
||
710 | * Uri::withSubDomains |
||
711 | * |
||
712 | * @param array $subDomains |
||
713 | * |
||
714 | * @return \O2System\Kernel\Http\Message\Uri |
||
715 | */ |
||
716 | public function withSubDomains(array $subDomains) |
||
717 | { |
||
718 | $uri = clone $this; |
||
719 | $uri->subDomain = reset($subDomains); |
||
720 | $uri->subDomains = $subDomains; |
||
721 | |||
722 | return $uri; |
||
723 | } |
||
724 | |||
725 | // ------------------------------------------------------------------------ |
||
726 | |||
727 | /** |
||
728 | * Uri::withScheme |
||
729 | * |
||
730 | * Return an instance with the specified scheme. |
||
731 | * |
||
732 | * This method MUST retain the state of the current instance, and return |
||
733 | * an instance that contains the specified scheme. |
||
734 | * |
||
735 | * Implementations MUST support the schemes "http" and "https" case |
||
736 | * insensitively, and MAY accommodate other schemes if required. |
||
737 | * |
||
738 | * An empty scheme is equivalent to removing the scheme. |
||
739 | * |
||
740 | * @param string $scheme The scheme to use with the new instance. |
||
741 | * |
||
742 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified scheme. |
||
743 | * @throws \InvalidArgumentException for invalid schemes. |
||
744 | * @throws \InvalidArgumentException for unsupported schemes. |
||
745 | */ |
||
746 | public function withScheme($scheme) |
||
747 | { |
||
748 | $uri = clone $this; |
||
749 | |||
750 | if (in_array($scheme, ['http', 'https'])) { |
||
751 | $uri->scheme = $scheme; |
||
752 | } |
||
753 | |||
754 | return $uri; |
||
755 | } |
||
756 | |||
757 | // ------------------------------------------------------------------------ |
||
758 | |||
759 | /** |
||
760 | * Uri::withUserInfo |
||
761 | * |
||
762 | * Return an instance with the specified user information. |
||
763 | * |
||
764 | * This method MUST retain the state of the current instance, and return |
||
765 | * an instance that contains the specified user information. |
||
766 | * |
||
767 | * Password is optional, but the user information MUST include the |
||
768 | * user; an empty string for the user is equivalent to removing user |
||
769 | * information. |
||
770 | * |
||
771 | * @param string $user The user name to use for authority. |
||
772 | * @param null|string $password The password associated with $user. |
||
773 | * |
||
774 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified user information. |
||
775 | */ |
||
776 | public function withUserInfo($user, $password = null) |
||
777 | { |
||
778 | $userInfo = clone $this; |
||
779 | $userInfo->username = $user; |
||
780 | |||
781 | return $userInfo; |
||
782 | } |
||
783 | |||
784 | // ------------------------------------------------------------------------ |
||
785 | |||
786 | /** |
||
787 | * Uri::withHost |
||
788 | * |
||
789 | * Return an instance with the specified host. |
||
790 | * |
||
791 | * This method MUST retain the state of the current instance, and return |
||
792 | * an instance that contains the specified host. |
||
793 | * |
||
794 | * An empty host value is equivalent to removing the host. |
||
795 | * |
||
796 | * @param string $host The hostname to use with the new instance. |
||
797 | * |
||
798 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified host. |
||
799 | * @throws \InvalidArgumentException for invalid hostnames. |
||
800 | */ |
||
801 | public function withHost($host) |
||
802 | { |
||
803 | $uri = clone $this; |
||
804 | $uri->host = $host; |
||
805 | |||
806 | return $uri; |
||
807 | } |
||
808 | |||
809 | // ------------------------------------------------------------------------ |
||
810 | |||
811 | /** |
||
812 | * Uri::withPort |
||
813 | * |
||
814 | * Return an instance with the specified port. |
||
815 | * |
||
816 | * This method MUST retain the state of the current instance, and return |
||
817 | * an instance that contains the specified port. |
||
818 | * |
||
819 | * Implementations MUST raise an exception for ports outside the |
||
820 | * established TCP and UDP port ranges. |
||
821 | * |
||
822 | * A null value provided for the port is equivalent to removing the port |
||
823 | * information. |
||
824 | * |
||
825 | * @param null|int $port The port to use with the new instance; a null value |
||
826 | * removes the port information. |
||
827 | * |
||
828 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified port. |
||
829 | * @throws \InvalidArgumentException for invalid ports. |
||
830 | */ |
||
831 | public function withPort($port) |
||
832 | { |
||
833 | $uri = clone $this; |
||
834 | $uri->port = $port; |
||
835 | |||
836 | return $uri; |
||
837 | } |
||
838 | |||
839 | // ------------------------------------------------------------------------ |
||
840 | |||
841 | /** |
||
842 | * Uri::withPath |
||
843 | * |
||
844 | * Return an instance with the specified path. |
||
845 | * |
||
846 | * This method MUST retain the state of the current instance, and return |
||
847 | * an instance that contains the specified path. |
||
848 | * |
||
849 | * The path can either be empty or absolute (starting with a slash) or |
||
850 | * rootless (not starting with a slash). Implementations MUST support all |
||
851 | * three syntaxes. |
||
852 | * |
||
853 | * If an HTTP path is intended to be host-relative rather than path-relative |
||
854 | * then it must begin with a slash ("/"). HTTP paths not starting with a slash |
||
855 | * are assumed to be relative to some base path known to the application or |
||
856 | * consumer. |
||
857 | * |
||
858 | * Users can provide both encoded and decoded path characters. |
||
859 | * Implementations ensure the correct encoding as outlined in getPath(). |
||
860 | * |
||
861 | * @param string $path The path to use with the new instance. |
||
862 | * |
||
863 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified path. |
||
864 | * @throws \InvalidArgumentException for invalid paths. |
||
865 | */ |
||
866 | public function withPath($path) |
||
867 | { |
||
868 | $uri = clone $this; |
||
869 | $uri->path = ltrim($path, '/'); |
||
870 | |||
871 | return $uri; |
||
872 | } |
||
873 | |||
874 | // ------------------------------------------------------------------------ |
||
875 | |||
876 | /** |
||
877 | * Uri::addPath |
||
878 | * |
||
879 | * @param string $path |
||
880 | * |
||
881 | * @return \O2System\Kernel\Http\Message\Uri |
||
882 | */ |
||
883 | public function addPath($path) |
||
889 | } |
||
890 | |||
891 | // ------------------------------------------------------------------------ |
||
892 | |||
893 | /** |
||
894 | * Uri::withQuery |
||
895 | * |
||
896 | * Return an instance with the specified query string. |
||
897 | * |
||
898 | * This method MUST retain the state of the current instance, and return |
||
899 | * an instance that contains the specified query string. |
||
900 | * |
||
901 | * Users can provide both encoded and decoded query characters. |
||
902 | * Implementations ensure the correct encoding as outlined in getQuery(). |
||
903 | * |
||
904 | * An empty query string value is equivalent to removing the query string. |
||
905 | * |
||
906 | * @param string|array $query The query string to use with the new instance. |
||
907 | * |
||
908 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified query string. |
||
909 | * @throws \InvalidArgumentException for invalid query strings. |
||
910 | */ |
||
911 | public function withQuery($query) |
||
912 | { |
||
913 | $uri = clone $this; |
||
914 | $uri->query = is_array($query) ? http_build_query($query, PHP_QUERY_RFC3986, '&', PHP_QUERY_RFC3986) : $query; |
||
915 | |||
916 | return $uri; |
||
917 | } |
||
918 | |||
919 | // ------------------------------------------------------------------------ |
||
920 | |||
921 | /** |
||
922 | * Uri::addQuery |
||
923 | * |
||
924 | * @param array|string $query |
||
925 | * |
||
926 | * @return \O2System\Kernel\Http\Message\Uri |
||
927 | */ |
||
928 | public function addQuery($query) |
||
947 | } |
||
948 | |||
949 | // ------------------------------------------------------------------------ |
||
950 | |||
951 | /** |
||
952 | * Uri::withFragment |
||
953 | * |
||
954 | * Return an instance with the specified URI fragment. |
||
955 | * |
||
956 | * This method MUST retain the state of the current instance, and return |
||
957 | * an instance that contains the specified URI fragment. |
||
958 | * |
||
959 | * Users can provide both encoded and decoded fragment characters. |
||
960 | * Implementations ensure the correct encoding as outlined in getFragment(). |
||
961 | * |
||
962 | * An empty fragment value is equivalent to removing the fragment. |
||
963 | * |
||
964 | * @param string $fragment The fragment to use with the new instance. |
||
965 | * |
||
966 | * @return static|\O2System\Kernel\Http\Message\Uri A new instance with the specified fragment. |
||
967 | */ |
||
968 | public function withFragment($fragment) |
||
969 | { |
||
970 | $uri = clone $this; |
||
971 | $uri->fragment = $fragment; |
||
972 | |||
973 | return $uri; |
||
974 | } |
||
975 | |||
976 | // ------------------------------------------------------------------------ |
||
977 | |||
978 | /** |
||
979 | * Uri::getSuffix |
||
980 | * |
||
981 | * @return string |
||
982 | */ |
||
983 | public function getSuffix() |
||
984 | { |
||
985 | return $this->suffix; |
||
986 | } |
||
987 | |||
988 | // ------------------------------------------------------------------------ |
||
989 | |||
990 | /** |
||
991 | * Uri::setSuffix |
||
992 | * |
||
993 | * @param string $suffix |
||
994 | */ |
||
995 | protected function setSuffix($suffix) |
||
1003 | } |
||
1004 | } |
||
1005 | |||
1006 | // ------------------------------------------------------------------------ |
||
1007 | |||
1008 | /** |
||
1009 | * Uri::withSuffix |
||
1010 | * |
||
1011 | * @param string $suffix |
||
1012 | * |
||
1013 | * @return \O2System\Kernel\Http\Message\Uri |
||
1014 | */ |
||
1015 | public function withSuffix($suffix) |
||
1021 | } |
||
1022 | |||
1023 | // ------------------------------------------------------------------------ |
||
1024 | |||
1025 | /** |
||
1026 | * Uri::__toString |
||
1027 | * |
||
1028 | * Return the string representation as a URI reference. |
||
1029 | * |
||
1030 | * Depending on which components of the URI are present, the resulting |
||
1031 | * string is either a full URI or relative reference according to RFC 3986, |
||
1032 | * Section 4.1. The method concatenates the various components of the URI, |
||
1033 | * using the appropriate delimiters: |
||
1034 | * |
||
1035 | * - If a scheme is present, it MUST be suffixed by ":". |
||
1036 | * - If an authority is present, it MUST be prefixed by "//". |
||
1037 | * - The path can be concatenated without delimiters. But there are two |
||
1038 | * cases where the path has to be adjusted to make the URI reference |
||
1039 | * valid as PHP does not allow to throw an exception in __toString(): |
||
1040 | * - If the path is rootless and an authority is present, the path MUST |
||
1041 | * be prefixed by "/". |
||
1042 | * - If the path is starting with more than one "/" and no authority is |
||
1043 | * present, the starting slashes MUST be reduced to one. |
||
1044 | * - If a query is present, it MUST be prefixed by "?". |
||
1045 | * - If a fragment is present, it MUST be prefixed by "#". |
||
1046 | * |
||
1047 | * @see http://tools.ietf.org/html/rfc3986#section-4.1 |
||
1048 | * @return string |
||
1049 | */ |
||
1050 | public function __toString() |
||
1100 | } |
||
1101 | } |