Update Composer packages
This commit is contained in:
parent
df93324906
commit
45bdef9a3b
378 changed files with 28466 additions and 28852 deletions
|
@ -19,9 +19,8 @@ class Cookie
|
|||
{
|
||||
/**
|
||||
* Key to use for cookie signing
|
||||
* @var string
|
||||
*/
|
||||
public static $key = 'KirbyHttpCookieKey';
|
||||
public static string $key = 'KirbyHttpCookieKey';
|
||||
|
||||
/**
|
||||
* Set a new cookie
|
||||
|
@ -68,19 +67,20 @@ class Cookie
|
|||
* Calculates the lifetime for a cookie
|
||||
*
|
||||
* @param int $minutes Number of minutes or timestamp
|
||||
* @return int
|
||||
*/
|
||||
public static function lifetime(int $minutes): int
|
||||
{
|
||||
if ($minutes > 1000000000) {
|
||||
// absolute timestamp
|
||||
return $minutes;
|
||||
} elseif ($minutes > 0) {
|
||||
}
|
||||
|
||||
if ($minutes > 0) {
|
||||
// minutes from now
|
||||
return time() + ($minutes * 60);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,9 +120,9 @@ class Cookie
|
|||
* @param string|null $key The name of the cookie
|
||||
* @param string|null $default The default value, which should be returned
|
||||
* if the cookie has not been found
|
||||
* @return mixed The found value
|
||||
* @return string|array|null The found value
|
||||
*/
|
||||
public static function get(string $key = null, string $default = null)
|
||||
public static function get(string|null $key = null, string|null $default = null): string|array|null
|
||||
{
|
||||
if ($key === null) {
|
||||
return $_COOKIE;
|
||||
|
@ -137,9 +137,6 @@ class Cookie
|
|||
|
||||
/**
|
||||
* Checks if a cookie exists
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists(string $key): bool
|
||||
{
|
||||
|
@ -149,9 +146,6 @@ class Cookie
|
|||
/**
|
||||
* Creates a HMAC for the cookie value
|
||||
* Used as a cookie signature to prevent easy tampering with cookie data
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected static function hmac(string $value): string
|
||||
{
|
||||
|
@ -161,11 +155,8 @@ class Cookie
|
|||
/**
|
||||
* Parses the hashed value from a cookie
|
||||
* and tries to extract the value
|
||||
*
|
||||
* @param string $string
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function parse(string $string)
|
||||
protected static function parse(string $string): string|null
|
||||
{
|
||||
// if no hash-value separator is present, we can't parse the value
|
||||
if (strpos($string, '+') === false) {
|
||||
|
@ -178,7 +169,7 @@ class Cookie
|
|||
|
||||
// if the hash or the value is missing at all return null
|
||||
// $value can be an empty string, $hash can't be!
|
||||
if (!is_string($hash) || $hash === '' || !is_string($value)) {
|
||||
if ($hash === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -207,7 +198,7 @@ class Cookie
|
|||
*/
|
||||
public static function remove(string $key): bool
|
||||
{
|
||||
if (isset($_COOKIE[$key])) {
|
||||
if (isset($_COOKIE[$key]) === true) {
|
||||
unset($_COOKIE[$key]);
|
||||
return setcookie($key, '', 1, '/') && setcookie($key, false);
|
||||
}
|
||||
|
@ -221,9 +212,6 @@ class Cookie
|
|||
* this ensures that the response is only cached for visitors who don't
|
||||
* have this cookie set;
|
||||
* https://github.com/getkirby/kirby/issues/4423#issuecomment-1166300526
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
protected static function trackUsage(string $key): void
|
||||
{
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Kirby\Http;
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Kirby\Toolkit\A;
|
||||
|
@ -26,143 +25,108 @@ class Environment
|
|||
{
|
||||
/**
|
||||
* Full base URL object
|
||||
*
|
||||
* @var \Kirby\Http\Uri
|
||||
*/
|
||||
protected $baseUri;
|
||||
protected Uri $baseUri;
|
||||
|
||||
/**
|
||||
* Full base URL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $baseUrl;
|
||||
protected string $baseUrl;
|
||||
|
||||
/**
|
||||
* Whether the request is being served by the CLI
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $cli;
|
||||
protected bool $cli;
|
||||
|
||||
/**
|
||||
* Current host name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host;
|
||||
protected string|null $host;
|
||||
|
||||
/**
|
||||
* Whether the HTTPS protocol is used
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $https;
|
||||
protected bool $https;
|
||||
|
||||
/**
|
||||
* Sanitized `$_SERVER` data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
protected array $info;
|
||||
|
||||
/**
|
||||
* Current server's IP address
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $ip;
|
||||
protected string|null $ip;
|
||||
|
||||
/**
|
||||
* Whether the site is behind a reverse proxy;
|
||||
* `null` if not known (fixed allowed URL setup)
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $isBehindProxy;
|
||||
protected bool|null $isBehindProxy;
|
||||
|
||||
/**
|
||||
* URI path to the base
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
protected string $path;
|
||||
|
||||
/**
|
||||
* Port number in the site URL
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $port;
|
||||
protected int|null $port;
|
||||
|
||||
/**
|
||||
* Intermediary value of the port
|
||||
* extracted from the host name
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $portInHost;
|
||||
protected int|null $portInHost = null;
|
||||
|
||||
/**
|
||||
* Uri object for the full request URI.
|
||||
* It is a combination of the base URL and `REQUEST_URI`
|
||||
*
|
||||
* @var \Kirby\Http\Uri
|
||||
*/
|
||||
protected $requestUri;
|
||||
protected Uri $requestUri;
|
||||
|
||||
/**
|
||||
* Full request URL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $requestUrl;
|
||||
protected string $requestUrl;
|
||||
|
||||
/**
|
||||
* Path to the php script within the
|
||||
* document root without the
|
||||
* filename of the script
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $scriptPath;
|
||||
protected string $scriptPath;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param array|null $options
|
||||
* @param array|null $info Optional override for `$_SERVER`
|
||||
*/
|
||||
public function __construct(?array $options = null, ?array $info = null)
|
||||
public function __construct(array|null $options = null, array|null $info = null)
|
||||
{
|
||||
$this->detect($options, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's IP address
|
||||
*
|
||||
* @see static::ip
|
||||
* @return string|null
|
||||
*/
|
||||
public function address(): ?string
|
||||
public function address(): string|null
|
||||
{
|
||||
return $this->ip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full base URL object
|
||||
*
|
||||
* @return \Kirby\Http\Uri
|
||||
*/
|
||||
public function baseUri()
|
||||
public function baseUri(): Uri
|
||||
{
|
||||
return $this->baseUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full base URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function baseUrl(): string
|
||||
{
|
||||
|
@ -171,8 +135,6 @@ class Environment
|
|||
|
||||
/**
|
||||
* Checks if the request is being served by the CLI
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function cli(): bool
|
||||
{
|
||||
|
@ -186,9 +148,7 @@ class Environment
|
|||
* the stored information and re-detect the
|
||||
* environment if necessary.
|
||||
*
|
||||
* @param array|null $options
|
||||
* @param array|null $info Optional override for `$_SERVER`
|
||||
* @return array
|
||||
*/
|
||||
public function detect(array $options = null, array $info = null): array
|
||||
{
|
||||
|
@ -208,18 +168,6 @@ class Environment
|
|||
$this->path = $this->detectPath($this->scriptPath);
|
||||
$this->port = null;
|
||||
|
||||
// keep Server flags compatible for now
|
||||
// TODO: remove in 3.8.0
|
||||
// @codeCoverageIgnoreStart
|
||||
if (is_int($options['allowed']) === true) {
|
||||
Helpers::deprecated('
|
||||
Using `Server::` constants for the `allowed` option has been deprecated and support will be removed in 3.8.0. Use one of the following instead: a single fixed URL, an array of allowed URLs to match dynamically, `*` wildcard to match dynamically even from insecure headers, or `true` to match automtically from safe server variables.
|
||||
');
|
||||
|
||||
$options['allowed'] = $this->detectAllowedFromFlag($options['allowed']);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// insecure auto-detection
|
||||
if ($options['allowed'] === '*' || $options['allowed'] === ['*']) {
|
||||
$this->detectAuto(true);
|
||||
|
@ -246,11 +194,8 @@ class Environment
|
|||
/**
|
||||
* Sets the host name, port, path and protocol from the
|
||||
* fixed list of allowed URLs
|
||||
*
|
||||
* @param array|string $allowed
|
||||
* @return void
|
||||
*/
|
||||
protected function detectAllowed($allowed): void
|
||||
protected function detectAllowed(array|string|object $allowed): void
|
||||
{
|
||||
$allowed = A::wrap($allowed);
|
||||
|
||||
|
@ -300,34 +245,10 @@ class Environment
|
|||
throw new InvalidArgumentException('The environment is not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL option receives a set of Server constant flags
|
||||
*
|
||||
* Server::HOST_FROM_SERVER
|
||||
* Server::HOST_FROM_SERVER | Server::HOST_ALLOW_EMPTY
|
||||
* Server::HOST_FROM_HEADER
|
||||
* Server::HOST_FROM_HEADER | Server::HOST_ALLOW_EMPTY
|
||||
* @todo Remove in 3.8.0
|
||||
*
|
||||
* @param int $flags
|
||||
* @return string|null
|
||||
*/
|
||||
protected function detectAllowedFromFlag(int $flags): ?string
|
||||
{
|
||||
// allow host detection from host headers
|
||||
if ($flags & Server::HOST_FROM_HEADER) {
|
||||
return '*';
|
||||
}
|
||||
|
||||
// detect host only from server name
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host name, port and protocol without configuration
|
||||
*
|
||||
* @param bool $insecure Include the `Host`, `Forwarded` and `X-Forwarded-*` headers in the search
|
||||
* @return void
|
||||
*/
|
||||
protected function detectAuto(bool $insecure = false): void
|
||||
{
|
||||
|
@ -364,10 +285,8 @@ class Environment
|
|||
/**
|
||||
* Builds the base URL based on the
|
||||
* given environment params
|
||||
*
|
||||
* @return \Kirby\Http\Uri
|
||||
*/
|
||||
protected function detectBaseUri()
|
||||
protected function detectBaseUri(): Uri
|
||||
{
|
||||
$this->baseUri = new Uri([
|
||||
'host' => $this->host,
|
||||
|
@ -385,9 +304,8 @@ class Environment
|
|||
* Detects if the request is served by the CLI
|
||||
*
|
||||
* @param bool|null $override Set to a boolean to override detection (for testing)
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectCli(?bool $override = null): bool
|
||||
protected function detectCli(bool|null $override = null): bool
|
||||
{
|
||||
if (is_bool($override) === true) {
|
||||
return $override;
|
||||
|
@ -411,8 +329,6 @@ class Environment
|
|||
/**
|
||||
* Detects the host, protocol, port and client IP
|
||||
* from the `Forwarded` and `X-Forwarded-*` headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function detectForwarded(): array
|
||||
{
|
||||
|
@ -482,10 +398,8 @@ class Environment
|
|||
/**
|
||||
* Detects the host name of the reverse proxy
|
||||
* from the `X-Forwarded-Host` header
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function detectForwardedHost(): ?string
|
||||
protected function detectForwardedHost(): string|null
|
||||
{
|
||||
$host = $this->get('HTTP_X_FORWARDED_HOST');
|
||||
$parts = $this->detectPortInHost($host);
|
||||
|
@ -498,8 +412,6 @@ class Environment
|
|||
/**
|
||||
* Detects the protocol of the reverse proxy from the
|
||||
* `X-Forwarded-SSL` or `X-Forwarded-Proto` header
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectForwardedHttps(): bool
|
||||
{
|
||||
|
@ -519,9 +431,8 @@ class Environment
|
|||
* `X-Forwarded-Host` or `X-Forwarded-Port` header
|
||||
*
|
||||
* @param bool $https Whether HTTPS was detected
|
||||
* @return int|null
|
||||
*/
|
||||
protected function detectForwardedPort(bool $https): ?int
|
||||
protected function detectForwardedPort(bool $https): int|null
|
||||
{
|
||||
// based on forwarded port
|
||||
$port = $this->get('HTTP_X_FORWARDED_PORT');
|
||||
|
@ -547,10 +458,11 @@ class Environment
|
|||
* Detects the host name from various headers
|
||||
*
|
||||
* @param bool $insecure Include the `Host` header in the search
|
||||
* @return string|null
|
||||
*/
|
||||
protected function detectHost(bool $insecure = false): ?string
|
||||
protected function detectHost(bool $insecure = false): string|null
|
||||
{
|
||||
$hosts = [];
|
||||
|
||||
if ($insecure === true) {
|
||||
$hosts[] = $this->get('HTTP_HOST');
|
||||
}
|
||||
|
@ -571,8 +483,6 @@ class Environment
|
|||
|
||||
/**
|
||||
* Detects the HTTPS status
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectHttps(): bool
|
||||
{
|
||||
|
@ -585,11 +495,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Normalizes the HTTPS status into a boolean
|
||||
*
|
||||
* @param string|bool|null|int $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectHttpsOn($value): bool
|
||||
protected function detectHttpsOn(string|int|bool|null $value): bool
|
||||
{
|
||||
// off can mean many things :)
|
||||
$off = ['off', null, '', 0, '0', false, 'false', -1, '-1'];
|
||||
|
@ -599,11 +506,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Detects the HTTPS status from a `X-Forwarded-Proto` string
|
||||
*
|
||||
* @param string|null $protocol
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectHttpsProtocol(?string $protocol = null): bool
|
||||
protected function detectHttpsProtocol(string|null $protocol = null): bool
|
||||
{
|
||||
if ($protocol === null) {
|
||||
return false;
|
||||
|
@ -614,21 +518,16 @@ class Environment
|
|||
|
||||
/**
|
||||
* Detects the server's IP address
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function detectIp(): ?string
|
||||
protected function detectIp(): string|null
|
||||
{
|
||||
return $this->get('SERVER_ADDR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the URI path unless in CLI mode
|
||||
*
|
||||
* @param string|null $path
|
||||
* @return string
|
||||
*/
|
||||
protected function detectPath(?string $path = null): string
|
||||
protected function detectPath(string|null $path = null): string
|
||||
{
|
||||
if ($this->cli === true) {
|
||||
return '';
|
||||
|
@ -639,10 +538,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Detects the port from various sources
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
protected function detectPort(): ?int
|
||||
protected function detectPort(): int|null
|
||||
{
|
||||
// based on server port
|
||||
$port = $this->get('SERVER_PORT');
|
||||
|
@ -666,11 +563,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Splits a hostname:port string into its components
|
||||
*
|
||||
* @param string|null $host
|
||||
* @return array
|
||||
*/
|
||||
protected function detectPortInHost(?string $host = null): array
|
||||
protected function detectPortInHost(string|null $host = null): array
|
||||
{
|
||||
if (empty($host) === true) {
|
||||
return [
|
||||
|
@ -689,11 +583,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Splits any URI into path and query
|
||||
*
|
||||
* @param string|null $requestUri
|
||||
* @return \Kirby\Http\Uri
|
||||
*/
|
||||
protected function detectRequestUri(?string $requestUri = null)
|
||||
protected function detectRequestUri(string|null $requestUri = null): Uri
|
||||
{
|
||||
// make sure the URL parser works properly when there's a
|
||||
// colon in the request URI but the URI is relative
|
||||
|
@ -720,11 +611,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Returns the sanitized script path unless in CLI mode
|
||||
*
|
||||
* @param string|null $scriptPath
|
||||
* @return string
|
||||
*/
|
||||
protected function detectScriptPath(?string $scriptPath = null): string
|
||||
protected function detectScriptPath(string|null $scriptPath = null): string
|
||||
{
|
||||
if ($this->cli === true) {
|
||||
return '';
|
||||
|
@ -748,9 +636,8 @@ class Environment
|
|||
* to return the entire server array.
|
||||
* @param mixed $default Optional default value, which should be
|
||||
* returned if no element has been found
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key = null, $default = null)
|
||||
public function get(string|false|null $key = null, $default = null)
|
||||
{
|
||||
if (is_string($key) === false) {
|
||||
return $this->info;
|
||||
|
@ -772,9 +659,8 @@ class Environment
|
|||
* to return the entire server array.
|
||||
* @param mixed $default Optional default value, which should be
|
||||
* returned if no element has been found
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getGlobally($key = null, $default = null)
|
||||
public static function getGlobally(string|false|null $key = null, $default = null)
|
||||
{
|
||||
// first try the global `Environment` object if the CMS is running
|
||||
$app = App::instance(null, true);
|
||||
|
@ -795,18 +681,14 @@ class Environment
|
|||
|
||||
/**
|
||||
* Returns the current host name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function host(): ?string
|
||||
public function host(): string|null
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the HTTPS protocol is used
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function https(): bool
|
||||
{
|
||||
|
@ -815,8 +697,6 @@ class Environment
|
|||
|
||||
/**
|
||||
* Returns the sanitized `$_SERVER` array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function info(): array
|
||||
{
|
||||
|
@ -825,10 +705,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Returns the server's IP address
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function ip(): ?string
|
||||
public function ip(): string|null
|
||||
{
|
||||
return $this->ip;
|
||||
}
|
||||
|
@ -836,10 +714,8 @@ class Environment
|
|||
/**
|
||||
* Returns if the server is behind a
|
||||
* reverse proxy server
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isBehindProxy(): ?bool
|
||||
public function isBehindProxy(): bool|null
|
||||
{
|
||||
return $this->isBehindProxy;
|
||||
}
|
||||
|
@ -847,8 +723,6 @@ class Environment
|
|||
/**
|
||||
* Checks if this is a local installation;
|
||||
* returns `false` if in doubt
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocal(): bool
|
||||
{
|
||||
|
@ -901,7 +775,6 @@ class Environment
|
|||
* PHP files (by host name and server IP address)
|
||||
*
|
||||
* @param string $root Root directory to load configs from
|
||||
* @return array
|
||||
*/
|
||||
public function options(string $root): array
|
||||
{
|
||||
|
@ -913,12 +786,20 @@ class Environment
|
|||
|
||||
// load the config for the host
|
||||
if (empty($host) === false) {
|
||||
$configHost = F::load($root . '/config.' . $host . '.php', []);
|
||||
$configHost = F::load(
|
||||
file: $root . '/config.' . $host . '.php',
|
||||
fallback: [],
|
||||
allowOutput: false
|
||||
);
|
||||
}
|
||||
|
||||
// load the config for the server IP
|
||||
if (empty($addr) === false) {
|
||||
$configAddr = F::load($root . '/config.' . $addr . '.php', []);
|
||||
$configAddr = F::load(
|
||||
file: $root . '/config.' . $addr . '.php',
|
||||
fallback: [],
|
||||
allowOutput: false
|
||||
);
|
||||
}
|
||||
|
||||
return array_replace_recursive($configHost, $configAddr);
|
||||
|
@ -926,30 +807,24 @@ class Environment
|
|||
|
||||
/**
|
||||
* Returns the detected path
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function path(): ?string
|
||||
public function path(): string|null
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the correct port number
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function port(): ?int
|
||||
public function port(): int|null
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an URI object for the requested URL
|
||||
*
|
||||
* @return \Kirby\Http\Uri
|
||||
*/
|
||||
public function requestUri()
|
||||
public function requestUri(): Uri
|
||||
{
|
||||
return $this->requestUri;
|
||||
}
|
||||
|
@ -957,8 +832,6 @@ class Environment
|
|||
/**
|
||||
* Returns the current URL, including the request path
|
||||
* and query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function requestUrl(): string
|
||||
{
|
||||
|
@ -967,12 +840,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Sanitizes some `$_SERVER` keys
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function sanitize($key, $value = null)
|
||||
public static function sanitize(string|array $key, $value = null)
|
||||
{
|
||||
if (is_array($key) === true) {
|
||||
foreach ($key as $k => $v) {
|
||||
|
@ -982,27 +851,23 @@ class Environment
|
|||
return $key;
|
||||
}
|
||||
|
||||
switch ($key) {
|
||||
case 'SERVER_ADDR':
|
||||
case 'SERVER_NAME':
|
||||
case 'HTTP_HOST':
|
||||
case 'HTTP_X_FORWARDED_HOST':
|
||||
return static::sanitizeHost($value);
|
||||
case 'SERVER_PORT':
|
||||
case 'HTTP_X_FORWARDED_PORT':
|
||||
return static::sanitizePort($value);
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
return match ($key) {
|
||||
'SERVER_ADDR',
|
||||
'SERVER_NAME',
|
||||
'HTTP_HOST',
|
||||
'HTTP_X_FORWARDED_HOST' => static::sanitizeHost($value),
|
||||
|
||||
'SERVER_PORT',
|
||||
'HTTP_X_FORWARDED_PORT' => static::sanitizePort($value),
|
||||
|
||||
default => $value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the given host name
|
||||
*
|
||||
* @param string|null $host
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function sanitizeHost(?string $host = null): ?string
|
||||
protected static function sanitizeHost(string|null $host = null): string|null
|
||||
{
|
||||
if (empty($host) === true) {
|
||||
return null;
|
||||
|
@ -1026,11 +891,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Sanitizes the given port number
|
||||
*
|
||||
* @param string|int|null $port
|
||||
* @return int|null
|
||||
*/
|
||||
protected static function sanitizePort($port = null): ?int
|
||||
protected static function sanitizePort(string|int|false|null $port = null): int|null
|
||||
{
|
||||
// already fine
|
||||
if (is_int($port) === true) {
|
||||
|
@ -1043,7 +905,7 @@ class Environment
|
|||
}
|
||||
|
||||
// remove any character that is not an integer
|
||||
$port = preg_replace('![^0-9]+!', '', (string)($port ?? ''));
|
||||
$port = preg_replace('![^0-9]+!', '', $port);
|
||||
|
||||
// no port
|
||||
if ($port === '') {
|
||||
|
@ -1056,11 +918,8 @@ class Environment
|
|||
|
||||
/**
|
||||
* Sanitizes the given script path
|
||||
*
|
||||
* @param string|null $scriptPath
|
||||
* @return string
|
||||
*/
|
||||
protected function sanitizeScriptPath(?string $scriptPath = null): string
|
||||
protected function sanitizeScriptPath(string|null $scriptPath = null): string
|
||||
{
|
||||
$scriptPath ??= '';
|
||||
$scriptPath = trim($scriptPath);
|
||||
|
@ -1097,8 +956,6 @@ class Environment
|
|||
*
|
||||
* This can be used to build the base baseUrl
|
||||
* for subfolder installations
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scriptPath(): string
|
||||
{
|
||||
|
@ -1107,8 +964,6 @@ class Environment
|
|||
|
||||
/**
|
||||
* Returns all environment data as array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ use Kirby\Filesystem\F;
|
|||
class Header
|
||||
{
|
||||
// configuration
|
||||
public static $codes = [
|
||||
public static array $codes = [
|
||||
|
||||
// successful
|
||||
'_200' => 'OK',
|
||||
|
@ -56,9 +56,6 @@ class Header
|
|||
/**
|
||||
* Sends a content type header
|
||||
*
|
||||
* @param string $mime
|
||||
* @param string $charset
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function contentType(string $mime, string $charset = 'UTF-8', bool $send = true)
|
||||
|
@ -82,12 +79,8 @@ class Header
|
|||
|
||||
/**
|
||||
* Creates headers by key and value
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param string|null $value
|
||||
* @return string
|
||||
*/
|
||||
public static function create($key, string $value = null): string
|
||||
public static function create(string|array $key, string|null $value = null): string
|
||||
{
|
||||
if (is_array($key) === true) {
|
||||
$headers = [];
|
||||
|
@ -106,9 +99,6 @@ class Header
|
|||
/**
|
||||
* Shortcut for static::contentType()
|
||||
*
|
||||
* @param string $mime
|
||||
* @param string $charset
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function type(string $mime, string $charset = 'UTF-8', bool $send = true)
|
||||
|
@ -123,11 +113,12 @@ class Header
|
|||
* and send a custom status code and message, use a $code string formatted
|
||||
* as 3 digits followed by a space and a message, e.g. '999 Custom Status'.
|
||||
*
|
||||
* @param int|string $code The HTTP status code
|
||||
* @param int|string|null $code The HTTP status code
|
||||
* @param bool $send If set to false the header will be returned instead
|
||||
* @return string|void
|
||||
* @psalm-return ($send is false ? string : void)
|
||||
*/
|
||||
public static function status($code = null, bool $send = true)
|
||||
public static function status(int|string|null $code = null, bool $send = true)
|
||||
{
|
||||
$codes = static::$codes;
|
||||
$protocol = Environment::getGlobally('SERVER_PROTOCOL', 'HTTP/1.1');
|
||||
|
@ -154,7 +145,6 @@ class Header
|
|||
/**
|
||||
* Sends a 200 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function success(bool $send = true)
|
||||
|
@ -165,7 +155,6 @@ class Header
|
|||
/**
|
||||
* Sends a 201 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function created(bool $send = true)
|
||||
|
@ -176,7 +165,6 @@ class Header
|
|||
/**
|
||||
* Sends a 202 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function accepted(bool $send = true)
|
||||
|
@ -187,7 +175,6 @@ class Header
|
|||
/**
|
||||
* Sends a 400 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function error(bool $send = true)
|
||||
|
@ -198,7 +185,6 @@ class Header
|
|||
/**
|
||||
* Sends a 403 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function forbidden(bool $send = true)
|
||||
|
@ -209,7 +195,6 @@ class Header
|
|||
/**
|
||||
* Sends a 404 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function notfound(bool $send = true)
|
||||
|
@ -220,7 +205,6 @@ class Header
|
|||
/**
|
||||
* Sends a 404 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function missing(bool $send = true)
|
||||
|
@ -231,7 +215,6 @@ class Header
|
|||
/**
|
||||
* Sends a 410 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function gone(bool $send = true)
|
||||
|
@ -242,7 +225,6 @@ class Header
|
|||
/**
|
||||
* Sends a 500 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function panic(bool $send = true)
|
||||
|
@ -253,7 +235,6 @@ class Header
|
|||
/**
|
||||
* Sends a 503 header
|
||||
*
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function unavailable(bool $send = true)
|
||||
|
@ -264,9 +245,6 @@ class Header
|
|||
/**
|
||||
* Sends a redirect header
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $code
|
||||
* @param bool $send
|
||||
* @return string|void
|
||||
*/
|
||||
public static function redirect(string $url, int $code = 302, bool $send = true)
|
||||
|
@ -288,7 +266,7 @@ class Header
|
|||
*
|
||||
* @param array $params Check out the defaults array for available parameters
|
||||
*/
|
||||
public static function download(array $params = [])
|
||||
public static function download(array $params = []): void
|
||||
{
|
||||
$defaults = [
|
||||
'name' => 'download',
|
||||
|
|
|
@ -17,31 +17,22 @@ class Idn
|
|||
{
|
||||
/**
|
||||
* Convert domain name from IDNA ASCII to Unicode
|
||||
*
|
||||
* @param string $domain
|
||||
* @return string|false
|
||||
*/
|
||||
public static function decode(string $domain)
|
||||
public static function decode(string $domain): string|false
|
||||
{
|
||||
return idn_to_utf8($domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert domain name to IDNA ASCII form
|
||||
*
|
||||
* @param string $domain
|
||||
* @return string|false
|
||||
*/
|
||||
public static function encode(string $domain)
|
||||
public static function encode(string $domain): string|false
|
||||
{
|
||||
return idn_to_ascii($domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a email address to the Unicode format
|
||||
*
|
||||
* @param string $email
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeEmail(string $email): string
|
||||
{
|
||||
|
@ -57,9 +48,6 @@ class Idn
|
|||
|
||||
/**
|
||||
* Encodes a email address to the Punycode format
|
||||
*
|
||||
* @param string $email
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeEmail(string $email): string
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Kirby\Http;
|
||||
|
||||
use Kirby\Toolkit\Obj;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
|
@ -15,19 +16,14 @@ use Kirby\Toolkit\Str;
|
|||
* @copyright Bastian Allgeier
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
*/
|
||||
class Params extends Query
|
||||
class Params extends Obj
|
||||
{
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public static $separator;
|
||||
public static string|null $separator = null;
|
||||
|
||||
/**
|
||||
* Creates a new params object
|
||||
*
|
||||
* @param array|string $params
|
||||
*/
|
||||
public function __construct($params)
|
||||
public function __construct(array|string|null $params)
|
||||
{
|
||||
if (is_string($params) === true) {
|
||||
$params = static::extract($params)['params'];
|
||||
|
@ -38,11 +34,8 @@ class Params extends Query
|
|||
|
||||
/**
|
||||
* Extract the params from a string or array
|
||||
*
|
||||
* @param string|array|null $path
|
||||
* @return array
|
||||
*/
|
||||
public static function extract($path = null): array
|
||||
public static function extract(string|array|null $path = null): array
|
||||
{
|
||||
if (empty($path) === true) {
|
||||
return [
|
||||
|
@ -93,14 +86,22 @@ class Params extends Query
|
|||
];
|
||||
}
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty((array)$this) === true;
|
||||
}
|
||||
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
return empty((array)$this) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the param separator according
|
||||
* to the operating system.
|
||||
*
|
||||
* Unix = ':'
|
||||
* Windows = ';'
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function separator(): string
|
||||
{
|
||||
|
@ -110,26 +111,16 @@ class Params extends Query
|
|||
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
return static::$separator = ':';
|
||||
} else {
|
||||
return static::$separator = ';';
|
||||
}
|
||||
|
||||
return static::$separator = ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the params object to a params string
|
||||
* which can then be used in the URL builder again
|
||||
*
|
||||
* @param bool $leadingSlash
|
||||
* @param bool $trailingSlash
|
||||
* @return string|null
|
||||
*
|
||||
* @todo The argument $leadingSlash is incompatible with
|
||||
* Query::toString($questionMark = false); the Query class
|
||||
* should be extracted into a common parent class for both
|
||||
* Query and Params
|
||||
* @psalm-suppress ParamNameMismatch
|
||||
*/
|
||||
public function toString($leadingSlash = false, $trailingSlash = false): string
|
||||
public function toString(bool $leadingSlash = false, bool $trailingSlash = false): string
|
||||
{
|
||||
if ($this->isEmpty() === true) {
|
||||
return '';
|
||||
|
@ -155,4 +146,9 @@ class Params extends Query
|
|||
|
||||
return $leadingSlash . $params . $trailingSlash;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use Kirby\Toolkit\Str;
|
|||
*/
|
||||
class Path extends Collection
|
||||
{
|
||||
public function __construct($items)
|
||||
public function __construct(string|array|null $items)
|
||||
{
|
||||
if (is_string($items) === true) {
|
||||
$items = Str::split($items, '/');
|
||||
|
|
|
@ -17,7 +17,7 @@ use Kirby\Toolkit\Obj;
|
|||
*/
|
||||
class Query extends Obj
|
||||
{
|
||||
public function __construct($query)
|
||||
public function __construct(string|array|null $query)
|
||||
{
|
||||
if (is_string($query) === true) {
|
||||
parse_str(ltrim($query, '?'), $query);
|
||||
|
@ -36,12 +36,7 @@ class Query extends Obj
|
|||
return empty((array)$this) === false;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
public function toString($questionMark = false): string
|
||||
public function toString(bool $questionMark = false): string
|
||||
{
|
||||
$query = http_build_query($this, '', '&', PHP_QUERY_RFC3986);
|
||||
|
||||
|
@ -55,4 +50,10 @@ class Query extends Obj
|
|||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
namespace Kirby\Http;
|
||||
|
||||
use CurlHandle;
|
||||
use Exception;
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Kirby\Toolkit\Str;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* A handy little class to handle
|
||||
|
@ -23,10 +25,7 @@ class Remote
|
|||
public const CA_INTERNAL = 1;
|
||||
public const CA_SYSTEM = 2;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $defaults = [
|
||||
public static array $defaults = [
|
||||
'agent' => null,
|
||||
'basicAuth' => null,
|
||||
'body' => true,
|
||||
|
@ -41,52 +40,17 @@ class Remote
|
|||
'timeout' => 10,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $content;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
public $curl;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $curlopt = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $errorCode;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $errorMessage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $headers = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $info = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $options = [];
|
||||
public string|null $content = null;
|
||||
public CurlHandle|false $curl;
|
||||
public array $curlopt = [];
|
||||
public int $errorCode;
|
||||
public string $errorMessage;
|
||||
public array $headers = [];
|
||||
public array $info = [];
|
||||
public array $options = [];
|
||||
|
||||
/**
|
||||
* Magic getter for request info data
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $method, array $arguments = [])
|
||||
{
|
||||
|
@ -96,9 +60,6 @@ class Remote
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(string $url, array $options = [])
|
||||
{
|
||||
|
@ -128,27 +89,23 @@ class Remote
|
|||
$this->fetch();
|
||||
}
|
||||
|
||||
public static function __callStatic(string $method, array $arguments = [])
|
||||
public static function __callStatic(string $method, array $arguments = []): static
|
||||
{
|
||||
return new static($arguments[0], array_merge(['method' => strtoupper($method)], $arguments[1] ?? []));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the http status code
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function code(): ?int
|
||||
public function code(): int|null
|
||||
{
|
||||
return $this->info['http_code'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response content
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function content()
|
||||
public function content(): string|null
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
@ -158,7 +115,7 @@ class Remote
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetch()
|
||||
public function fetch(): static
|
||||
{
|
||||
// curl options
|
||||
$this->curlopt = [
|
||||
|
@ -171,7 +128,7 @@ class Remote
|
|||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_HEADERFUNCTION => function ($curl, $header) {
|
||||
CURLOPT_HEADERFUNCTION => function ($curl, $header): int {
|
||||
$parts = Str::split($header, ':');
|
||||
|
||||
if (empty($parts[0]) === false && empty($parts[1]) === false) {
|
||||
|
@ -295,12 +252,8 @@ class Remote
|
|||
|
||||
/**
|
||||
* Static method to send a GET request
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @return static
|
||||
*/
|
||||
public static function get(string $url, array $params = [])
|
||||
public static function get(string $url, array $params = []): static
|
||||
{
|
||||
$defaults = [
|
||||
'method' => 'GET',
|
||||
|
@ -322,8 +275,6 @@ class Remote
|
|||
|
||||
/**
|
||||
* Returns all received headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function headers(): array
|
||||
{
|
||||
|
@ -332,8 +283,6 @@ class Remote
|
|||
|
||||
/**
|
||||
* Returns the request info
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function info(): array
|
||||
{
|
||||
|
@ -344,17 +293,14 @@ class Remote
|
|||
* Decode the response content
|
||||
*
|
||||
* @param bool $array decode as array or object
|
||||
* @return array|\stdClass
|
||||
*/
|
||||
public function json(bool $array = true)
|
||||
public function json(bool $array = true): array|stdClass|null
|
||||
{
|
||||
return json_decode($this->content(), $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function method(): string
|
||||
{
|
||||
|
@ -364,8 +310,6 @@ class Remote
|
|||
/**
|
||||
* Returns all options which have been
|
||||
* set for the current request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function options(): array
|
||||
{
|
||||
|
@ -374,35 +318,26 @@ class Remote
|
|||
|
||||
/**
|
||||
* Internal method to handle post field data
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return mixed
|
||||
*/
|
||||
protected function postfields($data)
|
||||
{
|
||||
if (is_object($data) || is_array($data)) {
|
||||
return http_build_query($data);
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to init this class and send a request
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @return static
|
||||
*/
|
||||
public static function request(string $url, array $params = [])
|
||||
public static function request(string $url, array $params = []): static
|
||||
{
|
||||
return new static($url, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request Url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url(): string
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Kirby\Http;
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Http\Request\Auth;
|
||||
use Kirby\Http\Request\Body;
|
||||
use Kirby\Http\Request\Files;
|
||||
use Kirby\Http\Request\Query;
|
||||
|
@ -22,7 +23,7 @@ use Kirby\Toolkit\Str;
|
|||
*/
|
||||
class Request
|
||||
{
|
||||
public static $authTypes = [
|
||||
public static array $authTypes = [
|
||||
'basic' => 'Kirby\Http\Request\Auth\BasicAuth',
|
||||
'bearer' => 'Kirby\Http\Request\Auth\BearerAuth',
|
||||
'session' => 'Kirby\Http\Request\Auth\SessionAuth',
|
||||
|
@ -30,10 +31,8 @@ class Request
|
|||
|
||||
/**
|
||||
* The auth object if available
|
||||
*
|
||||
* @var \Kirby\Http\Request\Auth|false|null
|
||||
*/
|
||||
protected $auth;
|
||||
protected Auth|false|null $auth = null;
|
||||
|
||||
/**
|
||||
* The Body object is a wrapper around
|
||||
|
@ -44,10 +43,8 @@ class Request
|
|||
* Examples:
|
||||
*
|
||||
* `$request->body()->get('foo')`
|
||||
*
|
||||
* @var Body
|
||||
*/
|
||||
protected $body;
|
||||
protected Body|null $body = null;
|
||||
|
||||
/**
|
||||
* The Files object is a wrapper around
|
||||
|
@ -59,25 +56,19 @@ class Request
|
|||
*
|
||||
* `$request->files()->get('upload')['size']`
|
||||
* `$request->file('upload')['size']`
|
||||
*
|
||||
* @var Files
|
||||
*/
|
||||
protected $files;
|
||||
protected Files|null $files = null;
|
||||
|
||||
/**
|
||||
* The Method type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $method;
|
||||
protected string $method;
|
||||
|
||||
/**
|
||||
* All options that have been passed to
|
||||
* the request in the constructor
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
protected array $options;
|
||||
|
||||
/**
|
||||
* The Query object is a wrapper around
|
||||
|
@ -88,25 +79,19 @@ class Request
|
|||
* Examples:
|
||||
*
|
||||
* `$request->query()->get('foo')`
|
||||
*
|
||||
* @var Query
|
||||
*/
|
||||
protected $query;
|
||||
protected Query $query;
|
||||
|
||||
/**
|
||||
* Request URL object
|
||||
*
|
||||
* @var Uri
|
||||
*/
|
||||
protected $url;
|
||||
protected Uri $url;
|
||||
|
||||
/**
|
||||
* Creates a new Request object
|
||||
* You can either pass your own request
|
||||
* data via the $options array or use
|
||||
* the data from the incoming request.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
|
@ -114,26 +99,24 @@ class Request
|
|||
$this->method = $this->detectRequestMethod($options['method'] ?? null);
|
||||
|
||||
if (isset($options['body']) === true) {
|
||||
$this->body = is_a($options['body'], Body::class) ? $options['body'] : new Body($options['body']);
|
||||
$this->body = $options['body'] instanceof Body ? $options['body'] : new Body($options['body']);
|
||||
}
|
||||
|
||||
if (isset($options['files']) === true) {
|
||||
$this->files = is_a($options['files'], Files::class) ? $options['files'] : new Files($options['files']);
|
||||
$this->files = $options['files'] instanceof Files ? $options['files'] : new Files($options['files']);
|
||||
}
|
||||
|
||||
if (isset($options['query']) === true) {
|
||||
$this->query = is_a($options['query'], Query::class) === true ? $options['query'] : new Query($options['query']);
|
||||
$this->query = $options['query'] instanceof Query ? $options['query'] : new Query($options['query']);
|
||||
}
|
||||
|
||||
if (isset($options['url']) === true) {
|
||||
$this->url = is_a($options['url'], Uri::class) === true ? $options['url'] : new Uri($options['url']);
|
||||
$this->url = $options['url'] instanceof Uri ? $options['url'] : new Uri($options['url']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
|
@ -148,10 +131,8 @@ class Request
|
|||
|
||||
/**
|
||||
* Returns the Auth object if authentication is set
|
||||
*
|
||||
* @return \Kirby\Http\Request\Auth|null
|
||||
*/
|
||||
public function auth()
|
||||
public function auth(): Auth|false|null
|
||||
{
|
||||
if ($this->auth !== null) {
|
||||
return $this->auth;
|
||||
|
@ -170,7 +151,7 @@ class Request
|
|||
$kirby->response()->usesAuth(true);
|
||||
}
|
||||
|
||||
if ($auth = $this->options['auth'] ?? $this->header('authorization')) {
|
||||
if ($auth = $this->authString()) {
|
||||
$type = Str::lower(Str::before($auth, ' '));
|
||||
$data = Str::after($auth, ' ');
|
||||
|
||||
|
@ -189,18 +170,14 @@ class Request
|
|||
|
||||
/**
|
||||
* Returns the Body object
|
||||
*
|
||||
* @return \Kirby\Http\Request\Body
|
||||
*/
|
||||
public function body()
|
||||
public function body(): Body
|
||||
{
|
||||
return $this->body ??= new Body();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the request has been made from the command line
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function cli(): bool
|
||||
{
|
||||
|
@ -209,18 +186,14 @@ class Request
|
|||
|
||||
/**
|
||||
* Returns a CSRF token if stored in a header or the query
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function csrf(): ?string
|
||||
public function csrf(): string|null
|
||||
{
|
||||
return $this->header('x-csrf') ?? $this->query()->get('csrf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request input as array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data(): array
|
||||
{
|
||||
|
@ -230,11 +203,8 @@ class Request
|
|||
/**
|
||||
* Detect the request method from various
|
||||
* options: given method, query string, server vars
|
||||
*
|
||||
* @param string $method
|
||||
* @return string
|
||||
*/
|
||||
public function detectRequestMethod(string $method = null): string
|
||||
public function detectRequestMethod(string|null $method = null): string
|
||||
{
|
||||
// all possible methods
|
||||
$methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'];
|
||||
|
@ -262,8 +232,6 @@ class Request
|
|||
|
||||
/**
|
||||
* Returns the domain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function domain(): string
|
||||
{
|
||||
|
@ -273,21 +241,16 @@ class Request
|
|||
/**
|
||||
* Fetches a single file array
|
||||
* from the Files object by key
|
||||
*
|
||||
* @param string $key
|
||||
* @return array|null
|
||||
*/
|
||||
public function file(string $key)
|
||||
public function file(string $key): array|null
|
||||
{
|
||||
return $this->files()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Files object
|
||||
*
|
||||
* @return \Kirby\Cms\Files
|
||||
*/
|
||||
public function files()
|
||||
public function files(): Files
|
||||
{
|
||||
return $this->files ??= new Files();
|
||||
}
|
||||
|
@ -295,12 +258,8 @@ class Request
|
|||
/**
|
||||
* Returns any data field from the request
|
||||
* if it exists
|
||||
*
|
||||
* @param string|null|array $key
|
||||
* @param mixed $fallback
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key = null, $fallback = null)
|
||||
public function get(string|array|null $key = null, $fallback = null)
|
||||
{
|
||||
return A::get($this->data(), $key, $fallback);
|
||||
}
|
||||
|
@ -309,22 +268,14 @@ class Request
|
|||
* Returns whether the request contains
|
||||
* the `Authorization` header
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAuth(): bool
|
||||
{
|
||||
$header = $this->options['auth'] ?? $this->header('authorization');
|
||||
|
||||
return $header !== null;
|
||||
return $this->authString() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a header by key if it exists
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $fallback
|
||||
* @return mixed
|
||||
*/
|
||||
public function header(string $key, $fallback = null)
|
||||
{
|
||||
|
@ -335,8 +286,6 @@ class Request
|
|||
/**
|
||||
* Return all headers with polyfill for
|
||||
* missing getallheaders function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function headers(): array
|
||||
{
|
||||
|
@ -371,9 +320,6 @@ class Request
|
|||
/**
|
||||
* Checks if the given method name
|
||||
* matches the name of the request method.
|
||||
*
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function is(string $method): bool
|
||||
{
|
||||
|
@ -382,8 +328,6 @@ class Request
|
|||
|
||||
/**
|
||||
* Returns the request method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function method(): string
|
||||
{
|
||||
|
@ -393,7 +337,7 @@ class Request
|
|||
/**
|
||||
* Shortcut to the Params object
|
||||
*/
|
||||
public function params()
|
||||
public function params(): Params
|
||||
{
|
||||
return $this->url()->params();
|
||||
}
|
||||
|
@ -401,25 +345,21 @@ class Request
|
|||
/**
|
||||
* Shortcut to the Path object
|
||||
*/
|
||||
public function path()
|
||||
public function path(): Path
|
||||
{
|
||||
return $this->url()->path();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Query object
|
||||
*
|
||||
* @return \Kirby\Http\Request\Query
|
||||
*/
|
||||
public function query()
|
||||
public function query(): Query
|
||||
{
|
||||
return $this->query ??= new Query();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a valid SSL connection
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ssl(): bool
|
||||
{
|
||||
|
@ -431,11 +371,8 @@ class Request
|
|||
* If you pass props you can safely modify
|
||||
* the Url with new parameters without destroying
|
||||
* the original object.
|
||||
*
|
||||
* @param array $props
|
||||
* @return \Kirby\Http\Uri
|
||||
*/
|
||||
public function url(array $props = null)
|
||||
public function url(array|null $props = null): Uri
|
||||
{
|
||||
if ($props !== null) {
|
||||
return $this->url()->clone($props);
|
||||
|
@ -443,4 +380,27 @@ class Request
|
|||
|
||||
return $this->url ??= Uri::current();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw auth string from the `auth` option
|
||||
* or `Authorization` header unless both are empty
|
||||
*/
|
||||
protected function authString(): string|null
|
||||
{
|
||||
// both variants need to be checked separately
|
||||
// because empty strings are treated as invalid
|
||||
// but the `??` operator wouldn't do the fallback
|
||||
|
||||
$option = $this->options['auth'] ?? null;
|
||||
if (empty($option) === false) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$header = $this->header('authorization');
|
||||
if (empty($header) === false) {
|
||||
return $header;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,11 @@ abstract class Auth
|
|||
/**
|
||||
* Raw authentication data after the first space
|
||||
* in the `Authorization` header
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $data;
|
||||
protected string $data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
public function __construct(string $data)
|
||||
{
|
||||
|
@ -33,8 +29,6 @@ abstract class Auth
|
|||
|
||||
/**
|
||||
* Converts the object to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
|
@ -44,8 +38,6 @@ abstract class Auth
|
|||
/**
|
||||
* Returns the raw authentication data after the
|
||||
* first space in the `Authorization` header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function data(): string
|
||||
{
|
||||
|
@ -54,8 +46,6 @@ abstract class Auth
|
|||
|
||||
/**
|
||||
* Returns the name of the auth type (lowercase)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function type(): string;
|
||||
}
|
||||
|
|
|
@ -16,24 +16,10 @@ use Kirby\Toolkit\Str;
|
|||
*/
|
||||
class BasicAuth extends Auth
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $credentials;
|
||||
protected string $credentials;
|
||||
protected string|null $password;
|
||||
protected string|null $username;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $username;
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*/
|
||||
public function __construct(string $data)
|
||||
{
|
||||
parent::__construct($data);
|
||||
|
@ -45,8 +31,6 @@ class BasicAuth extends Auth
|
|||
|
||||
/**
|
||||
* Returns the entire unencoded credentials string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function credentials(): string
|
||||
{
|
||||
|
@ -55,18 +39,14 @@ class BasicAuth extends Auth
|
|||
|
||||
/**
|
||||
* Returns the password
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function password(): ?string
|
||||
public function password(): string|null
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type(): string
|
||||
{
|
||||
|
@ -75,10 +55,8 @@ class BasicAuth extends Auth
|
|||
|
||||
/**
|
||||
* Returns the username
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function username(): ?string
|
||||
public function username(): string|null
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ class BearerAuth extends Auth
|
|||
{
|
||||
/**
|
||||
* Returns the authentication token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function token(): string
|
||||
{
|
||||
|
@ -27,8 +25,6 @@ class BearerAuth extends Auth
|
|||
|
||||
/**
|
||||
* Returns the auth type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type(): string
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Kirby\Http\Request\Auth;
|
|||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Http\Request\Auth;
|
||||
use Kirby\Session\Session;
|
||||
|
||||
/**
|
||||
* Authentication data using Kirby's session
|
||||
|
@ -18,18 +19,14 @@ class SessionAuth extends Auth
|
|||
{
|
||||
/**
|
||||
* Tries to return the session object
|
||||
*
|
||||
* @return \Kirby\Session\Session
|
||||
*/
|
||||
public function session()
|
||||
public function session(): Session
|
||||
{
|
||||
return App::instance()->sessionHandler()->getManually($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function token(): string
|
||||
{
|
||||
|
@ -38,8 +35,6 @@ class SessionAuth extends Auth
|
|||
|
||||
/**
|
||||
* Returns the authentication type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type(): string
|
||||
{
|
||||
|
|
|
@ -20,17 +20,13 @@ class Body
|
|||
|
||||
/**
|
||||
* The raw body content
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $contents;
|
||||
protected string|array|null $contents;
|
||||
|
||||
/**
|
||||
* The parsed content as array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
protected array|null $data = null;
|
||||
|
||||
/**
|
||||
* Creates a new request body object.
|
||||
|
@ -38,10 +34,8 @@ class Body
|
|||
* If null is being passed, the class will
|
||||
* fetch the body either from the $_POST global
|
||||
* or from php://input.
|
||||
*
|
||||
* @param array|string|null $contents
|
||||
*/
|
||||
public function __construct($contents = null)
|
||||
public function __construct(array|string|null $contents = null)
|
||||
{
|
||||
$this->contents = $contents;
|
||||
}
|
||||
|
@ -49,20 +43,18 @@ class Body
|
|||
/**
|
||||
* Fetches the raw contents for the body
|
||||
* or uses the passed contents.
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public function contents()
|
||||
public function contents(): string|array
|
||||
{
|
||||
if ($this->contents === null) {
|
||||
if (empty($_POST) === false) {
|
||||
$this->contents = $_POST;
|
||||
} else {
|
||||
$this->contents = file_get_contents('php://input');
|
||||
}
|
||||
if ($this->contents !== null) {
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
return $this->contents;
|
||||
if (empty($_POST) === false) {
|
||||
return $this->contents = $_POST;
|
||||
}
|
||||
|
||||
return $this->contents = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,8 +63,6 @@ class Body
|
|||
* the body with the json decoder first and
|
||||
* then run parse_str to get some results
|
||||
* if the json decoder failed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data(): array
|
||||
{
|
||||
|
@ -109,8 +99,6 @@ class Body
|
|||
/**
|
||||
* Converts the data array back
|
||||
* to a http query string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
|
@ -119,8 +107,6 @@ class Body
|
|||
|
||||
/**
|
||||
* Magic string converter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
|
|
|
@ -20,8 +20,6 @@ trait Data
|
|||
{
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
|
@ -33,8 +31,6 @@ trait Data
|
|||
* implemented by each class using this Trait
|
||||
* and has to return an associative array
|
||||
* for the get method
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function data(): array;
|
||||
|
||||
|
@ -43,12 +39,8 @@ trait Data
|
|||
* Trait. You can use it to fetch a single value
|
||||
* of the data array by key or multiple values by
|
||||
* passing an array of keys.
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param mixed|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
public function get(string|array $key, $default = null)
|
||||
{
|
||||
if (is_array($key) === true) {
|
||||
$result = [];
|
||||
|
@ -64,8 +56,6 @@ trait Data
|
|||
/**
|
||||
* Returns the data array.
|
||||
* This is basically an alias for Data::data()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
@ -74,8 +64,6 @@ trait Data
|
|||
|
||||
/**
|
||||
* Converts the data array to json
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson(): string
|
||||
{
|
||||
|
|
|
@ -21,19 +21,15 @@ class Files
|
|||
|
||||
/**
|
||||
* Sanitized array of all received files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $files;
|
||||
protected array $files;
|
||||
|
||||
/**
|
||||
* Creates a new Files object
|
||||
* Pass your own array to mock
|
||||
* uploads.
|
||||
*
|
||||
* @param array|null $files
|
||||
*/
|
||||
public function __construct($files = null)
|
||||
public function __construct(array|null $files = null)
|
||||
{
|
||||
if ($files === null) {
|
||||
$files = $_FILES;
|
||||
|
@ -63,8 +59,6 @@ class Files
|
|||
* array. This is only needed to make
|
||||
* the Data trait work for the Files::get($key)
|
||||
* method.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data(): array
|
||||
{
|
||||
|
|
|
@ -19,10 +19,8 @@ class Query
|
|||
|
||||
/**
|
||||
* The Query data array
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $data;
|
||||
protected array|null $data;
|
||||
|
||||
/**
|
||||
* Creates a new Query object.
|
||||
|
@ -30,14 +28,12 @@ class Query
|
|||
* or a parsable query string. If
|
||||
* null is passed, the current Query
|
||||
* will be taken from $_GET
|
||||
*
|
||||
* @param array|string|null $data
|
||||
*/
|
||||
public function __construct($data = null)
|
||||
public function __construct(array|string|null $data = null)
|
||||
{
|
||||
if ($data === null) {
|
||||
$this->data = $_GET;
|
||||
} elseif (is_array($data)) {
|
||||
} elseif (is_array($data) === true) {
|
||||
$this->data = $data;
|
||||
} else {
|
||||
parse_str($data, $parsed);
|
||||
|
@ -47,8 +43,6 @@ class Query
|
|||
|
||||
/**
|
||||
* Returns the Query data as array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data(): array
|
||||
{
|
||||
|
@ -57,8 +51,6 @@ class Query
|
|||
|
||||
/**
|
||||
* Returns `true` if the request doesn't contain query variables
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
|
@ -67,8 +59,6 @@ class Query
|
|||
|
||||
/**
|
||||
* Returns `true` if the request contains query variables
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
|
@ -78,8 +68,6 @@ class Query
|
|||
/**
|
||||
* Converts the query data array
|
||||
* back to a query string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
|
@ -88,8 +76,6 @@ class Query
|
|||
|
||||
/**
|
||||
* Magic string converter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace Kirby\Http;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Kirby\Exception\LogicException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Throwable;
|
||||
|
||||
|
@ -22,49 +24,33 @@ class Response
|
|||
/**
|
||||
* Store for all registered headers,
|
||||
* which will be sent with the response
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = [];
|
||||
protected array $headers = [];
|
||||
|
||||
/**
|
||||
* The response body
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $body;
|
||||
protected string $body;
|
||||
|
||||
/**
|
||||
* The HTTP response code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $code;
|
||||
protected int $code;
|
||||
|
||||
/**
|
||||
* The content type for the response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
protected string $type;
|
||||
|
||||
/**
|
||||
* The content type charset
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $charset = 'UTF-8';
|
||||
protected string $charset = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Creates a new response object
|
||||
*
|
||||
* @param string $body
|
||||
* @param string $type
|
||||
* @param int $code
|
||||
* @param array $headers
|
||||
* @param string $charset
|
||||
*/
|
||||
public function __construct($body = '', ?string $type = null, ?int $code = null, ?array $headers = null, ?string $charset = null)
|
||||
public function __construct(string|array $body = '', string|null $type = null, int|null $code = null, array|null $headers = null, string|null $charset = null)
|
||||
{
|
||||
// array construction
|
||||
if (is_array($body) === true) {
|
||||
|
@ -91,8 +77,6 @@ class Response
|
|||
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
|
@ -103,22 +87,18 @@ class Response
|
|||
* Makes it possible to convert the
|
||||
* entire response object to a string
|
||||
* to send the headers and print the body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
try {
|
||||
return $this->send();
|
||||
} catch (Throwable $e) {
|
||||
} catch (Throwable) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function body(): string
|
||||
{
|
||||
|
@ -127,8 +107,6 @@ class Response
|
|||
|
||||
/**
|
||||
* Getter for the content type charset
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function charset(): string
|
||||
{
|
||||
|
@ -137,8 +115,6 @@ class Response
|
|||
|
||||
/**
|
||||
* Getter for the HTTP status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function code(): int
|
||||
{
|
||||
|
@ -149,12 +125,9 @@ class Response
|
|||
* Creates a response that triggers
|
||||
* a file download for the given file
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $filename
|
||||
* @param array $props Custom overrides for response props (e.g. headers)
|
||||
* @return static
|
||||
*/
|
||||
public static function download(string $file, string $filename = null, array $props = [])
|
||||
public static function download(string $file, string|null $filename = null, array $props = []): static
|
||||
{
|
||||
if (file_exists($file) === false) {
|
||||
throw new Exception('The file could not be found');
|
||||
|
@ -186,11 +159,9 @@ class Response
|
|||
* Creates a response for a file and
|
||||
* sends the file content to the browser
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $props Custom overrides for response props (e.g. headers)
|
||||
* @return static
|
||||
*/
|
||||
public static function file(string $file, array $props = [])
|
||||
public static function file(string $file, array $props = []): static
|
||||
{
|
||||
$props = array_merge([
|
||||
'body' => F::read($file),
|
||||
|
@ -206,32 +177,42 @@ class Response
|
|||
* Urls can be relative or absolute.
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $code
|
||||
* @return void
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function go(string $url = '/', int $code = 302)
|
||||
public static function go(string $url = '/', int $code = 302): void
|
||||
{
|
||||
die(static::redirect($url, $code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the callback does not produce the first body output
|
||||
* (used to show when loading a file creates side effects)
|
||||
*/
|
||||
public static function guardAgainstOutput(Closure $callback, ...$args): mixed
|
||||
{
|
||||
$before = headers_sent();
|
||||
$result = $callback(...$args);
|
||||
$after = headers_sent($file, $line);
|
||||
|
||||
if ($before === false && $after === true) {
|
||||
throw new LogicException("Disallowed output from file $file:$line, possible accidental whitespace?");
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for single headers
|
||||
*
|
||||
* @param string $key Name of the header
|
||||
* @return string|null
|
||||
*/
|
||||
public function header(string $key): ?string
|
||||
public function header(string $key): string|null
|
||||
{
|
||||
return $this->headers[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for all headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function headers(): array
|
||||
{
|
||||
|
@ -241,14 +222,8 @@ class Response
|
|||
/**
|
||||
* Creates a json response with appropriate
|
||||
* header and automatic conversion of arrays.
|
||||
*
|
||||
* @param string|array $body
|
||||
* @param int $code
|
||||
* @param bool $pretty
|
||||
* @param array $headers
|
||||
* @return static
|
||||
*/
|
||||
public static function json($body = '', ?int $code = null, ?bool $pretty = null, array $headers = [])
|
||||
public static function json(string|array $body = '', int|null $code = null, bool|null $pretty = null, array $headers = []): static
|
||||
{
|
||||
if (is_array($body) === true) {
|
||||
$body = json_encode($body, $pretty === true ? JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES : 0);
|
||||
|
@ -266,12 +241,8 @@ class Response
|
|||
* Creates a redirect response,
|
||||
* which will send the visitor to the
|
||||
* given location.
|
||||
*
|
||||
* @param string $location
|
||||
* @param int $code
|
||||
* @return static
|
||||
*/
|
||||
public static function redirect(string $location = '/', int $code = 302)
|
||||
public static function redirect(string $location = '/', int $code = 302): static
|
||||
{
|
||||
return new static([
|
||||
'code' => $code,
|
||||
|
@ -284,8 +255,6 @@ class Response
|
|||
/**
|
||||
* Sends all registered headers and
|
||||
* returns the response body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function send(): string
|
||||
{
|
||||
|
@ -308,8 +277,6 @@ class Response
|
|||
* Converts all relevant response attributes
|
||||
* to an associative array for debugging,
|
||||
* testing or whatever.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
@ -324,8 +291,6 @@ class Response
|
|||
|
||||
/**
|
||||
* Getter for the content type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type(): string
|
||||
{
|
||||
|
|
|
@ -15,47 +15,35 @@ class Route
|
|||
{
|
||||
/**
|
||||
* The callback action function
|
||||
*
|
||||
* @var Closure
|
||||
*/
|
||||
protected $action;
|
||||
protected Closure $action;
|
||||
|
||||
/**
|
||||
* Listed of parsed arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
protected array $arguments = [];
|
||||
|
||||
/**
|
||||
* An array of all passed attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
protected array $attributes = [];
|
||||
|
||||
/**
|
||||
* The registered request method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $method;
|
||||
protected string $method;
|
||||
|
||||
/**
|
||||
* The registered pattern
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pattern;
|
||||
protected string $pattern;
|
||||
|
||||
/**
|
||||
* Wildcards, which can be used in
|
||||
* Route patterns to make regular expressions
|
||||
* a little more human
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $wildcards = [
|
||||
protected array $wildcards = [
|
||||
'required' => [
|
||||
'(:num)' => '(-?[0-9]+)',
|
||||
'(:alpha)' => '([a-zA-Z]+)',
|
||||
|
@ -74,10 +62,6 @@ class Route
|
|||
|
||||
/**
|
||||
* Magic getter for route attributes
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $key, array $arguments = null)
|
||||
{
|
||||
|
@ -87,13 +71,8 @@ class Route
|
|||
/**
|
||||
* Creates a new Route object for the given
|
||||
* pattern(s), method(s) and the callback action
|
||||
*
|
||||
* @param string|array $pattern
|
||||
* @param string|array $method
|
||||
* @param Closure $action
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct($pattern, $method, Closure $action, array $attributes = [])
|
||||
public function __construct(string $pattern, string $method, Closure $action, array $attributes = [])
|
||||
{
|
||||
$this->action = $action;
|
||||
$this->attributes = $attributes;
|
||||
|
@ -103,18 +82,14 @@ class Route
|
|||
|
||||
/**
|
||||
* Getter for the action callback
|
||||
*
|
||||
* @return Closure
|
||||
*/
|
||||
public function action()
|
||||
public function action(): Closure
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all parsed arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function arguments(): array
|
||||
{
|
||||
|
@ -123,8 +98,6 @@ class Route
|
|||
|
||||
/**
|
||||
* Getter for additional attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
@ -133,8 +106,6 @@ class Route
|
|||
|
||||
/**
|
||||
* Getter for the method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function method(): string
|
||||
{
|
||||
|
@ -143,10 +114,8 @@ class Route
|
|||
|
||||
/**
|
||||
* Returns the route name if set
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function name(): ?string
|
||||
public function name(): string|null
|
||||
{
|
||||
return $this->attributes['name'] ?? null;
|
||||
}
|
||||
|
@ -155,8 +124,6 @@ class Route
|
|||
* Throws a specific exception to tell
|
||||
* the router to jump to the next route
|
||||
* @since 3.0.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function next(): void
|
||||
{
|
||||
|
@ -165,8 +132,6 @@ class Route
|
|||
|
||||
/**
|
||||
* Getter for the pattern
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function pattern(): string
|
||||
{
|
||||
|
@ -176,9 +141,6 @@ class Route
|
|||
/**
|
||||
* Converts the pattern into a full regular
|
||||
* expression by replacing all the wildcards
|
||||
*
|
||||
* @param string $pattern
|
||||
* @return string
|
||||
*/
|
||||
public function regex(string $pattern): string
|
||||
{
|
||||
|
@ -200,12 +162,8 @@ class Route
|
|||
/**
|
||||
* Tries to match the path with the regular expression and
|
||||
* extracts all arguments for the Route action
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param string $path
|
||||
* @return array|false
|
||||
*/
|
||||
public function parse(string $pattern, string $path)
|
||||
public function parse(string $pattern, string $path): array|false
|
||||
{
|
||||
// check for direct matches
|
||||
if ($pattern === $path) {
|
||||
|
|
|
@ -18,35 +18,27 @@ class Router
|
|||
{
|
||||
/**
|
||||
* Hook that is called after each route
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $afterEach;
|
||||
protected Closure|null $afterEach;
|
||||
|
||||
/**
|
||||
* Hook that is called before each route
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $beforeEach;
|
||||
protected Closure|null $beforeEach;
|
||||
|
||||
/**
|
||||
* Store for the current route,
|
||||
* if one can be found
|
||||
*
|
||||
* @var \Kirby\Http\Route|null
|
||||
*/
|
||||
protected $route;
|
||||
protected Route|null $route = null;
|
||||
|
||||
/**
|
||||
* All registered routes, sorted by
|
||||
* their request method. This makes
|
||||
* it faster to find the right route
|
||||
* later.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routes = [
|
||||
protected array $routes = [
|
||||
'GET' => [],
|
||||
'HEAD' => [],
|
||||
'POST' => [],
|
||||
|
@ -62,7 +54,6 @@ class Router
|
|||
* Creates a new router object and
|
||||
* registers all the given routes
|
||||
*
|
||||
* @param array $routes
|
||||
* @param array<string, \Closure> $hooks Optional `beforeEach` and `afterEach` hooks
|
||||
*/
|
||||
public function __construct(array $routes = [], array $hooks = [])
|
||||
|
@ -104,14 +95,12 @@ class Router
|
|||
* and then call the Route action with
|
||||
* the appropriate arguments and a Result
|
||||
* object.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param Closure|null $callback
|
||||
* @return mixed
|
||||
*/
|
||||
public function call(string $path = null, string $method = 'GET', Closure $callback = null)
|
||||
{
|
||||
public function call(
|
||||
string|null $path = null,
|
||||
string $method = 'GET',
|
||||
Closure|null $callback = null
|
||||
) {
|
||||
$path ??= '';
|
||||
$ignore = [];
|
||||
$result = null;
|
||||
|
@ -120,7 +109,7 @@ class Router
|
|||
while ($loop === true) {
|
||||
$route = $this->find($path, $method, $ignore);
|
||||
|
||||
if (is_a($this->beforeEach, 'Closure') === true) {
|
||||
if ($this->beforeEach instanceof Closure) {
|
||||
($this->beforeEach)($route, $path, $method);
|
||||
}
|
||||
|
||||
|
@ -128,15 +117,15 @@ class Router
|
|||
if ($callback) {
|
||||
$result = $callback($route);
|
||||
} else {
|
||||
$result = $route->action()->call($route, ...$route->arguments());
|
||||
$result = $route?->action()->call($route, ...$route->arguments());
|
||||
}
|
||||
|
||||
$loop = false;
|
||||
} catch (Exceptions\NextRouteException $e) {
|
||||
} catch (Exceptions\NextRouteException) {
|
||||
$ignore[] = $route;
|
||||
}
|
||||
|
||||
if (is_a($this->afterEach, 'Closure') === true) {
|
||||
if ($this->afterEach instanceof Closure) {
|
||||
$final = $loop === false;
|
||||
$result = ($this->afterEach)($route, $path, $method, $result, $final);
|
||||
}
|
||||
|
@ -149,14 +138,8 @@ class Router
|
|||
* Creates a micro-router and executes
|
||||
* the routing action immediately
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string|null $path
|
||||
* @param string $method
|
||||
* @param array $routes
|
||||
* @param \Closure|null $callback
|
||||
* @return mixed
|
||||
*/
|
||||
public static function execute(?string $path = null, string $method = 'GET', array $routes = [], ?Closure $callback = null)
|
||||
public static function execute(string|null $path = null, string $method = 'GET', array $routes = [], Closure|null $callback = null)
|
||||
{
|
||||
return (new static($routes))->call($path, $method, $callback);
|
||||
}
|
||||
|
@ -166,13 +149,8 @@ class Router
|
|||
* The Route's arguments method is used to
|
||||
* find matches and return all the found
|
||||
* arguments in the path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param array $ignore
|
||||
* @return \Kirby\Http\Route|null
|
||||
*/
|
||||
public function find(string $path, string $method, array $ignore = null)
|
||||
public function find(string $path, string $method, array|null $ignore = null): Route|null
|
||||
{
|
||||
if (isset($this->routes[$method]) === false) {
|
||||
throw new InvalidArgumentException('Invalid routing method: ' . $method, 400);
|
||||
|
@ -199,10 +177,8 @@ class Router
|
|||
* This will only return something,
|
||||
* once Router::find() has been called
|
||||
* and only if a route was found.
|
||||
*
|
||||
* @return \Kirby\Http\Route|null
|
||||
*/
|
||||
public function route()
|
||||
public function route(): Route|null
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Http;
|
||||
|
||||
use Kirby\Toolkit\Facade;
|
||||
|
||||
/**
|
||||
* A set of methods that make it more convenient to get variables
|
||||
* from the global server array
|
||||
*
|
||||
* @package Kirby Http
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
* @deprecated 3.7.0 Use `Kirby\Http\Environment` instead
|
||||
* @todo Remove in 3.8.0
|
||||
*/
|
||||
class Server extends Facade
|
||||
{
|
||||
public const HOST_FROM_SERVER = 1;
|
||||
public const HOST_FROM_HEADER = 2;
|
||||
public const HOST_ALLOW_EMPTY = 4;
|
||||
|
||||
public static $cli;
|
||||
public static $hosts;
|
||||
|
||||
/**
|
||||
* @return \Kirby\Http\Environment
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
return new Environment([
|
||||
'cli' => static::$cli,
|
||||
'allowed' => static::$hosts
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -22,99 +22,68 @@ class Uri
|
|||
|
||||
/**
|
||||
* Cache for the current Uri object
|
||||
*
|
||||
* @var Uri|null
|
||||
*/
|
||||
public static $current;
|
||||
public static Uri|null $current = null;
|
||||
|
||||
/**
|
||||
* The fragment after the hash
|
||||
*
|
||||
* @var string|false
|
||||
*/
|
||||
protected $fragment;
|
||||
protected string|false|null $fragment = null;
|
||||
|
||||
/**
|
||||
* The host address
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host;
|
||||
protected string|null $host = null;
|
||||
|
||||
/**
|
||||
* The optional password for basic authentication
|
||||
*
|
||||
* @var string|false
|
||||
*/
|
||||
protected $password;
|
||||
protected string|false|null $password = null;
|
||||
|
||||
/**
|
||||
* The optional list of params
|
||||
*
|
||||
* @var Params
|
||||
*/
|
||||
protected $params;
|
||||
protected Params|null $params = null;
|
||||
|
||||
/**
|
||||
* The optional path
|
||||
*
|
||||
* @var Path
|
||||
*/
|
||||
protected $path;
|
||||
protected Path|null $path = null;
|
||||
|
||||
/**
|
||||
* The optional port number
|
||||
*
|
||||
* @var int|false
|
||||
*/
|
||||
protected $port;
|
||||
protected int|false|null $port = null;
|
||||
|
||||
/**
|
||||
* All original properties
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $props;
|
||||
protected array $props;
|
||||
|
||||
/**
|
||||
* The optional query string without leading ?
|
||||
*
|
||||
* @var Query
|
||||
*/
|
||||
protected $query;
|
||||
protected Query|null $query = null;
|
||||
|
||||
/**
|
||||
* https or http
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $scheme = 'http';
|
||||
protected string|null $scheme = 'http';
|
||||
|
||||
/**
|
||||
* Supported schemes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $schemes = ['http', 'https', 'ftp'];
|
||||
protected static array $schemes = ['http', 'https', 'ftp'];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $slash = false;
|
||||
protected bool $slash = false;
|
||||
|
||||
/**
|
||||
* The optional username for basic authentication
|
||||
*
|
||||
* @var string|false
|
||||
*/
|
||||
protected $username;
|
||||
protected string|false|null $username = null;
|
||||
|
||||
/**
|
||||
* Magic caller to access all properties
|
||||
*
|
||||
* @param string $property
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $property, array $arguments = [])
|
||||
{
|
||||
|
@ -124,8 +93,6 @@ class Uri
|
|||
/**
|
||||
* Make sure that cloning also clones
|
||||
* the path and query objects
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
|
@ -137,10 +104,9 @@ class Uri
|
|||
/**
|
||||
* Creates a new URI object
|
||||
*
|
||||
* @param array|string $props
|
||||
* @param array $inject Additional props to inject if a URL string is passed
|
||||
*/
|
||||
public function __construct($props = [], array $inject = [])
|
||||
public function __construct(array|string $props = [], array $inject = [])
|
||||
{
|
||||
if (is_string($props) === true) {
|
||||
$props = parse_url($props);
|
||||
|
@ -160,9 +126,6 @@ class Uri
|
|||
|
||||
/**
|
||||
* Magic getter
|
||||
*
|
||||
* @param string $property
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get(string $property)
|
||||
{
|
||||
|
@ -171,10 +134,6 @@ class Uri
|
|||
|
||||
/**
|
||||
* Magic setter
|
||||
*
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function __set(string $property, $value): void
|
||||
{
|
||||
|
@ -185,24 +144,20 @@ class Uri
|
|||
|
||||
/**
|
||||
* Converts the URL object to string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
try {
|
||||
return $this->toString();
|
||||
} catch (Throwable $e) {
|
||||
} catch (Throwable) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the auth details (username:password)
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function auth(): ?string
|
||||
public function auth(): string|null
|
||||
{
|
||||
$auth = trim($this->username . ':' . $this->password);
|
||||
return $auth !== ':' ? $auth : null;
|
||||
|
@ -211,10 +166,8 @@ class Uri
|
|||
/**
|
||||
* Returns the base url (scheme + host)
|
||||
* without trailing slash
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function base(): ?string
|
||||
public function base(): string|null
|
||||
{
|
||||
if ($domain = $this->domain()) {
|
||||
return $this->scheme ? $this->scheme . '://' . $domain : $domain;
|
||||
|
@ -226,11 +179,8 @@ class Uri
|
|||
/**
|
||||
* Clones the Uri object and applies optional
|
||||
* new props.
|
||||
*
|
||||
* @param array $props
|
||||
* @return static
|
||||
*/
|
||||
public function clone(array $props = [])
|
||||
public function clone(array $props = []): static
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
|
@ -241,11 +191,7 @@ class Uri
|
|||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $props
|
||||
* @return static
|
||||
*/
|
||||
public static function current(array $props = [])
|
||||
public static function current(array $props = []): static
|
||||
{
|
||||
if (static::$current !== null) {
|
||||
return static::$current;
|
||||
|
@ -261,11 +207,11 @@ class Uri
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the domain without scheme, path or query
|
||||
*
|
||||
* @return string|null
|
||||
* Returns the domain without scheme, path or query.
|
||||
* Includes auth part when not empty.
|
||||
* Includes port number when different from 80 or 443.
|
||||
*/
|
||||
public function domain(): ?string
|
||||
public function domain(): string|null
|
||||
{
|
||||
if (empty($this->host) === true || $this->host === '/') {
|
||||
return null;
|
||||
|
@ -287,33 +233,21 @@ class Uri
|
|||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFragment(): bool
|
||||
{
|
||||
return empty($this->fragment) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPath(): bool
|
||||
{
|
||||
return $this->path()->isNotEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasQuery(): bool
|
||||
{
|
||||
return $this->query()->isNotEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function https(): bool
|
||||
{
|
||||
return $this->scheme() === 'https';
|
||||
|
@ -325,7 +259,7 @@ class Uri
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function idn()
|
||||
public function idn(): static
|
||||
{
|
||||
if (empty($this->host) === false) {
|
||||
$this->setHost(Idn::decode($this->host));
|
||||
|
@ -336,11 +270,8 @@ class Uri
|
|||
/**
|
||||
* Creates an Uri object for the URL to the index.php
|
||||
* or any other executed script.
|
||||
*
|
||||
* @param array $props
|
||||
* @return static
|
||||
*/
|
||||
public static function index(array $props = [])
|
||||
public static function index(array $props = []): static
|
||||
{
|
||||
if ($app = App::instance(null, true)) {
|
||||
$url = $app->url('index');
|
||||
|
@ -353,8 +284,6 @@ class Uri
|
|||
|
||||
/**
|
||||
* Checks if the host exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAbsolute(): bool
|
||||
{
|
||||
|
@ -362,30 +291,27 @@ class Uri
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string|null $fragment
|
||||
* @return $this
|
||||
*/
|
||||
public function setFragment(string $fragment = null)
|
||||
public function setFragment(string|null $fragment = null): static
|
||||
{
|
||||
$this->fragment = $fragment ? ltrim($fragment, '#') : null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @return $this
|
||||
*/
|
||||
public function setHost(string $host = null)
|
||||
public function setHost(string|null $host = null): static
|
||||
{
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Kirby\Http\Params|string|array|false|null $params
|
||||
* @return $this
|
||||
*/
|
||||
public function setParams($params = null)
|
||||
public function setParams(Params|string|array|false|null $params = null): static
|
||||
{
|
||||
// ensure that the special constructor value of `false`
|
||||
// is never passed through as it's not supported by `Params`
|
||||
|
@ -393,35 +319,32 @@ class Uri
|
|||
$params = [];
|
||||
}
|
||||
|
||||
$this->params = is_a($params, 'Kirby\Http\Params') === true ? $params : new Params($params);
|
||||
$this->params = $params instanceof Params ? $params : new Params($params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $password
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword(string $password = null)
|
||||
public function setPassword(string|null $password = null): static
|
||||
{
|
||||
$this->password = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Kirby\Http\Path|string|array|null $path
|
||||
* @return $this
|
||||
*/
|
||||
public function setPath($path = null)
|
||||
public function setPath(Path|string|array|null $path = null): static
|
||||
{
|
||||
$this->path = is_a($path, 'Kirby\Http\Path') === true ? $path : new Path($path);
|
||||
$this->path = $path instanceof Path ? $path : new Path($path);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $port
|
||||
* @return $this
|
||||
*/
|
||||
public function setPort(int $port = null)
|
||||
public function setPort(int|null $port = null): static
|
||||
{
|
||||
if ($port === 0) {
|
||||
$port = null;
|
||||
|
@ -438,20 +361,18 @@ class Uri
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \Kirby\Http\Query|string|array|null $query
|
||||
* @return $this
|
||||
*/
|
||||
public function setQuery($query = null)
|
||||
public function setQuery(Query|string|array|null $query = null): static
|
||||
{
|
||||
$this->query = is_a($query, 'Kirby\Http\Query') === true ? $query : new Query($query);
|
||||
$this->query = $query instanceof Query ? $query : new Query($query);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @return $this
|
||||
*/
|
||||
public function setScheme(string $scheme = null)
|
||||
public function setScheme(string|null $scheme = null): static
|
||||
{
|
||||
if ($scheme !== null && in_array($scheme, static::$schemes) === false) {
|
||||
throw new InvalidArgumentException('Invalid URL scheme: ' . $scheme);
|
||||
|
@ -465,20 +386,18 @@ class Uri
|
|||
* Set if a trailing slash should be added to
|
||||
* the path when the URI is being built
|
||||
*
|
||||
* @param bool $slash
|
||||
* @return $this
|
||||
*/
|
||||
public function setSlash(bool $slash = false)
|
||||
public function setSlash(bool $slash = false): static
|
||||
{
|
||||
$this->slash = $slash;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $username
|
||||
* @return $this
|
||||
*/
|
||||
public function setUsername(string $username = null)
|
||||
public function setUsername(string|null $username = null): static
|
||||
{
|
||||
$this->username = $username;
|
||||
return $this;
|
||||
|
@ -486,8 +405,6 @@ class Uri
|
|||
|
||||
/**
|
||||
* Converts the Url object to an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
@ -513,8 +430,6 @@ class Uri
|
|||
|
||||
/**
|
||||
* Returns the full URL as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
|
@ -548,7 +463,7 @@ class Uri
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function unIdn()
|
||||
public function unIdn(): static
|
||||
{
|
||||
if (empty($this->host) === false) {
|
||||
$this->setHost(Idn::encode($this->host));
|
||||
|
@ -560,7 +475,6 @@ class Uri
|
|||
* Parses the path inside the props and extracts
|
||||
* the params unless disabled
|
||||
*
|
||||
* @param array $props
|
||||
* @return array Modified props array
|
||||
*/
|
||||
protected static function parsePath(array $props): array
|
||||
|
|
|
@ -17,26 +17,18 @@ class Url
|
|||
{
|
||||
/**
|
||||
* The base Url to build absolute Urls from
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $home = '/';
|
||||
public static string|null $home = '/';
|
||||
|
||||
/**
|
||||
* The current Uri object
|
||||
*
|
||||
* @var Uri
|
||||
* The current Uri object as string
|
||||
*/
|
||||
public static $current = null;
|
||||
public static string|null $current = null;
|
||||
|
||||
/**
|
||||
* Facade for all Uri object methods
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic(string $method, $arguments)
|
||||
public static function __callStatic(string $method, array $arguments)
|
||||
{
|
||||
return (new Uri($arguments[0] ?? static::current()))->$method(...array_slice($arguments, 1));
|
||||
}
|
||||
|
@ -44,30 +36,22 @@ class Url
|
|||
/**
|
||||
* Url Builder
|
||||
* Actually just a factory for `new Uri($parts)`
|
||||
*
|
||||
* @param array $parts
|
||||
* @param string|null $url
|
||||
* @return string
|
||||
*/
|
||||
public static function build(array $parts = [], string $url = null): string
|
||||
public static function build(array $parts = [], string|null $url = null): string
|
||||
{
|
||||
return (string)(new Uri($url ?? static::current()))->clone($parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current url with all bells and whistles
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function current(): string
|
||||
{
|
||||
return static::$current = static::$current ?? static::toObject()->toString();
|
||||
return static::$current ??= static::toObject()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url for the current directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function currentDir(): string
|
||||
{
|
||||
|
@ -76,11 +60,9 @@ class Url
|
|||
|
||||
/**
|
||||
* Tries to fix a broken url without protocol
|
||||
*
|
||||
* @param string|null $url
|
||||
* @return string
|
||||
* @psalm-return ($url is null ? string|null : string)
|
||||
*/
|
||||
public static function fix(string $url = null): string
|
||||
public static function fix(string|null $url = null): string|null
|
||||
{
|
||||
// make sure to not touch absolute urls
|
||||
return (!preg_match('!^(https|http|ftp)\:\/\/!i', $url ?? '')) ? 'http://' . $url : $url;
|
||||
|
@ -88,8 +70,6 @@ class Url
|
|||
|
||||
/**
|
||||
* Returns the home url if defined
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function home(): string
|
||||
{
|
||||
|
@ -98,9 +78,6 @@ class Url
|
|||
|
||||
/**
|
||||
* Returns the url to the executed script
|
||||
*
|
||||
* @param array $props
|
||||
* @return string
|
||||
*/
|
||||
public static function index(array $props = []): string
|
||||
{
|
||||
|
@ -109,11 +86,8 @@ class Url
|
|||
|
||||
/**
|
||||
* Checks if an URL is absolute
|
||||
*
|
||||
* @param string|null $url
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAbsolute(string $url = null): bool
|
||||
public static function isAbsolute(string|null $url = null): bool
|
||||
{
|
||||
// matches the following groups of URLs:
|
||||
// //example.com/uri
|
||||
|
@ -124,12 +98,8 @@ class Url
|
|||
|
||||
/**
|
||||
* Convert a relative path into an absolute URL
|
||||
*
|
||||
* @param string|null $path
|
||||
* @param string|null $home
|
||||
* @return string
|
||||
*/
|
||||
public static function makeAbsolute(string $path = null, string $home = null): string
|
||||
public static function makeAbsolute(string|null $path = null, string|null $home = null): string
|
||||
{
|
||||
if ($path === '' || $path === '/' || $path === null) {
|
||||
return $home ?? static::home();
|
||||
|
@ -156,32 +126,22 @@ class Url
|
|||
|
||||
/**
|
||||
* Returns the path for the given url
|
||||
*
|
||||
* @param string|array|null $url
|
||||
* @param bool $leadingSlash
|
||||
* @param bool $trailingSlash
|
||||
* @return string
|
||||
*/
|
||||
public static function path($url = null, bool $leadingSlash = false, bool $trailingSlash = false): string
|
||||
public static function path(string|array|null $url = null, bool $leadingSlash = false, bool $trailingSlash = false): string
|
||||
{
|
||||
return Url::toObject($url)->path()->toString($leadingSlash, $trailingSlash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query for the given url
|
||||
*
|
||||
* @param string|array|null $url
|
||||
* @return string
|
||||
*/
|
||||
public static function query($url = null): string
|
||||
public static function query(string|array|null $url = null): string
|
||||
{
|
||||
return Url::toObject($url)->query()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last url the user has been on if detectable
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function last(): string
|
||||
{
|
||||
|
@ -190,14 +150,8 @@ class Url
|
|||
|
||||
/**
|
||||
* Shortens the Url by removing all unnecessary parts
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $length
|
||||
* @param bool $base
|
||||
* @param string $rep
|
||||
* @return string
|
||||
*/
|
||||
public static function short($url = null, int $length = 0, bool $base = false, string $rep = '…'): string
|
||||
public static function short(string|null $url = null, int $length = 0, bool $base = false, string $rep = '…'): string
|
||||
{
|
||||
$uri = static::toObject($url);
|
||||
|
||||
|
@ -219,45 +173,32 @@ class Url
|
|||
|
||||
/**
|
||||
* Removes the path from the Url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function stripPath($url = null): string
|
||||
public static function stripPath(string|null $url = null): string
|
||||
{
|
||||
return static::toObject($url)->setPath(null)->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the query string from the Url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function stripQuery($url = null): string
|
||||
public static function stripQuery(string|null $url = null): string
|
||||
{
|
||||
return static::toObject($url)->setQuery(null)->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the fragment (hash) from the Url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function stripFragment($url = null): string
|
||||
public static function stripFragment(string|null $url = null): string
|
||||
{
|
||||
return static::toObject($url)->setFragment(null)->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart resolver for internal and external urls
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $options
|
||||
* @return string
|
||||
*/
|
||||
public static function to(string $path = null, $options = null): string
|
||||
public static function to(string|null $path = null, array $options = null): string
|
||||
{
|
||||
// make sure $path is string
|
||||
$path ??= '';
|
||||
|
@ -278,11 +219,8 @@ class Url
|
|||
|
||||
/**
|
||||
* Converts the Url to a Uri object
|
||||
*
|
||||
* @param string $url
|
||||
* @return \Kirby\Http\Uri
|
||||
*/
|
||||
public static function toObject($url = null)
|
||||
public static function toObject(string|null $url = null): Uri
|
||||
{
|
||||
return $url === null ? Uri::current() : new Uri($url);
|
||||
}
|
||||
|
|
|
@ -20,29 +20,10 @@ use Kirby\Toolkit\Str;
|
|||
*/
|
||||
class Visitor
|
||||
{
|
||||
/**
|
||||
* IP address
|
||||
* @var string|null
|
||||
*/
|
||||
protected $ip;
|
||||
|
||||
/**
|
||||
* user agent
|
||||
* @var string|null
|
||||
*/
|
||||
protected $userAgent;
|
||||
|
||||
/**
|
||||
* accepted language
|
||||
* @var string|null
|
||||
*/
|
||||
protected $acceptedLanguage;
|
||||
|
||||
/**
|
||||
* accepted mime type
|
||||
* @var string|null
|
||||
*/
|
||||
protected $acceptedMimeType;
|
||||
protected string|null $ip = null;
|
||||
protected string|null $userAgent = null;
|
||||
protected string|null $acceptedLanguage = null;
|
||||
protected string|null $acceptedMimeType = null;
|
||||
|
||||
/**
|
||||
* Creates a new visitor object.
|
||||
|
@ -50,8 +31,6 @@ class Visitor
|
|||
* modify the information about the visitor.
|
||||
*
|
||||
* By default everything is pulled from $_SERVER
|
||||
*
|
||||
* @param array $arguments
|
||||
*/
|
||||
public function __construct(array $arguments = [])
|
||||
{
|
||||
|
@ -66,10 +45,9 @@ class Visitor
|
|||
* provided or returns the user's
|
||||
* accepted language otherwise
|
||||
*
|
||||
* @param string|null $acceptedLanguage
|
||||
* @return \Kirby\Toolkit\Obj|\Kirby\Http\Visitor|null
|
||||
* @return $this|\Kirby\Toolkit\Obj|null
|
||||
*/
|
||||
public function acceptedLanguage(string $acceptedLanguage = null)
|
||||
public function acceptedLanguage(string|null $acceptedLanguage = null): static|Obj|null
|
||||
{
|
||||
if ($acceptedLanguage === null) {
|
||||
return $this->acceptedLanguages()->first();
|
||||
|
@ -82,10 +60,8 @@ class Visitor
|
|||
/**
|
||||
* Returns an array of all accepted languages
|
||||
* including their quality and locale
|
||||
*
|
||||
* @return \Kirby\Toolkit\Collection
|
||||
*/
|
||||
public function acceptedLanguages()
|
||||
public function acceptedLanguages(): Collection
|
||||
{
|
||||
$accepted = Str::accepted($this->acceptedLanguage);
|
||||
$languages = [];
|
||||
|
@ -111,9 +87,6 @@ class Visitor
|
|||
|
||||
/**
|
||||
* Checks if the user accepts the given language
|
||||
*
|
||||
* @param string $code
|
||||
* @return bool
|
||||
*/
|
||||
public function acceptsLanguage(string $code): bool
|
||||
{
|
||||
|
@ -133,10 +106,9 @@ class Visitor
|
|||
* provided or returns the user's
|
||||
* accepted mime type otherwise
|
||||
*
|
||||
* @param string|null $acceptedMimeType
|
||||
* @return \Kirby\Toolkit\Obj|\Kirby\Http\Visitor
|
||||
* @return $this|\Kirby\Toolkit\Obj|null
|
||||
*/
|
||||
public function acceptedMimeType(string $acceptedMimeType = null)
|
||||
public function acceptedMimeType(string|null $acceptedMimeType = null): static|Obj|null
|
||||
{
|
||||
if ($acceptedMimeType === null) {
|
||||
return $this->acceptedMimeTypes()->first();
|
||||
|
@ -148,10 +120,8 @@ class Visitor
|
|||
|
||||
/**
|
||||
* Returns a collection of all accepted mime types
|
||||
*
|
||||
* @return \Kirby\Toolkit\Collection
|
||||
*/
|
||||
public function acceptedMimeTypes()
|
||||
public function acceptedMimeTypes(): Collection
|
||||
{
|
||||
$accepted = Str::accepted($this->acceptedMimeType);
|
||||
$mimes = [];
|
||||
|
@ -168,9 +138,6 @@ class Visitor
|
|||
|
||||
/**
|
||||
* Checks if the user accepts the given mime type
|
||||
*
|
||||
* @param string $mimeType
|
||||
* @return bool
|
||||
*/
|
||||
public function acceptsMimeType(string $mimeType): bool
|
||||
{
|
||||
|
@ -185,7 +152,7 @@ class Visitor
|
|||
* @param string ...$mimeTypes MIME types to query for
|
||||
* @return string|null Preferred MIME type
|
||||
*/
|
||||
public function preferredMimeType(string ...$mimeTypes): ?string
|
||||
public function preferredMimeType(string ...$mimeTypes): string|null
|
||||
{
|
||||
foreach ($this->acceptedMimeTypes() as $acceptedMime) {
|
||||
// look for direct matches
|
||||
|
@ -208,8 +175,6 @@ class Visitor
|
|||
* Returns true if the visitor prefers a JSON response over
|
||||
* an HTML response based on the `Accept` request header
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function prefersJson(): bool
|
||||
{
|
||||
|
@ -221,10 +186,9 @@ class Visitor
|
|||
* or returns the ip of the current
|
||||
* visitor otherwise
|
||||
*
|
||||
* @param string|null $ip
|
||||
* @return string|Visitor|null
|
||||
* @return $this|string|null
|
||||
*/
|
||||
public function ip(string $ip = null)
|
||||
public function ip(string|null $ip = null): static|string|null
|
||||
{
|
||||
if ($ip === null) {
|
||||
return $this->ip;
|
||||
|
@ -238,10 +202,9 @@ class Visitor
|
|||
* or returns the user agent string of
|
||||
* the current visitor otherwise
|
||||
*
|
||||
* @param string|null $userAgent
|
||||
* @return string|Visitor|null
|
||||
* @return $this|string|null
|
||||
*/
|
||||
public function userAgent(string $userAgent = null)
|
||||
public function userAgent(string|null $userAgent = null): static|string|null
|
||||
{
|
||||
if ($userAgent === null) {
|
||||
return $this->userAgent;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue