Upgrade to 4.6.0

This commit is contained in:
Bastian Allgeier
2025-01-30 12:15:44 +01:00
parent d71db84033
commit daf499e2e4
179 changed files with 1848 additions and 688 deletions

View File

@@ -592,7 +592,7 @@ class Api
* @return $this
*/
protected function setRequestMethod(
string $requestMethod = null
string|null $requestMethod = null
): static {
$this->requestMethod = $requestMethod ?? 'GET';
return $this;

View File

@@ -285,7 +285,7 @@ class App
*
* @return $this
*/
protected function bakeRoots(array $roots = null): static
protected function bakeRoots(array|null $roots = null): static
{
$roots = array_merge($this->core->roots(), (array)$roots);
$this->roots = Ingredients::bake($roots);
@@ -297,7 +297,7 @@ class App
*
* @return $this
*/
protected function bakeUrls(array $urls = null): static
protected function bakeUrls(array|null $urls = null): static
{
$urls = array_merge($this->core->urls(), (array)$urls);
$this->urls = Ingredients::bake($urls);
@@ -331,7 +331,7 @@ class App
/**
* Calls any Kirby route
*/
public function call(string $path = null, string $method = null): mixed
public function call(string|null $path = null, string|null $method = null): mixed
{
$path ??= $this->path();
$method ??= $this->request()->method();
@@ -697,7 +697,7 @@ class App
* @psalm-return ($lazy is false ? static : static|null)
*/
public static function instance(
self $instance = null,
self|null $instance = null,
bool $lazy = false
): static|null {
if ($instance !== null) {
@@ -852,7 +852,7 @@ class App
*
* @internal
*/
public function kirbytags(string $text = null, array $data = []): string
public function kirbytags(string|null $text = null, array $data = []): string
{
$data['kirby'] ??= $this;
$data['site'] ??= $data['kirby']->site();
@@ -872,7 +872,7 @@ class App
*
* @internal
*/
public function kirbytext(string $text = null, array $options = []): string
public function kirbytext(string|null $text = null, array $options = []): string
{
$text = $this->apply('kirbytext:before', compact('text'), 'text');
$text = $this->kirbytags($text, $options);
@@ -891,7 +891,7 @@ class App
* Returns the language by code or shortcut (`default`, `current`).
* Passing `null` is an alias for passing `current`
*/
public function language(string $code = null): Language|null
public function language(string|null $code = null): Language|null
{
if ($this->multilang() === false) {
return null;
@@ -909,7 +909,7 @@ class App
*
* @internal
*/
public function languageCode(string $languageCode = null): string|null
public function languageCode(string|null $languageCode = null): string|null
{
return $this->language($languageCode)?->code();
}
@@ -952,7 +952,7 @@ class App
*
* @internal
*/
public function markdown(string $text = null, array $options = null): string
public function markdown(string|null $text = null, array|null $options = null): string
{
// merge global options with local options
$options = array_merge(
@@ -1181,8 +1181,8 @@ class App
* current request
*/
public function render(
string $path = null,
string $method = null
string|null $path = null,
string|null $method = null
): Response|null {
if (($_ENV['KIRBY_RENDER'] ?? true) === false) {
return null;
@@ -1441,7 +1441,7 @@ class App
*
* @return $this
*/
protected function setLanguages(array $languages = null): static
protected function setLanguages(array|null $languages = null): static
{
if ($languages !== null) {
$objects = [];
@@ -1462,7 +1462,7 @@ class App
*
* @return $this
*/
protected function setPath(string $path = null): static
protected function setPath(string|null $path = null): static
{
$this->path = $path !== null ? trim($path, '/') : null;
return $this;
@@ -1473,7 +1473,7 @@ class App
*
* @return $this
*/
protected function setRequest(array $request = null): static
protected function setRequest(array|null $request = null): static
{
if ($request !== null) {
$this->request = new Request($request);
@@ -1487,7 +1487,7 @@ class App
*
* @return $this
*/
protected function setRoles(array $roles = null): static
protected function setRoles(array|null $roles = null): static
{
if ($roles !== null) {
$this->roles = Roles::factory($roles);
@@ -1501,7 +1501,7 @@ class App
*
* @return $this
*/
protected function setSite(Site|array $site = null): static
protected function setSite(Site|array|null $site = null): static
{
if (is_array($site) === true) {
$site = new Site($site);
@@ -1528,7 +1528,7 @@ class App
*
* @internal
*/
public function smartypants(string $text = null): string
public function smartypants(string|null $text = null): string
{
$options = $this->option('smartypants', []);

View File

@@ -99,7 +99,7 @@ trait AppPlugins
*/
public function extend(
array $extensions,
Plugin $plugin = null
Plugin|null $plugin = null
): array {
foreach ($this->extensions as $type => $registered) {
if (isset($extensions[$type]) === true) {
@@ -382,7 +382,7 @@ trait AppPlugins
*/
protected function extendOptions(
array $options,
Plugin $plugin = null
Plugin|null $plugin = null
): array {
if ($plugin !== null) {
$options = [$plugin->prefix() => $options];
@@ -428,7 +428,7 @@ trait AppPlugins
*/
protected function extendPermissions(
array $permissions,
Plugin $plugin = null
Plugin|null $plugin = null
): array {
if ($plugin !== null) {
$permissions = [$plugin->prefix() => $permissions];
@@ -583,7 +583,7 @@ trait AppPlugins
*
* @internal
*/
public function extensions(string $type = null): array
public function extensions(string|null $type = null): array
{
if ($type === null) {
return $this->extensions;
@@ -713,7 +713,7 @@ trait AppPlugins
*/
public static function plugin(
string $name,
array $extends = null,
array|null $extends = null,
array $info = [],
string|null $root = null,
string|null $version = null
@@ -747,7 +747,7 @@ trait AppPlugins
* @internal
* @param array|null $plugins Can be used to overwrite the plugins registry
*/
public function plugins(array $plugins = null): array
public function plugins(array|null $plugins = null): array
{
// overwrite the existing plugins registry
if ($plugins !== null) {

View File

@@ -108,7 +108,7 @@ trait AppTranslations
*
* @internal
*/
public function setCurrentTranslation(string $translationCode = null): void
public function setCurrentTranslation(string|null $translationCode = null): void
{
I18n::$locale = $translationCode ?? 'en';
}

View File

@@ -72,7 +72,7 @@ trait AppUsers
*
* @return $this
*/
protected function setUser(User|string $user = null): static
protected function setUser(User|string|null $user = null): static
{
$this->user = $user;
return $this;
@@ -83,7 +83,7 @@ trait AppUsers
*
* @return $this
*/
protected function setUsers(array $users = null): static
protected function setUsers(array|null $users = null): static
{
if ($users !== null) {
$this->users = Users::factory($users);

View File

@@ -202,7 +202,7 @@ class Auth
* @throws \Kirby\Exception\InvalidArgumentException if the authorization header is invalid
* @throws \Kirby\Exception\PermissionException if basic authentication is not allowed
*/
public function currentUserFromBasicAuth(BasicAuth $auth = null): User|null
public function currentUserFromBasicAuth(BasicAuth|null $auth = null): User|null
{
if ($this->kirby->option('api.basicAuth', false) !== true) {
throw new PermissionException('Basic authentication is not activated');
@@ -250,7 +250,7 @@ class Auth
* valid user id in there
*/
public function currentUserFromSession(
Session|array $session = null
Session|array|null $session = null
): User|null {
$session = $this->session($session);
@@ -440,7 +440,7 @@ class Auth
* logged in user will be returned
*/
public function status(
Session|array $session = null,
Session|array|null $session = null,
bool $allowImpersonation = true
): Status {
// try to return from cache
@@ -723,7 +723,7 @@ class Auth
* @throws \Throwable If an authentication error occurred
*/
public function user(
Session|array $session = null,
Session|array|null $session = null,
bool $allowImpersonation = true
): User|null {
if ($allowImpersonation === true && $this->impersonate !== null) {
@@ -887,7 +887,7 @@ class Auth
*/
protected function fail(
Throwable $exception,
Throwable $fallback = null
Throwable|null $fallback = null
): void {
$debug = $this->kirby->option('auth.debug', 'log');
@@ -911,7 +911,7 @@ class Auth
/**
* Creates a session object from the passed options
*/
protected function session(Session|array $session = null): Session
protected function session(Session|array|null $session = null): Session
{
// use passed session options or session object if set
if (is_array($session) === true) {

View File

@@ -54,7 +54,7 @@ class Blocks extends Items
* catch blocks from layouts
*/
public static function factory(
array $items = null,
array|null $items = null,
array $params = []
): static {
$items = static::extractFromLayouts($items);

View File

@@ -39,7 +39,7 @@ class Blueprint
/**
* Magic getter/caller for any blueprint prop
*/
public function __call(string $key, array $arguments = null): mixed
public function __call(string $key, array|null $arguments = null): mixed
{
return $this->props[$key] ?? null;
}
@@ -102,7 +102,7 @@ class Blueprint
* Gathers what file templates are allowed in
* this model based on the blueprint
*/
public function acceptedFileTemplates(string $inSection = null): array
public function acceptedFileTemplates(string|null $inSection = null): array
{
// get cached results for the current file model
// (except when collecting for a specific section)
@@ -320,7 +320,7 @@ class Blueprint
*/
public static function factory(
string $name,
string $fallback = null,
string|null $fallback,
ModelWithContent $model
): static|null {
try {

View File

@@ -365,7 +365,7 @@ class Collection extends BaseCollection
* Searches the collection
*/
public function search(
string $query = null,
string|null $query = null,
string|array $params = []
): static {
return Search::collection($this, $query, $params);
@@ -376,7 +376,7 @@ class Collection extends BaseCollection
* to an array. This can also take a callback
* function to further modify the array result.
*/
public function toArray(Closure $map = null): array
public function toArray(Closure|null $map = null): array
{
return parent::toArray($map ?? fn ($object) => $object->toArray());
}

View File

@@ -173,7 +173,7 @@ class ContentLocks
) {
unset($this->data[$file][$id]);
// there is empty unlock data, but still lock data
// there is empty unlock data, but still lock data
} elseif (
isset($data['unlock']) === true &&
count($data['unlock']) === 0

View File

@@ -113,7 +113,7 @@ class Email
$this->props['body']['text'] = $text->render($data);
}
// fallback to single email text template
// fallback to single email text template
} elseif ($text->exists()) {
$this->props['body'] = $text->render($data);
} else {
@@ -125,7 +125,7 @@ class Email
/**
* Returns an email template by name and type
*/
protected function getTemplate(string $name, string $type = null): Template
protected function getTemplate(string $name, string|null $type = null): Template
{
return App::instance()->template('emails/' . $name, $type, 'text');
}
@@ -163,7 +163,7 @@ class Email
string $prop,
string $class,
string $contentValue,
string $contentKey = null
string|null $contentKey = null
): array {
$value = $this->props[$prop] ?? [];

View File

@@ -74,7 +74,7 @@ class Fieldsets extends Items
}
public static function factory(
array $items = null,
array|null $items = null,
array $params = []
): static {
$items ??= App::instance()->option('blocks.fieldsets', [

View File

@@ -155,7 +155,7 @@ class File extends ModelWithContent
* Returns an array with all blueprints that are available for the file
* by comparing files sections and files fields of the parent model
*/
public function blueprints(string $inSection = null): array
public function blueprints(string|null $inSection = null): array
{
// get cached results for the current file model
// (except when collecting for a specific section)
@@ -227,7 +227,7 @@ class File extends ModelWithContent
*/
public function contentFileData(
array $data,
string $languageCode = null
string|null $languageCode = null
): array {
// only add the template in, if the $data array
// doesn't explicitly unsets it
@@ -443,7 +443,7 @@ class File extends ModelWithContent
* Timestamp of the last modification
* of the content file
*/
protected function modifiedContent(string $languageCode = null): int
protected function modifiedContent(string|null $languageCode = null): int
{
return $this->storage()->modified('published', $languageCode) ?? 0;
}
@@ -548,7 +548,7 @@ class File extends ModelWithContent
*
* @return $this
*/
protected function setBlueprint(array $blueprint = null): static
protected function setBlueprint(array|null $blueprint = null): static
{
if ($blueprint !== null) {
$blueprint['model'] = $this;

View File

@@ -404,8 +404,8 @@ trait FileActions
* @internal
*/
public function save(
array $data = null,
string $languageCode = null,
array|null $data = null,
string|null $languageCode = null,
bool $overwrite = false
): static {
$file = parent::save($data, $languageCode, $overwrite);
@@ -444,8 +444,8 @@ trait FileActions
* @throws \Kirby\Exception\InvalidArgumentException If the input array contains invalid values
*/
public function update(
array $input = null,
string $languageCode = null,
array|null $input = null,
string|null $languageCode = null,
bool $validate = false
): static {
// delete all public media versions when focus field gets changed

View File

@@ -38,7 +38,7 @@ trait FileModifications
*/
public function crop(
int $width,
int $height = null,
int|null $height = null,
$options = null
): FileVersion|File|Asset {
$quality = null;
@@ -94,9 +94,9 @@ trait FileModifications
* @throws \Kirby\Exception\InvalidArgumentException
*/
public function resize(
int $width = null,
int $height = null,
int $quality = null
int|null $width = null,
int|null $height = null,
int|null $quality = null
): FileVersion|File|Asset {
return $this->thumb([
'width' => $width,

View File

@@ -252,7 +252,7 @@ class FileRules
* Validates the extension, MIME type and filename
*
* @param $mime If not passed, the MIME type is detected from the file,
* if `false`, the MIME type is not validated for performance reasons
* if `false`, the MIME type is not validated for performance reasons
* @throws \Kirby\Exception\InvalidArgumentException If the extension, MIME type or filename is missing or forbidden
*/
public static function validFile(
@@ -312,7 +312,7 @@ class FileRules
*
* @throws \Kirby\Exception\InvalidArgumentException If the MIME type is missing or forbidden
*/
public static function validMime(File $file, string $mime = null): bool
public static function validMime(File $file, string|null $mime = null): bool
{
// make it easier to compare the mime
$mime = strtolower($mime ?? '');

View File

@@ -44,19 +44,19 @@ class Files extends Collection
if ($object instanceof self) {
$this->data = array_merge($this->data, $object->data);
// add a file by id
// add a file by id
} elseif (
is_string($object) === true &&
$file = App::instance()->file($object)
) {
$this->__set($file->id(), $file);
// add a file object
// add a file object
} elseif ($object instanceof File) {
$this->__set($object->id(), $object);
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
} elseif (in_array($object, [null, false, true], true) !== true) {
throw new InvalidArgumentException('You must pass a Files or File object or an ID of an existing file to the Files collection');
}

View File

@@ -142,7 +142,7 @@ class Find
* @param string|null $id User's id
* @throws \Kirby\Exception\NotFoundException if the user for the given id cannot be found
*/
public static function user(string $id = null): User|null
public static function user(string|null $id = null): User|null
{
// account is a reserved word to find the current
// user. It's used in various API and area routes.

View File

@@ -176,7 +176,7 @@ trait HasChildren
*
* @return $this
*/
protected function setChildren(array $children = null): static
protected function setChildren(array|null $children = null): static
{
if ($children !== null) {
$this->children = Pages::factory($children, $this);
@@ -190,7 +190,7 @@ trait HasChildren
*
* @return $this
*/
protected function setDrafts(array $drafts = null): static
protected function setDrafts(array|null $drafts = null): static
{
if ($drafts !== null) {
$this->drafts = Pages::factory($drafts, $this, true);

View File

@@ -63,7 +63,7 @@ trait HasFiles
* Returns a specific file by filename or the first one
*/
public function file(
string $filename = null,
string|null $filename = null,
string $in = 'files'
): File|null {
if ($filename === null) {
@@ -152,7 +152,7 @@ trait HasFiles
/**
* Returns a specific image by filename or the first one
*/
public function image(string $filename = null): File|null
public function image(string|null $filename = null): File|null
{
return $this->file($filename, 'images');
}
@@ -170,7 +170,7 @@ trait HasFiles
*
* @return $this
*/
protected function setFiles(array $files = null): static
protected function setFiles(array|null $files = null): static
{
if ($files !== null) {
$this->files = Files::factory($files, $this);

View File

@@ -81,7 +81,7 @@ class Html extends \Kirby\Toolkit\Html
*/
public static function link(
string|null $href = null,
string|array $text = null,
string|array|null $text = null,
array $attr = []
): string {
return parent::link(Url::to($href), $text, $attr);

View File

@@ -34,7 +34,7 @@ class Ingredients
/**
* Magic getter for single ingredients
*/
public function __call(string $method, array $args = null): mixed
public function __call(string $method, array|null $args = null): mixed
{
return $this->ingredients[$method] ?? null;
}

View File

@@ -48,7 +48,7 @@ class Items extends Collection
* an array of item props
*/
public static function factory(
array $items = null,
array|null $items = null,
array $params = []
): static {
if (empty($items) === true || is_array($items) === false) {
@@ -93,7 +93,7 @@ class Items extends Collection
/**
* Convert the items to an array
*/
public function toArray(Closure $map = null): array
public function toArray(Closure|null $map = null): array
{
return array_values(parent::toArray($map));
}

View File

@@ -344,7 +344,7 @@ class Language
*
* @param int $category If passed, returns the locale for the specified category (e.g. LC_ALL) as string
*/
public function locale(int $category = null): array|string|null
public function locale(int|null $category = null): array|string|null
{
if ($category !== null) {
return $this->locale[$category] ?? $this->locale[LC_ALL] ?? null;
@@ -513,7 +513,7 @@ class Language
* Update language properties and save them
* @internal
*/
public function update(array $props = null): static
public function update(array|null $props = null): static
{
$kirby = App::instance();
$user = $kirby->user();

View File

@@ -26,7 +26,7 @@ class Layouts extends Items
public static array $methods = [];
public static function factory(
array $items = null,
array|null $items = null,
array $params = []
): static {
// convert single layout to layouts array

View File

@@ -27,7 +27,7 @@ class Media
* and to copy it to the media folder.
*/
public static function link(
Page|Site|User $model = null,
Page|Site|User|null $model,
string $hash,
string $filename
): Response|false {

View File

@@ -86,7 +86,7 @@ abstract class Model
* @param \Kirby\Cms\App|null $kirby
* @return $this
*/
protected function setKirby(App $kirby = null)
protected function setKirby(App|null $kirby = null)
{
static::$kirby = $kirby;
return $this;
@@ -99,7 +99,7 @@ abstract class Model
* @param \Kirby\Cms\Site|null $site
* @return $this
*/
public function setSite(Site $site = null)
public function setSite(Site|null $site = null)
{
$this->site = $site;
return $this;

View File

@@ -71,7 +71,7 @@ abstract class ModelWithContent implements Identifiable
/**
* Returns an array with all blueprints that are available
*/
public function blueprints(string $inSection = null): array
public function blueprints(string|null $inSection = null): array
{
// helper function
$toBlueprints = function (array $sections): array {
@@ -176,7 +176,7 @@ abstract class ModelWithContent implements Identifiable
* @throws \Kirby\Exception\InvalidArgumentException If the language for the given code does not exist
*/
public function contentFile(
string $languageCode = null,
string|null $languageCode = null,
bool $force = false
): string {
Helpers::deprecated('The internal $model->contentFile() method has been deprecated. You can use $model->storage()->contentFile() instead, however please note that this method is also internal and may be removed in the future.', 'model-content-file');
@@ -212,7 +212,7 @@ abstract class ModelWithContent implements Identifiable
*/
public function contentFileData(
array $data,
string $languageCode = null
string|null $languageCode = null
): array {
return $data;
}
@@ -371,7 +371,7 @@ abstract class ModelWithContent implements Identifiable
public function increment(
string $field,
int $by = 1,
int $max = null
int|null $max = null
): static {
$value = (int)$this->content()->get($field)->value() + $by;
@@ -462,8 +462,8 @@ abstract class ModelWithContent implements Identifiable
* @internal
*/
public function query(
string $query = null,
string $expect = null
string|null $query = null,
string|null $expect = null
): mixed {
if ($query === null) {
return null;
@@ -491,7 +491,7 @@ abstract class ModelWithContent implements Identifiable
* Read the content from the content file
* @internal
*/
public function readContent(string $languageCode = null): array
public function readContent(string|null $languageCode = null): array
{
try {
return $this->storage()->read(
@@ -531,7 +531,7 @@ abstract class ModelWithContent implements Identifiable
* Save the single language content
*/
protected function saveContent(
array $data = null,
array|null $data = null,
bool $overwrite = false
): static {
// create a clone to avoid modifying the original
@@ -552,8 +552,8 @@ abstract class ModelWithContent implements Identifiable
* @throws \Kirby\Exception\InvalidArgumentException If the language for the given code does not exist
*/
protected function saveTranslation(
array $data = null,
string $languageCode = null,
array|null $data = null,
string|null $languageCode = null,
bool $overwrite = false
): static {
// create a clone to not touch the original
@@ -603,7 +603,7 @@ abstract class ModelWithContent implements Identifiable
*
* @return $this
*/
protected function setContent(array $content = null): static
protected function setContent(array|null $content = null): static
{
if ($content !== null) {
$content = new Content($content, $this);
@@ -618,7 +618,7 @@ abstract class ModelWithContent implements Identifiable
*
* @return $this
*/
protected function setTranslations(array $translations = null): static
protected function setTranslations(array|null $translations = null): static
{
if ($translations !== null) {
$this->translations = new Collection();
@@ -675,7 +675,7 @@ abstract class ModelWithContent implements Identifiable
* (`null` to keep the original token)
*/
public function toSafeString(
string $template = null,
string|null $template = null,
array $data = [],
string|null $fallback = ''
): string {
@@ -691,7 +691,7 @@ abstract class ModelWithContent implements Identifiable
* @param string $handler For internal use
*/
public function toString(
string $template = null,
string|null $template = null,
array $data = [],
string|null $fallback = '',
string $handler = 'template'
@@ -728,7 +728,7 @@ abstract class ModelWithContent implements Identifiable
* If no code is specified the current translation is returned
*/
public function translation(
string $languageCode = null
string|null $languageCode = null
): ContentTranslation|null {
if ($language = $this->kirby()->language($languageCode)) {
return $this->translations()->find($language->code());
@@ -766,8 +766,8 @@ abstract class ModelWithContent implements Identifiable
* @throws \Kirby\Exception\InvalidArgumentException If the input array contains invalid values
*/
public function update(
array $input = null,
string $languageCode = null,
array|null $input = null,
string|null $languageCode = null,
bool $validate = false
): static {
$form = Form::for($this, [
@@ -811,7 +811,7 @@ abstract class ModelWithContent implements Identifiable
* to store the given data on disk or anywhere else
* @internal
*/
public function writeContent(array $data, string $languageCode = null): bool
public function writeContent(array $data, string|null $languageCode = null): bool
{
$data = $this->contentFileData($data, $languageCode);
$id = $this->storage()->defaultVersion();

View File

@@ -21,7 +21,7 @@ class NestCollection extends BaseCollection
* to an array. This can also take a callback
* function to further modify the array result.
*/
public function toArray(Closure $map = null): array
public function toArray(Closure|null $map = null): array
{
return parent::toArray($map ?? fn ($object) => $object->toArray());
}

View File

@@ -776,7 +776,7 @@ class Page extends ModelWithContent
* This is only used for drafts so far.
* @internal
*/
public function isVerified(string $token = null): bool
public function isVerified(string|null $token = null): bool
{
if (
$this->isPublished() === true &&
@@ -1091,7 +1091,7 @@ class Page extends ModelWithContent
*
* @return $this
*/
protected function setBlueprint(array $blueprint = null): static
protected function setBlueprint(array|null $blueprint = null): static
{
if ($blueprint !== null) {
$blueprint['model'] = $this;
@@ -1106,7 +1106,7 @@ class Page extends ModelWithContent
*
* @return $this
*/
protected function setTemplate(string $template = null): static
protected function setTemplate(string|null $template = null): static
{
if ($template !== null) {
$this->intendedTemplate = $this->kirby()->template($template);
@@ -1120,7 +1120,7 @@ class Page extends ModelWithContent
*
* @return $this
*/
protected function setUrl(string $url = null): static
protected function setUrl(string|null $url = null): static
{
if (is_string($url) === true) {
$url = rtrim($url, '/');
@@ -1133,7 +1133,7 @@ class Page extends ModelWithContent
/**
* Returns the slug of the page
*/
public function slug(string $languageCode = null): string
public function slug(string|null $languageCode = null): string
{
if ($this->kirby()->multilang() === true) {
$languageCode ??= $this->kirby()->languageCode();
@@ -1245,7 +1245,7 @@ class Page extends ModelWithContent
* The uri is the same as the id, except
* that it will be translated in multi-language setups
*/
public function uri(string $languageCode = null): string
public function uri(string|null $languageCode = null): string
{
// set the id, depending on the parent
if ($parent = $this->parent()) {
@@ -1301,7 +1301,7 @@ class Page extends ModelWithContent
*/
public function urlForLanguage(
$language = null,
array $options = null
array|null $options = null
): string {
if ($options !== null) {
return Url::to($this->urlForLanguage($language), $options);

View File

@@ -578,7 +578,7 @@ trait PageActions
* Create the sorting number for the page
* depending on the blueprint settings
*/
public function createNum(int $num = null): int
public function createNum(int|null $num = null): int
{
$mode = $this->blueprint()->num();
@@ -827,7 +827,7 @@ trait PageActions
/**
* @throws \Kirby\Exception\LogicException If the page is not included in the siblings collection
*/
protected function resortSiblingsAfterListing(int $position = null): bool
protected function resortSiblingsAfterListing(int|null $position = null): bool
{
// get all siblings including the current page
$siblings = $this

View File

@@ -79,7 +79,7 @@ class PagePicker extends Picker
* parent model that is currently selected
* in the page picker.
*/
public function modelToArray(Page|Site $model = null): array|null
public function modelToArray(Page|Site|null $model = null): array|null
{
if ($model === null) {
return null;
@@ -126,13 +126,13 @@ class PagePicker extends Picker
if (empty($this->options['query']) === true) {
$items = $this->itemsForParent();
// when subpage navigation is enabled, a parent
// might be passed in addition to the query.
// The parent then takes priority.
// when subpage navigation is enabled, a parent
// might be passed in addition to the query.
// The parent then takes priority.
} elseif ($this->options['subpages'] === true && empty($this->options['parent']) === false) {
$items = $this->itemsForParent();
// search by query
// search by query
} else {
$items = $this->itemsForQuery();
}

View File

@@ -25,7 +25,7 @@ class PageRules
*
* @throws \Kirby\Exception\InvalidArgumentException If the given number is invalid
*/
public static function changeNum(Page $page, int $num = null): bool
public static function changeNum(Page $page, int|null $num = null): bool
{
if ($num !== null && $num < 0) {
throw new InvalidArgumentException(['key' => 'page.num.invalid']);
@@ -86,7 +86,7 @@ class PageRules
public static function changeStatus(
Page $page,
string $status,
int $position = null
int|null $position = null
): bool {
if (isset($page->blueprint()->status()[$status]) === false) {
throw new InvalidArgumentException(['key' => 'page.status.invalid']);

View File

@@ -61,19 +61,19 @@ class Pages extends Collection
if ($object instanceof self) {
$this->data = array_merge($this->data, $object->data);
// add a page by id
// add a page by id
} elseif (
is_string($object) === true &&
$page = $site->find($object)
) {
$this->__set($page->id(), $page);
// add a page object
// add a page object
} elseif ($object instanceof Page) {
$this->__set($object->id(), $object);
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
} elseif (in_array($object, [null, false, true], true) !== true) {
throw new InvalidArgumentException('You must pass a Pages or Page object or an ID of an existing page to the Pages collection');
}
@@ -142,8 +142,8 @@ class Pages extends Collection
*/
public static function factory(
array $pages,
Page|Site $model = null,
bool $draft = null
Page|Site|null $model = null,
bool|null $draft = null
): static {
$model ??= App::instance()->site();
$children = new static([], $model);
@@ -248,7 +248,7 @@ class Pages extends Collection
*/
protected function findByKeyRecursive(
string $id,
string $startAt = null,
string|null $startAt = null,
bool $multiLang = false
) {
$path = explode('/', $id);

View File

@@ -125,7 +125,7 @@ class Pagination extends BasePagination
* If the `$page` variable is set, the URL
* for that page will be returned.
*/
public function pageUrl(int $page = null): string|null
public function pageUrl(int|null $page = null): string|null
{
if ($page === null) {
return $this->pageUrl($this->page());

View File

@@ -68,7 +68,7 @@ abstract class Picker
* array that is already optimized for the
* panel picker component.
*/
public function itemsToArray(Collection $items = null): array
public function itemsToArray(Collection|null $items = null): array
{
if ($items === null) {
return [];

View File

@@ -77,7 +77,7 @@ class Plugin
/**
* Allows access to any composer.json field by method call
*/
public function __call(string $key, array $arguments = null): mixed
public function __call(string $key, array|null $arguments = null): mixed
{
return $this->info()[$key] ?? null;
}

View File

@@ -75,7 +75,7 @@ class Responder
*
* @return $this|string|null
*/
public function body(string $body = null): static|string|null
public function body(string|null $body = null): static|string|null
{
if ($body === null) {
return $this->body;
@@ -210,7 +210,7 @@ class Responder
*
* @return int|$this
*/
public function code(int $code = null)
public function code(int|null $code = null)
{
if ($code === null) {
return $this->code;
@@ -266,7 +266,7 @@ class Responder
*
* @return array|$this
*/
public function headers(array $headers = null)
public function headers(array|null $headers = null)
{
if ($headers === null) {
$injectedHeaders = [];
@@ -305,7 +305,7 @@ class Responder
*
* @return string|$this
*/
public function json(array $json = null)
public function json(array|null $json = null)
{
if ($json !== null) {
$this->body(json_encode($json));
@@ -334,7 +334,7 @@ class Responder
/**
* Creates and returns the response object from the config
*/
public function send(string $body = null): Response
public function send(string|null $body = null): Response
{
if ($body !== null) {
$this->body($body);
@@ -365,7 +365,7 @@ class Responder
*
* @return string|$this
*/
public function type(string $type = null)
public function type(string|null $type = null)
{
if ($type === null) {
return $this->type;

View File

@@ -82,7 +82,11 @@ class Role
public static function factory(array $props, array $inject = []): static
{
return new static($props + $inject);
// ensure to properly extend the blueprint
$props = $props + $inject;
$props = Blueprint::extend($props);
return new static($props);
}
public function id(): string

View File

@@ -96,7 +96,7 @@ class Roles extends Collection
return $collection->sort('name', 'asc');
}
public static function load(string $root = null, array $inject = []): static
public static function load(string|null $root = null, array $inject = []): static
{
$kirby = App::instance();
$roles = new static();

View File

@@ -17,7 +17,7 @@ namespace Kirby\Cms;
class Search
{
public static function files(
string $query = null,
string|null $query = null,
array $params = []
): Files {
return App::instance()->site()->index()->files()->search($query, $params);
@@ -36,14 +36,14 @@ class Search
}
public static function pages(
string $query = null,
string|null $query = null,
array $params = []
): Pages {
return App::instance()->site()->index()->search($query, $params);
}
public static function users(
string $query = null,
string|null $query = null,
array $params = []
): Users {
return App::instance()->users()->search($query, $params);

View File

@@ -30,7 +30,7 @@ class Structure extends Items
* an array of item props
*/
public static function factory(
array $items = null,
array|null $items = null,
array $params = []
): static {
if (is_array($items) === true) {

View File

@@ -364,7 +364,7 @@ class System
{
return
version_compare(PHP_VERSION, '8.1.0', '>=') === true &&
version_compare(PHP_VERSION, '8.4.0', '<') === true;
version_compare(PHP_VERSION, '8.5.0', '<') === true;
}
/**
@@ -385,7 +385,7 @@ class System
* @throws \Kirby\Exception\Exception
* @throws \Kirby\Exception\InvalidArgumentException
*/
public function register(string $license = null, string $email = null): bool
public function register(string|null $license = null, string|null $email = null): bool
{
$license = new License(
code: $license,
@@ -405,6 +405,16 @@ class System
return $this->app->environment()->get('SERVER_SOFTWARE', '');
}
/**
* Returns the short version of the detected server software
* @since 4.6.0
*/
public function serverSoftwareShort(): string
{
$software = $this->serverSoftware();
return strtok($software, ' ');
}
/**
* Check for a writable sessions folder
*/

View File

@@ -87,7 +87,7 @@ class Translation
* Returns a single translation
* string by key
*/
public function get(string $key, string $default = null): string|null
public function get(string $key, string|null $default = null): string|null
{
return $this->data[$key] ?? $default;
}

View File

@@ -44,9 +44,9 @@ class Url extends BaseUrl
* @return string The safe string
*/
public static function slug(
string $string = null,
string $separator = null,
string $allowed = null,
string|null $string = null,
string|null $separator = null,
string|null $allowed = null,
): string {
$maxlength = App::instance()->option('slugs.maxlength', 255);
return Str::slug($string, $separator, $allowed, $maxlength);

View File

@@ -239,7 +239,7 @@ class User extends ModelWithContent
*/
public static function hashPassword(
#[SensitiveParameter]
string $password = null
string|null $password = null
): string|null {
if ($password !== null) {
$password = password_hash($password, PASSWORD_DEFAULT);
@@ -279,7 +279,7 @@ class User extends ModelWithContent
/**
* Compares the current object with the given user object
*/
public function is(User $user = null): bool
public function is(User|null $user = null): bool
{
if ($user === null) {
return false;
@@ -625,7 +625,7 @@ class User extends ModelWithContent
*
* @return $this
*/
protected function setBlueprint(array $blueprint = null): static
protected function setBlueprint(array|null $blueprint = null): static
{
if ($blueprint !== null) {
$blueprint['model'] = $this;
@@ -683,7 +683,7 @@ class User extends ModelWithContent
* (`null` to keep the original token)
*/
public function toString(
string $template = null,
string|null $template = null,
array $data = [],
string|null $fallback = '',
string $handler = 'template'
@@ -711,7 +711,7 @@ class User extends ModelWithContent
*/
public function validatePassword(
#[SensitiveParameter]
string $password = null
string|null $password = null
): bool {
if (empty($this->password()) === true) {
throw new NotFoundException(['key' => 'user.password.undefined']);

View File

@@ -209,7 +209,7 @@ trait UserActions
/**
* Creates a new User from the given props and returns a new User object
*/
public static function create(array $props = null): User
public static function create(array|null $props = null): User
{
$data = $props;
@@ -364,8 +364,8 @@ trait UserActions
* Updates the user data
*/
public function update(
array $input = null,
string $languageCode = null,
array|null $input = null,
string|null $languageCode = null,
bool $validate = false
): static {
$user = parent::update($input, $languageCode, $validate);
@@ -408,7 +408,7 @@ trait UserActions
*/
protected function writePassword(
#[SensitiveParameter]
string $password = null
string|null $password = null
): bool {
return $this->writeSecret('password', $password);
}

View File

@@ -49,19 +49,19 @@ class Users extends Collection
if ($object instanceof self) {
$this->data = array_merge($this->data, $object->data);
// add a user by id
// add a user by id
} elseif (
is_string($object) === true &&
$user = App::instance()->user($object)
) {
$this->__set($user->id(), $user);
// add a user object
// add a user object
} elseif ($object instanceof User) {
$this->__set($object->id(), $object);
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
} elseif (in_array($object, [null, false, true], true) !== true) {
throw new InvalidArgumentException('You must pass a Users or User object or an ID of an existing user to the Users collection');
}

View File

@@ -54,7 +54,7 @@ class Content
*/
public function __construct(
array $data = [],
ModelWithContent $parent = null,
ModelWithContent|null $parent = null,
bool $normalize = true
) {
if ($normalize === true) {
@@ -149,7 +149,7 @@ class Content
* Returns either a single field object
* or all registered fields
*/
public function get(string $key = null): Field|array
public function get(string|null $key = null): Field|array
{
if ($key === null) {
return $this->fields();
@@ -234,7 +234,7 @@ class Content
* @return $this
*/
public function update(
array $content = null,
array|null $content = null,
bool $overwrite = false
): static {
$content = array_change_key_case((array)$content, CASE_LOWER);

View File

@@ -145,7 +145,7 @@ class ContentTranslation
*
* @return $this
*/
public function update(array $data = null, bool $overwrite = false): static
public function update(array|null $data = null, bool $overwrite = false): static
{
$data = array_change_key_case((array)$data);

View File

@@ -210,7 +210,7 @@ class Field
* the modified field will be returned. Otherwise it
* will return the field value.
*/
public function value(string|Closure $value = null): mixed
public function value(string|Closure|null $value = null): mixed
{
if ($value === null) {
return $this->value;

View File

@@ -45,7 +45,7 @@ class Txt extends Handler
// avoid problems with arrays
if (is_array($value) === true) {
$value = Data::encode($value, 'yaml');
// avoid problems with localized floats
// avoid problems with localized floats
} elseif (is_float($value) === true) {
$value = Str::float($value);
}

View File

@@ -421,7 +421,7 @@ class Query
* @param string|null $order
* @return $this
*/
public function order(string $order = null)
public function order(string|null $order = null)
{
$this->order = $order;
return $this;
@@ -828,13 +828,13 @@ class Query
if ($args[0] === null) {
return $current;
// ->where('username like "myuser"');
// ->where('username like "myuser"');
} elseif (is_string($args[0]) === true) {
// simply add the entire string to the where clause
// escaping or using bindings has to be done before calling this method
$result = $args[0];
// ->where(['username' => 'myuser']);
// ->where(['username' => 'myuser']);
} elseif (is_array($args[0]) === true) {
// simple array mode (AND operator)
$sql = $this->database->sql()->values($this->table, $args[0], ' AND ', true, true);
@@ -868,7 +868,7 @@ class Query
// store the bindings
$this->bindings($args[1]);
// ->where('username like ?', 'myuser')
// ->where('username like ?', 'myuser')
} elseif (is_string($args[0]) === true && is_scalar($args[1]) === true) {
// prepared where clause
$result = $args[0];
@@ -913,7 +913,7 @@ class Query
};
$result = $key . ' ' . $predicate . ' ' . $values;
// ->where('username', 'like', 'myuser');
// ->where('username', 'like', 'myuser');
} else {
$predicates = [
'=', '>=', '>', '<=', '<', '<>', '!=', '<=>',

View File

@@ -146,7 +146,7 @@ abstract class Sql
* Combines an identifier (table and column)
*
* @param $values bool Whether the identifier is going to be used for a VALUES clause;
* only relevant for SQLite
* only relevant for SQLite
*/
public function combineIdentifier(string $table, string $column, bool $values = false): string
{

View File

@@ -130,7 +130,7 @@ class Sqlite extends Sql
public function tables(): array
{
return [
'query' => 'SELECT name FROM sqlite_master WHERE type = "table" OR type = "view"',
'query' => 'SELECT name FROM sqlite_master WHERE type = \'table\' OR type = \'view\'',
'bindings' => []
];
}

View File

@@ -149,7 +149,7 @@ class Dir
string $dir,
bool $recursive = false,
array|false|null $ignore = [],
string $path = null
string|null $path = null
): array {
$result = [];
$dir = realpath($dir);
@@ -434,7 +434,7 @@ class Dir
*/
public static function modified(
string $dir,
string $format = null,
string|null $format = null,
string|null $handler = null
): int|string {
$modified = filemtime($dir);

View File

@@ -59,8 +59,8 @@ class File
* @throws \Kirby\Exception\InvalidArgumentException When the model does not use the `Kirby\Filesystem\IsFile` trait
*/
public function __construct(
array|string $props = null,
string $url = null
array|string|null $props = null,
string|null $url = null
) {
// Legacy support for old constructor of
// the `Kirby\Image\Image` class

View File

@@ -251,7 +251,7 @@ class Mime
/**
* Returns the extension for a given MIME type
*/
public static function toExtension(string $mime = null): string|false
public static function toExtension(string|null $mime = null): string|false
{
foreach (static::$types as $key => $value) {
if (is_array($value) === true && in_array($mime, $value) === true) {
@@ -269,7 +269,7 @@ class Mime
/**
* Returns all available extensions for a given MIME type
*/
public static function toExtensions(string $mime = null, bool $matchWildcards = false): array
public static function toExtensions(string|null $mime = null, bool $matchWildcards = false): array
{
$extensions = [];
$testMime = fn (string $v) => static::matches($v, $mime);

View File

@@ -127,7 +127,7 @@ class Field extends Component
/**
* Sets the focus on this field when the form loads. Only the first field with this label gets
*/
'autofocus' => function (bool $autofocus = null): bool {
'autofocus' => function (bool|null $autofocus = null): bool {
return $autofocus ?? false;
},
/**
@@ -145,7 +145,7 @@ class Field extends Component
/**
* If `true`, the field is no longer editable and will not be saved
*/
'disabled' => function (bool $disabled = null): bool {
'disabled' => function (bool|null $disabled = null): bool {
return $disabled ?? false;
},
/**
@@ -157,7 +157,7 @@ class Field extends Component
/**
* Optional icon that will be shown at the end of the field
*/
'icon' => function (string $icon = null) {
'icon' => function (string|null $icon = null) {
return $icon;
},
/**
@@ -175,7 +175,7 @@ class Field extends Component
/**
* If `true`, the field has to be filled in correctly to be saved.
*/
'required' => function (bool $required = null): bool {
'required' => function (bool|null $required = null): bool {
return $required ?? false;
},
/**

View File

@@ -214,7 +214,7 @@ class BlocksField extends FieldClass
'action' => function (
string $fieldsetType,
string $fieldName,
string $path = null
string|null $path = null
) use ($field) {
$fields = $field->fields($fieldsetType);
$field = $field->form($fields)->field($fieldName);
@@ -276,7 +276,7 @@ class BlocksField extends FieldClass
);
}
protected function setGroup(string $group = null): void
protected function setGroup(string|null $group = null): void
{
$this->group = $group;
}

View File

@@ -175,7 +175,7 @@ class LayoutField extends BlocksField
'method' => 'ALL',
'action' => function (
string $fieldName,
string $path = null
string|null $path = null
) use ($field): array {
$form = $field->attrsForm();
$field = $form->field($fieldName);

View File

@@ -610,7 +610,7 @@ abstract class FieldClass
}
protected function valueToJson(
array $value = null,
array|null $value = null,
bool $pretty = false
): string {
$constants = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
@@ -622,7 +622,7 @@ abstract class FieldClass
return json_encode($value, $constants);
}
protected function valueToYaml(array $value = null): string
protected function valueToYaml(array|null $value = null): string
{
return Data::encode($value, 'yaml');
}

View File

@@ -39,7 +39,7 @@ class Fields extends Collection
* array and also does that for every
* included field.
*/
public function toArray(Closure $map = null): array
public function toArray(Closure|null $map = null): array
{
$array = [];

View File

@@ -11,7 +11,7 @@ trait Max
return $this->max;
}
protected function setMax(int $max = null)
protected function setMax(int|null $max = null)
{
$this->max = $max;
}

View File

@@ -11,7 +11,7 @@ trait Min
return $this->min;
}
protected function setMin(int $min = null)
protected function setMin(int|null $min = null)
{
$this->min = $min;
}

View File

@@ -153,8 +153,8 @@ class Environment
* @param array|null $info Optional override for `$_SERVER`
*/
public function detect(
array $options = null,
array $info = null
array|null $options = null,
array|null $info = null
): array {
$defaults = [
'cli' => null,
@@ -178,11 +178,11 @@ class Environment
if ($options['allowed'] === '*' || $options['allowed'] === ['*']) {
$this->detectAuto(true);
// fixed environments
// fixed environments
} elseif (empty($options['allowed']) === false) {
$this->detectAllowed($options['allowed']);
// secure auto-detection
// secure auto-detection
} else {
$this->detectAuto();
}

View File

@@ -63,7 +63,7 @@ class Route
/**
* Magic getter for route attributes
*/
public function __call(string $key, array $args = null): mixed
public function __call(string $key, array|null $args = null): mixed
{
return $this->attributes[$key] ?? null;
}

View File

@@ -220,7 +220,7 @@ class Url
*/
public static function to(
string|null $path = null,
array $options = null
array|null $options = null
): string {
// make sure $path is string
$path ??= '';

View File

@@ -2,6 +2,7 @@
namespace Kirby\Image;
use Kirby\Cms\FileVersion;
use Kirby\Content\Content;
use Kirby\Exception\LogicException;
use Kirby\Filesystem\File;
@@ -115,15 +116,20 @@ class Image extends File
*/
public function html(array $attr = []): string
{
$model = match (true) {
$this->model instanceof FileVersion => $this->model->original(),
default => $this->model
};
// if no alt text explicitly provided,
// try to infer from model content file
if (
$this->model !== null &&
method_exists($this->model, 'content') === true &&
$this->model->content() instanceof Content &&
$this->model->content()->get('alt')->isNotEmpty() === true
$model !== null &&
method_exists($model, 'content') === true &&
$model->content() instanceof Content &&
$model->content()->get('alt')->isNotEmpty() === true
) {
$attr['alt'] ??= $this->model->content()->get('alt')->value();
$attr['alt'] ??= $model->content()->get('alt')->value();
}
if ($url = $this->url()) {

View File

@@ -28,7 +28,7 @@ class Option
$this->text ??= new NodeText(['en' => $this->value]);
}
public static function factory(string|int|float|null|array $props): static
public static function factory(string|int|float|array|null $props): static
{
if (is_array($props) === false) {
$props = ['value' => $props];

View File

@@ -115,12 +115,19 @@ abstract class Model
$blueprint = null;
}
// convert string blueprint settings to proper array
if (is_string($blueprint) === true) {
$blueprint = ['query' => $blueprint];
}
// skip image thumbnail if option
// is explicitly set to show the icon
if ($settings === 'icon') {
$settings = ['query' => false];
} elseif (is_string($settings) === true) {
// convert string settings to proper array
}
// convert string settings to proper array
if (is_string($settings) === true) {
$settings = ['query' => $settings];
}

View File

@@ -235,7 +235,7 @@ class Panel
if ($result === null || $result === false) {
$result = new NotFoundException('The data could not be found');
// interpret strings as errors
// interpret strings as errors
} elseif (is_string($result) === true) {
$result = new Exception($result);
}

View File

@@ -330,15 +330,15 @@ class View
if ($data instanceof Redirect) {
return Response::redirect($data->location(), $data->code());
// handle Kirby exceptions
// handle Kirby exceptions
} elseif ($data instanceof Exception) {
$data = static::error($data->getMessage(), $data->getHttpCode());
// handle regular exceptions
// handle regular exceptions
} elseif ($data instanceof Throwable) {
$data = static::error($data->getMessage(), 500);
// only expect arrays from here on
// only expect arrays from here on
} elseif (is_array($data) === false) {
$data = static::error('Invalid Panel response', 500);
}

View File

@@ -212,7 +212,7 @@ class Parsley
) {
$this->blocks[$lastIndex]['content']['text'] .= ' ' . $block['content']['text'];
// append
// append
} else {
$this->blocks[] = $block;
}

View File

@@ -25,7 +25,7 @@ class Expression
/**
* Parses an expression string into its parts
*/
public static function factory(string $expression, Query $parent = null): static|Segments
public static function factory(string $expression, Query|null $parent = null): static|Segments
{
// split into different expression parts and operators
$parts = static::parse($expression);

View File

@@ -131,12 +131,12 @@ Query::$entries['site'] = function (): Site {
Query::$entries['t'] = function (
string $key,
string|array $fallback = null,
string $locale = null
string|array|null $fallback = null,
string|null $locale = null
): string|null {
return I18n::translate($key, $fallback, $locale);
};
Query::$entries['user'] = function (string $id = null): User|null {
Query::$entries['user'] = function (string|null $id = null): User|null {
return App::instance()->user($id);
};

View File

@@ -28,7 +28,7 @@ class Segments extends Collection
* Split query string into segments by dot
* but not inside (nested) parens
*/
public static function factory(string $query, Query $parent = null): static
public static function factory(string $query, Query|null $parent = null): static
{
$segments = static::parse($query);
$position = 0;

View File

@@ -149,7 +149,7 @@ class Session
* @param string|null $mode Optional new transmission mode
* @return string Transmission mode
*/
public function mode(string $mode = null): string
public function mode(string|null $mode = null): string
{
if ($mode !== null) {
// only allow this if this is a new session, otherwise the change
@@ -214,7 +214,7 @@ class Session
* @param int|null $duration Optional new duration in seconds to set
* @return int Number of seconds
*/
public function duration(int $duration = null): int
public function duration(int|null $duration = null): int
{
if ($duration !== null) {
// verify that the duration is at least 1 second

View File

@@ -105,7 +105,7 @@ class Sessions
* @param string $token Session token, either including or without the key
* @param string|null $mode Optional transmission mode override
*/
public function get(string $token, string $mode = null): Session
public function get(string $token, string|null $mode = null): Session
{
return $this->cache[$token] ??= new Session(
$this,

View File

@@ -508,7 +508,7 @@ class A
) {
$merged[] = $value;
// recursively merge the two array values
// recursively merge the two array values
} elseif (
is_array($value) === true &&
isset($merged[$key]) === true &&
@@ -516,7 +516,7 @@ class A
) {
$merged[$key] = static::merge($merged[$key], $value, $mode);
// simply overwrite with the value from the second array
// simply overwrite with the value from the second array
} else {
$merged[$key] = $value;
}

View File

@@ -198,7 +198,7 @@ class Collection extends Iterator implements Countable
* @param array|null $data
* @return array|$this
*/
public function data(array $data = null)
public function data(array|null $data = null)
{
if ($data === null) {
return $this->data;
@@ -775,7 +775,7 @@ class Collection extends Iterator implements Countable
* @param bool $unique
* @return array
*/
public function pluck(string $field, string $split = null, bool $unique = false): array
public function pluck(string $field, string|null $split = null, bool $unique = false): array
{
$result = [];
@@ -956,7 +956,7 @@ class Collection extends Iterator implements Countable
* @param int|null $limit The optional number of elements to return
* @return $this|static
*/
public function slice(int $offset = 0, int $limit = null)
public function slice(int $offset = 0, int|null $limit = null)
{
if ($offset === 0 && $limit === null) {
return $this;
@@ -1027,7 +1027,7 @@ class Collection extends Iterator implements Countable
} elseif ($arg === SORT_DESC || $argLower === 'desc') {
$fields[$currentField]['direction'] = SORT_DESC;
// other string: the field name
// other string: the field name
} elseif (is_string($arg) === true) {
$values = [];
@@ -1041,7 +1041,7 @@ class Collection extends Iterator implements Countable
$fields[] = ['field' => $arg, 'values' => $values];
// callable: custom field values
// callable: custom field values
} elseif (is_callable($arg) === true) {
$values = [];
@@ -1055,7 +1055,7 @@ class Collection extends Iterator implements Countable
$fields[] = ['field' => null, 'values' => $values];
// flags
// flags
} else {
$fields[$currentField]['flags'] = $arg;
}
@@ -1126,7 +1126,7 @@ class Collection extends Iterator implements Countable
* @param \Closure|null $map
* @return array
*/
public function toArray(Closure $map = null): array
public function toArray(Closure|null $map = null): array
{
if ($map !== null) {
return array_map($map, $this->data);
@@ -1163,7 +1163,7 @@ class Collection extends Iterator implements Countable
* @param Closure|null $map
* @return array
*/
public function values(Closure $map = null): array
public function values(Closure|null $map = null): array
{
$data = $map === null ? $this->data : array_map($map, $this->data);
return array_values($data);
@@ -1181,7 +1181,7 @@ class Collection extends Iterator implements Countable
* @param \Closure|null $fallback
* @return mixed
*/
public function when($condition, Closure $callback, Closure $fallback = null)
public function when($condition, Closure $callback, Closure|null $fallback = null)
{
if ($condition) {
return $callback->call($this, $condition);

View File

@@ -23,7 +23,7 @@ abstract class Facade
/**
* Proxy for all public instance calls
*/
public static function __callStatic(string $method, array $args = null)
public static function __callStatic(string $method, array|null $args = null)
{
return static::instance()->$method(...$args);
}

View File

@@ -405,7 +405,7 @@ class Html extends Xml
string $name,
array|string|null $content = '',
array $attr = [],
string $indent = null,
string|null $indent = null,
int $level = 0
): string {
// treat an explicit `null` value as an empty tag

View File

@@ -78,7 +78,7 @@ class I18n
/**
* Formats a number
*/
public static function formatNumber(int|float $number, string $locale = null): string
public static function formatNumber(int|float $number, string|null $locale = null): string
{
$locale ??= static::locale();
$formatter = static::decimalNumberFormatter($locale);
@@ -108,7 +108,7 @@ class I18n
*/
public static function template(
string $key,
string|array $fallback = null,
string|array|null $fallback = null,
array|null $replace = null,
string|null $locale = null
): string {
@@ -130,8 +130,8 @@ class I18n
*/
public static function translate(
string|array|null $key,
string|array $fallback = null,
string $locale = null
string|array|null $fallback = null,
string|null $locale = null
): string|array|Closure|null {
// use current locale if no specific is passed
$locale ??= static::locale();
@@ -242,7 +242,7 @@ class I18n
* by locale. If the translation does not exist
* yet, the loader will try to load it, if defined.
*/
public static function translation(string $locale = null): array
public static function translation(string|null $locale = null): array
{
$locale ??= static::locale();
@@ -304,7 +304,7 @@ class I18n
public static function translateCount(
string $key,
int $count,
string $locale = null,
string|null $locale = null,
bool $formatNumber = true
) {
$locale ??= static::locale();

View File

@@ -96,7 +96,7 @@ trait Properties
}
}
protected function setProperties($props, array $keys = null)
protected function setProperties($props, array|null $keys = null)
{
foreach (get_object_vars($this) as $name => $default) {
if ($name === 'propertyData') {

View File

@@ -30,7 +30,7 @@ class Silo
return static::$data;
}
public static function get(string|array $key = null, $default = null)
public static function get(string|array|null $key = null, $default = null)
{
if ($key === null) {
return static::$data;
@@ -42,7 +42,7 @@ class Silo
/**
* Removes an item from the data array
*/
public static function remove(string $key = null): array
public static function remove(string|null $key = null): array
{
// reset the entire array
if ($key === null) {

View File

@@ -263,7 +263,7 @@ class Str
* Returns everything between two strings from the first occurrence of a given string
*/
public static function between(
string $string = null,
string|null $string,
string $start,
string $end
): string {
@@ -275,7 +275,7 @@ class Str
*
* @param string $value The string to convert
*/
public static function camel(string $value = null): string
public static function camel(string|null $value = null): string
{
return lcfirst(static::studly($value));
}
@@ -286,7 +286,7 @@ class Str
*
* @param string $value The string to convert
*/
public static function camelToKebab(string $value = null): string
public static function camelToKebab(string|null $value = null): string
{
return static::lower(preg_replace('!([a-z0-9])([A-Z])!', '$1-$2', $value));
}
@@ -295,7 +295,7 @@ class Str
* Checks if a str contains another string
*/
public static function contains(
string $string = null,
string|null $string,
string $needle,
bool $caseInsensitive = false
): bool {
@@ -316,7 +316,7 @@ class Str
*/
public static function date(
int|null $time = null,
string|IntlDateFormatter $format = null,
string|IntlDateFormatter|null $format = null,
string|null $handler = null
): string|int|false {
if (is_null($format) === true) {
@@ -365,7 +365,7 @@ class Str
public static function convert(
string $string,
string $targetEncoding,
string $sourceEncoding = null
string|null $sourceEncoding = null
): string {
// detect the source encoding if not passed as third argument
$sourceEncoding ??= static::encoding($string);
@@ -414,7 +414,7 @@ class Str
* Checks if a string ends with the passed needle
*/
public static function endsWith(
string $string = null,
string|null $string,
string $needle,
bool $caseInsensitive = false
): bool {
@@ -574,7 +574,7 @@ class Str
/**
* Convert a string to kebab case.
*/
public static function kebab(string $value = null): string
public static function kebab(string|null $value = null): string
{
return static::snake($value, '-');
}
@@ -582,7 +582,7 @@ class Str
/**
* Convert a kebab case string to camel case.
*/
public static function kebabToCamel(string $value = null): string
public static function kebabToCamel(string|null $value = null): string
{
return ucfirst(preg_replace_callback(
'/-(.)/',
@@ -594,7 +594,7 @@ class Str
/**
* A UTF-8 safe version of strlen()
*/
public static function length(string $string = null): int
public static function length(string|null $string = null): int
{
return mb_strlen($string ?? '', 'UTF-8');
}
@@ -602,7 +602,7 @@ class Str
/**
* A UTF-8 safe version of strtolower()
*/
public static function lower(string $string = null): string
public static function lower(string|null $string = null): string
{
return mb_strtolower($string ?? '', 'UTF-8');
}
@@ -707,7 +707,7 @@ class Str
* @throws \Kirby\Exception\InvalidArgumentException for empty $needle
*/
public static function position(
string $string = null,
string|null $string,
string $needle,
bool $caseInsensitive = false
): int|false {
@@ -739,7 +739,7 @@ class Str
* @param string $type Pool type (type of allowed characters)
*/
public static function random(
int $length = null,
int|null $length = null,
string $type = 'alphaNum'
): string|false {
$length ??= random_int(5, 10);
@@ -967,7 +967,7 @@ class Str
* @return string The filled-in and partially escaped string
*/
public static function safeTemplate(
string $string = null,
string|null $string = null,
array $data = [],
array $options = []
): string {
@@ -1024,7 +1024,7 @@ class Str
* @return string The shortened string
*/
public static function short(
string $string = null,
string|null $string = null,
int $length = 0,
string $appendix = '…'
): string {
@@ -1129,9 +1129,9 @@ class Str
* @return string The safe string
*/
public static function slug(
string $string = null,
string $separator = null,
string $allowed = null,
string|null $string = null,
string|null $separator = null,
string|null $allowed = null,
int|false $maxlength = 128
): string {
$separator ??= static::$defaults['slug']['separator'];
@@ -1176,7 +1176,7 @@ class Str
* Convert a string to snake case.
*/
public static function snake(
string $value = null,
string|null $value = null,
string $delimiter = '_'
): string {
if (ctype_lower($value) === false) {
@@ -1230,7 +1230,7 @@ class Str
* Checks if a string starts with the passed needle
*/
public static function startsWith(
string $string = null,
string|null $string,
string $needle,
bool $caseInsensitive = false
): bool {
@@ -1247,7 +1247,7 @@ class Str
*
* @param string $value The string to convert
*/
public static function studly(string $value = null): string
public static function studly(string|null $value = null): string
{
$value = str_replace(['-', '_'], ' ', $value);
$value = ucwords($value);
@@ -1258,9 +1258,9 @@ class Str
* A UTF-8 safe version of substr()
*/
public static function substr(
string $string = null,
string|null $string = null,
int $start = 0,
int $length = null
int|null $length = null
): string {
return mb_substr($string ?? '', $start, $length, 'UTF-8');
}
@@ -1287,7 +1287,7 @@ class Str
* @return string The filled-in string
*/
public static function template(
string $string = null,
string|null $string = null,
array $data = [],
array $options = []
): string {
@@ -1384,7 +1384,7 @@ class Str
/**
* A UTF-8 safe version of ucfirst()
*/
public static function ucfirst(string $string = null): string
public static function ucfirst(string|null $string = null): string
{
$first = static::substr($string, 0, 1);
$rest = static::substr($string, 1);
@@ -1394,7 +1394,7 @@ class Str
/**
* A UTF-8 safe version of ucwords()
*/
public static function ucwords(string $string = null): string
public static function ucwords(string|null $string = null): string
{
return mb_convert_case($string ?? '', MB_CASE_TITLE, 'UTF-8');
}
@@ -1409,7 +1409,7 @@ class Str
*
* </code>
*/
public static function unhtml(string $string = null): string
public static function unhtml(string|null $string = null): string
{
return Html::decode($string);
}
@@ -1434,7 +1434,7 @@ class Str
/**
* A UTF-8 safe version of strotoupper()
*/
public static function upper(string $string = null): string
public static function upper(string|null $string = null): string
{
return mb_strtoupper($string ?? '', 'UTF-8');
}
@@ -1472,7 +1472,7 @@ class Str
* typographical widows at the end of a paragraph
* that's a single word in the last line
*/
public static function widont(string $string = null): string
public static function widont(string|null $string = null): string
{
// make sure $string is string
$string ??= '';
@@ -1504,7 +1504,7 @@ class Str
public static function wrap(
string $string,
string $before,
string $after = null
string|null $after = null
): string {
return $before . $string . ($after ?? $before);
}

View File

@@ -306,7 +306,7 @@ V::$validators = [
* Pass an operator as second argument and another date as
* third argument to compare them.
*/
'date' => function (string|null $value, string $operator = null, string $test = null): bool {
'date' => function (string|null $value, string|null $operator = null, string|null $test = null): bool {
// make sure $value is a string
$value ??= '';
@@ -474,28 +474,28 @@ V::$validators = [
/**
* Checks if the number of characters in the value equals or is below the given maximum
*/
'maxLength' => function (string $value = null, $max): bool {
'maxLength' => function (string|null $value, $max): bool {
return Str::length(trim($value)) <= $max;
},
/**
* Checks if the number of characters in the value equals or is greater than the given minimum
*/
'minLength' => function (string $value = null, $min): bool {
'minLength' => function (string|null $value, $min): bool {
return Str::length(trim($value)) >= $min;
},
/**
* Checks if the number of words in the value equals or is below the given maximum
*/
'maxWords' => function (string $value = null, $max): bool {
'maxWords' => function (string|null $value, $max): bool {
return V::max(explode(' ', trim($value)), $max) === true;
},
/**
* Checks if the number of words in the value equals or is below the given maximum
*/
'minWords' => function (string $value = null, $min): bool {
'minWords' => function (string|null $value, $min): bool {
return V::min(explode(' ', trim($value)), $min) === true;
},
@@ -628,7 +628,7 @@ V::$validators = [
/**
* Checks for a valid Uuid, optionally for specific model type
*/
'uuid' => function (string $value, string $type = null): bool {
'uuid' => function (string $value, string|null $type = null): bool {
return Uuid::is($value, $type);
}
];

View File

@@ -373,7 +373,7 @@ class Xml
string $name,
array|string|null $content = '',
array $attr = [],
string $indent = null,
string|null $indent = null,
int $level = 0
): string {
$attr = static::attr($attr);

View File

@@ -61,7 +61,7 @@ class Uri extends BaseUri
* Returns the ID part of the UUID string
* (and sets it when new one passed)
*/
public function host(string $host = null): string|null
public function host(string|null $host = null): string|null
{
if ($host !== null) {
return $this->host = $host;