composer update
This commit is contained in:
parent
0b3c362c5e
commit
a1f0701630
142 changed files with 4530 additions and 1195 deletions
|
|
@ -222,7 +222,6 @@ class Cookie
|
|||
protected static function trackUsage(string $key): void
|
||||
{
|
||||
// lazily request the instance for non-CMS use cases
|
||||
$kirby = App::instance(null, true);
|
||||
$kirby?->response()->usesCookie($key);
|
||||
App::instance(lazy: true)?->response()->usesCookie($key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ use Kirby\Toolkit\Str;
|
|||
* secure host and base URL detection, as
|
||||
* well as loading the dedicated
|
||||
* environment options.
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @package Kirby Http
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class Environment
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class Header
|
|||
|
||||
$header = 'Content-type: ' . $mime;
|
||||
|
||||
if (empty($charset) === false) {
|
||||
if ($charset !== '') {
|
||||
$header .= '; charset=' . $charset;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Params extends Obj implements Stringable
|
|||
*/
|
||||
public static function extract(string|array|null $path = null): array
|
||||
{
|
||||
if (empty($path) === true) {
|
||||
if ($path === null || $path === '' || $path === []) {
|
||||
return [
|
||||
'path' => null,
|
||||
'params' => null,
|
||||
|
|
@ -62,12 +62,16 @@ class Params extends Obj implements Stringable
|
|||
continue;
|
||||
}
|
||||
|
||||
$paramParts = Str::split($p, $separator);
|
||||
$paramKey = $paramParts[0] ?? null;
|
||||
$paramValue = $paramParts[1] ?? null;
|
||||
$parts = Str::split($p, $separator);
|
||||
|
||||
if ($paramKey !== null) {
|
||||
$params[rawurldecode($paramKey)] = $paramValue !== null ? rawurldecode($paramValue) : null;
|
||||
if ($key = $parts[0] ?? null) {
|
||||
$key = rawurldecode($key);
|
||||
|
||||
if ($value = $parts[1] ?? null) {
|
||||
$value = rawurldecode($value);
|
||||
}
|
||||
|
||||
$params[$key] = $value;
|
||||
}
|
||||
|
||||
unset($path[$index]);
|
||||
|
|
@ -89,7 +93,7 @@ class Params extends Obj implements Stringable
|
|||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty((array)$this) === true;
|
||||
return (array)$this === [];
|
||||
}
|
||||
|
||||
public function isNotEmpty(): bool
|
||||
|
|
@ -97,6 +101,23 @@ class Params extends Obj implements Stringable
|
|||
return $this->isEmpty() === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the current params with the given params
|
||||
* @since 5.1.0
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function merge(array|string|null $params): static
|
||||
{
|
||||
$params = new static($params);
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the param separator according
|
||||
* to the operating system.
|
||||
|
|
@ -106,15 +127,7 @@ class Params extends Obj implements Stringable
|
|||
*/
|
||||
public static function separator(): string
|
||||
{
|
||||
if (static::$separator !== null) {
|
||||
return static::$separator;
|
||||
}
|
||||
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
return static::$separator = ':';
|
||||
}
|
||||
|
||||
return static::$separator = ';';
|
||||
return static::$separator ??= DIRECTORY_SEPARATOR === '/' ? ':' : ';';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -134,7 +147,9 @@ class Params extends Obj implements Stringable
|
|||
|
||||
foreach ($this as $key => $value) {
|
||||
if ($value !== null && $value !== '') {
|
||||
$params[] = rawurlencode($key) . $separator . rawurlencode($value);
|
||||
$key = rawurlencode($key);
|
||||
$value = rawurlencode($value);
|
||||
$params[] = $key . $separator . $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Query extends Obj implements Stringable
|
|||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty((array)$this) === true;
|
||||
return (array)$this === [];
|
||||
}
|
||||
|
||||
public function isNotEmpty(): bool
|
||||
|
|
@ -37,11 +37,28 @@ class Query extends Obj implements Stringable
|
|||
return $this->isEmpty() === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the current query with the given query
|
||||
* @since 5.1.0
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function merge(string|array|null $query): static
|
||||
{
|
||||
$query = new static($query);
|
||||
|
||||
foreach ($query as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toString(bool $questionMark = false): string
|
||||
{
|
||||
$query = http_build_query($this, '', '&', PHP_QUERY_RFC3986);
|
||||
|
||||
if (empty($query) === true) {
|
||||
if ($query === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,13 +47,14 @@ class Remote
|
|||
public string $errorMessage;
|
||||
public array $headers = [];
|
||||
public array $info = [];
|
||||
public array $options = [];
|
||||
|
||||
/**
|
||||
* @throws \Exception when the curl request failed
|
||||
*/
|
||||
public function __construct(string $url, array $options = [])
|
||||
{
|
||||
public function __construct(
|
||||
string $url,
|
||||
public array $options = []
|
||||
) {
|
||||
$defaults = static::$defaults;
|
||||
|
||||
// use the system CA store by default if
|
||||
|
|
@ -71,11 +72,8 @@ class Remote
|
|||
$defaults = [...$defaults, ...$app->option('remote', [])];
|
||||
}
|
||||
|
||||
// set all options
|
||||
$this->options = [...$defaults, ...$options];
|
||||
|
||||
// add the url
|
||||
$this->options['url'] = $url;
|
||||
// set all options, incl. url
|
||||
$this->options = [...$defaults, ...$options, 'url' => $url];
|
||||
|
||||
// send the request
|
||||
$this->fetch();
|
||||
|
|
@ -277,7 +275,7 @@ class Remote
|
|||
|
||||
$query = http_build_query($options['data']);
|
||||
|
||||
if (empty($query) === false) {
|
||||
if ($query !== '') {
|
||||
$url = match (Url::hasQuery($url)) {
|
||||
true => $url . '&' . $query,
|
||||
default => $url . '?' . $query
|
||||
|
|
@ -339,7 +337,7 @@ class Remote
|
|||
*/
|
||||
protected function postfields($data)
|
||||
{
|
||||
if (is_object($data) || is_array($data)) {
|
||||
if (is_object($data) === true || is_array($data) === true) {
|
||||
return http_build_query($data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,12 +67,6 @@ class Request
|
|||
*/
|
||||
protected string $method;
|
||||
|
||||
/**
|
||||
* All options that have been passed to
|
||||
* the request in the constructor
|
||||
*/
|
||||
protected array $options;
|
||||
|
||||
/**
|
||||
* The Query object is a wrapper around
|
||||
* the URL query string, which parses the
|
||||
|
|
@ -96,9 +90,9 @@ class Request
|
|||
* data via the $options array or use
|
||||
* the data from the incoming request.
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = $options;
|
||||
public function __construct(
|
||||
protected array $options = []
|
||||
) {
|
||||
$this->method = $this->detectRequestMethod($options['method'] ?? null);
|
||||
|
||||
if (isset($options['body']) === true) {
|
||||
|
|
@ -155,7 +149,7 @@ class Request
|
|||
}
|
||||
|
||||
// lazily request the instance for non-CMS use cases
|
||||
$kirby = App::instance(null, true);
|
||||
$kirby = App::instance(lazy: true);
|
||||
|
||||
// tell the CMS responder that the response relies on
|
||||
// the `Authorization` header and its value (even if
|
||||
|
|
@ -224,13 +218,26 @@ class Request
|
|||
public function detectRequestMethod(string|null $method = null): string
|
||||
{
|
||||
// all possible methods
|
||||
$methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'];
|
||||
$methods = [
|
||||
'CONNECT',
|
||||
'DELETE',
|
||||
'GET',
|
||||
'HEAD',
|
||||
'OPTIONS',
|
||||
'PATCH',
|
||||
'POST',
|
||||
'PUT',
|
||||
'TRACE',
|
||||
];
|
||||
|
||||
// the request method can be overwritten with a header
|
||||
$methodOverride = strtoupper(Environment::getGlobally('HTTP_X_HTTP_METHOD_OVERRIDE', ''));
|
||||
if ($method === null) {
|
||||
$override = Environment::getGlobally('HTTP_X_HTTP_METHOD_OVERRIDE', '');
|
||||
$override = strtoupper($override);
|
||||
|
||||
if (in_array($methodOverride, $methods, true) === true) {
|
||||
$method ??= $methodOverride;
|
||||
if (in_array($override, $methods, true) === true) {
|
||||
$method = $override;
|
||||
}
|
||||
}
|
||||
|
||||
// final chain of options to detect the method
|
||||
|
|
@ -410,14 +417,15 @@ class Request
|
|||
// 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) {
|
||||
|
||||
if (is_string($option) === true && $option !== '') {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$header = $this->header('authorization');
|
||||
if (empty($header) === false) {
|
||||
|
||||
if (is_string($header) === true && $header !== '') {
|
||||
return $header;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,6 @@ class Body implements Stringable
|
|||
{
|
||||
use Data;
|
||||
|
||||
/**
|
||||
* The raw body content
|
||||
*/
|
||||
protected string|array|null $contents;
|
||||
|
||||
/**
|
||||
* The parsed content as array
|
||||
*/
|
||||
|
|
@ -36,10 +31,12 @@ class Body implements Stringable
|
|||
* 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 The raw body content
|
||||
*/
|
||||
public function __construct(array|string|null $contents = null)
|
||||
{
|
||||
$this->contents = $contents;
|
||||
public function __construct(
|
||||
protected array|string|null $contents = null
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,7 +49,7 @@ class Body implements Stringable
|
|||
return $this->contents;
|
||||
}
|
||||
|
||||
if (empty($_POST) === false) {
|
||||
if ($_POST !== []) {
|
||||
return $this->contents = $_POST;
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +87,7 @@ class Body implements Stringable
|
|||
// try to parse the body as query string
|
||||
parse_str($contents, $parsed);
|
||||
|
||||
if (is_array($parsed)) {
|
||||
if (is_array($parsed) === true) {
|
||||
return $this->data = $parsed;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,9 +45,11 @@ trait Data
|
|||
{
|
||||
if (is_array($key) === true) {
|
||||
$result = [];
|
||||
|
||||
foreach ($key as $k) {
|
||||
$result[$k] = $this->get($k);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Files
|
|||
$files ??= $_FILES;
|
||||
|
||||
foreach ($files as $key => $file) {
|
||||
if (is_array($file['name'])) {
|
||||
if (is_array($file['name']) === true) {
|
||||
foreach ($file['name'] as $i => $name) {
|
||||
$this->files[$key][] = [
|
||||
'name' => $file['name'][$i] ?? null,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class Query implements Stringable
|
|||
/**
|
||||
* The Query data array
|
||||
*/
|
||||
protected array|null $data = null;
|
||||
protected array $data;
|
||||
|
||||
/**
|
||||
* Creates a new Query object.
|
||||
|
|
@ -56,7 +56,7 @@ class Query implements Stringable
|
|||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->data) === true;
|
||||
return $this->data === [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -64,7 +64,7 @@ class Query implements Stringable
|
|||
*/
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
return empty($this->data) === false;
|
||||
return $this->data !== [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -281,8 +281,11 @@ class Response implements Stringable
|
|||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function refresh(string $location = '/', int $code = 302, int $refresh = 0): static
|
||||
{
|
||||
public static function refresh(
|
||||
string $location = '/',
|
||||
int $code = 302,
|
||||
int $refresh = 0
|
||||
): static {
|
||||
return new static([
|
||||
'code' => $code,
|
||||
'headers' => [
|
||||
|
|
@ -312,6 +315,19 @@ class Response implements Stringable
|
|||
return $this->body();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the provided headers in case they are not already set
|
||||
* @internal
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeaderFallbacks(array $headers): static
|
||||
{
|
||||
// the case-insensitive nature of headers will be
|
||||
// handled by PHP's `header()` functions
|
||||
$this->headers = [...$headers, ...$this->headers];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all relevant response attributes
|
||||
* to an associative array for debugging,
|
||||
|
|
|
|||
|
|
@ -13,26 +13,11 @@ use Closure;
|
|||
*/
|
||||
class Route
|
||||
{
|
||||
/**
|
||||
* The callback action function
|
||||
*/
|
||||
protected Closure $action;
|
||||
|
||||
/**
|
||||
* Listed of parsed arguments
|
||||
*/
|
||||
protected array $arguments = [];
|
||||
|
||||
/**
|
||||
* An array of all passed attributes
|
||||
*/
|
||||
protected array $attributes = [];
|
||||
|
||||
/**
|
||||
* The registered request method
|
||||
*/
|
||||
protected string $method;
|
||||
|
||||
/**
|
||||
* The registered pattern
|
||||
*/
|
||||
|
|
@ -74,14 +59,11 @@ class Route
|
|||
*/
|
||||
public function __construct(
|
||||
string $pattern,
|
||||
string $method,
|
||||
Closure $action,
|
||||
array $attributes = []
|
||||
protected string $method,
|
||||
protected Closure $action,
|
||||
protected array $attributes = []
|
||||
) {
|
||||
$this->action = $action;
|
||||
$this->attributes = $attributes;
|
||||
$this->method = $method;
|
||||
$this->pattern = $this->regex(ltrim($pattern, '/'));
|
||||
$this->pattern = $this->regex(ltrim($pattern, '/'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -158,6 +158,9 @@ class Router
|
|||
* The Route's arguments method is used to
|
||||
* find matches and return all the found
|
||||
* arguments in the path.
|
||||
*
|
||||
* @param array|null $ignore (Passing null has been deprecated)
|
||||
* @todo Remove support for `$ignore = null` in v6
|
||||
*/
|
||||
public function find(
|
||||
string $path,
|
||||
|
|
@ -172,16 +175,14 @@ class Router
|
|||
}
|
||||
|
||||
// remove leading and trailing slashes
|
||||
$path = trim($path, '/');
|
||||
$path = trim($path, '/');
|
||||
$ignore ??= [];
|
||||
|
||||
foreach ($this->routes[$method] as $route) {
|
||||
$arguments = $route->parse($route->pattern(), $path);
|
||||
|
||||
if ($arguments !== false) {
|
||||
if (
|
||||
empty($ignore) === true ||
|
||||
in_array($route, $ignore, true) === false
|
||||
) {
|
||||
if (in_array($route, $ignore, true) === false) {
|
||||
return $this->route = $route;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,10 +216,10 @@ class Uri implements Stringable
|
|||
|
||||
if ($app = App::instance(null, true)) {
|
||||
$environment = $app->environment();
|
||||
} else {
|
||||
$environment = new Environment();
|
||||
}
|
||||
|
||||
$environment ??= new Environment();
|
||||
|
||||
return new static($environment->requestUrl(), $props);
|
||||
}
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ class Uri implements Stringable
|
|||
*/
|
||||
public function domain(): string|null
|
||||
{
|
||||
if (empty($this->host) === true || $this->host === '/') {
|
||||
if ($this->host === null || $this->host === '' || $this->host === '/') {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ class Uri implements Stringable
|
|||
|
||||
public function hasFragment(): bool
|
||||
{
|
||||
return empty($this->fragment) === false;
|
||||
return $this->fragment !== null && $this->fragment !== '';
|
||||
}
|
||||
|
||||
public function hasPath(): bool
|
||||
|
|
@ -281,8 +281,9 @@ class Uri implements Stringable
|
|||
*/
|
||||
public function idn(): static
|
||||
{
|
||||
if (empty($this->host) === false) {
|
||||
$this->setHost(Idn::decode($this->host));
|
||||
if ($this->isAbsolute() === true) {
|
||||
$host = Idn::decode($this->host);
|
||||
$this->setHost($host);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
|
@ -295,10 +296,10 @@ class Uri implements Stringable
|
|||
{
|
||||
if ($app = App::instance(null, true)) {
|
||||
$url = $app->url('index');
|
||||
} else {
|
||||
$url = (new Environment())->baseUrl();
|
||||
}
|
||||
|
||||
$url ??= (new Environment())->baseUrl();
|
||||
|
||||
return new static($url, $props);
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +308,16 @@ class Uri implements Stringable
|
|||
*/
|
||||
public function isAbsolute(): bool
|
||||
{
|
||||
return empty($this->host) === false;
|
||||
return $this->host !== null && $this->host !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fragment after the hash
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function fragment(): string|null
|
||||
{
|
||||
return $this->fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -465,7 +475,7 @@ class Uri implements Stringable
|
|||
$url = $this->base();
|
||||
$slash = true;
|
||||
|
||||
if (empty($url) === true) {
|
||||
if ($url === null || $url === '') {
|
||||
$url = '/';
|
||||
$slash = false;
|
||||
}
|
||||
|
|
@ -479,8 +489,8 @@ class Uri implements Stringable
|
|||
$url .= $path;
|
||||
$url .= $this->query->toString(true);
|
||||
|
||||
if (empty($this->fragment) === false) {
|
||||
$url .= '#' . $this->fragment;
|
||||
if ($this->hasFragment() === true) {
|
||||
$url .= '#' . $this->fragment();
|
||||
}
|
||||
|
||||
return $url;
|
||||
|
|
@ -494,8 +504,9 @@ class Uri implements Stringable
|
|||
*/
|
||||
public function unIdn(): static
|
||||
{
|
||||
if (empty($this->host) === false) {
|
||||
$this->setHost(Idn::encode($this->host));
|
||||
if ($this->isAbsolute() === true) {
|
||||
$host = Idn::encode($this->host);
|
||||
$this->setHost($host);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,8 +110,10 @@ class Url
|
|||
/**
|
||||
* Convert a relative path into an absolute URL
|
||||
*/
|
||||
public static function makeAbsolute(string|null $path = null, string|null $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();
|
||||
}
|
||||
|
|
@ -120,7 +122,7 @@ class Url
|
|||
return $path;
|
||||
}
|
||||
|
||||
if (static::isAbsolute($path)) {
|
||||
if (static::isAbsolute($path) === true) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
|
|
@ -128,11 +130,15 @@ class Url
|
|||
$path = ltrim($path, '/');
|
||||
$home ??= static::home();
|
||||
|
||||
if (empty($path) === true) {
|
||||
if ($path === '') {
|
||||
return $home;
|
||||
}
|
||||
|
||||
return $home === '/' ? '/' . $path : $home . '/' . $path;
|
||||
if ($home === '/') {
|
||||
return '/' . $path;
|
||||
}
|
||||
|
||||
return $home . '/' . $path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -165,16 +165,16 @@ class Visitor
|
|||
*/
|
||||
public function preferredMimeType(string ...$mimeTypes): string|null
|
||||
{
|
||||
foreach ($this->acceptedMimeTypes() as $acceptedMime) {
|
||||
foreach ($this->acceptedMimeTypes() as $accepted) {
|
||||
// look for direct matches
|
||||
if (in_array($acceptedMime->type(), $mimeTypes, true)) {
|
||||
return $acceptedMime->type();
|
||||
if (in_array($accepted->type(), $mimeTypes, true) === true) {
|
||||
return $accepted->type();
|
||||
}
|
||||
|
||||
// test each option against wildcard `Accept` values
|
||||
foreach ($mimeTypes as $expectedMime) {
|
||||
if (Mime::matches($expectedMime, $acceptedMime->type()) === true) {
|
||||
return $expectedMime;
|
||||
foreach ($mimeTypes as $expected) {
|
||||
if (Mime::matches($expected, $accepted->type()) === true) {
|
||||
return $expected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue