Upgrade to 3.9.1
This commit is contained in:
@@ -1612,13 +1612,11 @@ class App
|
||||
* Uses the snippet component to create
|
||||
* and return a template snippet
|
||||
*
|
||||
* @param mixed $name
|
||||
* @param array|object $data Variables or an object that becomes `$item`
|
||||
* @param bool $return On `false`, directly echo the snippet
|
||||
* @return string|null
|
||||
* @psalm-return ($return is true ? string : null)
|
||||
*/
|
||||
public function snippet($name, $data = [], bool $return = true, bool $slots = false): Snippet|string|null
|
||||
public function snippet(string|array|null $name, $data = [], bool $return = true, bool $slots = false): Snippet|string|null
|
||||
{
|
||||
if (is_object($data) === true) {
|
||||
$data = ['item' => $data];
|
||||
|
@@ -44,7 +44,7 @@ trait AppCaches
|
||||
|
||||
if (array_key_exists($type, $types) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'app.invalid.cacheType',
|
||||
'key' => 'cache.type.invalid',
|
||||
'data' => ['type' => $type]
|
||||
]);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ trait AppCaches
|
||||
// check if it is a usable cache object
|
||||
if ($cache instanceof Cache === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'app.invalid.cacheType',
|
||||
'key' => 'cache.type.invalid',
|
||||
'data' => ['type' => $type]
|
||||
]);
|
||||
}
|
||||
|
@@ -19,21 +19,57 @@ use Kirby\Toolkit\Str;
|
||||
class Helpers
|
||||
{
|
||||
/**
|
||||
* Triggers a deprecation warning if debug mode is active
|
||||
* Allows to disable specific deprecation warnings
|
||||
* by setting them to `false`.
|
||||
* You can do this by putting the following code in
|
||||
* `site/config/config.php`:
|
||||
*
|
||||
* @param string $message
|
||||
* ```php
|
||||
* Helpers::$deprecations['<deprecation-key>'] = false;
|
||||
* ```
|
||||
*/
|
||||
public static $deprecations = [
|
||||
// Passing the $slot or $slots variables to snippets is
|
||||
// deprecated and will break in a future version.
|
||||
'snippet-pass-slots' => true,
|
||||
|
||||
// The `Toolkit\Query` class has been deprecated and will
|
||||
// be removed in a future version. Use `Query\Query` instead:
|
||||
// Kirby\Query\Query::factory($query)->resolve($data).
|
||||
'toolkit-query-class' => true,
|
||||
|
||||
// Passing an empty string as value to `Xml::attr()` has been
|
||||
// deprecated. In a future version, passing an empty string won't
|
||||
// omit the attribute anymore but render it with an empty value.
|
||||
// To omit the attribute, please pass `null`.
|
||||
'xml-attr-empty-string' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* Triggers a deprecation warning if debug mode is active
|
||||
* and warning has not been surpressed via `Helpers::$deprecations`
|
||||
*
|
||||
* @param string|null $key If given, the key will be checked against the static array
|
||||
* @return bool Whether the warning was triggered
|
||||
*/
|
||||
public static function deprecated(string $message): bool
|
||||
public static function deprecated(string $message, string|null $key = null): bool
|
||||
{
|
||||
// only trigger warning in debug mode or when running PHPUnit tests
|
||||
// @codeCoverageIgnoreStart
|
||||
if (
|
||||
App::instance()->option('debug') === true ||
|
||||
(defined('KIRBY_TESTING') === true && KIRBY_TESTING === true)
|
||||
App::instance()->option('debug') !== true &&
|
||||
(defined('KIRBY_TESTING') !== true || KIRBY_TESTING !== true)
|
||||
) {
|
||||
return trigger_error($message, E_USER_DEPRECATED) === true;
|
||||
return false;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// don't trigger the warning if disabled by default or by the dev
|
||||
if ($key !== null && (static::$deprecations[$key] ?? true) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return trigger_error($message, E_USER_DEPRECATED) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -217,9 +217,6 @@ class Cookie
|
||||
{
|
||||
// lazily request the instance for non-CMS use cases
|
||||
$kirby = App::instance(null, true);
|
||||
|
||||
if ($kirby) {
|
||||
$kirby->response()->usesCookie($key);
|
||||
}
|
||||
$kirby?->response()->usesCookie($key);
|
||||
}
|
||||
}
|
||||
|
@@ -152,7 +152,7 @@ class Environment
|
||||
*/
|
||||
public function detect(array $options = null, array $info = null): array
|
||||
{
|
||||
$info ??= $_SERVER;
|
||||
$info ??= $_SERVER;
|
||||
$options = array_merge([
|
||||
'cli' => null,
|
||||
'allowed' => null
|
||||
@@ -922,7 +922,7 @@ class Environment
|
||||
protected function sanitizeScriptPath(string|null $scriptPath = null): string
|
||||
{
|
||||
$scriptPath ??= '';
|
||||
$scriptPath = trim($scriptPath);
|
||||
$scriptPath = trim($scriptPath);
|
||||
|
||||
// skip all the sanitizing steps if the path is empty
|
||||
if ($scriptPath === '') {
|
||||
|
@@ -101,8 +101,11 @@ class Header
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function type(string $mime, string $charset = 'UTF-8', bool $send = true)
|
||||
{
|
||||
public static function type(
|
||||
string $mime,
|
||||
string $charset = 'UTF-8',
|
||||
bool $send = true
|
||||
) {
|
||||
return static::contentType($mime, $charset, $send);
|
||||
}
|
||||
|
||||
@@ -118,17 +121,25 @@ class Header
|
||||
* @return string|void
|
||||
* @psalm-return ($send is false ? string : void)
|
||||
*/
|
||||
public static function status(int|string|null $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');
|
||||
|
||||
// allow full control over code and message
|
||||
if (is_string($code) === true && preg_match('/^\d{3} \w.+$/', $code) === 1) {
|
||||
if (
|
||||
is_string($code) === true &&
|
||||
preg_match('/^\d{3} \w.+$/', $code) === 1
|
||||
) {
|
||||
$message = substr(rtrim($code), 4);
|
||||
$code = substr($code, 0, 3);
|
||||
} else {
|
||||
$code = array_key_exists('_' . $code, $codes) === false ? 500 : $code;
|
||||
if (array_key_exists('_' . $code, $codes) === false) {
|
||||
$code = 500;
|
||||
}
|
||||
|
||||
$message = $codes['_' . $code] ?? 'Something went wrong';
|
||||
}
|
||||
|
||||
|
@@ -120,8 +120,10 @@ class Params extends Obj
|
||||
* Converts the params object to a params string
|
||||
* which can then be used in the URL builder again
|
||||
*/
|
||||
public function toString(bool $leadingSlash = false, bool $trailingSlash = false): string
|
||||
{
|
||||
public function toString(
|
||||
bool $leadingSlash = false,
|
||||
bool $trailingSlash = false
|
||||
): string {
|
||||
if ($this->isEmpty() === true) {
|
||||
return '';
|
||||
}
|
||||
|
@@ -31,8 +31,10 @@ class Path extends Collection
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
public function toString(bool $leadingSlash = false, bool $trailingSlash = false): string
|
||||
{
|
||||
public function toString(
|
||||
bool $leadingSlash = false,
|
||||
bool $trailingSlash = false
|
||||
): string {
|
||||
if (empty($this->data) === true) {
|
||||
return '';
|
||||
}
|
||||
|
@@ -91,7 +91,13 @@ class Remote
|
||||
|
||||
public static function __callStatic(string $method, array $arguments = []): static
|
||||
{
|
||||
return new static($arguments[0], array_merge(['method' => strtoupper($method)], $arguments[1] ?? []));
|
||||
return new static(
|
||||
url: $arguments[0],
|
||||
options: array_merge(
|
||||
['method' => strtoupper($method)],
|
||||
$arguments[1] ?? []
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,10 +182,10 @@ class Remote
|
||||
$headers = [];
|
||||
foreach ($this->options['headers'] as $key => $value) {
|
||||
if (is_string($key) === true) {
|
||||
$headers[] = $key . ': ' . $value;
|
||||
} else {
|
||||
$headers[] = $value;
|
||||
$value = $key . ': ' . $value;
|
||||
}
|
||||
|
||||
$headers[] = $value;
|
||||
}
|
||||
|
||||
$this->curlopt[CURLOPT_HTTPHEADER] = $headers;
|
||||
@@ -264,7 +270,10 @@ class Remote
|
||||
$query = http_build_query($options['data']);
|
||||
|
||||
if (empty($query) === false) {
|
||||
$url = Url::hasQuery($url) === true ? $url . '&' . $query : $url . '?' . $query;
|
||||
$url = match (Url::hasQuery($url)) {
|
||||
true => $url . '&' . $query,
|
||||
default => $url . '?' . $query
|
||||
};
|
||||
}
|
||||
|
||||
// remove the data array from the options
|
||||
|
@@ -147,9 +147,7 @@ class Request
|
||||
// this ensures that the response is only cached for
|
||||
// unauthenticated visitors;
|
||||
// https://github.com/getkirby/kirby/issues/4423#issuecomment-1166300526
|
||||
if ($kirby) {
|
||||
$kirby->response()->usesAuth(true);
|
||||
}
|
||||
$kirby?->response()->usesAuth(true);
|
||||
|
||||
if ($auth = $this->authString()) {
|
||||
$type = Str::lower(Str::before($auth, ' '));
|
||||
@@ -292,7 +290,10 @@ class Request
|
||||
$headers = [];
|
||||
|
||||
foreach (Environment::getGlobally() as $key => $value) {
|
||||
if (substr($key, 0, 5) !== 'HTTP_' && substr($key, 0, 14) !== 'REDIRECT_HTTP_') {
|
||||
if (
|
||||
substr($key, 0, 5) !== 'HTTP_' &&
|
||||
substr($key, 0, 14) !== 'REDIRECT_HTTP_'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -50,8 +50,13 @@ class Response
|
||||
/**
|
||||
* Creates a new response object
|
||||
*/
|
||||
public function __construct(string|array $body = '', string|null $type = null, int|null $code = null, array|null $headers = null, string|null $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) {
|
||||
$params = $body;
|
||||
@@ -127,8 +132,11 @@ class Response
|
||||
*
|
||||
* @param array $props Custom overrides for response props (e.g. headers)
|
||||
*/
|
||||
public static function download(string $file, string|null $filename = null, array $props = []): static
|
||||
{
|
||||
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');
|
||||
}
|
||||
@@ -224,8 +232,12 @@ class Response
|
||||
* Creates a json response with appropriate
|
||||
* header and automatic conversion of arrays.
|
||||
*/
|
||||
public static function json(string|array $body = '', int|null $code = null, bool|null $pretty = null, array $headers = []): static
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@@ -72,8 +72,12 @@ class Route
|
||||
* Creates a new Route object for the given
|
||||
* pattern(s), method(s) and the callback action
|
||||
*/
|
||||
public function __construct(string $pattern, string $method, Closure $action, array $attributes = [])
|
||||
{
|
||||
public function __construct(
|
||||
string $pattern,
|
||||
string $method,
|
||||
Closure $action,
|
||||
array $attributes = []
|
||||
) {
|
||||
$this->action = $action;
|
||||
$this->attributes = $attributes;
|
||||
$this->method = $method;
|
||||
|
@@ -117,7 +117,10 @@ class Router
|
||||
if ($callback) {
|
||||
$result = $callback($route);
|
||||
} else {
|
||||
$result = $route->action()->call($route, ...$route->arguments());
|
||||
$result = $route->action()->call(
|
||||
$route,
|
||||
...$route->arguments()
|
||||
);
|
||||
}
|
||||
|
||||
$loop = false;
|
||||
@@ -139,8 +142,12 @@ class Router
|
||||
* the routing action immediately
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function execute(string|null $path = null, string $method = 'GET', array $routes = [], Closure|null $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);
|
||||
}
|
||||
|
||||
@@ -150,8 +157,11 @@ class Router
|
||||
* find matches and return all the found
|
||||
* arguments in the path.
|
||||
*/
|
||||
public function find(string $path, string $method, array|null $ignore = null): Route
|
||||
{
|
||||
public function find(
|
||||
string $path,
|
||||
string $method,
|
||||
array|null $ignore = null
|
||||
): Route {
|
||||
if (isset($this->routes[$method]) === false) {
|
||||
throw new InvalidArgumentException('Invalid routing method: ' . $method, 400);
|
||||
}
|
||||
@@ -163,7 +173,10 @@ class Router
|
||||
$arguments = $route->parse($route->pattern(), $path);
|
||||
|
||||
if ($arguments !== false) {
|
||||
if (empty($ignore) === true || in_array($route, $ignore) === false) {
|
||||
if (
|
||||
empty($ignore) === true ||
|
||||
in_array($route, $ignore) === false
|
||||
) {
|
||||
return $this->route = $route;
|
||||
}
|
||||
}
|
||||
|
@@ -227,7 +227,10 @@ class Uri
|
||||
|
||||
$domain .= $this->host;
|
||||
|
||||
if ($this->port !== null && in_array($this->port, [80, 443]) === false) {
|
||||
if (
|
||||
$this->port !== null &&
|
||||
in_array($this->port, [80, 443]) === false
|
||||
) {
|
||||
$domain .= ':' . $this->port;
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,8 @@ class Url
|
||||
*/
|
||||
public static function __callStatic(string $method, array $arguments)
|
||||
{
|
||||
return (new Uri($arguments[0] ?? static::current()))->$method(...array_slice($arguments, 1));
|
||||
$uri = new Uri($arguments[0] ?? static::current());
|
||||
return $uri->$method(...array_slice($arguments, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +66,11 @@ class Url
|
||||
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;
|
||||
if (!preg_match('!^(https|http|ftp)\:\/\/!i', $url ?? '')) {
|
||||
return 'http://' . $url;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +98,9 @@ class Url
|
||||
// //example.com/uri
|
||||
// http://example.com/uri, https://example.com/uri, ftp://example.com/uri
|
||||
// mailto:example@example.com, geo:49.0158,8.3239?z=11
|
||||
return $url !== null && preg_match('!^(//|[a-z0-9+-.]+://|mailto:|tel:|geo:)!i', $url) === 1;
|
||||
return
|
||||
$url !== null &&
|
||||
preg_match('!^(//|[a-z0-9+-.]+://|mailto:|tel:|geo:)!i', $url) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,8 +134,11 @@ class Url
|
||||
/**
|
||||
* Returns the path for the given url
|
||||
*/
|
||||
public static function path(string|array|null $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);
|
||||
}
|
||||
|
||||
@@ -151,8 +161,12 @@ class Url
|
||||
/**
|
||||
* Shortens the Url by removing all unnecessary parts
|
||||
*/
|
||||
public static function short(string|null $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);
|
||||
|
||||
$uri->fragment = null;
|
||||
|
@@ -153,11 +153,14 @@ class Snippet extends Tpl
|
||||
* or the template string for self-enclosed snippets
|
||||
*/
|
||||
public static function factory(
|
||||
string|array $name,
|
||||
string|array|null $name,
|
||||
array $data = [],
|
||||
bool $slots = false
|
||||
): static|string {
|
||||
$file = static::file($name);
|
||||
// instead of returning empty string when `$name` is null
|
||||
// allow rest of code to run, otherwise the wrong snippet would be closed
|
||||
// and potential issues for nested snippets may occur
|
||||
$file = $name !== null ? static::file($name) : null;
|
||||
|
||||
// for snippets with slots, make sure to open a new
|
||||
// snippet and start capturing slots
|
||||
@@ -309,7 +312,7 @@ class Snippet extends Tpl
|
||||
array_key_exists('slot', $data) === true ||
|
||||
array_key_exists('slots', $data) === true
|
||||
) {
|
||||
Helpers::deprecated('Passing the $slot or $slots variables to snippets is deprecated and will break in Kirby 3.10.');
|
||||
Helpers::deprecated('Passing the $slot or $slots variables to snippets is deprecated and will break in a future version.', 'snippet-pass-slots');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
@@ -58,7 +58,7 @@ class Query
|
||||
$this->query = $query;
|
||||
$this->data = $data;
|
||||
|
||||
Helpers::deprecated('The `Toolkit\Query` class has been deprecated and will be removed in a future version. Use `Query\Query` instead: Kirby\Query\Query::factory($query)->resolve($data).');
|
||||
Helpers::deprecated('The `Toolkit\Query` class has been deprecated and will be removed in a future version. Use `Query\Query` instead: Kirby\Query\Query::factory($query)->resolve($data).', 'toolkit-query-class');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -97,7 +97,7 @@ class Xml
|
||||
// TODO: Remove in 3.10
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($value === '') {
|
||||
Helpers::deprecated('Passing an empty string as value to `Xml::attr()` has been deprecated. In a future version, passing an empty string won\'t omit the attribute anymore but render it with an empty value. To omit the attribute, please pass `null`.');
|
||||
Helpers::deprecated('Passing an empty string as value to `Xml::attr()` has been deprecated. In a future version, passing an empty string won\'t omit the attribute anymore but render it with an empty value. To omit the attribute, please pass `null`.', 'xml-attr-empty-string');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
Reference in New Issue
Block a user