Update website
This commit is contained in:
parent
bb4b0f9be8
commit
011b183e28
4263 changed files with 3014 additions and 720369 deletions
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 ignace nyamagana butera
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,68 +0,0 @@
|
|||
{
|
||||
"name": "league/uri-interfaces",
|
||||
"description" : "Common interface for URI representation",
|
||||
"keywords": [
|
||||
"url",
|
||||
"uri",
|
||||
"rfc3986",
|
||||
"rfc3987"
|
||||
],
|
||||
"license": "MIT",
|
||||
"homepage": "http://github.com/thephpleague/uri-interfaces",
|
||||
"authors": [
|
||||
{
|
||||
"name" : "Ignace Nyamagana Butera",
|
||||
"email" : "nyamsprod@gmail.com",
|
||||
"homepage" : "https://nyamsprod.com"
|
||||
}
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/nyamsprod"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php" : "^7.2 || ^8.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.19",
|
||||
"phpstan/phpstan": "^0.12.90",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.9",
|
||||
"phpstan/phpstan-phpunit": "^0.12.19",
|
||||
"phpunit/phpunit": "^8.5.15 || ^9.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Uri\\": "src/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpunit": "phpunit --coverage-text",
|
||||
"phpcs": "php-cs-fixer fix --dry-run --diff -vvv --allow-risky=yes --ansi",
|
||||
"phpcs:fix": "php-cs-fixer fix -vvv --allow-risky=yes --ansi",
|
||||
"phpstan": "phpstan analyse -l max -c phpstan.neon src --ansi --memory-limit 192M",
|
||||
"test": [
|
||||
"@phpunit",
|
||||
"@phpstan",
|
||||
"@phpcs:fix"
|
||||
]
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"phpunit": "Runs package test suite",
|
||||
"phpstan": "Runs complete codebase static analysis",
|
||||
"phpcs": "Runs coding style testing",
|
||||
"phpcs:fix": "Fix coding style issues",
|
||||
"test": "Runs all tests"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "to use the IDNA feature",
|
||||
"symfony/intl": "to use the IDNA feature via Symfony Polyfill"
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use League\Uri\Exceptions\IdnSupportMissing;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
|
||||
interface AuthorityInterface extends UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the host component of the authority.
|
||||
*/
|
||||
public function getHost(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the port component of the authority.
|
||||
*/
|
||||
public function getPort(): ?int;
|
||||
|
||||
/**
|
||||
* Returns the user information component of the authority.
|
||||
*/
|
||||
public function getUserInfo(): ?string;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified host.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified host.
|
||||
*
|
||||
* A null value provided for the host is equivalent to removing the host
|
||||
* information.
|
||||
*
|
||||
* @param ?string $host
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
* @throws IdnSupportMissing for component or transformations
|
||||
* requiring IDN support when IDN support is not present
|
||||
* or misconfigured.
|
||||
*/
|
||||
public function withHost(?string $host): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified port.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified port.
|
||||
*
|
||||
* A null value provided for the port is equivalent to removing the port
|
||||
* information.
|
||||
*
|
||||
* @param ?int $port
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withPort(?int $port): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified user information.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified user information.
|
||||
*
|
||||
* Password is optional, but the user information MUST include the
|
||||
* user; a null value for the user is equivalent to removing user
|
||||
* information.
|
||||
*
|
||||
* @param ?string $user
|
||||
* @param ?string $password
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withUserInfo(?string $user, ?string $password = null): self;
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
interface DataPathInterface extends PathInterface
|
||||
{
|
||||
/**
|
||||
* Retrieve the data mime type associated to the URI.
|
||||
*
|
||||
* If no mimetype is present, this method MUST return the default mimetype 'text/plain'.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2397#section-2
|
||||
*/
|
||||
public function getMimeType(): string;
|
||||
|
||||
/**
|
||||
* Retrieve the parameters associated with the Mime Type of the URI.
|
||||
*
|
||||
* If no parameters is present, this method MUST return the default parameter 'charset=US-ASCII'.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2397#section-2
|
||||
*/
|
||||
public function getParameters(): string;
|
||||
|
||||
/**
|
||||
* Retrieve the mediatype associated with the URI.
|
||||
*
|
||||
* If no mediatype is present, this method MUST return the default parameter 'text/plain;charset=US-ASCII'.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2397#section-3
|
||||
*
|
||||
* @return string The URI scheme.
|
||||
*/
|
||||
public function getMediaType(): string;
|
||||
|
||||
/**
|
||||
* Retrieves the data string.
|
||||
*
|
||||
* Retrieves the data part of the path. If no data part is provided return
|
||||
* a empty string
|
||||
*/
|
||||
public function getData(): string;
|
||||
|
||||
/**
|
||||
* Tells whether the data is binary safe encoded.
|
||||
*/
|
||||
public function isBinaryData(): bool;
|
||||
|
||||
/**
|
||||
* Save the data to a specific file.
|
||||
*/
|
||||
public function save(string $path, string $mode = 'w'): \SplFileObject;
|
||||
|
||||
/**
|
||||
* Returns an instance where the data part is base64 encoded.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance where the data part is base64 encoded
|
||||
*/
|
||||
public function toBinary(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance where the data part is url encoded following RFC3986 rules.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance where the data part is url encoded
|
||||
*/
|
||||
public function toAscii(): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified mediatype parameters.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified mediatype parameters.
|
||||
*
|
||||
* Users must provide encoded characters.
|
||||
*
|
||||
* An empty parameters value is equivalent to removing the parameter.
|
||||
*/
|
||||
public function withParameters(string $parameters): self;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
|
||||
/**
|
||||
* @extends \IteratorAggregate<string>
|
||||
*/
|
||||
interface DomainHostInterface extends \Countable, HostInterface, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Returns the labels total number.
|
||||
*/
|
||||
public function count(): int;
|
||||
|
||||
/**
|
||||
* Iterate over the Domain labels.
|
||||
*
|
||||
* @return \Iterator<string>
|
||||
*/
|
||||
public function getIterator(): \Iterator;
|
||||
|
||||
/**
|
||||
* Retrieves a single host label.
|
||||
*
|
||||
* If the label offset has not been set, returns the null value.
|
||||
*/
|
||||
public function get(int $offset): ?string;
|
||||
|
||||
/**
|
||||
* Returns the associated key for a specific label or all the keys.
|
||||
*
|
||||
* @param ?string $label
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function keys(?string $label = null): array;
|
||||
|
||||
/**
|
||||
* Tells whether the domain is absolute.
|
||||
*/
|
||||
public function isAbsolute(): bool;
|
||||
|
||||
/**
|
||||
* Prepends a label to the host.
|
||||
*/
|
||||
public function prepend(string $label): self;
|
||||
|
||||
/**
|
||||
* Appends a label to the host.
|
||||
*/
|
||||
public function append(string $label): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with its Root label.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*/
|
||||
public function withRootLabel(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without its Root label.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*/
|
||||
public function withoutRootLabel(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the modified label.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the new label
|
||||
*
|
||||
* If $key is non-negative, the added label will be the label at $key position from the start.
|
||||
* If $key is negative, the added label will be the label at $key position from the end.
|
||||
*
|
||||
* @throws SyntaxError If the key is invalid
|
||||
*/
|
||||
public function withLabel(int $key, string $label): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without the specified label.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified component
|
||||
*
|
||||
* If $key is non-negative, the removed label will be the label at $key position from the start.
|
||||
* If $key is negative, the removed label will be the label at $key position from the end.
|
||||
*
|
||||
* @param int ...$keys
|
||||
*
|
||||
* @throws SyntaxError If the key is invalid
|
||||
*/
|
||||
public function withoutLabel(int ...$keys): self;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
interface FragmentInterface extends UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the decoded fragment.
|
||||
*/
|
||||
public function decoded(): ?string;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
interface HostInterface extends UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the ascii representation.
|
||||
*/
|
||||
public function toAscii(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the unicode representation.
|
||||
*/
|
||||
public function toUnicode(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the IP version.
|
||||
*
|
||||
* If the host is a not an IP this method will return null
|
||||
*/
|
||||
public function getIpVersion(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the IP component If the Host is an IP address.
|
||||
*
|
||||
* If the host is a not an IP this method will return null
|
||||
*/
|
||||
public function getIp(): ?string;
|
||||
|
||||
/**
|
||||
* Tells whether the host is a domain name.
|
||||
*/
|
||||
public function isDomain(): bool;
|
||||
|
||||
/**
|
||||
* Tells whether the host is an IP Address.
|
||||
*/
|
||||
public function isIp(): bool;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
interface IpHostInterface extends HostInterface
|
||||
{
|
||||
/**
|
||||
* Returns whether or not the host is an IPv4 address.
|
||||
*/
|
||||
public function isIpv4(): bool;
|
||||
/**
|
||||
* Returns whether or not the host is an IPv6 address.
|
||||
*/
|
||||
public function isIpv6(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether or not the host is an IPv6 address.
|
||||
*/
|
||||
public function isIpFuture(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether or not the host has a ZoneIdentifier.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6874#section-4
|
||||
*/
|
||||
public function hasZoneIdentifier(): bool;
|
||||
|
||||
/**
|
||||
* Returns an host without its zone identifier according to RFC6874.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance without the host zone identifier according to RFC6874
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6874#section-4
|
||||
*/
|
||||
public function withoutZoneIdentifier(): self;
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
|
||||
interface PathInterface extends UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the decoded path.
|
||||
*/
|
||||
public function decoded(): string;
|
||||
|
||||
/**
|
||||
* Returns whether or not the path is absolute or relative.
|
||||
*/
|
||||
public function isAbsolute(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether or not the path has a trailing delimiter.
|
||||
*/
|
||||
public function hasTrailingSlash(): bool;
|
||||
|
||||
/**
|
||||
* Returns an instance without dot segments.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the path component normalized by removing
|
||||
* the dot segment.
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withoutDotSegments(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with a leading slash.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the path component with a leading slash
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withLeadingSlash(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without a leading slash.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the path component without a leading slash
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withoutLeadingSlash(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with a trailing slash.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the path component with a trailing slash
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withTrailingSlash(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without a trailing slash.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the path component without a trailing slash
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withoutTrailingSlash(): self;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
interface PortInterface extends UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the integer representation of the Port.
|
||||
*/
|
||||
public function toInt(): ?int;
|
||||
}
|
|
@ -1,227 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
/**
|
||||
* @extends \IteratorAggregate<array{0:string, 1:string|null}>
|
||||
*/
|
||||
interface QueryInterface extends \Countable, \IteratorAggregate, UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the query separator.
|
||||
*/
|
||||
public function getSeparator(): string;
|
||||
|
||||
/**
|
||||
* Returns the number of key/value pairs present in the object.
|
||||
*/
|
||||
public function count(): int;
|
||||
|
||||
/**
|
||||
* Returns an iterator allowing to go through all key/value pairs contained in this object.
|
||||
*
|
||||
* The pair is represented as an array where the first value is the pair key
|
||||
* and the second value the pair value.
|
||||
*
|
||||
* The key of each pair is a string
|
||||
* The value of each pair is a scalar or the null value
|
||||
*
|
||||
* @return \Iterator<int, array{0:string, 1:string|null}>
|
||||
*/
|
||||
public function getIterator(): \Iterator;
|
||||
|
||||
/**
|
||||
* Returns an iterator allowing to go through all key/value pairs contained in this object.
|
||||
*
|
||||
* The return type is as a Iterator where its offset is the pair key and its value the pair value.
|
||||
*
|
||||
* The key of each pair is a string
|
||||
* The value of each pair is a scalar or the null value
|
||||
*
|
||||
* @return iterable<string, string|null>
|
||||
*/
|
||||
public function pairs(): iterable;
|
||||
|
||||
/**
|
||||
* Tells whether a pair with a specific name exists.
|
||||
*
|
||||
* @see https://url.spec.whatwg.org/#dom-urlsearchparams-has
|
||||
*/
|
||||
public function has(string $key): bool;
|
||||
|
||||
/**
|
||||
* Returns the first value associated to the given pair name.
|
||||
*
|
||||
* If no value is found null is returned
|
||||
*
|
||||
* @see https://url.spec.whatwg.org/#dom-urlsearchparams-get
|
||||
*/
|
||||
public function get(string $key): ?string;
|
||||
|
||||
/**
|
||||
* Returns all the values associated to the given pair name as an array or all
|
||||
* the instance pairs.
|
||||
*
|
||||
* If no value is found an empty array is returned
|
||||
*
|
||||
* @see https://url.spec.whatwg.org/#dom-urlsearchparams-getall
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function getAll(string $key): array;
|
||||
|
||||
/**
|
||||
* Returns the store PHP variables as elements of an array.
|
||||
*
|
||||
* The result is similar as PHP parse_str when used with its
|
||||
* second argument with the difference that variable names are
|
||||
* not mangled.
|
||||
*
|
||||
* If a key is submitted it will returns the value attached to it or null
|
||||
*
|
||||
* @see http://php.net/parse_str
|
||||
* @see https://wiki.php.net/rfc/on_demand_name_mangling
|
||||
*
|
||||
* @param ?string $key
|
||||
* @return mixed the collection of stored PHP variables or the empty array if no input is given,
|
||||
* the single value of a stored PHP variable or null if the variable is not present in the collection
|
||||
*/
|
||||
public function params(?string $key = null);
|
||||
|
||||
/**
|
||||
* Returns the RFC1738 encoded query.
|
||||
*/
|
||||
public function toRFC1738(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the RFC3986 encoded query.
|
||||
*
|
||||
* @see ::getContent
|
||||
*/
|
||||
public function toRFC3986(): ?string;
|
||||
|
||||
/**
|
||||
* Returns an instance with a different separator.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the query component with a different separator
|
||||
*/
|
||||
public function withSeparator(string $separator): self;
|
||||
|
||||
/**
|
||||
* Sorts the query string by offset, maintaining offset to data correlations.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified query
|
||||
*
|
||||
* @see https://url.spec.whatwg.org/#dom-urlsearchparams-sort
|
||||
*/
|
||||
public function sort(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without duplicate key/value pair.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the query component normalized by removing
|
||||
* duplicate pairs whose key/value are the same.
|
||||
*/
|
||||
public function withoutDuplicates(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without empty key/value where the value is the null value.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the query component normalized by removing
|
||||
* empty pairs.
|
||||
*
|
||||
* A pair is considered empty if its value is equal to the null value
|
||||
*/
|
||||
public function withoutEmptyPairs(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance where numeric indices associated to PHP's array like key are removed.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the query component normalized so that numeric indexes
|
||||
* are removed from the pair key value.
|
||||
*
|
||||
* ie.: toto[3]=bar[3]&foo=bar becomes toto[]=bar[3]&foo=bar
|
||||
*/
|
||||
public function withoutNumericIndices(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the a new key/value pair added to it.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified query
|
||||
*
|
||||
* If the pair already exists the value will replace the existing value.
|
||||
*
|
||||
* @see https://url.spec.whatwg.org/#dom-urlsearchparams-set
|
||||
*
|
||||
* @param ?string $value
|
||||
*/
|
||||
public function withPair(string $key, ?string $value): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the new pairs set to it.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified query
|
||||
*
|
||||
* @see ::withPair
|
||||
*/
|
||||
public function merge(string $query): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without the specified keys.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified component
|
||||
*
|
||||
* @param string ...$keys
|
||||
*/
|
||||
public function withoutPair(string ...$keys): self;
|
||||
|
||||
/**
|
||||
* Returns a new instance with a specified key/value pair appended as a new pair.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified query
|
||||
*
|
||||
* @param ?string $value
|
||||
*/
|
||||
public function appendTo(string $key, ?string $value): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the new pairs appended to it.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified query
|
||||
*
|
||||
* If the pair already exists the value will be added to it.
|
||||
*/
|
||||
public function append(string $query): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without the specified params.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified component without PHP's value.
|
||||
* PHP's mangled is not taken into account.
|
||||
*
|
||||
* @param string ...$keys
|
||||
*/
|
||||
public function withoutParam(string ...$keys): self;
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
|
||||
/**
|
||||
* @extends \IteratorAggregate<string>
|
||||
*/
|
||||
interface SegmentedPathInterface extends \Countable, \IteratorAggregate, PathInterface
|
||||
{
|
||||
/**
|
||||
* Returns the total number of segments in the path.
|
||||
*/
|
||||
public function count(): int;
|
||||
|
||||
/**
|
||||
* Iterate over the path segment.
|
||||
*
|
||||
* @return \Iterator<string>
|
||||
*/
|
||||
public function getIterator(): \Iterator;
|
||||
|
||||
/**
|
||||
* Returns parent directory's path.
|
||||
*/
|
||||
public function getDirname(): string;
|
||||
|
||||
/**
|
||||
* Returns the path basename.
|
||||
*/
|
||||
public function getBasename(): string;
|
||||
|
||||
/**
|
||||
* Returns the basename extension.
|
||||
*/
|
||||
public function getExtension(): string;
|
||||
|
||||
/**
|
||||
* Retrieves a single path segment.
|
||||
*
|
||||
* If the segment offset has not been set, returns null.
|
||||
*/
|
||||
public function get(int $offset): ?string;
|
||||
|
||||
/**
|
||||
* Returns the associated key for a specific segment.
|
||||
*
|
||||
* If a value is specified only the keys associated with
|
||||
* the given value will be returned
|
||||
*
|
||||
* @param ?string $segment
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function keys(?string $segment = null): array;
|
||||
|
||||
/**
|
||||
* Appends a segment to the path.
|
||||
*/
|
||||
public function append(string $segment): self;
|
||||
|
||||
/**
|
||||
* Prepends a segment to the path.
|
||||
*/
|
||||
public function prepend(string $segment): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the modified segment.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the new segment
|
||||
*
|
||||
* If $key is non-negative, the added segment will be the segment at $key position from the start.
|
||||
* If $key is negative, the added segment will be the segment at $key position from the end.
|
||||
*
|
||||
* @param ?string $segment
|
||||
*
|
||||
* @throws SyntaxError If the key is invalid
|
||||
*/
|
||||
public function withSegment(int $key, ?string $segment): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without the specified segment.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified component
|
||||
*
|
||||
* If $key is non-negative, the removed segment will be the segment at $key position from the start.
|
||||
* If $key is negative, the removed segment will be the segment at $key position from the end.
|
||||
*
|
||||
* @param int ...$keys remaining keys to remove
|
||||
*
|
||||
* @throws SyntaxError If the key is invalid
|
||||
*/
|
||||
public function withoutSegment(int ...$keys): self;
|
||||
|
||||
/**
|
||||
* Returns an instance without duplicate delimiters.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the path component normalized by removing
|
||||
* multiple consecutive empty segment
|
||||
*/
|
||||
public function withoutEmptySegments(): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the specified parent directory's path.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the extension basename modified.
|
||||
*
|
||||
* @param ?string $path
|
||||
*/
|
||||
public function withDirname(?string $path): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the specified basename.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the extension basename modified.
|
||||
*
|
||||
* @param ?string $basename
|
||||
*/
|
||||
public function withBasename(?string $basename): self;
|
||||
|
||||
/**
|
||||
* Returns an instance with the specified basename extension.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the extension basename modified.
|
||||
*
|
||||
* @param ?string $extension
|
||||
*/
|
||||
public function withExtension(?string $extension): self;
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use League\Uri\Exceptions\IdnSupportMissing;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
|
||||
interface UriComponentInterface extends \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Returns the instance content.
|
||||
*
|
||||
* If the instance is defined, the value returned MUST be encoded according to the
|
||||
* selected encoding algorithm. In any case, the value MUST NOT double-encode any character
|
||||
* depending on the selected encoding algorithm.
|
||||
*
|
||||
* To determine what characters to encode, please refer to RFC 3986, Sections 2 and 3.
|
||||
* or RFC 3987 Section 3. By default the content is encoded according to RFC3986
|
||||
*
|
||||
* If the instance is not defined null is returned
|
||||
*/
|
||||
public function getContent(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the instance string representation.
|
||||
*
|
||||
* If the instance is defined, the value returned MUST be percent-encoded,
|
||||
* but MUST NOT double-encode any characters. To determine what characters
|
||||
* to encode, please refer to RFC 3986, Sections 2 and 3.
|
||||
*
|
||||
* If the instance is not defined an empty string is returned
|
||||
*/
|
||||
public function __toString(): string;
|
||||
|
||||
/**
|
||||
* Returns the instance json representation.
|
||||
*
|
||||
* If the instance is defined, the value returned MUST be percent-encoded,
|
||||
* but MUST NOT double-encode any characters. To determine what characters
|
||||
* to encode, please refer to RFC 3986 or RFC 1738.
|
||||
*
|
||||
* If the instance is not defined null is returned
|
||||
*/
|
||||
public function jsonSerialize(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the instance string representation with its optional URI delimiters.
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode any
|
||||
* characters. To determine what characters to encode, please refer to RFC 3986,
|
||||
* Sections 2 and 3.
|
||||
*
|
||||
* If the instance is not defined an empty string is returned
|
||||
*/
|
||||
public function getUriComponent(): string;
|
||||
|
||||
/**
|
||||
* Returns an instance with the specified content.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified content.
|
||||
*
|
||||
* Users can provide both encoded and decoded content characters.
|
||||
*
|
||||
* A null value is equivalent to removing the component content.
|
||||
*
|
||||
*
|
||||
* @param ?string $content
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
* @throws IdnSupportMissing for component or transformations
|
||||
* requiring IDN support when IDN support is not present
|
||||
* or misconfigured.
|
||||
*/
|
||||
public function withContent(?string $content): self;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface UriException extends Throwable
|
||||
{
|
||||
}
|
|
@ -1,292 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
use League\Uri\Exceptions\IdnSupportMissing;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
|
||||
interface UriInterface extends \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Returns the string representation as a URI reference.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3986#section-4.1
|
||||
*/
|
||||
public function __toString(): string;
|
||||
|
||||
/**
|
||||
* Returns the string representation as a URI reference.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3986#section-4.1
|
||||
* @see ::__toString
|
||||
*/
|
||||
public function jsonSerialize(): string;
|
||||
|
||||
/**
|
||||
* Retrieve the scheme component of the URI.
|
||||
*
|
||||
* If no scheme is present, this method MUST return a null value.
|
||||
*
|
||||
* The value returned MUST be normalized to lowercase, per RFC 3986
|
||||
* Section 3.1.
|
||||
*
|
||||
* The trailing ":" character is not part of the scheme and MUST NOT be
|
||||
* added.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.1
|
||||
*/
|
||||
public function getScheme(): ?string;
|
||||
|
||||
/**
|
||||
* Retrieve the authority component of the URI.
|
||||
*
|
||||
* If no scheme is present, this method MUST return a null value.
|
||||
*
|
||||
* If the port component is not set or is the standard port for the current
|
||||
* scheme, it SHOULD NOT be included.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.2
|
||||
*/
|
||||
public function getAuthority(): ?string;
|
||||
|
||||
/**
|
||||
* Retrieve the user information component of the URI.
|
||||
*
|
||||
* If no scheme is present, this method MUST return a null value.
|
||||
*
|
||||
* If a user is present in the URI, this will return that value;
|
||||
* additionally, if the password is also present, it will be appended to the
|
||||
* user value, with a colon (":") separating the values.
|
||||
*
|
||||
* The trailing "@" character is not part of the user information and MUST
|
||||
* NOT be added.
|
||||
*/
|
||||
public function getUserInfo(): ?string;
|
||||
|
||||
/**
|
||||
* Retrieve the host component of the URI.
|
||||
*
|
||||
* If no host is present this method MUST return a null value.
|
||||
*
|
||||
* The value returned MUST be normalized to lowercase, per RFC 3986
|
||||
* Section 3.2.2.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*/
|
||||
public function getHost(): ?string;
|
||||
|
||||
/**
|
||||
* Retrieve the port component of the URI.
|
||||
*
|
||||
* If a port is present, and it is non-standard for the current scheme,
|
||||
* this method MUST return it as an integer. If the port is the standard port
|
||||
* used with the current scheme, this method SHOULD return null.
|
||||
*
|
||||
* If no port is present, and no scheme is present, this method MUST return
|
||||
* a null value.
|
||||
*
|
||||
* If no port is present, but a scheme is present, this method MAY return
|
||||
* the standard port for that scheme, but SHOULD return null.
|
||||
*/
|
||||
public function getPort(): ?int;
|
||||
|
||||
/**
|
||||
* Retrieve the path component of the URI.
|
||||
*
|
||||
* The path can either be empty or absolute (starting with a slash) or
|
||||
* rootless (not starting with a slash). Implementations MUST support all
|
||||
* three syntaxes.
|
||||
*
|
||||
* Normally, the empty path "" and absolute path "/" are considered equal as
|
||||
* defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
|
||||
* do this normalization because in contexts with a trimmed base path, e.g.
|
||||
* the front controller, this difference becomes significant. It's the task
|
||||
* of the user to handle both "" and "/".
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode
|
||||
* any characters. To determine what characters to encode, please refer to
|
||||
* RFC 3986, Sections 2 and 3.3.
|
||||
*
|
||||
* As an example, if the value should include a slash ("/") not intended as
|
||||
* delimiter between path segments, that value MUST be passed in encoded
|
||||
* form (e.g., "%2F") to the instance.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-2
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.3
|
||||
*/
|
||||
public function getPath(): string;
|
||||
|
||||
/**
|
||||
* Retrieve the query string of the URI.
|
||||
*
|
||||
* If no host is present this method MUST return a null value.
|
||||
*
|
||||
* The leading "?" character is not part of the query and MUST NOT be
|
||||
* added.
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode
|
||||
* any characters. To determine what characters to encode, please refer to
|
||||
* RFC 3986, Sections 2 and 3.4.
|
||||
*
|
||||
* As an example, if a value in a key/value pair of the query string should
|
||||
* include an ampersand ("&") not intended as a delimiter between values,
|
||||
* that value MUST be passed in encoded form (e.g., "%26") to the instance.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-2
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.4
|
||||
*/
|
||||
public function getQuery(): ?string;
|
||||
|
||||
/**
|
||||
* Retrieve the fragment component of the URI.
|
||||
*
|
||||
* If no host is present this method MUST return a null value.
|
||||
*
|
||||
* The leading "#" character is not part of the fragment and MUST NOT be
|
||||
* added.
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode
|
||||
* any characters. To determine what characters to encode, please refer to
|
||||
* RFC 3986, Sections 2 and 3.5.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-2
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.5
|
||||
*/
|
||||
public function getFragment(): ?string;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified scheme.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified scheme.
|
||||
*
|
||||
* A null value provided for the scheme is equivalent to removing the scheme
|
||||
* information.
|
||||
*
|
||||
* @param ?string $scheme
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withScheme(?string $scheme): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified user information.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified user information.
|
||||
*
|
||||
* Password is optional, but the user information MUST include the
|
||||
* user; a null value for the user is equivalent to removing user
|
||||
* information.
|
||||
*
|
||||
* @param ?string $user
|
||||
* @param ?string $password
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withUserInfo(?string $user, ?string $password = null): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified host.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified host.
|
||||
*
|
||||
* A null value provided for the host is equivalent to removing the host
|
||||
* information.
|
||||
*
|
||||
* @param ?string $host
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
* @throws IdnSupportMissing for component or transformations
|
||||
* requiring IDN support when IDN support is not present
|
||||
* or misconfigured.
|
||||
*/
|
||||
public function withHost(?string $host): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified port.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified port.
|
||||
*
|
||||
* A null value provided for the port is equivalent to removing the port
|
||||
* information.
|
||||
*
|
||||
* @param ?int $port
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withPort(?int $port): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified path.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified path.
|
||||
*
|
||||
* The path can either be empty or absolute (starting with a slash) or
|
||||
* rootless (not starting with a slash). Implementations MUST support all
|
||||
* three syntaxes.
|
||||
*
|
||||
* Users can provide both encoded and decoded path characters.
|
||||
* Implementations ensure the correct encoding as outlined in getPath().
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withPath(string $path): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified query string.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified query string.
|
||||
*
|
||||
* Users can provide both encoded and decoded query characters.
|
||||
* Implementations ensure the correct encoding as outlined in getQuery().
|
||||
*
|
||||
* A null value provided for the query is equivalent to removing the query
|
||||
* information.
|
||||
*
|
||||
* @param ?string $query
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withQuery(?string $query): self;
|
||||
|
||||
/**
|
||||
* Return an instance with the specified URI fragment.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified URI fragment.
|
||||
*
|
||||
* Users can provide both encoded and decoded fragment characters.
|
||||
* Implementations ensure the correct encoding as outlined in getFragment().
|
||||
*
|
||||
* A null value provided for the fragment is equivalent to removing the fragment
|
||||
* information.
|
||||
*
|
||||
* @param ?string $fragment
|
||||
*
|
||||
* @throws SyntaxError for invalid component or transformations
|
||||
* that would result in a object in invalid state.
|
||||
*/
|
||||
public function withFragment(?string $fragment): self;
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Contracts;
|
||||
|
||||
interface UserInfoInterface extends UriComponentInterface
|
||||
{
|
||||
/**
|
||||
* Returns the user component part.
|
||||
*/
|
||||
public function getUser(): ?string;
|
||||
|
||||
/**
|
||||
* Returns the pass component part.
|
||||
*/
|
||||
public function getPass(): ?string;
|
||||
|
||||
/**
|
||||
* Returns an instance with the specified user and/or pass.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified user.
|
||||
*
|
||||
* An empty user is equivalent to removing the user information.
|
||||
*
|
||||
* @param ?string $user
|
||||
* @param ?string $pass
|
||||
*/
|
||||
public function withUserInfo(?string $user, ?string $pass = null): self;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Exceptions;
|
||||
|
||||
use League\Uri\Contracts\UriException;
|
||||
|
||||
class FileinfoSupportMissing extends \RuntimeException implements UriException
|
||||
{
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Exceptions;
|
||||
|
||||
use League\Uri\Contracts\UriException;
|
||||
|
||||
class IdnSupportMissing extends \RuntimeException implements UriException
|
||||
{
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Exceptions;
|
||||
|
||||
use League\Uri\Idna\IdnaInfo;
|
||||
|
||||
final class IdnaConversionFailed extends SyntaxError
|
||||
{
|
||||
/** @var IdnaInfo|null */
|
||||
private $idnaInfo;
|
||||
|
||||
private function __construct(string $message, IdnaInfo $idnaInfo = null)
|
||||
{
|
||||
parent::__construct($message);
|
||||
$this->idnaInfo = $idnaInfo;
|
||||
}
|
||||
|
||||
public static function dueToIDNAError(string $domain, IdnaInfo $idnaInfo): self
|
||||
{
|
||||
return new self(
|
||||
'The host `'.$domain.'` is invalid : '.implode(', ', $idnaInfo->errorList()).' .',
|
||||
$idnaInfo
|
||||
);
|
||||
}
|
||||
|
||||
public static function dueToInvalidHost(string $domain): self
|
||||
{
|
||||
return new self('The host `'.$domain.'` is not a valid IDN host');
|
||||
}
|
||||
|
||||
public function idnaInfo(): ?IdnaInfo
|
||||
{
|
||||
return $this->idnaInfo;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Exceptions;
|
||||
|
||||
use League\Uri\Contracts\UriException;
|
||||
|
||||
class SyntaxError extends \InvalidArgumentException implements UriException
|
||||
{
|
||||
}
|
|
@ -1,212 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Idna;
|
||||
|
||||
use League\Uri\Exceptions\IdnaConversionFailed;
|
||||
use League\Uri\Exceptions\IdnSupportMissing;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use function defined;
|
||||
use function function_exists;
|
||||
use function idn_to_ascii;
|
||||
use function idn_to_utf8;
|
||||
use function rawurldecode;
|
||||
use const INTL_IDNA_VARIANT_UTS46;
|
||||
|
||||
/**
|
||||
* @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html
|
||||
*/
|
||||
final class Idna
|
||||
{
|
||||
private const REGEXP_IDNA_PATTERN = '/[^\x20-\x7f]/';
|
||||
private const MAX_DOMAIN_LENGTH = 253;
|
||||
private const MAX_LABEL_LENGTH = 63;
|
||||
|
||||
/**
|
||||
* General registered name regular expression.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
* @see https://regex101.com/r/fptU8V/1
|
||||
*/
|
||||
private const REGEXP_REGISTERED_NAME = '/
|
||||
(?(DEFINE)
|
||||
(?<unreserved>[a-z0-9_~\-]) # . is missing as it is used to separate labels
|
||||
(?<sub_delims>[!$&\'()*+,;=])
|
||||
(?<encoded>%[A-F0-9]{2})
|
||||
(?<reg_name>(?:(?&unreserved)|(?&sub_delims)|(?&encoded))*)
|
||||
)
|
||||
^(?:(?®_name)\.)*(?®_name)\.?$
|
||||
/ix';
|
||||
|
||||
/**
|
||||
* IDNA options.
|
||||
*/
|
||||
public const IDNA_DEFAULT = 0;
|
||||
public const IDNA_ALLOW_UNASSIGNED = 1;
|
||||
public const IDNA_USE_STD3_RULES = 2;
|
||||
public const IDNA_CHECK_BIDI = 4;
|
||||
public const IDNA_CHECK_CONTEXTJ = 8;
|
||||
public const IDNA_NONTRANSITIONAL_TO_ASCII = 0x10;
|
||||
public const IDNA_NONTRANSITIONAL_TO_UNICODE = 0x20;
|
||||
public const IDNA_CHECK_CONTEXTO = 0x40;
|
||||
|
||||
/**
|
||||
* IDNA errors.
|
||||
*/
|
||||
public const ERROR_NONE = 0;
|
||||
public const ERROR_EMPTY_LABEL = 1;
|
||||
public const ERROR_LABEL_TOO_LONG = 2;
|
||||
public const ERROR_DOMAIN_NAME_TOO_LONG = 4;
|
||||
public const ERROR_LEADING_HYPHEN = 8;
|
||||
public const ERROR_TRAILING_HYPHEN = 0x10;
|
||||
public const ERROR_HYPHEN_3_4 = 0x20;
|
||||
public const ERROR_LEADING_COMBINING_MARK = 0x40;
|
||||
public const ERROR_DISALLOWED = 0x80;
|
||||
public const ERROR_PUNYCODE = 0x100;
|
||||
public const ERROR_LABEL_HAS_DOT = 0x200;
|
||||
public const ERROR_INVALID_ACE_LABEL = 0x400;
|
||||
public const ERROR_BIDI = 0x800;
|
||||
public const ERROR_CONTEXTJ = 0x1000;
|
||||
public const ERROR_CONTEXTO_PUNCTUATION = 0x2000;
|
||||
public const ERROR_CONTEXTO_DIGITS = 0x4000;
|
||||
|
||||
/**
|
||||
* IDNA default options.
|
||||
*/
|
||||
public const IDNA2008_ASCII = self::IDNA_NONTRANSITIONAL_TO_ASCII
|
||||
| self::IDNA_CHECK_BIDI
|
||||
| self::IDNA_USE_STD3_RULES
|
||||
| self::IDNA_CHECK_CONTEXTJ;
|
||||
public const IDNA2008_UNICODE = self::IDNA_NONTRANSITIONAL_TO_UNICODE
|
||||
| self::IDNA_CHECK_BIDI
|
||||
| self::IDNA_USE_STD3_RULES
|
||||
| self::IDNA_CHECK_CONTEXTJ;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private static function supportsIdna(): void
|
||||
{
|
||||
static $idnSupport;
|
||||
if (null === $idnSupport) {
|
||||
$idnSupport = function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46');
|
||||
}
|
||||
|
||||
if (!$idnSupport) {
|
||||
throw new IdnSupportMissing('IDN host can not be processed. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the input to its IDNA ASCII form.
|
||||
*
|
||||
* This method returns the string converted to IDN ASCII form
|
||||
*
|
||||
* @throws SyntaxError if the string can not be converted to ASCII using IDN UTS46 algorithm
|
||||
*/
|
||||
public static function toAscii(string $domain, int $options): IdnaInfo
|
||||
{
|
||||
$domain = rawurldecode($domain);
|
||||
|
||||
if (1 === preg_match(self::REGEXP_IDNA_PATTERN, $domain)) {
|
||||
self::supportsIdna();
|
||||
|
||||
/* @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
|
||||
idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
|
||||
if ([] === $idnaInfo) {
|
||||
return IdnaInfo::fromIntl([
|
||||
'result' => strtolower($domain),
|
||||
'isTransitionalDifferent' => false,
|
||||
'errors' => self::validateDomainAndLabelLength($domain),
|
||||
]);
|
||||
}
|
||||
|
||||
/* @var array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
|
||||
return IdnaInfo::fromIntl($idnaInfo);
|
||||
}
|
||||
|
||||
$error = self::ERROR_NONE;
|
||||
if (1 !== preg_match(self::REGEXP_REGISTERED_NAME, $domain)) {
|
||||
$error |= self::ERROR_DISALLOWED;
|
||||
}
|
||||
|
||||
return IdnaInfo::fromIntl([
|
||||
'result' => strtolower($domain),
|
||||
'isTransitionalDifferent' => false,
|
||||
'errors' => self::validateDomainAndLabelLength($domain) | $error,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the input to its IDNA UNICODE form.
|
||||
*
|
||||
* This method returns the string converted to IDN UNICODE form
|
||||
*
|
||||
* @throws SyntaxError if the string can not be converted to UNICODE using IDN UTS46 algorithm
|
||||
*/
|
||||
public static function toUnicode(string $domain, int $options): IdnaInfo
|
||||
{
|
||||
$domain = rawurldecode($domain);
|
||||
|
||||
if (false === stripos($domain, 'xn--')) {
|
||||
return IdnaInfo::fromIntl(['result' => $domain, 'isTransitionalDifferent' => false, 'errors' => self::ERROR_NONE]);
|
||||
}
|
||||
|
||||
self::supportsIdna();
|
||||
|
||||
/* @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
|
||||
idn_to_utf8($domain, $options, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
|
||||
if ([] === $idnaInfo) {
|
||||
throw IdnaConversionFailed::dueToInvalidHost($domain);
|
||||
}
|
||||
|
||||
/* @var array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
|
||||
return IdnaInfo::fromIntl($idnaInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapted from https://github.com/TRowbotham/idna.
|
||||
*
|
||||
* @see https://github.com/TRowbotham/idna/blob/master/src/Idna.php#L236
|
||||
*/
|
||||
private static function validateDomainAndLabelLength(string $domain): int
|
||||
{
|
||||
$error = self::ERROR_NONE;
|
||||
$labels = explode('.', $domain);
|
||||
$maxDomainSize = self::MAX_DOMAIN_LENGTH;
|
||||
$length = count($labels);
|
||||
|
||||
// If the last label is empty and it is not the first label, then it is the root label.
|
||||
// Increase the max size by 1, making it 254, to account for the root label's "."
|
||||
// delimiter. This also means we don't need to check the last label's length for being too
|
||||
// long.
|
||||
if ($length > 1 && $labels[$length - 1] === '') {
|
||||
++$maxDomainSize;
|
||||
array_pop($labels);
|
||||
}
|
||||
|
||||
if (strlen($domain) > $maxDomainSize) {
|
||||
$error |= self::ERROR_DOMAIN_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
foreach ($labels as $label) {
|
||||
if (strlen($label) > self::MAX_LABEL_LENGTH) {
|
||||
$error |= self::ERROR_LABEL_TOO_LONG;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Idna;
|
||||
|
||||
use function array_filter;
|
||||
use const ARRAY_FILTER_USE_KEY;
|
||||
|
||||
/**
|
||||
* @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html
|
||||
*/
|
||||
final class IdnaInfo
|
||||
{
|
||||
private const ERRORS = [
|
||||
Idna::ERROR_EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty',
|
||||
Idna::ERROR_LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes',
|
||||
Idna::ERROR_DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form',
|
||||
Idna::ERROR_LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")',
|
||||
Idna::ERROR_TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")',
|
||||
Idna::ERROR_HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions',
|
||||
Idna::ERROR_LEADING_COMBINING_MARK => 'a label starts with a combining mark',
|
||||
Idna::ERROR_DISALLOWED => 'a label or domain name contains disallowed characters',
|
||||
Idna::ERROR_PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode',
|
||||
Idna::ERROR_LABEL_HAS_DOT => 'a label contains a dot=full stop',
|
||||
Idna::ERROR_INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string',
|
||||
Idna::ERROR_BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)',
|
||||
Idna::ERROR_CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements',
|
||||
Idna::ERROR_CONTEXTO_DIGITS => 'a label does not meet the IDNA CONTEXTO requirements for digits',
|
||||
Idna::ERROR_CONTEXTO_PUNCTUATION => 'a label does not meet the IDNA CONTEXTO requirements for punctuation characters. Some punctuation characters "Would otherwise have been DISALLOWED" but are allowed in certain contexts',
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $result;
|
||||
|
||||
/** @var bool */
|
||||
private $isTransitionalDifferent;
|
||||
|
||||
/** @var int */
|
||||
private $errors;
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private $errorList;
|
||||
|
||||
private function __construct(string $result, bool $isTransitionalDifferent, int $errors)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->errors = $errors;
|
||||
$this->isTransitionalDifferent = $isTransitionalDifferent;
|
||||
$this->errorList = array_filter(
|
||||
self::ERRORS,
|
||||
function (int $error): bool {
|
||||
return 0 !== ($error & $this->errors);
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{result:string, isTransitionalDifferent:bool, errors:int} $infos
|
||||
*/
|
||||
public static function fromIntl(array $infos): self
|
||||
{
|
||||
return new self($infos['result'], $infos['isTransitionalDifferent'], $infos['errors']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{result:string, isTransitionalDifferent:bool, errors:int} $properties
|
||||
*/
|
||||
public static function __set_state(array $properties): self
|
||||
{
|
||||
return self::fromIntl($properties);
|
||||
}
|
||||
|
||||
public function result(): string
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
public function isTransitionalDifferent(): bool
|
||||
{
|
||||
return $this->isTransitionalDifferent;
|
||||
}
|
||||
|
||||
public function errors(): int
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function error(int $error): ?string
|
||||
{
|
||||
return $this->errorList[$error] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public function errorList(): array
|
||||
{
|
||||
return $this->errorList;
|
||||
}
|
||||
}
|
20
admin/phpMyAdmin/vendor/league/uri/LICENSE
vendored
20
admin/phpMyAdmin/vendor/league/uri/LICENSE
vendored
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 ignace nyamagana butera
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
110
admin/phpMyAdmin/vendor/league/uri/composer.json
vendored
110
admin/phpMyAdmin/vendor/league/uri/composer.json
vendored
|
@ -1,110 +0,0 @@
|
|||
{
|
||||
"name": "league/uri",
|
||||
"type": "library",
|
||||
"description" : "URI manipulation library",
|
||||
"keywords": [
|
||||
"url",
|
||||
"uri",
|
||||
"rfc3986",
|
||||
"rfc3987",
|
||||
"rfc6570",
|
||||
"psr-7",
|
||||
"parse_url",
|
||||
"http",
|
||||
"https",
|
||||
"ws",
|
||||
"ftp",
|
||||
"data-uri",
|
||||
"file-uri",
|
||||
"middleware",
|
||||
"parse_str",
|
||||
"query-string",
|
||||
"querystring",
|
||||
"hostname",
|
||||
"uri-template"
|
||||
],
|
||||
"license": "MIT",
|
||||
"homepage": "http://uri.thephpleague.com",
|
||||
"authors": [
|
||||
{
|
||||
"name" : "Ignace Nyamagana Butera",
|
||||
"email" : "nyamsprod@gmail.com",
|
||||
"homepage" : "https://nyamsprod.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://thephpleague.slack.com",
|
||||
"docs": "https://uri.thephpleague.com",
|
||||
"issues": "https://github.com/thephpleague/uri/issues"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/nyamsprod"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-json": "*",
|
||||
"psr/http-message": "^1.0",
|
||||
"league/uri-interfaces": "^2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"phpunit/phpunit" : "^8.0 || ^9.0",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-strict-rules": "^0.12",
|
||||
"phpstan/phpstan-phpunit": "^0.12",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Uri\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"LeagueTest\\Uri\\": "tests"
|
||||
}
|
||||
},
|
||||
"conflict": {
|
||||
"league/uri-schemes": "^1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"phpcs": "php-cs-fixer fix -v --diff --dry-run --allow-risky=yes --ansi",
|
||||
"phpstan-src": "phpstan analyse -l max -c phpstan.src.neon src --ansi",
|
||||
"phpstan-tests": "phpstan analyse -l max -c phpstan.tests.neon tests --ansi",
|
||||
"phpstan": [
|
||||
"@phpstan-src",
|
||||
"@phpstan-tests"
|
||||
],
|
||||
"phpunit": "phpunit --coverage-text",
|
||||
"test": [
|
||||
"@phpcs",
|
||||
"@phpstan",
|
||||
"@phpunit"
|
||||
]
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"phpcs": "Runs coding style test suite",
|
||||
"phpstan": "Runs complete codebase static analysis",
|
||||
"phpstan-src": "Runs source code static analysis",
|
||||
"phpstan-test": "Runs test suite static analysis",
|
||||
"phpunit": "Runs unit and functional testing",
|
||||
"test": "Runs full test suite"
|
||||
},
|
||||
"suggest": {
|
||||
"league/uri-components" : "Needed to easily manipulate URI objects",
|
||||
"ext-intl" : "Needed to improve host validation",
|
||||
"ext-fileinfo": "Needed to create Data URI from a filepath",
|
||||
"psr/http-factory": "Needed to use the URI factory"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\Exceptions;
|
||||
|
||||
use League\Uri\Contracts\UriException;
|
||||
|
||||
class TemplateCanNotBeExpanded extends \InvalidArgumentException implements UriException
|
||||
{
|
||||
public static function dueToUnableToProcessValueListWithPrefix(string $variableName): self
|
||||
{
|
||||
return new self('The ":" modifier can not be applied on "'.$variableName.'" since it is a list of values.');
|
||||
}
|
||||
|
||||
public static function dueToNestedListOfValue(string $variableName): self
|
||||
{
|
||||
return new self('The "'.$variableName.'" can not be a nested list.');
|
||||
}
|
||||
}
|
335
admin/phpMyAdmin/vendor/league/uri/src/Http.php
vendored
335
admin/phpMyAdmin/vendor/league/uri/src/Http.php
vendored
|
@ -1,335 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri;
|
||||
|
||||
use League\Uri\Contracts\UriInterface;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use Psr\Http\Message\UriInterface as Psr7UriInterface;
|
||||
use function is_object;
|
||||
use function is_scalar;
|
||||
use function method_exists;
|
||||
use function sprintf;
|
||||
|
||||
final class Http implements Psr7UriInterface, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var UriInterface
|
||||
*/
|
||||
private $uri;
|
||||
|
||||
/**
|
||||
* New instance.
|
||||
*/
|
||||
private function __construct(UriInterface $uri)
|
||||
{
|
||||
$this->validate($uri);
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the submitted uri against PSR-7 UriInterface.
|
||||
*
|
||||
* @throws SyntaxError if the given URI does not follow PSR-7 UriInterface rules
|
||||
*/
|
||||
private function validate(UriInterface $uri): void
|
||||
{
|
||||
$scheme = $uri->getScheme();
|
||||
if (null === $scheme && '' === $uri->getHost()) {
|
||||
throw new SyntaxError(sprintf('an URI without scheme can not contains a empty host string according to PSR-7: %s', (string) $uri));
|
||||
}
|
||||
|
||||
$port = $uri->getPort();
|
||||
if (null !== $port && ($port < 0 || $port > 65535)) {
|
||||
throw new SyntaxError(sprintf('The URI port is outside the established TCP and UDP port ranges: %s', (string) $uri->getPort()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method called by PHP's var export.
|
||||
*/
|
||||
public static function __set_state(array $components): self
|
||||
{
|
||||
return new self($components['uri']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from a string.
|
||||
*
|
||||
* @param string|mixed $uri
|
||||
*/
|
||||
public static function createFromString($uri = ''): self
|
||||
{
|
||||
return new self(Uri::createFromString($uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from a hash of parse_url parts.
|
||||
*
|
||||
* @param array $components a hash representation of the URI similar
|
||||
* to PHP parse_url function result
|
||||
*/
|
||||
public static function createFromComponents(array $components): self
|
||||
{
|
||||
return new self(Uri::createFromComponents($components));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from the environment.
|
||||
*/
|
||||
public static function createFromServer(array $server): self
|
||||
{
|
||||
return new self(Uri::createFromServer($server));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from a URI and a Base URI.
|
||||
*
|
||||
* The returned URI must be absolute.
|
||||
*
|
||||
* @param mixed $uri the input URI to create
|
||||
* @param mixed $base_uri the base URI used for reference
|
||||
*/
|
||||
public static function createFromBaseUri($uri, $base_uri = null): self
|
||||
{
|
||||
return new self(Uri::createFromBaseUri($uri, $base_uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from a URI object.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri the input URI to create
|
||||
*/
|
||||
public static function createFromUri($uri): self
|
||||
{
|
||||
if ($uri instanceof UriInterface) {
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
return new self(Uri::createFromUri($uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getScheme(): string
|
||||
{
|
||||
return (string) $this->uri->getScheme();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getAuthority(): string
|
||||
{
|
||||
return (string) $this->uri->getAuthority();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUserInfo(): string
|
||||
{
|
||||
return (string) $this->uri->getUserInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getHost(): string
|
||||
{
|
||||
return (string) $this->uri->getHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPort(): ?int
|
||||
{
|
||||
return $this->uri->getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->uri->getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getQuery(): string
|
||||
{
|
||||
return (string) $this->uri->getQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFragment(): string
|
||||
{
|
||||
return (string) $this->uri->getFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withScheme($scheme): self
|
||||
{
|
||||
$scheme = $this->filterInput($scheme);
|
||||
if ('' === $scheme) {
|
||||
$scheme = null;
|
||||
}
|
||||
|
||||
$uri = $this->uri->withScheme($scheme);
|
||||
if ($uri->getScheme() === $this->uri->getScheme()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely stringify input when possible.
|
||||
*
|
||||
* @param mixed $str the value to evaluate as a string
|
||||
*
|
||||
* @throws SyntaxError if the submitted data can not be converted to string
|
||||
*
|
||||
* @return string|mixed
|
||||
*/
|
||||
private function filterInput($str)
|
||||
{
|
||||
if (is_scalar($str) || (is_object($str) && method_exists($str, '__toString'))) {
|
||||
return (string) $str;
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withUserInfo($user, $password = null): self
|
||||
{
|
||||
$user = $this->filterInput($user);
|
||||
if ('' === $user) {
|
||||
$user = null;
|
||||
}
|
||||
|
||||
$uri = $this->uri->withUserInfo($user, $password);
|
||||
if ($uri->getUserInfo() === $this->uri->getUserInfo()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withHost($host): self
|
||||
{
|
||||
$host = $this->filterInput($host);
|
||||
if ('' === $host) {
|
||||
$host = null;
|
||||
}
|
||||
|
||||
$uri = $this->uri->withHost($host);
|
||||
if ($uri->getHost() === $this->uri->getHost()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withPort($port): self
|
||||
{
|
||||
$uri = $this->uri->withPort($port);
|
||||
if ($uri->getPort() === $this->uri->getPort()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withPath($path): self
|
||||
{
|
||||
$uri = $this->uri->withPath($path);
|
||||
if ($uri->getPath() === $this->uri->getPath()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withQuery($query): self
|
||||
{
|
||||
$query = $this->filterInput($query);
|
||||
if ('' === $query) {
|
||||
$query = null;
|
||||
}
|
||||
|
||||
$uri = $this->uri->withQuery($query);
|
||||
if ($uri->getQuery() === $this->uri->getQuery()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function withFragment($fragment): self
|
||||
{
|
||||
$fragment = $this->filterInput($fragment);
|
||||
if ('' === $fragment) {
|
||||
$fragment = null;
|
||||
}
|
||||
|
||||
$uri = $this->uri->withFragment($fragment);
|
||||
if ($uri->getFragment() === $this->uri->getFragment()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new self($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->uri->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function jsonSerialize(): string
|
||||
{
|
||||
return $this->uri->__toString();
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri;
|
||||
|
||||
use Psr\Http\Message\UriFactoryInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
final class HttpFactory implements UriFactoryInterface
|
||||
{
|
||||
public function createUri(string $uri = ''): UriInterface
|
||||
{
|
||||
return Http::createFromString($uri);
|
||||
}
|
||||
}
|
1501
admin/phpMyAdmin/vendor/league/uri/src/Uri.php
vendored
1501
admin/phpMyAdmin/vendor/league/uri/src/Uri.php
vendored
File diff suppressed because it is too large
Load diff
205
admin/phpMyAdmin/vendor/league/uri/src/UriInfo.php
vendored
205
admin/phpMyAdmin/vendor/league/uri/src/UriInfo.php
vendored
|
@ -1,205 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri;
|
||||
|
||||
use League\Uri\Contracts\UriInterface;
|
||||
use Psr\Http\Message\UriInterface as Psr7UriInterface;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function preg_replace_callback;
|
||||
use function rawurldecode;
|
||||
use function sprintf;
|
||||
|
||||
final class UriInfo
|
||||
{
|
||||
private const REGEXP_ENCODED_CHARS = ',%(2[D|E]|3[0-9]|4[1-9|A-F]|5[0-9|A|F]|6[1-9|A-F]|7[0-9|E]),i';
|
||||
|
||||
private const WHATWG_SPECIAL_SCHEMES = ['ftp', 'http', 'https', 'ws', 'wss'];
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
private static function emptyComponentValue($uri): ?string
|
||||
{
|
||||
return $uri instanceof Psr7UriInterface ? '' : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the URI object.
|
||||
*
|
||||
* To be valid an URI MUST implement at least one of the following interface:
|
||||
* - League\Uri\UriInterface
|
||||
* - Psr\Http\Message\UriInterface
|
||||
*
|
||||
* @param mixed $uri the URI to validate
|
||||
*
|
||||
* @throws \TypeError if the URI object does not implements the supported interfaces.
|
||||
*
|
||||
* @return Psr7UriInterface|UriInterface
|
||||
*/
|
||||
private static function filterUri($uri)
|
||||
{
|
||||
if ($uri instanceof Psr7UriInterface || $uri instanceof UriInterface) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
throw new \TypeError(sprintf('The uri must be a valid URI object received `%s`', is_object($uri) ? get_class($uri) : gettype($uri)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an URI for comparison.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*
|
||||
* @return Psr7UriInterface|UriInterface
|
||||
*/
|
||||
private static function normalize($uri)
|
||||
{
|
||||
$uri = self::filterUri($uri);
|
||||
$null = self::emptyComponentValue($uri);
|
||||
|
||||
$path = $uri->getPath();
|
||||
if ('/' === ($path[0] ?? '') || '' !== $uri->getScheme().$uri->getAuthority()) {
|
||||
$path = UriResolver::resolve($uri, $uri->withPath('')->withQuery($null))->getPath();
|
||||
}
|
||||
|
||||
$query = $uri->getQuery();
|
||||
$fragment = $uri->getFragment();
|
||||
$fragmentOrig = $fragment;
|
||||
$pairs = null === $query ? [] : explode('&', $query);
|
||||
sort($pairs, SORT_REGULAR);
|
||||
|
||||
$replace = static function (array $matches): string {
|
||||
return rawurldecode($matches[0]);
|
||||
};
|
||||
|
||||
$retval = preg_replace_callback(self::REGEXP_ENCODED_CHARS, $replace, [$path, implode('&', $pairs), $fragment]);
|
||||
if (null !== $retval) {
|
||||
[$path, $query, $fragment] = $retval + ['', $null, $null];
|
||||
}
|
||||
|
||||
if ($null !== $uri->getAuthority() && '' === $path) {
|
||||
$path = '/';
|
||||
}
|
||||
|
||||
return $uri
|
||||
->withHost(Uri::createFromComponents(['host' => $uri->getHost()])->getHost())
|
||||
->withPath($path)
|
||||
->withQuery([] === $pairs ? $null : $query)
|
||||
->withFragment($null === $fragmentOrig ? $fragmentOrig : $fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the URI represents an absolute URI.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
public static function isAbsolute($uri): bool
|
||||
{
|
||||
return self::emptyComponentValue($uri) !== self::filterUri($uri)->getScheme();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the URI represents a network path.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
public static function isNetworkPath($uri): bool
|
||||
{
|
||||
$uri = self::filterUri($uri);
|
||||
$null = self::emptyComponentValue($uri);
|
||||
|
||||
return $null === $uri->getScheme() && $null !== $uri->getAuthority();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the URI represents an absolute path.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
public static function isAbsolutePath($uri): bool
|
||||
{
|
||||
$uri = self::filterUri($uri);
|
||||
$null = self::emptyComponentValue($uri);
|
||||
|
||||
return $null === $uri->getScheme()
|
||||
&& $null === $uri->getAuthority()
|
||||
&& '/' === ($uri->getPath()[0] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the URI represents a relative path.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
public static function isRelativePath($uri): bool
|
||||
{
|
||||
$uri = self::filterUri($uri);
|
||||
$null = self::emptyComponentValue($uri);
|
||||
|
||||
return $null === $uri->getScheme()
|
||||
&& $null === $uri->getAuthority()
|
||||
&& '/' !== ($uri->getPath()[0] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether both URI refers to the same document.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
* @param Psr7UriInterface|UriInterface $base_uri
|
||||
*/
|
||||
public static function isSameDocument($uri, $base_uri): bool
|
||||
{
|
||||
$uri = self::normalize($uri);
|
||||
$base_uri = self::normalize($base_uri);
|
||||
|
||||
return (string) $uri->withFragment($uri instanceof Psr7UriInterface ? '' : null)
|
||||
=== (string) $base_uri->withFragment($base_uri instanceof Psr7UriInterface ? '' : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI origin property as defined by WHATWG URL living standard.
|
||||
*
|
||||
* {@see https://url.spec.whatwg.org/#origin}
|
||||
*
|
||||
* For URI without a special scheme the method returns null
|
||||
* For URI with the file scheme the method will return null (as this is left to the implementation decision)
|
||||
* For URI with a special scheme the method returns the scheme followed by its authority (without the userinfo part)
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
public static function getOrigin($uri): ?string
|
||||
{
|
||||
$scheme = self::filterUri($uri)->getScheme();
|
||||
if ('blob' === $scheme) {
|
||||
$uri = Uri::createFromString($uri->getPath());
|
||||
$scheme = $uri->getScheme();
|
||||
}
|
||||
|
||||
if (in_array($scheme, self::WHATWG_SPECIAL_SCHEMES, true)) {
|
||||
$null = self::emptyComponentValue($uri);
|
||||
|
||||
return (string) $uri->withFragment($null)->withQuery($null)->withPath('')->withUserInfo($null, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,375 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri;
|
||||
|
||||
use League\Uri\Contracts\UriInterface;
|
||||
use Psr\Http\Message\UriInterface as Psr7UriInterface;
|
||||
use function array_pop;
|
||||
use function array_reduce;
|
||||
use function count;
|
||||
use function end;
|
||||
use function explode;
|
||||
use function gettype;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
final class UriResolver
|
||||
{
|
||||
/**
|
||||
* @var array<string,int>
|
||||
*/
|
||||
const DOT_SEGMENTS = ['.' => 1, '..' => 1];
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an URI against a base URI using RFC3986 rules.
|
||||
*
|
||||
* If the first argument is a UriInterface the method returns a UriInterface object
|
||||
* If the first argument is a Psr7UriInterface the method returns a Psr7UriInterface object
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
* @param Psr7UriInterface|UriInterface $base_uri
|
||||
*
|
||||
* @return Psr7UriInterface|UriInterface
|
||||
*/
|
||||
public static function resolve($uri, $base_uri)
|
||||
{
|
||||
self::filterUri($uri);
|
||||
self::filterUri($base_uri);
|
||||
$null = $uri instanceof Psr7UriInterface ? '' : null;
|
||||
|
||||
if ($null !== $uri->getScheme()) {
|
||||
return $uri
|
||||
->withPath(self::removeDotSegments($uri->getPath()));
|
||||
}
|
||||
|
||||
if ($null !== $uri->getAuthority()) {
|
||||
return $uri
|
||||
->withScheme($base_uri->getScheme())
|
||||
->withPath(self::removeDotSegments($uri->getPath()));
|
||||
}
|
||||
|
||||
$user = $null;
|
||||
$pass = null;
|
||||
$userInfo = $base_uri->getUserInfo();
|
||||
if (null !== $userInfo) {
|
||||
[$user, $pass] = explode(':', $userInfo, 2) + [1 => null];
|
||||
}
|
||||
|
||||
[$uri_path, $uri_query] = self::resolvePathAndQuery($uri, $base_uri);
|
||||
|
||||
return $uri
|
||||
->withPath(self::removeDotSegments($uri_path))
|
||||
->withQuery($uri_query)
|
||||
->withHost($base_uri->getHost())
|
||||
->withPort($base_uri->getPort())
|
||||
->withUserInfo((string) $user, $pass)
|
||||
->withScheme($base_uri->getScheme())
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the URI object.
|
||||
*
|
||||
* @param mixed $uri an URI object
|
||||
*
|
||||
* @throws \TypeError if the URI object does not implements the supported interfaces.
|
||||
*/
|
||||
private static function filterUri($uri): void
|
||||
{
|
||||
if (!$uri instanceof UriInterface && !$uri instanceof Psr7UriInterface) {
|
||||
throw new \TypeError(sprintf('The uri must be a valid URI object received `%s`', gettype($uri)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove dot segments from the URI path.
|
||||
*/
|
||||
private static function removeDotSegments(string $path): string
|
||||
{
|
||||
if (false === strpos($path, '.')) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$old_segments = explode('/', $path);
|
||||
$new_path = implode('/', array_reduce($old_segments, [UriResolver::class, 'reducer'], []));
|
||||
if (isset(self::DOT_SEGMENTS[end($old_segments)])) {
|
||||
$new_path .= '/';
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
// added because some PSR-7 implementations do not respect RFC3986
|
||||
if (0 === strpos($path, '/') && 0 !== strpos($new_path, '/')) {
|
||||
return '/'.$new_path;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $new_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove dot segments.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private static function reducer(array $carry, string $segment): array
|
||||
{
|
||||
if ('..' === $segment) {
|
||||
array_pop($carry);
|
||||
|
||||
return $carry;
|
||||
}
|
||||
|
||||
if (!isset(self::DOT_SEGMENTS[$segment])) {
|
||||
$carry[] = $segment;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an URI path and query component.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
* @param Psr7UriInterface|UriInterface $base_uri
|
||||
*
|
||||
* @return array{0:string, 1:string|null}
|
||||
*/
|
||||
private static function resolvePathAndQuery($uri, $base_uri): array
|
||||
{
|
||||
$target_path = $uri->getPath();
|
||||
$target_query = $uri->getQuery();
|
||||
$null = $uri instanceof Psr7UriInterface ? '' : null;
|
||||
$baseNull = $base_uri instanceof Psr7UriInterface ? '' : null;
|
||||
|
||||
if (0 === strpos($target_path, '/')) {
|
||||
return [$target_path, $target_query];
|
||||
}
|
||||
|
||||
if ('' === $target_path) {
|
||||
if ($null === $target_query) {
|
||||
$target_query = $base_uri->getQuery();
|
||||
}
|
||||
|
||||
$target_path = $base_uri->getPath();
|
||||
//@codeCoverageIgnoreStart
|
||||
//because some PSR-7 Uri implementations allow this RFC3986 forbidden construction
|
||||
if ($baseNull !== $base_uri->getAuthority() && 0 !== strpos($target_path, '/')) {
|
||||
$target_path = '/'.$target_path;
|
||||
}
|
||||
//@codeCoverageIgnoreEnd
|
||||
|
||||
return [$target_path, $target_query];
|
||||
}
|
||||
|
||||
$base_path = $base_uri->getPath();
|
||||
if ($baseNull !== $base_uri->getAuthority() && '' === $base_path) {
|
||||
$target_path = '/'.$target_path;
|
||||
}
|
||||
|
||||
if ('' !== $base_path) {
|
||||
$segments = explode('/', $base_path);
|
||||
array_pop($segments);
|
||||
if ([] !== $segments) {
|
||||
$target_path = implode('/', $segments).'/'.$target_path;
|
||||
}
|
||||
}
|
||||
|
||||
return [$target_path, $target_query];
|
||||
}
|
||||
|
||||
/**
|
||||
* Relativize an URI according to a base URI.
|
||||
*
|
||||
* This method MUST retain the state of the submitted URI instance, and return
|
||||
* an URI instance of the same type that contains the applied modifications.
|
||||
*
|
||||
* This method MUST be transparent when dealing with error and exceptions.
|
||||
* It MUST not alter of silence them apart from validating its own parameters.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
* @param Psr7UriInterface|UriInterface $base_uri
|
||||
*
|
||||
* @return Psr7UriInterface|UriInterface
|
||||
*/
|
||||
public static function relativize($uri, $base_uri)
|
||||
{
|
||||
self::filterUri($uri);
|
||||
self::filterUri($base_uri);
|
||||
$uri = self::formatHost($uri);
|
||||
$base_uri = self::formatHost($base_uri);
|
||||
if (!self::isRelativizable($uri, $base_uri)) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
$null = $uri instanceof Psr7UriInterface ? '' : null;
|
||||
$uri = $uri->withScheme($null)->withPort(null)->withUserInfo($null)->withHost($null);
|
||||
$target_path = $uri->getPath();
|
||||
if ($target_path !== $base_uri->getPath()) {
|
||||
return $uri->withPath(self::relativizePath($target_path, $base_uri->getPath()));
|
||||
}
|
||||
|
||||
if (self::componentEquals('getQuery', $uri, $base_uri)) {
|
||||
return $uri->withPath('')->withQuery($null);
|
||||
}
|
||||
|
||||
if ($null === $uri->getQuery()) {
|
||||
return $uri->withPath(self::formatPathWithEmptyBaseQuery($target_path));
|
||||
}
|
||||
|
||||
return $uri->withPath('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the component value from both URI object equals.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
* @param Psr7UriInterface|UriInterface $base_uri
|
||||
*/
|
||||
private static function componentEquals(string $method, $uri, $base_uri): bool
|
||||
{
|
||||
return self::getComponent($method, $uri) === self::getComponent($method, $base_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component value from the submitted URI object.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
*/
|
||||
private static function getComponent(string $method, $uri): ?string
|
||||
{
|
||||
$component = $uri->$method();
|
||||
if ($uri instanceof Psr7UriInterface && '' === $component) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the URI object.
|
||||
*
|
||||
* @param null|mixed $uri
|
||||
*
|
||||
* @throws \TypeError if the URI object does not implements the supported interfaces.
|
||||
*
|
||||
* @return Psr7UriInterface|UriInterface
|
||||
*/
|
||||
private static function formatHost($uri)
|
||||
{
|
||||
if (!$uri instanceof Psr7UriInterface) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
$host = $uri->getHost();
|
||||
if ('' === $host) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
return $uri->withHost((string) Uri::createFromComponents(['host' => $host])->getHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the submitted URI object can be relativize.
|
||||
*
|
||||
* @param Psr7UriInterface|UriInterface $uri
|
||||
* @param Psr7UriInterface|UriInterface $base_uri
|
||||
*/
|
||||
private static function isRelativizable($uri, $base_uri): bool
|
||||
{
|
||||
return !UriInfo::isRelativePath($uri)
|
||||
&& self::componentEquals('getScheme', $uri, $base_uri)
|
||||
&& self::componentEquals('getAuthority', $uri, $base_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Relative the URI for a authority-less target URI.
|
||||
*/
|
||||
private static function relativizePath(string $path, string $basepath): string
|
||||
{
|
||||
$base_segments = self::getSegments($basepath);
|
||||
$target_segments = self::getSegments($path);
|
||||
$target_basename = array_pop($target_segments);
|
||||
array_pop($base_segments);
|
||||
foreach ($base_segments as $offset => $segment) {
|
||||
if (!isset($target_segments[$offset]) || $segment !== $target_segments[$offset]) {
|
||||
break;
|
||||
}
|
||||
unset($base_segments[$offset], $target_segments[$offset]);
|
||||
}
|
||||
$target_segments[] = $target_basename;
|
||||
|
||||
return self::formatPath(
|
||||
str_repeat('../', count($base_segments)).implode('/', $target_segments),
|
||||
$basepath
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the path segments.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private static function getSegments(string $path): array
|
||||
{
|
||||
if ('' !== $path && '/' === $path[0]) {
|
||||
$path = substr($path, 1);
|
||||
}
|
||||
|
||||
return explode('/', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting the path to keep a valid URI.
|
||||
*/
|
||||
private static function formatPath(string $path, string $basepath): string
|
||||
{
|
||||
if ('' === $path) {
|
||||
return in_array($basepath, ['', '/'], true) ? $basepath : './';
|
||||
}
|
||||
|
||||
if (false === ($colon_pos = strpos($path, ':'))) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$slash_pos = strpos($path, '/');
|
||||
if (false === $slash_pos || $colon_pos < $slash_pos) {
|
||||
return "./$path";
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatting the path to keep a resolvable URI.
|
||||
*/
|
||||
private static function formatPathWithEmptyBaseQuery(string $path): string
|
||||
{
|
||||
$target_segments = self::getSegments($path);
|
||||
/** @var string $basename */
|
||||
$basename = end($target_segments);
|
||||
|
||||
return '' === $basename ? './' : $basename;
|
||||
}
|
||||
}
|
567
admin/phpMyAdmin/vendor/league/uri/src/UriString.php
vendored
567
admin/phpMyAdmin/vendor/league/uri/src/UriString.php
vendored
|
@ -1,567 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri;
|
||||
|
||||
use League\Uri\Exceptions\IdnSupportMissing;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use function array_merge;
|
||||
use function defined;
|
||||
use function explode;
|
||||
use function filter_var;
|
||||
use function function_exists;
|
||||
use function gettype;
|
||||
use function idn_to_ascii;
|
||||
use function implode;
|
||||
use function inet_pton;
|
||||
use function is_object;
|
||||
use function is_scalar;
|
||||
use function method_exists;
|
||||
use function preg_match;
|
||||
use function rawurldecode;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
use const FILTER_FLAG_IPV6;
|
||||
use const FILTER_VALIDATE_IP;
|
||||
use const IDNA_ERROR_BIDI;
|
||||
use const IDNA_ERROR_CONTEXTJ;
|
||||
use const IDNA_ERROR_DISALLOWED;
|
||||
use const IDNA_ERROR_DOMAIN_NAME_TOO_LONG;
|
||||
use const IDNA_ERROR_EMPTY_LABEL;
|
||||
use const IDNA_ERROR_HYPHEN_3_4;
|
||||
use const IDNA_ERROR_INVALID_ACE_LABEL;
|
||||
use const IDNA_ERROR_LABEL_HAS_DOT;
|
||||
use const IDNA_ERROR_LABEL_TOO_LONG;
|
||||
use const IDNA_ERROR_LEADING_COMBINING_MARK;
|
||||
use const IDNA_ERROR_LEADING_HYPHEN;
|
||||
use const IDNA_ERROR_PUNYCODE;
|
||||
use const IDNA_ERROR_TRAILING_HYPHEN;
|
||||
use const INTL_IDNA_VARIANT_UTS46;
|
||||
|
||||
/**
|
||||
* A class to parse a URI string according to RFC3986.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986
|
||||
* @package League\Uri
|
||||
* @author Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
* @since 6.0.0
|
||||
*/
|
||||
final class UriString
|
||||
{
|
||||
/**
|
||||
* Default URI component values.
|
||||
*/
|
||||
private const URI_COMPONENTS = [
|
||||
'scheme' => null, 'user' => null, 'pass' => null, 'host' => null,
|
||||
'port' => null, 'path' => '', 'query' => null, 'fragment' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Simple URI which do not need any parsing.
|
||||
*/
|
||||
private const URI_SCHORTCUTS = [
|
||||
'' => [],
|
||||
'#' => ['fragment' => ''],
|
||||
'?' => ['query' => ''],
|
||||
'?#' => ['query' => '', 'fragment' => ''],
|
||||
'/' => ['path' => '/'],
|
||||
'//' => ['host' => ''],
|
||||
];
|
||||
|
||||
/**
|
||||
* Range of invalid characters in URI string.
|
||||
*/
|
||||
private const REGEXP_INVALID_URI_CHARS = '/[\x00-\x1f\x7f]/';
|
||||
|
||||
/**
|
||||
* RFC3986 regular expression URI splitter.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#appendix-B
|
||||
*/
|
||||
private const REGEXP_URI_PARTS = ',^
|
||||
(?<scheme>(?<scontent>[^:/?\#]+):)? # URI scheme component
|
||||
(?<authority>//(?<acontent>[^/?\#]*))? # URI authority part
|
||||
(?<path>[^?\#]*) # URI path component
|
||||
(?<query>\?(?<qcontent>[^\#]*))? # URI query component
|
||||
(?<fragment>\#(?<fcontent>.*))? # URI fragment component
|
||||
,x';
|
||||
|
||||
/**
|
||||
* URI scheme regular expresssion.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.1
|
||||
*/
|
||||
private const REGEXP_URI_SCHEME = '/^([a-z][a-z\d\+\.\-]*)?$/i';
|
||||
|
||||
/**
|
||||
* IPvFuture regular expression.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*/
|
||||
private const REGEXP_IP_FUTURE = '/^
|
||||
v(?<version>[A-F0-9])+\.
|
||||
(?:
|
||||
(?<unreserved>[a-z0-9_~\-\.])|
|
||||
(?<sub_delims>[!$&\'()*+,;=:]) # also include the : character
|
||||
)+
|
||||
$/ix';
|
||||
|
||||
/**
|
||||
* General registered name regular expression.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*/
|
||||
private const REGEXP_REGISTERED_NAME = '/(?(DEFINE)
|
||||
(?<unreserved>[a-z0-9_~\-]) # . is missing as it is used to separate labels
|
||||
(?<sub_delims>[!$&\'()*+,;=])
|
||||
(?<encoded>%[A-F0-9]{2})
|
||||
(?<reg_name>(?:(?&unreserved)|(?&sub_delims)|(?&encoded))*)
|
||||
)
|
||||
^(?:(?®_name)\.)*(?®_name)\.?$/ix';
|
||||
|
||||
/**
|
||||
* Invalid characters in host regular expression.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*/
|
||||
private const REGEXP_INVALID_HOST_CHARS = '/
|
||||
[:\/?#\[\]@ ] # gen-delims characters as well as the space character
|
||||
/ix';
|
||||
|
||||
/**
|
||||
* Invalid path for URI without scheme and authority regular expression.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.3
|
||||
*/
|
||||
private const REGEXP_INVALID_PATH = ',^(([^/]*):)(.*)?/,';
|
||||
|
||||
/**
|
||||
* Host and Port splitter regular expression.
|
||||
*/
|
||||
private const REGEXP_HOST_PORT = ',^(?<host>\[.*\]|[^:]*)(:(?<port>.*))?$,';
|
||||
|
||||
/**
|
||||
* IDN Host detector regular expression.
|
||||
*/
|
||||
private const REGEXP_IDN_PATTERN = '/[^\x20-\x7f]/';
|
||||
|
||||
/**
|
||||
* Only the address block fe80::/10 can have a Zone ID attach to
|
||||
* let's detect the link local significant 10 bits.
|
||||
*/
|
||||
private const ZONE_ID_ADDRESS_BLOCK = "\xfe\x80";
|
||||
|
||||
/**
|
||||
* Generate an URI string representation from its parsed representation
|
||||
* returned by League\Uri\parse() or PHP's parse_url.
|
||||
*
|
||||
* If you supply your own array, you are responsible for providing
|
||||
* valid components without their URI delimiters.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-5.3
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-7.5
|
||||
*
|
||||
* @param array{
|
||||
* scheme:?string,
|
||||
* user:?string,
|
||||
* pass:?string,
|
||||
* host:?string,
|
||||
* port:?int,
|
||||
* path:string,
|
||||
* query:?string,
|
||||
* fragment:?string
|
||||
* } $components
|
||||
*/
|
||||
public static function build(array $components): string
|
||||
{
|
||||
$result = $components['path'] ?? '';
|
||||
if (isset($components['query'])) {
|
||||
$result .= '?'.$components['query'];
|
||||
}
|
||||
|
||||
if (isset($components['fragment'])) {
|
||||
$result .= '#'.$components['fragment'];
|
||||
}
|
||||
|
||||
$scheme = null;
|
||||
if (isset($components['scheme'])) {
|
||||
$scheme = $components['scheme'].':';
|
||||
}
|
||||
|
||||
if (!isset($components['host'])) {
|
||||
return $scheme.$result;
|
||||
}
|
||||
|
||||
$scheme .= '//';
|
||||
$authority = $components['host'];
|
||||
if (isset($components['port'])) {
|
||||
$authority .= ':'.$components['port'];
|
||||
}
|
||||
|
||||
if (!isset($components['user'])) {
|
||||
return $scheme.$authority.$result;
|
||||
}
|
||||
|
||||
$authority = '@'.$authority;
|
||||
if (!isset($components['pass'])) {
|
||||
return $scheme.$components['user'].$authority.$result;
|
||||
}
|
||||
|
||||
return $scheme.$components['user'].':'.$components['pass'].$authority.$result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an URI string into its components.
|
||||
*
|
||||
* This method parses a URI and returns an associative array containing any
|
||||
* of the various components of the URI that are present.
|
||||
*
|
||||
* <code>
|
||||
* $components = (new Parser())->parse('http://foo@test.example.com:42?query#');
|
||||
* var_export($components);
|
||||
* //will display
|
||||
* array(
|
||||
* 'scheme' => 'http', // the URI scheme component
|
||||
* 'user' => 'foo', // the URI user component
|
||||
* 'pass' => null, // the URI pass component
|
||||
* 'host' => 'test.example.com', // the URI host component
|
||||
* 'port' => 42, // the URI port component
|
||||
* 'path' => '', // the URI path component
|
||||
* 'query' => 'query', // the URI query component
|
||||
* 'fragment' => '', // the URI fragment component
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* The returned array is similar to PHP's parse_url return value with the following
|
||||
* differences:
|
||||
*
|
||||
* <ul>
|
||||
* <li>All components are always present in the returned array</li>
|
||||
* <li>Empty and undefined component are treated differently. And empty component is
|
||||
* set to the empty string while an undefined component is set to the `null` value.</li>
|
||||
* <li>The path component is never undefined</li>
|
||||
* <li>The method parses the URI following the RFC3986 rules but you are still
|
||||
* required to validate the returned components against its related scheme specific rules.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986
|
||||
*
|
||||
* @param mixed $uri any scalar or stringable object
|
||||
*
|
||||
* @throws SyntaxError if the URI contains invalid characters
|
||||
* @throws SyntaxError if the URI contains an invalid scheme
|
||||
* @throws SyntaxError if the URI contains an invalid path
|
||||
*
|
||||
* @return array{
|
||||
* scheme:?string,
|
||||
* user:?string,
|
||||
* pass:?string,
|
||||
* host:?string,
|
||||
* port:?int,
|
||||
* path:string,
|
||||
* query:?string,
|
||||
* fragment:?string
|
||||
* }
|
||||
*/
|
||||
public static function parse($uri): array
|
||||
{
|
||||
if (is_object($uri) && method_exists($uri, '__toString')) {
|
||||
$uri = (string) $uri;
|
||||
}
|
||||
|
||||
if (!is_scalar($uri)) {
|
||||
throw new \TypeError(sprintf('The uri must be a scalar or a stringable object `%s` given', gettype($uri)));
|
||||
}
|
||||
|
||||
$uri = (string) $uri;
|
||||
|
||||
if (isset(self::URI_SCHORTCUTS[$uri])) {
|
||||
/** @var array{scheme:?string, user:?string, pass:?string, host:?string, port:?int, path:string, query:?string, fragment:?string} $components */
|
||||
$components = array_merge(self::URI_COMPONENTS, self::URI_SCHORTCUTS[$uri]);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
if (1 === preg_match(self::REGEXP_INVALID_URI_CHARS, $uri)) {
|
||||
throw new SyntaxError(sprintf('The uri `%s` contains invalid characters', $uri));
|
||||
}
|
||||
|
||||
//if the first character is a known URI delimiter parsing can be simplified
|
||||
$first_char = $uri[0];
|
||||
|
||||
//The URI is made of the fragment only
|
||||
if ('#' === $first_char) {
|
||||
[, $fragment] = explode('#', $uri, 2);
|
||||
$components = self::URI_COMPONENTS;
|
||||
$components['fragment'] = $fragment;
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
//The URI is made of the query and fragment
|
||||
if ('?' === $first_char) {
|
||||
[, $partial] = explode('?', $uri, 2);
|
||||
[$query, $fragment] = explode('#', $partial, 2) + [1 => null];
|
||||
$components = self::URI_COMPONENTS;
|
||||
$components['query'] = $query;
|
||||
$components['fragment'] = $fragment;
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
//use RFC3986 URI regexp to split the URI
|
||||
preg_match(self::REGEXP_URI_PARTS, $uri, $parts);
|
||||
$parts += ['query' => '', 'fragment' => ''];
|
||||
|
||||
if (':' === $parts['scheme'] || 1 !== preg_match(self::REGEXP_URI_SCHEME, $parts['scontent'])) {
|
||||
throw new SyntaxError(sprintf('The uri `%s` contains an invalid scheme', $uri));
|
||||
}
|
||||
|
||||
if ('' === $parts['scheme'].$parts['authority'] && 1 === preg_match(self::REGEXP_INVALID_PATH, $parts['path'])) {
|
||||
throw new SyntaxError(sprintf('The uri `%s` contains an invalid path.', $uri));
|
||||
}
|
||||
|
||||
/** @var array{scheme:?string, user:?string, pass:?string, host:?string, port:?int, path:string, query:?string, fragment:?string} $components */
|
||||
$components = array_merge(
|
||||
self::URI_COMPONENTS,
|
||||
'' === $parts['authority'] ? [] : self::parseAuthority($parts['acontent']),
|
||||
[
|
||||
'path' => $parts['path'],
|
||||
'scheme' => '' === $parts['scheme'] ? null : $parts['scontent'],
|
||||
'query' => '' === $parts['query'] ? null : $parts['qcontent'],
|
||||
'fragment' => '' === $parts['fragment'] ? null : $parts['fcontent'],
|
||||
]
|
||||
);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the URI authority part.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2
|
||||
*
|
||||
* @throws SyntaxError If the port component is invalid
|
||||
*
|
||||
* @return array{user:?string, pass:?string, host:?string, port:?int}
|
||||
*/
|
||||
private static function parseAuthority(string $authority): array
|
||||
{
|
||||
$components = ['user' => null, 'pass' => null, 'host' => '', 'port' => null];
|
||||
if ('' === $authority) {
|
||||
return $components;
|
||||
}
|
||||
|
||||
$parts = explode('@', $authority, 2);
|
||||
if (isset($parts[1])) {
|
||||
[$components['user'], $components['pass']] = explode(':', $parts[0], 2) + [1 => null];
|
||||
}
|
||||
|
||||
preg_match(self::REGEXP_HOST_PORT, $parts[1] ?? $parts[0], $matches);
|
||||
$matches += ['port' => ''];
|
||||
|
||||
$components['port'] = self::filterPort($matches['port']);
|
||||
$components['host'] = self::filterHost($matches['host']);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter and format the port component.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*
|
||||
* @throws SyntaxError if the registered name is invalid
|
||||
*/
|
||||
private static function filterPort(string $port): ?int
|
||||
{
|
||||
if ('' === $port) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (1 === preg_match('/^\d*$/', $port)) {
|
||||
return (int) $port;
|
||||
}
|
||||
|
||||
throw new SyntaxError(sprintf('The port `%s` is invalid', $port));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a hostname is valid.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*
|
||||
* @throws SyntaxError if the registered name is invalid
|
||||
*/
|
||||
private static function filterHost(string $host): string
|
||||
{
|
||||
if ('' === $host) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
if ('[' !== $host[0] || ']' !== substr($host, -1)) {
|
||||
return self::filterRegisteredName($host);
|
||||
}
|
||||
|
||||
if (!self::isIpHost(substr($host, 1, -1))) {
|
||||
throw new SyntaxError(sprintf('Host `%s` is invalid : the IP host is malformed', $host));
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the host is an IPv4 or a registered named.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
*
|
||||
* @throws SyntaxError if the registered name is invalid
|
||||
* @throws IdnSupportMissing if IDN support or ICU requirement are not available or met.
|
||||
*/
|
||||
private static function filterRegisteredName(string $host): string
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
// added because it is not possible in travis to disabled the ext/intl extension
|
||||
// see travis issue https://github.com/travis-ci/travis-ci/issues/4701
|
||||
static $idn_support = null;
|
||||
$idn_support = $idn_support ?? function_exists('idn_to_ascii') && defined('INTL_IDNA_VARIANT_UTS46');
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$formatted_host = rawurldecode($host);
|
||||
if (1 === preg_match(self::REGEXP_REGISTERED_NAME, $formatted_host)) {
|
||||
if (false === strpos($formatted_host, 'xn--')) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!$idn_support) {
|
||||
throw new IdnSupportMissing(sprintf('the host `%s` could not be processed for IDN. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.', $host));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$unicode = idn_to_utf8($host, 0, INTL_IDNA_VARIANT_UTS46, $arr);
|
||||
if (0 !== $arr['errors']) {
|
||||
throw new SyntaxError(sprintf('The host `%s` is invalid : %s', $host, self::getIDNAErrors($arr['errors'])));
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (false === $unicode) {
|
||||
throw new IdnSupportMissing(sprintf('The Intl extension is misconfigured for %s, please correct this issue before proceeding.', PHP_OS));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
//to test IDN host non-ascii characters must be present in the host
|
||||
if (1 !== preg_match(self::REGEXP_IDN_PATTERN, $formatted_host)) {
|
||||
throw new SyntaxError(sprintf('Host `%s` is invalid : the host is not a valid registered name', $host));
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!$idn_support) {
|
||||
throw new IdnSupportMissing(sprintf('the host `%s` could not be processed for IDN. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.', $host));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$retval = idn_to_ascii($formatted_host, 0, INTL_IDNA_VARIANT_UTS46, $arr);
|
||||
|
||||
if ([] === $arr) {
|
||||
throw new SyntaxError(sprintf('Host `%s` is not a valid IDN host', $host));
|
||||
}
|
||||
|
||||
if (0 !== $arr['errors']) {
|
||||
throw new SyntaxError(sprintf('Host `%s` is not a valid IDN host : %s', $host, self::getIDNAErrors($arr['errors'])));
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (false === $retval) {
|
||||
throw new IdnSupportMissing(sprintf('The Intl extension is misconfigured for %s, please correct this issue before proceeding.', PHP_OS));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
if (false !== strpos($retval, '%')) {
|
||||
throw new SyntaxError(sprintf('Host `%s` is invalid : the host is not a valid registered name', $host));
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and format IDNA conversion error message.
|
||||
*
|
||||
* @link http://icu-project.org/apiref/icu4j/com/ibm/icu/text/IDNA.Error.html
|
||||
*/
|
||||
private static function getIDNAErrors(int $error_byte): string
|
||||
{
|
||||
/**
|
||||
* IDNA errors.
|
||||
*/
|
||||
static $idn_errors = [
|
||||
IDNA_ERROR_EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty',
|
||||
IDNA_ERROR_LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes',
|
||||
IDNA_ERROR_DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form',
|
||||
IDNA_ERROR_LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")',
|
||||
IDNA_ERROR_TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")',
|
||||
IDNA_ERROR_HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions',
|
||||
IDNA_ERROR_LEADING_COMBINING_MARK => 'a label starts with a combining mark',
|
||||
IDNA_ERROR_DISALLOWED => 'a label or domain name contains disallowed characters',
|
||||
IDNA_ERROR_PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode',
|
||||
IDNA_ERROR_LABEL_HAS_DOT => 'a label contains a dot=full stop',
|
||||
IDNA_ERROR_INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string',
|
||||
IDNA_ERROR_BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)',
|
||||
IDNA_ERROR_CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements',
|
||||
];
|
||||
|
||||
$res = [];
|
||||
foreach ($idn_errors as $error => $reason) {
|
||||
if ($error === ($error_byte & $error)) {
|
||||
$res[] = $reason;
|
||||
}
|
||||
}
|
||||
|
||||
return [] === $res ? 'Unknown IDNA conversion error.' : implode(', ', $res).'.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a IPv6/IPvfuture host.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
* @link https://tools.ietf.org/html/rfc6874#section-2
|
||||
* @link https://tools.ietf.org/html/rfc6874#section-4
|
||||
*/
|
||||
private static function isIpHost(string $ip_host): bool
|
||||
{
|
||||
if (false !== filter_var($ip_host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (1 === preg_match(self::REGEXP_IP_FUTURE, $ip_host, $matches)) {
|
||||
return !in_array($matches['version'], ['4', '6'], true);
|
||||
}
|
||||
|
||||
$pos = strpos($ip_host, '%');
|
||||
if (false === $pos || 1 === preg_match(
|
||||
self::REGEXP_INVALID_HOST_CHARS,
|
||||
rawurldecode(substr($ip_host, $pos))
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ip_host = substr($ip_host, 0, $pos);
|
||||
|
||||
return false !== filter_var($ip_host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)
|
||||
&& 0 === strpos((string) inet_pton($ip_host), self::ZONE_ID_ADDRESS_BLOCK);
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri;
|
||||
|
||||
use League\Uri\Contracts\UriException;
|
||||
use League\Uri\Contracts\UriInterface;
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use League\Uri\Exceptions\TemplateCanNotBeExpanded;
|
||||
use League\Uri\UriTemplate\Template;
|
||||
use League\Uri\UriTemplate\VariableBag;
|
||||
|
||||
/**
|
||||
* Defines the URI Template syntax and the process for expanding a URI Template into a URI reference.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6570
|
||||
* @package League\Uri
|
||||
* @author Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
* @since 6.1.0
|
||||
*
|
||||
* Based on GuzzleHttp\UriTemplate class in Guzzle v6.5.
|
||||
* @link https://github.com/guzzle/guzzle/blob/6.5/src/UriTemplate.php
|
||||
*/
|
||||
final class UriTemplate
|
||||
{
|
||||
/**
|
||||
* @var Template
|
||||
*/
|
||||
private $template;
|
||||
|
||||
/**
|
||||
* @var VariableBag
|
||||
*/
|
||||
private $defaultVariables;
|
||||
|
||||
/**
|
||||
* @param object|string $template a string or an object with the __toString method
|
||||
*
|
||||
* @throws \TypeError if the template is not a string or an object with the __toString method
|
||||
* @throws SyntaxError if the template syntax is invalid
|
||||
* @throws TemplateCanNotBeExpanded if the template variables are invalid
|
||||
*/
|
||||
public function __construct($template, array $defaultVariables = [])
|
||||
{
|
||||
$this->template = Template::createFromString($template);
|
||||
$this->defaultVariables = $this->filterVariables($defaultVariables);
|
||||
}
|
||||
|
||||
public static function __set_state(array $properties): self
|
||||
{
|
||||
return new self($properties['template']->toString(), $properties['defaultVariables']->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out variables for the given template.
|
||||
*
|
||||
* @param array<string,string|array<string>> $variables
|
||||
*/
|
||||
private function filterVariables(array $variables): VariableBag
|
||||
{
|
||||
$output = new VariableBag();
|
||||
foreach ($this->template->variableNames() as $name) {
|
||||
if (isset($variables[$name])) {
|
||||
$output->assign($name, $variables[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The template string.
|
||||
*/
|
||||
public function getTemplate(): string
|
||||
{
|
||||
return $this->template->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the variables in the template, in order.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getVariableNames(): array
|
||||
{
|
||||
return $this->template->variableNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default values used to expand the template.
|
||||
*
|
||||
* The returned list only contains variables whose name is part of the current template.
|
||||
*
|
||||
* @return array<string,string|array>
|
||||
*/
|
||||
public function getDefaultVariables(): array
|
||||
{
|
||||
return $this->defaultVariables->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance with the updated default variables.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the modified default variables.
|
||||
*
|
||||
* If present, variables whose name is not part of the current template
|
||||
* possible variable names are removed.
|
||||
*/
|
||||
public function withDefaultVariables(array $defaultDefaultVariables): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->defaultVariables = $this->filterVariables($defaultDefaultVariables);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TemplateCanNotBeExpanded if the variable contains nested array values
|
||||
* @throws UriException if the resulting expansion can not be converted to a UriInterface instance
|
||||
*/
|
||||
public function expand(array $variables = []): UriInterface
|
||||
{
|
||||
$uriString = $this->template->expand(
|
||||
$this->filterVariables($variables)->replace($this->defaultVariables)
|
||||
);
|
||||
|
||||
return Uri::createFromString($uriString);
|
||||
}
|
||||
}
|
|
@ -1,353 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\UriTemplate;
|
||||
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use League\Uri\Exceptions\TemplateCanNotBeExpanded;
|
||||
use function array_filter;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_unique;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function preg_match;
|
||||
use function rawurlencode;
|
||||
use function str_replace;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
final class Expression
|
||||
{
|
||||
/**
|
||||
* Expression regular expression pattern.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6570#section-2.2
|
||||
*/
|
||||
private const REGEXP_EXPRESSION = '/^\{
|
||||
(?:
|
||||
(?<operator>[\.\/;\?&\=,\!@\|\+#])?
|
||||
(?<variables>[^\}]*)
|
||||
)
|
||||
\}$/x';
|
||||
|
||||
/**
|
||||
* Reserved Operator characters.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6570#section-2.2
|
||||
*/
|
||||
private const RESERVED_OPERATOR = '=,!@|';
|
||||
|
||||
/**
|
||||
* Processing behavior according to the expression type operator.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6570#appendix-A
|
||||
*/
|
||||
private const OPERATOR_HASH_LOOKUP = [
|
||||
'' => ['prefix' => '', 'joiner' => ',', 'query' => false],
|
||||
'+' => ['prefix' => '', 'joiner' => ',', 'query' => false],
|
||||
'#' => ['prefix' => '#', 'joiner' => ',', 'query' => false],
|
||||
'.' => ['prefix' => '.', 'joiner' => '.', 'query' => false],
|
||||
'/' => ['prefix' => '/', 'joiner' => '/', 'query' => false],
|
||||
';' => ['prefix' => ';', 'joiner' => ';', 'query' => true],
|
||||
'?' => ['prefix' => '?', 'joiner' => '&', 'query' => true],
|
||||
'&' => ['prefix' => '&', 'joiner' => '&', 'query' => true],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $operator;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $joiner;
|
||||
|
||||
/**
|
||||
* @var array<VarSpecifier>
|
||||
*/
|
||||
private $varSpecifiers;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private $variableNames;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $expressionString;
|
||||
|
||||
private function __construct(string $operator, VarSpecifier ...$varSpecifiers)
|
||||
{
|
||||
$this->operator = $operator;
|
||||
$this->varSpecifiers = $varSpecifiers;
|
||||
$this->joiner = self::OPERATOR_HASH_LOOKUP[$operator]['joiner'];
|
||||
$this->variableNames = $this->setVariableNames();
|
||||
$this->expressionString = $this->setExpressionString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
private function setVariableNames(): array
|
||||
{
|
||||
$mapper = static function (VarSpecifier $varSpecifier): string {
|
||||
return $varSpecifier->name();
|
||||
};
|
||||
|
||||
return array_unique(array_map($mapper, $this->varSpecifiers));
|
||||
}
|
||||
|
||||
private function setExpressionString(): string
|
||||
{
|
||||
$mapper = static function (VarSpecifier $variable): string {
|
||||
return $variable->toString();
|
||||
};
|
||||
|
||||
$varSpecifierString = implode(',', array_map($mapper, $this->varSpecifiers));
|
||||
|
||||
return '{'.$this->operator.$varSpecifierString.'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function __set_state(array $properties): self
|
||||
{
|
||||
return new self($properties['operator'], ...$properties['varSpecifiers']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SyntaxError if the expression is invalid
|
||||
* @throws SyntaxError if the operator used in the expression is invalid
|
||||
* @throws SyntaxError if the variable specifiers is invalid
|
||||
*/
|
||||
public static function createFromString(string $expression): self
|
||||
{
|
||||
if (1 !== preg_match(self::REGEXP_EXPRESSION, $expression, $parts)) {
|
||||
throw new SyntaxError('The expression "'.$expression.'" is invalid.');
|
||||
}
|
||||
|
||||
/** @var array{operator:string, variables:string} $parts */
|
||||
$parts = $parts + ['operator' => ''];
|
||||
if ('' !== $parts['operator'] && false !== strpos(self::RESERVED_OPERATOR, $parts['operator'])) {
|
||||
throw new SyntaxError('The operator used in the expression "'.$expression.'" is reserved.');
|
||||
}
|
||||
|
||||
$mapper = static function (string $varSpec): VarSpecifier {
|
||||
return VarSpecifier::createFromString($varSpec);
|
||||
};
|
||||
|
||||
return new Expression($parts['operator'], ...array_map($mapper, explode(',', $parts['variables'])));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expression string representation.
|
||||
*
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->expressionString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
public function variableNames(): array
|
||||
{
|
||||
return $this->variableNames;
|
||||
}
|
||||
|
||||
public function expand(VariableBag $variables): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($this->varSpecifiers as $varSpecifier) {
|
||||
$parts[] = $this->replace($varSpecifier, $variables);
|
||||
}
|
||||
|
||||
$nullFilter = static function ($value): bool {
|
||||
return '' !== $value;
|
||||
};
|
||||
|
||||
$expanded = implode($this->joiner, array_filter($parts, $nullFilter));
|
||||
if ('' === $expanded) {
|
||||
return $expanded;
|
||||
}
|
||||
|
||||
$prefix = self::OPERATOR_HASH_LOOKUP[$this->operator]['prefix'];
|
||||
if ('' === $prefix) {
|
||||
return $expanded;
|
||||
}
|
||||
|
||||
return $prefix.$expanded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an expression with the given variables.
|
||||
*
|
||||
* @throws TemplateCanNotBeExpanded if the variables is an array and a ":" modifier needs to be applied
|
||||
* @throws TemplateCanNotBeExpanded if the variables contains nested array values
|
||||
*/
|
||||
private function replace(VarSpecifier $varSpec, VariableBag $variables): string
|
||||
{
|
||||
$value = $variables->fetch($varSpec->name());
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$useQuery = self::OPERATOR_HASH_LOOKUP[$this->operator]['query'];
|
||||
[$expanded, $actualQuery] = $this->inject($value, $varSpec, $useQuery);
|
||||
if (!$actualQuery) {
|
||||
return $expanded;
|
||||
}
|
||||
|
||||
if ('&' !== $this->joiner && '' === $expanded) {
|
||||
return $varSpec->name();
|
||||
}
|
||||
|
||||
return $varSpec->name().'='.$expanded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array<string> $value
|
||||
*
|
||||
* @return array{0:string, 1:bool}
|
||||
*/
|
||||
private function inject($value, VarSpecifier $varSpec, bool $useQuery): array
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return $this->replaceString($value, $varSpec, $useQuery);
|
||||
}
|
||||
|
||||
return $this->replaceList($value, $varSpec, $useQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands an expression using a string value.
|
||||
*
|
||||
* @return array{0:string, 1:bool}
|
||||
*/
|
||||
private function replaceString(string $value, VarSpecifier $varSpec, bool $useQuery): array
|
||||
{
|
||||
if (':' === $varSpec->modifier()) {
|
||||
$value = substr($value, 0, $varSpec->position());
|
||||
}
|
||||
|
||||
$expanded = rawurlencode($value);
|
||||
if ('+' === $this->operator || '#' === $this->operator) {
|
||||
return [$this->decodeReserved($expanded), $useQuery];
|
||||
}
|
||||
|
||||
return [$expanded, $useQuery];
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands an expression using a list of values.
|
||||
*
|
||||
* @param array<string> $value
|
||||
*
|
||||
* @throws TemplateCanNotBeExpanded if the variables is an array and a ":" modifier needs to be applied
|
||||
*
|
||||
* @return array{0:string, 1:bool}
|
||||
*/
|
||||
private function replaceList(array $value, VarSpecifier $varSpec, bool $useQuery): array
|
||||
{
|
||||
if ([] === $value) {
|
||||
return ['', false];
|
||||
}
|
||||
|
||||
if (':' === $varSpec->modifier()) {
|
||||
throw TemplateCanNotBeExpanded::dueToUnableToProcessValueListWithPrefix($varSpec->name());
|
||||
}
|
||||
|
||||
$pairs = [];
|
||||
$isAssoc = $this->isAssoc($value);
|
||||
foreach ($value as $key => $var) {
|
||||
if ($isAssoc) {
|
||||
$key = rawurlencode((string) $key);
|
||||
}
|
||||
|
||||
$var = rawurlencode($var);
|
||||
if ('+' === $this->operator || '#' === $this->operator) {
|
||||
$var = $this->decodeReserved($var);
|
||||
}
|
||||
|
||||
if ('*' === $varSpec->modifier()) {
|
||||
if ($isAssoc) {
|
||||
$var = $key.'='.$var;
|
||||
} elseif ($key > 0 && $useQuery) {
|
||||
$var = $varSpec->name().'='.$var;
|
||||
}
|
||||
}
|
||||
|
||||
$pairs[$key] = $var;
|
||||
}
|
||||
|
||||
if ('*' === $varSpec->modifier()) {
|
||||
if ($isAssoc) {
|
||||
// Don't prepend the value name when using the explode
|
||||
// modifier with an associative array.
|
||||
$useQuery = false;
|
||||
}
|
||||
|
||||
return [implode($this->joiner, $pairs), $useQuery];
|
||||
}
|
||||
|
||||
if ($isAssoc) {
|
||||
// When an associative array is encountered and the
|
||||
// explode modifier is not set, then the result must be
|
||||
// a comma separated list of keys followed by their
|
||||
// respective values.
|
||||
foreach ($pairs as $offset => &$data) {
|
||||
$data = $offset.','.$data;
|
||||
}
|
||||
|
||||
unset($data);
|
||||
}
|
||||
|
||||
return [implode(',', $pairs), $useQuery];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an array is associative.
|
||||
*
|
||||
* This makes the assumption that input arrays are sequences or hashes.
|
||||
* This assumption is a trade-off for accuracy in favor of speed, but it
|
||||
* should work in almost every case where input is supplied for a URI
|
||||
* template.
|
||||
*/
|
||||
private function isAssoc(array $array): bool
|
||||
{
|
||||
return [] !== $array && 0 !== array_keys($array)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes percent encoding on reserved characters (used with + and # modifiers).
|
||||
*/
|
||||
private function decodeReserved(string $str): string
|
||||
{
|
||||
static $delimiters = [
|
||||
':', '/', '?', '#', '[', ']', '@', '!', '$',
|
||||
'&', '\'', '(', ')', '*', '+', ',', ';', '=',
|
||||
];
|
||||
|
||||
static $delimitersEncoded = [
|
||||
'%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40', '%21', '%24',
|
||||
'%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D',
|
||||
];
|
||||
|
||||
return str_replace($delimitersEncoded, $delimiters, $str);
|
||||
}
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\UriTemplate;
|
||||
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use League\Uri\Exceptions\TemplateCanNotBeExpanded;
|
||||
use function array_merge;
|
||||
use function array_unique;
|
||||
use function gettype;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function method_exists;
|
||||
use function preg_match_all;
|
||||
use function preg_replace;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use const PREG_SET_ORDER;
|
||||
|
||||
final class Template
|
||||
{
|
||||
/**
|
||||
* Expression regular expression pattern.
|
||||
*/
|
||||
private const REGEXP_EXPRESSION_DETECTOR = '/\{[^\}]*\}/x';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $template;
|
||||
|
||||
/**
|
||||
* @var array<string, Expression>
|
||||
*/
|
||||
private $expressions = [];
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private $variableNames;
|
||||
|
||||
private function __construct(string $template, Expression ...$expressions)
|
||||
{
|
||||
$this->template = $template;
|
||||
$variableNames = [];
|
||||
foreach ($expressions as $expression) {
|
||||
$this->expressions[$expression->toString()] = $expression;
|
||||
$variableNames[] = $expression->variableNames();
|
||||
}
|
||||
$this->variableNames = array_unique(array_merge([], ...$variableNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function __set_state(array $properties): self
|
||||
{
|
||||
return new self($properties['template'], ...array_values($properties['expressions']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object|string $template a string or an object with the __toString method
|
||||
*
|
||||
* @throws \TypeError if the template is not a string or an object with the __toString method
|
||||
* @throws SyntaxError if the template contains invalid expressions
|
||||
* @throws SyntaxError if the template contains invalid variable specification
|
||||
*/
|
||||
public static function createFromString($template): self
|
||||
{
|
||||
if (is_object($template) && method_exists($template, '__toString')) {
|
||||
$template = (string) $template;
|
||||
}
|
||||
|
||||
if (!is_string($template)) {
|
||||
throw new \TypeError(sprintf('The template must be a string or a stringable object %s given.', gettype($template)));
|
||||
}
|
||||
|
||||
/** @var string $remainder */
|
||||
$remainder = preg_replace(self::REGEXP_EXPRESSION_DETECTOR, '', $template);
|
||||
if (false !== strpos($remainder, '{') || false !== strpos($remainder, '}')) {
|
||||
throw new SyntaxError('The template "'.$template.'" contains invalid expressions.');
|
||||
}
|
||||
|
||||
$names = [];
|
||||
preg_match_all(self::REGEXP_EXPRESSION_DETECTOR, $template, $findings, PREG_SET_ORDER);
|
||||
$arguments = [];
|
||||
foreach ($findings as $finding) {
|
||||
if (!isset($names[$finding[0]])) {
|
||||
$arguments[] = Expression::createFromString($finding[0]);
|
||||
$names[$finding[0]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new self($template, ...$arguments);
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
public function variableNames(): array
|
||||
{
|
||||
return $this->variableNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TemplateCanNotBeExpanded if the variables is an array and a ":" modifier needs to be applied
|
||||
* @throws TemplateCanNotBeExpanded if the variables contains nested array values
|
||||
*/
|
||||
public function expand(VariableBag $variables): string
|
||||
{
|
||||
$uriString = $this->template;
|
||||
/** @var Expression $expression */
|
||||
foreach ($this->expressions as $pattern => $expression) {
|
||||
$uriString = str_replace($pattern, $expression->expand($variables), $uriString);
|
||||
}
|
||||
|
||||
return $uriString;
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\UriTemplate;
|
||||
|
||||
use League\Uri\Exceptions\SyntaxError;
|
||||
use function preg_match;
|
||||
|
||||
final class VarSpecifier
|
||||
{
|
||||
/**
|
||||
* Variables specification regular expression pattern.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6570#section-2.3
|
||||
*/
|
||||
private const REGEXP_VARSPEC = '/^
|
||||
(?<name>(?:[A-z0-9_\.]|%[0-9a-fA-F]{2})+)
|
||||
(?<modifier>\:(?<position>\d+)|\*)?
|
||||
$/x';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $modifier;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $position;
|
||||
|
||||
private function __construct(string $name, string $modifier, int $position)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->modifier = $modifier;
|
||||
$this->position = $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function __set_state(array $properties): self
|
||||
{
|
||||
return new self($properties['name'], $properties['modifier'], $properties['position']);
|
||||
}
|
||||
|
||||
public static function createFromString(string $specification): self
|
||||
{
|
||||
if (1 !== preg_match(self::REGEXP_VARSPEC, $specification, $parsed)) {
|
||||
throw new SyntaxError('The variable specification "'.$specification.'" is invalid.');
|
||||
}
|
||||
|
||||
$parsed += ['modifier' => '', 'position' => ''];
|
||||
if ('' !== $parsed['position']) {
|
||||
$parsed['position'] = (int) $parsed['position'];
|
||||
$parsed['modifier'] = ':';
|
||||
}
|
||||
|
||||
if ('' === $parsed['position']) {
|
||||
$parsed['position'] = 0;
|
||||
}
|
||||
|
||||
if (10000 <= $parsed['position']) {
|
||||
throw new SyntaxError('The variable specification "'.$specification.'" is invalid the position modifier must be lower than 10000.');
|
||||
}
|
||||
|
||||
return new self($parsed['name'], $parsed['modifier'], $parsed['position']);
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
if (0 < $this->position) {
|
||||
return $this->name.$this->modifier.$this->position;
|
||||
}
|
||||
|
||||
return $this->name.$this->modifier;
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function modifier(): string
|
||||
{
|
||||
return $this->modifier;
|
||||
}
|
||||
|
||||
public function position(): int
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* League.Uri (https://uri.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Uri\UriTemplate;
|
||||
|
||||
use League\Uri\Exceptions\TemplateCanNotBeExpanded;
|
||||
use function gettype;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function is_object;
|
||||
use function is_scalar;
|
||||
use function method_exists;
|
||||
use function sprintf;
|
||||
|
||||
final class VariableBag
|
||||
{
|
||||
/**
|
||||
* @var array<string,string|array<string>>
|
||||
*/
|
||||
private $variables = [];
|
||||
|
||||
/**
|
||||
* @param iterable<string,mixed> $variables
|
||||
*/
|
||||
public function __construct(iterable $variables = [])
|
||||
{
|
||||
foreach ($variables as $name => $value) {
|
||||
$this->assign($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public static function __set_state(array $properties): self
|
||||
{
|
||||
return new self($properties['variables']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,string|array<string>>
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the variable value if none found returns null.
|
||||
*
|
||||
* @return null|string|array<string>
|
||||
*/
|
||||
public function fetch(string $name)
|
||||
{
|
||||
return $this->variables[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array<string> $value
|
||||
*/
|
||||
public function assign(string $name, $value): void
|
||||
{
|
||||
$this->variables[$name] = $this->normalizeValue($value, $name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value the value to be expanded
|
||||
*
|
||||
* @throws TemplateCanNotBeExpanded if the value contains nested list
|
||||
*
|
||||
* @return string|array<string>
|
||||
*/
|
||||
private function normalizeValue($value, string $name, bool $isNestedListAllowed)
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
return true === $value ? '1' : '0';
|
||||
}
|
||||
|
||||
if (null === $value || is_scalar($value) || (is_object($value) && method_exists($value, '__toString'))) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
if (!is_array($value)) {
|
||||
throw new \TypeError(sprintf('The variable '.$name.' must be NULL, a scalar or a stringable object `%s` given', gettype($value)));
|
||||
}
|
||||
|
||||
if (!$isNestedListAllowed) {
|
||||
throw TemplateCanNotBeExpanded::dueToNestedListOfValue($name);
|
||||
}
|
||||
|
||||
foreach ($value as &$var) {
|
||||
$var = self::normalizeValue($var, $name, false);
|
||||
}
|
||||
unset($var);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces elements from passed variables into the current instance.
|
||||
*/
|
||||
public function replace(VariableBag $variables): self
|
||||
{
|
||||
$instance = clone $this;
|
||||
$instance->variables += $variables->variables;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue