%PDF- %PDF-
Direktori : /proc/self/root/www/varak.net/losik.varak.net/vendor/nette/http/src/Http/ |
Current File : //proc/self/root/www/varak.net/losik.varak.net/vendor/nette/http/src/Http/Url.php |
<?php /** * This file is part of the Nette Framework (https://nette.org) * Copyright (c) 2004 David Grudl (https://davidgrudl.com) */ declare(strict_types=1); namespace Nette\Http; use Nette; /** * Mutable representation of a URL. * * <pre> * scheme user password host port path query fragment * | | | | | | | | * /--\ /--\ /------\ /-------\ /--\/------------\ /--------\ /------\ * http://john:x0y17575@nette.org:8042/en/manual.php?name=param#fragment <-- absoluteUrl * \______\__________________________/ * | | * hostUrl authority * </pre> * * @property string $scheme * @property string $user * @property string $password * @property string $host * @property int $port * @property string $path * @property string $query * @property string $fragment * @property-read string $absoluteUrl * @property-read string $authority * @property-read string $hostUrl * @property-read string $basePath * @property-read string $baseUrl * @property-read string $relativeUrl * @property-read array $queryParameters */ class Url implements \JsonSerializable { use Nette\SmartObject; /** @var array */ public static $defaultPorts = [ 'http' => 80, 'https' => 443, 'ftp' => 21, ]; /** @var string */ private $scheme = ''; /** @var string */ private $user = ''; /** @var string */ private $password = ''; /** @var string */ private $host = ''; /** @var int|null */ private $port; /** @var string */ private $path = ''; /** @var array */ private $query = []; /** @var string */ private $fragment = ''; /** * @param string|self|UrlImmutable $url * @throws Nette\InvalidArgumentException if URL is malformed */ public function __construct($url = null) { if (is_string($url)) { $p = @parse_url($url); // @ - is escalated to exception if ($p === false) { throw new Nette\InvalidArgumentException("Malformed or unsupported URI '$url'."); } $this->scheme = $p['scheme'] ?? ''; $this->port = $p['port'] ?? null; $this->host = rawurldecode($p['host'] ?? ''); $this->user = rawurldecode($p['user'] ?? ''); $this->password = rawurldecode($p['pass'] ?? ''); $this->setPath($p['path'] ?? ''); $this->setQuery($p['query'] ?? []); $this->fragment = rawurldecode($p['fragment'] ?? ''); } elseif ($url instanceof UrlImmutable || $url instanceof self) { [$this->scheme, $this->user, $this->password, $this->host, $this->port, $this->path, $this->query, $this->fragment] = $url->export(); } elseif ($url !== null) { throw new Nette\InvalidArgumentException; } } /** @return static */ public function setScheme(string $scheme) { $this->scheme = $scheme; return $this; } public function getScheme(): string { return $this->scheme; } /** @return static */ public function setUser(string $user) { $this->user = $user; return $this; } public function getUser(): string { return $this->user; } /** @return static */ public function setPassword(string $password) { $this->password = $password; return $this; } public function getPassword(): string { return $this->password; } /** @return static */ public function setHost(string $host) { $this->host = $host; $this->setPath($this->path); return $this; } public function getHost(): string { return $this->host; } /** * Returns the part of domain. */ public function getDomain(int $level = 2): string { $parts = ip2long($this->host) ? [$this->host] : explode('.', $this->host); $parts = $level >= 0 ? array_slice($parts, -$level) : array_slice($parts, 0, $level); return implode('.', $parts); } /** @return static */ public function setPort(int $port) { $this->port = $port; return $this; } public function getPort(): ?int { return $this->port ?: $this->getDefaultPort(); } public function getDefaultPort(): ?int { return self::$defaultPorts[$this->scheme] ?? null; } /** @return static */ public function setPath(string $path) { $this->path = $path; if ($this->host && substr($this->path, 0, 1) !== '/') { $this->path = '/' . $this->path; } return $this; } public function getPath(): string { return $this->path; } /** * @param string|array $value * @return static */ public function setQuery($query) { $this->query = is_array($query) ? $query : self::parseQuery($query); return $this; } /** * @param string|array $value * @return static */ public function appendQuery($query) { $this->query = is_array($query) ? $query + $this->query : self::parseQuery($this->getQuery() . '&' . $query); return $this; } public function getQuery(): string { return http_build_query($this->query, '', '&', PHP_QUERY_RFC3986); } public function getQueryParameters(): array { return $this->query; } /** @return mixed */ public function getQueryParameter(string $name) { if (func_num_args() > 1) { trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', E_USER_DEPRECATED); } return $this->query[$name] ?? null; } /** * @param mixed $value null unsets the parameter * @return static */ public function setQueryParameter(string $name, $value) { $this->query[$name] = $value; return $this; } /** @return static */ public function setFragment(string $fragment) { $this->fragment = $fragment; return $this; } public function getFragment(): string { return $this->fragment; } public function getAbsoluteUrl(): string { return $this->getHostUrl() . $this->path . (($tmp = $this->getQuery()) ? '?' . $tmp : '') . ($this->fragment === '' ? '' : '#' . $this->fragment); } /** * Returns the [user[:pass]@]host[:port] part of URI. */ public function getAuthority(): string { return $this->host === '' ? '' : ($this->user !== '' ? rawurlencode($this->user) . ($this->password === '' ? '' : ':' . rawurlencode($this->password)) . '@' : '') . $this->host . ($this->port && $this->port !== $this->getDefaultPort() ? ':' . $this->port : ''); } /** * Returns the scheme and authority part of URI. */ public function getHostUrl(): string { return ($this->scheme ? $this->scheme . ':' : '') . (($authority = $this->getAuthority()) !== '' ? '//' . $authority : ''); } /** @deprecated use UrlScript::getBasePath() instead */ public function getBasePath(): string { $pos = strrpos($this->path, '/'); return $pos === false ? '' : substr($this->path, 0, $pos + 1); } /** @deprecated use UrlScript::getBaseUrl() instead */ public function getBaseUrl(): string { return $this->getHostUrl() . $this->getBasePath(); } /** @deprecated use UrlScript::getRelativeUrl() instead */ public function getRelativeUrl(): string { return substr($this->getAbsoluteUrl(), strlen($this->getBaseUrl())); } /** * URL comparison. * @param string|self $url */ public function isEqual($url): bool { $url = new self($url); $query = $url->query; ksort($query); $query2 = $this->query; ksort($query2); $host = rtrim($url->host, '.'); $host2 = rtrim($this->host, '.'); return $url->scheme === $this->scheme && (!strcasecmp($host, $host2) || self::idnHostToUnicode($host) === self::idnHostToUnicode($host2)) && $url->getPort() === $this->getPort() && $url->user === $this->user && $url->password === $this->password && self::unescape($url->path, '%/') === self::unescape($this->path, '%/') && $query === $query2 && $url->fragment === $this->fragment; } /** * Transforms URL to canonical form. * @return static * @deprecated */ public function canonicalize() { $this->path = preg_replace_callback( '#[^!$&\'()*+,/:;=@%]+#', function (array $m): string { return rawurlencode($m[0]); }, self::unescape($this->path, '%/') ); $this->host = rtrim($this->host, '.'); $this->host = self::idnHostToUnicode(strtolower($this->host)); return $this; } public function __toString(): string { return $this->getAbsoluteUrl(); } public function jsonSerialize(): string { return $this->getAbsoluteUrl(); } /** @internal */ final public function export(): array { return [$this->scheme, $this->user, $this->password, $this->host, $this->port, $this->path, $this->query, $this->fragment]; } /** * Converts IDN ASCII host to UTF-8. */ private static function idnHostToUnicode(string $host): string { if (strpos($host, '--') === false) { // host does not contain IDN return $host; } if (function_exists('idn_to_utf8') && defined('INTL_IDNA_VARIANT_UTS46')) { return idn_to_utf8($host, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: $host; } trigger_error('PHP extension idn is not loaded or is too old', E_USER_WARNING); } /** * Similar to rawurldecode, but preserves reserved chars encoded. */ public static function unescape(string $s, string $reserved = '%;/?:@&=+$,'): string { // reserved (@see RFC 2396) = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," // within a path segment, the characters "/", ";", "=", "?" are reserved // within a query component, the characters ";", "/", "?", ":", "@", "&", "=", "+", ",", "$" are reserved. if ($reserved !== '') { $s = preg_replace_callback( '#%(' . substr(chunk_split(bin2hex($reserved), 2, '|'), 0, -1) . ')#i', function (array $m): string { return '%25' . strtoupper($m[1]); }, $s ); } return rawurldecode($s); } /** * Parses query string. Is affected by directive arg_separator.input. */ public static function parseQuery(string $s): array { $s = str_replace(['%5B', '%5b'], '[', $s); $sep = preg_quote(ini_get('arg_separator.input')); $s = preg_replace("#([$sep])([^[$sep=]+)([^$sep]*)#", '&0[$2]$3', '&' . $s); parse_str($s, $res); return $res[0] ?? []; } }