Upgrade to 3.8.0

This commit is contained in:
Bastian Allgeier
2022-10-06 10:11:54 +02:00
parent a9ed4e45ca
commit 7d168aae58
332 changed files with 26337 additions and 21977 deletions

View File

@@ -2,6 +2,8 @@
namespace Kirby\Panel;
use Kirby\Http\Response;
/**
* The Dialog response class handles Fiber
* requests to render the JSON object for
@@ -16,16 +18,12 @@ namespace Kirby\Panel;
*/
class Dialog extends Json
{
protected static $key = '$dialog';
protected static string $key = '$dialog';
/**
* Renders dialogs
*
* @param mixed $data
* @param array $options
* @return \Kirby\Http\Response
*/
public static function response($data, array $options = [])
public static function response($data, array $options = []): Response
{
// interpret true as success
if ($data === true) {

View File

@@ -3,7 +3,6 @@
namespace Kirby\Panel;
use Kirby\Cms\App;
use Kirby\Cms\Helpers;
use Kirby\Exception\Exception;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Filesystem\Asset;
@@ -31,8 +30,6 @@ class Document
/**
* Generates an array with all assets
* that need to be loaded for the panel (js, css, icons)
*
* @return array
*/
public static function assets(): array
{
@@ -137,9 +134,8 @@ class Document
* @since 3.7.0
*
* @param string $option asset option name
* @return string|null
*/
public static function customAsset(string $option): ?string
public static function customAsset(string $option): string|null
{
if ($path = App::instance()->option($option)) {
$asset = new Asset($path);
@@ -153,34 +149,12 @@ class Document
}
/**
* @deprecated 3.7.0 Use `Document::customAsset('panel.css)` instead
* @todo remove in 3.8.0
* @codeCoverageIgnore
*/
public static function customCss(): ?string
{
Helpers::deprecated('Panel\Document::customCss() has been deprecated and will be removed in Kirby 3.8.0. Use Panel\Document::customAsset(\'panel.css\') instead.');
return static::customAsset('panel.css');
}
/**
* @deprecated 3.7.0 Use `Document::customAsset('panel.js)` instead
* @todo remove in 3.8.0
* @codeCoverageIgnore
*/
public static function customJs(): ?string
{
Helpers::deprecated('Panel\Document::customJs() has been deprecated and will be removed in Kirby 3.8.0. Use Panel\Document::customAsset(\'panel.js\') instead.');
return static::customAsset('panel.js');
}
/**
* Returns array of favion icons
* Returns array of favicon icons
* based on config option
* @since 3.7.0
*
* @param string $url URL prefix for default icons
* @return array
* @throws \Kirby\Exception\InvalidArgumentException
*/
public static function favicon(string $url = ''): array
{
@@ -190,13 +164,13 @@ class Document
'type' => 'image/png',
'url' => $url . '/apple-touch-icon.png',
],
'shortcut icon' => [
'type' => 'image/svg+xml',
'url' => $url . '/favicon.svg',
],
'alternate icon' => [
'type' => 'image/png',
'url' => $url . '/favicon.png',
],
'shortcut icon' => [
'type' => 'image/svg+xml',
'url' => $url . '/favicon.svg',
]
]);
@@ -221,8 +195,6 @@ class Document
* Load the SVG icon sprite
* This will be injected in the
* initial HTML document for the Panel
*
* @return string
*/
public static function icons(): string
{
@@ -233,7 +205,6 @@ class Document
* Links all dist files in the media folder
* and returns the link to the requested asset
*
* @return bool
* @throws \Kirby\Exception\Exception If Panel assets could not be moved to the public directory
*/
public static function link(): bool
@@ -265,11 +236,8 @@ class Document
/**
* Renders the panel document
*
* @param array $fiber
* @return \Kirby\Http\Response
*/
public static function response(array $fiber)
public static function response(array $fiber): Response
{
$kirby = App::instance();

View File

@@ -5,6 +5,7 @@ namespace Kirby\Panel;
use Kirby\Cms\App;
use Kirby\Cms\Find;
use Kirby\Exception\LogicException;
use Kirby\Http\Response;
use Kirby\Http\Uri;
use Kirby\Toolkit\Str;
use Throwable;
@@ -23,12 +24,10 @@ use Throwable;
*/
class Dropdown extends Json
{
protected static $key = '$dropdown';
protected static string $key = '$dropdown';
/**
* Returns the options for the changes dropdown
*
* @return array
*/
public static function changes(): array
{
@@ -54,7 +53,7 @@ class Dropdown extends Json
}
$options[] = $option;
} catch (Throwable $e) {
} catch (Throwable) {
continue;
}
}
@@ -72,12 +71,8 @@ class Dropdown extends Json
/**
* Renders dropdowns
*
* @param mixed $data
* @param array $options
* @return \Kirby\Http\Response
*/
public static function response($data, array $options = [])
public static function response($data, array $options = []): Response
{
if (is_array($data) === true) {
$data = [

View File

@@ -22,9 +22,6 @@ class Field
{
/**
* A standard email field
*
* @param array $props
* @return array
*/
public static function email(array $props = []): array
{
@@ -37,10 +34,6 @@ class Field
/**
* File position
*
* @param \Kirby\Cms\File
* @param array $props
* @return array
*/
public static function filePosition(File $file, array $props = []): array
{
@@ -78,9 +71,6 @@ class Field
}
/**
* @return array
*/
public static function hidden(): array
{
return ['type' => 'hidden'];
@@ -88,10 +78,6 @@ class Field
/**
* Page position
*
* @param \Kirby\Cms\Page
* @param array $props
* @return array
*/
public static function pagePosition(Page $page, array $props = []): array
{
@@ -137,9 +123,6 @@ class Field
/**
* A regular password field
*
* @param array $props
* @return array
*/
public static function password(array $props = []): array
{
@@ -151,9 +134,6 @@ class Field
/**
* User role radio buttons
*
* @param array $props
* @return array
*/
public static function role(array $props = []): array
{
@@ -183,10 +163,6 @@ class Field
], $props);
}
/**
* @param array $props
* @return array
*/
public static function slug(array $props = []): array
{
return array_merge([
@@ -195,12 +171,7 @@ class Field
], $props);
}
/**
* @param array $blueprints
* @param array $props
* @return array
*/
public static function template(?array $blueprints = [], ?array $props = []): array
public static function template(array|null $blueprints = [], array|null $props = []): array
{
$options = [];
@@ -221,10 +192,6 @@ class Field
], $props);
}
/**
* @param array $props
* @return array
*/
public static function title(array $props = []): array
{
return array_merge([
@@ -236,9 +203,6 @@ class Field
/**
* Panel translation select box
*
* @param array $props
* @return array
*/
public static function translation(array $props = []): array
{
@@ -259,10 +223,6 @@ class Field
], $props);
}
/**
* @param array $props
* @return array
*/
public static function username(array $props = []): array
{
return array_merge([

View File

@@ -2,6 +2,8 @@
namespace Kirby\Panel;
use Kirby\Cms\File as CmsFile;
use Kirby\Filesystem\Asset;
use Kirby\Toolkit\I18n;
use Throwable;
@@ -17,15 +19,8 @@ use Throwable;
*/
class File extends Model
{
/**
* @var \Kirby\Cms\File
*/
protected $model;
/**
* Breadcrumb array
*
* @return array
*/
public function breadcrumb(): array
{
@@ -34,6 +29,7 @@ class File extends Model
switch ($parent::CLASS_ALIAS) {
case 'user':
/** @var \Kirby\Cms\User $parent */
// The breadcrumb is not necessary
// on the account view
if ($parent->isLoggedIn() === false) {
@@ -44,6 +40,7 @@ class File extends Model
}
break;
case 'page':
/** @var \Kirby\Cms\Page $parent */
$breadcrumb = $this->model->parents()->flip()->values(fn ($parent) => [
'label' => $parent->title()->toString(),
'link' => $parent->panel()->url(true),
@@ -67,41 +64,41 @@ class File extends Model
*
* @internal
* @param string|null $type (`auto`|`kirbytext`|`markdown`)
* @param bool $absolute
* @return string
*/
public function dragText(string $type = null, bool $absolute = false): string
public function dragText(string|null $type = null, bool $absolute = false): string
{
$type = $this->dragTextType($type);
$url = $absolute ? $this->model->id() : $this->model->filename();
$url = $this->model->filename();
$file = $this->model->type();
// By default only the filename is added as relative URL.
// If an absolute URL is required, either use the permalink
// for markdown notation or the UUID for Kirbytext (since
// Kirbytags support can resolve UUIDs directly)
if ($absolute === true) {
$url = $type === 'markdown' ? $this->model->permalink() : $this->model->uuid();
}
if ($dragTextFromCallback = $this->dragTextFromCallback($type, $url)) {
return $dragTextFromCallback;
}
if ($type === 'markdown') {
if ($this->model->type() === 'image') {
return '![' . $this->model->alt() . '](' . $url . ')';
}
return '[' . $this->model->filename() . '](' . $url . ')';
return match ($file) {
'image' => '![' . $this->model->alt() . '](' . $url . ')',
default => '[' . $this->model->filename() . '](' . $url . ')'
};
}
if ($this->model->type() === 'image') {
return '(image: ' . $url . ')';
}
if ($this->model->type() === 'video') {
return '(video: ' . $url . ')';
}
return '(file: ' . $url . ')';
return match ($file) {
'image', 'video' => '(' . $file . ': ' . $url . ')',
default => '(file: ' . $url . ')'
};
}
/**
* Provides options for the file dropdown
*
* @param array $options
* @return array
*/
public function dropdown(array $options = []): array
{
@@ -163,9 +160,7 @@ class File extends Model
/**
* Returns the setup for a dropdown option
* which is used in the changes dropdown
* for example.
*
* @return array
* for example
*/
public function dropdownOption(): array
{
@@ -177,8 +172,6 @@ class File extends Model
/**
* Returns the Panel icon color
*
* @return string
*/
protected function imageColor(): string
{
@@ -208,8 +201,6 @@ class File extends Model
/**
* Default settings for the file's Panel image
*
* @return array
*/
protected function imageDefaults(): array
{
@@ -221,8 +212,6 @@ class File extends Model
/**
* Returns the Panel icon type
*
* @return string
*/
protected function imageIcon(): string
{
@@ -253,13 +242,11 @@ class File extends Model
/**
* Returns the image file object based on provided query
*
* @internal
* @param string|null $query
* @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null
*/
protected function imageSource(string $query = null)
{
protected function imageSource(
string|null $query = null
): CmsFile|Asset|null {
if ($query === null && $this->model->isViewable()) {
return $this->model;
}
@@ -272,7 +259,6 @@ class File extends Model
* that can be performed in the Panel
*
* @param array $unlock An array of options that will be force-unlocked
* @return array
*/
public function options(array $unlock = []): array
{
@@ -282,7 +268,7 @@ class File extends Model
// check if the file type is allowed at all,
// otherwise it cannot be replaced
$this->model->match($this->model->blueprint()->accept());
} catch (Throwable $e) {
} catch (Throwable) {
$options['replace'] = false;
}
@@ -291,8 +277,6 @@ class File extends Model
/**
* Returns the full path without leading slash
*
* @return string
*/
public function path(): string
{
@@ -302,18 +286,13 @@ class File extends Model
/**
* Prepares the response data for file pickers
* and file fields
*
* @param array|null $params
* @return array
*/
public function pickerData(array $params = []): array
{
$id = $this->model->id();
$name = $this->model->filename();
if (empty($params['model']) === false) {
$parent = $this->model->parent();
$uuid = $parent === $params['model'] ? $name : $id;
$absolute = $parent !== $params['model'];
}
@@ -323,18 +302,14 @@ class File extends Model
'filename' => $name,
'dragText' => $this->dragText('auto', $absolute ?? false),
'type' => $this->model->type(),
'url' => $this->model->url(),
'uuid' => $uuid ?? $id,
'url' => $this->model->url()
]);
}
/**
* Returns the data array for the
* view's component props
*
* @internal
*
* @return array
*/
public function props(): array
{
@@ -408,10 +383,7 @@ class File extends Model
/**
* Returns navigation array with
* previous and next file
*
* @internal
*
* @return array
*/
public function prevNext(): array
{
@@ -424,11 +396,11 @@ class File extends Model
);
return [
'next' => function () use ($file, $siblings): ?array {
'next' => function () use ($file, $siblings): array|null {
$next = $siblings->nth($siblings->indexOf($file) + 1);
return $this->toPrevNextLink($next, 'filename');
},
'prev' => function () use ($file, $siblings): ?array {
'prev' => function () use ($file, $siblings): array|null {
$prev = $siblings->nth($siblings->indexOf($file) - 1);
return $this->toPrevNextLink($prev, 'filename');
}
@@ -437,9 +409,6 @@ class File extends Model
/**
* Returns the url to the editing view
* in the panel
*
* @param bool $relative
* @return string
*/
public function url(bool $relative = false): string
{
@@ -450,21 +419,16 @@ class File extends Model
/**
* Returns the data array for
* this model's Panel view
*
* @internal
*
* @return array
*/
public function view(): array
{
$file = $this->model;
return [
'breadcrumb' => fn (): array => $file->panel()->breadcrumb(),
'breadcrumb' => fn (): array => $this->model->panel()->breadcrumb(),
'component' => 'k-file-view',
'props' => $this->props(),
'search' => 'files',
'title' => $file->filename(),
'title' => $this->model->filename(),
];
}
}

View File

@@ -38,9 +38,6 @@ class Home
* It will go through the entire menu and
* take the first area which is not disabled
* or locked in other ways
*
* @param \Kirby\Cms\User $user
* @return string
*/
public static function alternative(User $user): string
{
@@ -85,10 +82,6 @@ class Home
* panel path. This is quite tricky, because we
* need to call a trimmed down router to check
* for available routes and their firewall status.
*
* @param \Kirby\Cms\User
* @param string $path
* @return bool
*/
public static function hasAccess(User $user, string $path): bool
{
@@ -124,7 +117,7 @@ class Home
// check the firewall
return Panel::hasAccess($user, $areaId);
});
} catch (Throwable $e) {
} catch (Throwable) {
return false;
}
}
@@ -134,9 +127,6 @@ class Home
* as the index URL of the Kirby installation.
* This is used to block external URLs to third-party
* domains as redirect options.
*
* @param \Kirby\Http\Uri $uri
* @return bool
*/
public static function hasValidDomain(Uri $uri): bool
{
@@ -145,10 +135,7 @@ class Home
}
/**
* Checks if the given URL is a Panel Url.
*
* @param string $url
* @return bool
* Checks if the given URL is a Panel Url
*/
public static function isPanelUrl(string $url): bool
{
@@ -158,11 +145,8 @@ class Home
/**
* Returns the path after /panel/ which can then
* be used in the router or to find a matching view
*
* @param string $url
* @return string|null
*/
public static function panelPath(string $url): ?string
public static function panelPath(string $url): string|null
{
$after = Str::after($url, App::instance()->url('panel'));
return trim($after, '/');
@@ -173,10 +157,8 @@ class Home
* before the last logout. We take this Url if possible
* to redirect the user back to the last point where they
* left before they got logged out.
*
* @return string|null
*/
public static function remembered(): ?string
public static function remembered(): string|null
{
// check for a stored path after login
$remembered = App::instance()->session()->pull('panel.path');
@@ -206,8 +188,6 @@ class Home
* Afterwards, we also check for permissions before the redirect happens
* to avoid redirects to inaccessible Panel views. In such a case
* the next best accessible view is picked from the menu.
*
* @return string
*/
public static function url(): string
{

View File

@@ -2,6 +2,10 @@
namespace Kirby\Panel;
use Kirby\Exception\Exception;
use Kirby\Http\Response;
use Throwable;
/**
* The Json abstract response class provides
* common framework for Fiber requests
@@ -17,16 +21,12 @@ namespace Kirby\Panel;
*/
abstract class Json
{
protected static $key = '$response';
protected static string $key = '$response';
/**
* Renders the error response with the provided message
*
* @param string $message
* @param int $code
* @return array
*/
public static function error(string $message, int $code = 404)
public static function error(string $message, int $code = 404): array
{
return [
'code' => $code,
@@ -36,26 +36,22 @@ abstract class Json
/**
* Prepares the JSON response for the Panel
*
* @param mixed $data
* @param array $options
* @return mixed
*/
public static function response($data, array $options = [])
public static function response($data, array $options = []): Response
{
// handle redirects
if (is_a($data, 'Kirby\Panel\Redirect') === true) {
if ($data instanceof Redirect) {
$data = [
'redirect' => $data->location(),
'code' => $data->code()
];
// handle Kirby exceptions
} elseif (is_a($data, 'Kirby\Exception\Exception') === true) {
} elseif ($data instanceof Exception) {
$data = static::error($data->getMessage(), $data->getHttpCode());
// handle exceptions
} elseif (is_a($data, 'Throwable') === true) {
} elseif ($data instanceof Throwable) {
$data = static::error($data->getMessage(), 500);
// only expect arrays from here on

View File

@@ -2,6 +2,10 @@
namespace Kirby\Panel;
use Closure;
use Kirby\Cms\File as CmsFile;
use Kirby\Cms\ModelWithContent;
use Kirby\Filesystem\Asset;
use Kirby\Form\Form;
use Kirby\Http\Uri;
use Kirby\Toolkit\A;
@@ -18,23 +22,15 @@ use Kirby\Toolkit\A;
*/
abstract class Model
{
/**
* @var \Kirby\Cms\ModelWithContent
*/
protected $model;
protected ModelWithContent $model;
/**
* @param \Kirby\Cms\ModelWithContent $model
*/
public function __construct($model)
public function __construct(ModelWithContent $model)
{
$this->model = $model;
}
/**
* Get the content values for the model
*
* @return array
*/
public function content(): array
{
@@ -47,20 +43,14 @@ abstract class Model
* @internal
*
* @param string $type markdown or kirbytext
* @param mixed ...$args
* @return string|null
*/
public function dragTextFromCallback(string $type, ...$args): ?string
public function dragTextFromCallback(string $type, ...$args): string|null
{
$option = 'panel.' . $type . '.' . $this->model::CLASS_ALIAS . 'DragText';
$callback = $this->model->kirby()->option($option);
if (
empty($callback) === false &&
is_a($callback, 'Closure') === true &&
($dragText = $callback($this->model, ...$args)) !== null
) {
return $dragText;
if ($callback instanceof Closure) {
return $callback($this->model, ...$args);
}
return null;
@@ -74,9 +64,8 @@ abstract class Model
* @internal
*
* @param string|null $type (`auto`|`kirbytext`|`markdown`)
* @return string
*/
public function dragTextType(string $type = null): string
public function dragTextType(string|null $type = null): string
{
$type ??= 'auto';
@@ -92,8 +81,6 @@ abstract class Model
* Returns the setup for a dropdown option
* which is used in the changes dropdown
* for example.
*
* @return array
*/
public function dropdownOption(): array
{
@@ -106,14 +93,12 @@ abstract class Model
/**
* Returns the Panel image definition
*
* @internal
*
* @param string|array|false|null $settings
* @return array|null
*/
public function image($settings = [], string $layout = 'list'): ?array
{
public function image(
string|array|false|null $settings = [],
string $layout = 'list'
): array|null {
// completely switched off
if ($settings === false) {
return null;
@@ -147,18 +132,11 @@ abstract class Model
if ($image->isResizable() === true) {
$settings['src'] = static::imagePlaceholder();
switch ($layout) {
case 'cards':
$sizes = [352, 864, 1408];
break;
case 'cardlets':
$sizes = [96, 192];
break;
case 'list':
default:
$sizes = [38, 76];
break;
}
$sizes = match ($layout) {
'cards' => [352, 864, 1408],
'cardlets' => [96, 192],
default => [38, 76]
};
if (($settings['cover'] ?? false) === false || $layout === 'cards') {
$settings['srcset'] = $image->srcset($sizes);
@@ -197,8 +175,6 @@ abstract class Model
/**
* Default settings for Panel image
*
* @return array
*/
protected function imageDefaults(): array
{
@@ -213,10 +189,7 @@ abstract class Model
/**
* Data URI placeholder string for Panel image
*
* @internal
*
* @return string
*/
public static function imagePlaceholder(): string
{
@@ -225,20 +198,17 @@ abstract class Model
/**
* Returns the image file object based on provided query
*
* @internal
*
* @param string|null $query
* @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null
*/
protected function imageSource(?string $query = null)
{
protected function imageSource(
string|null $query = null
): CmsFile|Asset|null {
$image = $this->model->query($query ?? null);
// validate the query result
if (
is_a($image, 'Kirby\Cms\File') === true ||
is_a($image, 'Kirby\Filesystem\Asset') === true
$image instanceof CmsFile ||
$image instanceof Asset
) {
return $image;
}
@@ -249,11 +219,6 @@ abstract class Model
/**
* Checks for disabled dropdown options according
* to the given permissions
*
* @param string $action
* @param array $options
* @param array $permissions
* @return bool
*/
public function isDisabledDropdownOption(string $action, array $options, array $permissions): bool
{
@@ -267,21 +232,10 @@ abstract class Model
* @return array|false array with lock info,
* false if locking is not supported
*/
public function lock()
public function lock(): array|false
{
if ($lock = $this->model->lock()) {
if ($lock->isUnlocked() === true) {
return ['state' => 'unlock'];
}
if ($lock->isLocked() === true) {
return [
'state' => 'lock',
'data' => $lock->get()
];
}
return ['state' => null];
return $lock->toArray();
}
return false;
@@ -293,7 +247,6 @@ abstract class Model
* This also checks for the lock status
*
* @param array $unlock An array of options that will be force-unlocked
* @return array
*/
public function options(array $unlock = []): array
{
@@ -314,17 +267,12 @@ abstract class Model
/**
* Returns the full path without leading slash
*
* @return string
*/
abstract public function path(): string;
/**
* Prepares the response data for page pickers
* and page fields
*
* @param array|null $params
* @return array
*/
public function pickerData(array $params = []): array
{
@@ -338,16 +286,14 @@ abstract class Model
'link' => $this->url(true),
'sortable' => true,
'text' => $this->model->toSafeString($params['text'] ?? false),
'uuid' => $this->model->uuid()->toString(),
];
}
/**
* Returns the data array for the
* view's component props
*
* @internal
*
* @return array
*/
public function props(): array
{
@@ -376,11 +322,7 @@ abstract class Model
* Returns link url and tooltip
* for model (e.g. used for prev/next
* navigation)
*
* @internal
*
* @param string $tooltip
* @return array
*/
public function toLink(string $tooltip = 'title'): array
{
@@ -396,12 +338,8 @@ abstract class Model
* preserves tab selection
*
* @internal
*
* @param \Kirby\Cms\ModelWithContent|null $model
* @param string $tooltip
* @return array
*/
protected function toPrevNextLink($model = null, string $tooltip = 'title'): ?array
protected function toPrevNextLink(ModelWithContent|null $model = null, string $tooltip = 'title'): array|null
{
if ($model === null) {
return null;
@@ -425,9 +363,6 @@ abstract class Model
* in the Panel
*
* @internal
*
* @param bool $relative
* @return string
*/
public function url(bool $relative = false): string
{
@@ -443,8 +378,6 @@ abstract class Model
* this model's Panel view
*
* @internal
*
* @return array
*/
abstract public function view(): array;
}

View File

@@ -2,6 +2,8 @@
namespace Kirby\Panel;
use Kirby\Cms\File as CmsFile;
use Kirby\Filesystem\Asset;
use Kirby\Toolkit\I18n;
/**
@@ -16,15 +18,8 @@ use Kirby\Toolkit\I18n;
*/
class Page extends Model
{
/**
* @var \Kirby\Cms\Page
*/
protected $model;
/**
* Breadcrumb array
*
* @return array
*/
public function breadcrumb(): array
{
@@ -43,9 +38,8 @@ class Page extends Model
*
* @internal
* @param string|null $type (`auto`|`kirbytext`|`markdown`)
* @return string
*/
public function dragText(string $type = null): string
public function dragText(string|null $type = null): string
{
$type = $this->dragTextType($type);
@@ -53,18 +47,16 @@ class Page extends Model
return $callback;
}
if ($type === 'markdown') {
return '[' . $this->model->title() . '](' . $this->model->url() . ')';
}
$title = $this->model->title();
return '(link: ' . $this->model->id() . ' text: ' . $this->model->title() . ')';
return match ($type) {
'markdown' => '[' . $title . '](' . $this->model->permalink() . ')',
default => '(link: ' . $this->model->uuid() . ' text: ' . $title . ')'
};
}
/**
* Provides options for the page dropdown
*
* @param array $options
* @return array
*/
public function dropdown(array $options = []): array
{
@@ -160,8 +152,6 @@ class Page extends Model
* Returns the setup for a dropdown option
* which is used in the changes dropdown
* for example.
*
* @return array
*/
public function dropdownOption(): array
{
@@ -173,8 +163,6 @@ class Page extends Model
/**
* Returns the escaped Id, which is
* used in the panel to make routing work properly
*
* @return string
*/
public function id(): string
{
@@ -183,8 +171,6 @@ class Page extends Model
/**
* Default settings for the page's Panel image
*
* @return array
*/
protected function imageDefaults(): array
{
@@ -201,11 +187,10 @@ class Page extends Model
* Returns the image file object based on provided query
*
* @internal
* @param string|null $query
* @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null
*/
protected function imageSource(string $query = null)
{
protected function imageSource(
string|null $query = null
): CmsFile|Asset|null {
if ($query === null) {
$query = 'page.image';
}
@@ -217,7 +202,6 @@ class Page extends Model
* Returns the full path without leading slash
*
* @internal
* @return string
*/
public function path(): string
{
@@ -227,9 +211,6 @@ class Page extends Model
/**
* Prepares the response data for page pickers
* and page fields
*
* @param array|null $params
* @return array
*/
public function pickerData(array $params = []): array
{
@@ -245,12 +226,11 @@ class Page extends Model
/**
* The best applicable position for
* the position/status dialog
*
* @return int
*/
public function position(): int
{
return $this->model->num() ?? $this->model->parentModel()->children()->listed()->not($this->model)->count() + 1;
return $this->model->num() ??
$this->model->parentModel()->children()->listed()->not($this->model)->count() + 1;
}
/**
@@ -259,8 +239,6 @@ class Page extends Model
* based on blueprint definition
*
* @internal
*
* @return array
*/
public function prevNext(): array
{
@@ -323,8 +301,6 @@ class Page extends Model
* view's component props
*
* @internal
*
* @return array
*/
public function props(): array
{
@@ -334,7 +310,7 @@ class Page extends Model
parent::props(),
$this->prevNext(),
[
'blueprint' => $this->model->intendedTemplate()->name(),
'blueprint' => $page->intendedTemplate()->name(),
'model' => [
'content' => $this->content(),
'id' => $page->id(),
@@ -358,8 +334,6 @@ class Page extends Model
* this model's Panel view
*
* @internal
*
* @return array
*/
public function view(): array
{

View File

@@ -2,6 +2,7 @@
namespace Kirby\Panel;
use Closure;
use Kirby\Cms\App;
use Kirby\Cms\Url as CmsUrl;
use Kirby\Cms\User;
@@ -32,12 +33,8 @@ class Panel
{
/**
* Normalize a panel area
*
* @param string $id
* @param array|string $area
* @return array
*/
public static function area(string $id, $area): array
public static function area(string $id, array|string $area): array
{
$area['id'] = $id;
$area['label'] ??= $id;
@@ -53,8 +50,6 @@ class Panel
/**
* Collect all registered areas
*
* @return array
*/
public static function areas(): array
{
@@ -116,13 +111,11 @@ class Panel
/**
* Check for access permissions
*
* @param \Kirby\Cms\User|null $user
* @param string|null $areaId
* @return bool
*/
public static function firewall(?User $user = null, ?string $areaId = null): bool
{
public static function firewall(
User|null $user = null,
string|null $areaId = null
): bool {
// a user has to be logged in
if ($user === null) {
throw new PermissionException(['key' => 'access.panel']);
@@ -158,13 +151,10 @@ class Panel
/**
* Redirect to a Panel url
*
* @param string|null $path
* @param int $code
* @throws \Kirby\Panel\Redirect
* @return void
* @codeCoverageIgnore
*/
public static function go(?string $url = null, int $code = 302): void
public static function go(string|null $url = null, int $code = 302): void
{
throw new Redirect(static::url($url), $code);
}
@@ -172,17 +162,15 @@ class Panel
/**
* Check if the given user has access to the panel
* or to a given area
*
* @param \Kirby\Cms\User|null $user
* @param string|null $area
* @return bool
*/
public static function hasAccess(?User $user = null, string $area = null): bool
{
public static function hasAccess(
User|null $user = null,
string|null $area = null
): bool {
try {
static::firewall($user, $area);
return true;
} catch (Throwable $e) {
} catch (Throwable) {
return false;
}
}
@@ -190,8 +178,6 @@ class Panel
/**
* Checks for a Fiber request
* via get parameters or headers
*
* @return bool
*/
public static function isFiberRequest(): bool
{
@@ -207,12 +193,8 @@ class Panel
/**
* Returns a JSON response
* for Fiber calls
*
* @param array $data
* @param int $code
* @return \Kirby\Http\Response
*/
public static function json(array $data, int $code = 200)
public static function json(array $data, int $code = 200): Response
{
$request = App::instance()->request();
@@ -224,8 +206,6 @@ class Panel
/**
* Checks for a multilanguage installation
*
* @return bool
*/
public static function multilang(): bool
{
@@ -236,8 +216,6 @@ class Panel
/**
* Returns the referrer path if present
*
* @return string
*/
public static function referrer(): string
{
@@ -253,15 +231,11 @@ class Panel
/**
* Creates a Response object from the result of
* a Panel route call
*
* @params mixed $result
* @params array $options
* @return \Kirby\Http\Response
*/
public static function response($result, array $options = [])
public static function response($result, array $options = []): Response
{
// pass responses directly down to the Kirby router
if (is_a($result, 'Kirby\Http\Response') === true) {
if ($result instanceof Response) {
return $result;
}
@@ -275,25 +249,18 @@ class Panel
}
// handle different response types (view, dialog, ...)
switch ($options['type'] ?? null) {
case 'dialog':
return Dialog::response($result, $options);
case 'dropdown':
return Dropdown::response($result, $options);
case 'search':
return Search::response($result, $options);
default:
return View::response($result, $options);
}
return match ($options['type'] ?? null) {
'dialog' => Dialog::response($result, $options),
'dropdown' => Dropdown::response($result, $options),
'search' => Search::response($result, $options),
default => View::response($result, $options)
};
}
/**
* Router for the Panel views
*
* @param string $path
* @return \Kirby\Http\Response|false
*/
public static function router(string $path = null)
public static function router(string|null $path = null): Response|null
{
$kirby = App::instance();
@@ -349,8 +316,6 @@ class Panel
/**
* Extract the routes from the given array
* of active areas.
*
* @return array
*/
public static function routes(array $areas): array
{
@@ -404,10 +369,6 @@ class Panel
/**
* Extract all routes from an area
*
* @param string $areaId
* @param array $area
* @return array
*/
public static function routesForDialogs(string $areaId, array $area): array
{
@@ -441,10 +402,6 @@ class Panel
/**
* Extract all routes for dropdowns
*
* @param string $areaId
* @param array $area
* @return array
*/
public static function routesForDropdowns(string $areaId, array $area): array
{
@@ -454,7 +411,7 @@ class Panel
foreach ($dropdowns as $name => $dropdown) {
// Handle shortcuts for dropdowns. The name is the pattern
// and options are defined in a Closure
if (is_a($dropdown, 'Closure') === true) {
if ($dropdown instanceof Closure) {
$dropdown = [
'pattern' => $name,
'action' => $dropdown
@@ -479,10 +436,6 @@ class Panel
/**
* Extract all routes for searches
*
* @param string $areaId
* @param array $area
* @return array
*/
public static function routesForSearches(string $areaId, array $area): array
{
@@ -511,10 +464,6 @@ class Panel
/**
* Extract all views from an area
*
* @param string $areaId
* @param array $area
* @return array
*/
public static function routesForViews(string $areaId, array $area): array
{
@@ -534,10 +483,8 @@ class Panel
* Set the current language in multi-lang
* installations based on the session or the
* query language query parameter
*
* @return string|null
*/
public static function setLanguage(): ?string
public static function setLanguage(): string|null
{
$kirby = App::instance();
@@ -570,8 +517,6 @@ class Panel
/**
* Set the currently active Panel translation
* based on the current user or config
*
* @return string
*/
public static function setTranslation(): string
{
@@ -593,11 +538,8 @@ class Panel
/**
* Creates an absolute Panel URL
* independent of the Panel slug config
*
* @param string|null $url
* @return string
*/
public static function url(?string $url = null): string
public static function url(string|null $url = null): string
{
$slug = App::instance()->option('panel.slug', 'panel');

View File

@@ -23,15 +23,11 @@ class Plugins
{
/**
* Cache of all collected plugin files
*
* @var array
*/
public $files;
public array|null $files = null;
/**
* Collects and returns the plugin files for all plugins
*
* @return array
*/
public function files(): array
{
@@ -58,8 +54,6 @@ class Plugins
/**
* Returns the last modification
* of the collected plugin files
*
* @return int
*/
public function modified(): int
{
@@ -75,9 +69,6 @@ class Plugins
/**
* Read the files from all plugins and concatenate them
*
* @param string $type
* @return string
*/
public function read(string $type): string
{
@@ -140,9 +131,6 @@ class Plugins
/**
* Absolute url to the cache file
* This is used by the panel to link the plugins
*
* @param string $type
* @return string
*/
public function url(string $type): string
{

View File

@@ -20,8 +20,6 @@ class Redirect extends Exception
{
/**
* Returns the HTTP code for the redirect
*
* @return int
*/
public function code(): int
{
@@ -36,8 +34,6 @@ class Redirect extends Exception
/**
* Returns the URL for the redirect
*
* @return string
*/
public function location(): string
{

View File

@@ -2,6 +2,8 @@
namespace Kirby\Panel;
use Kirby\Http\Response;
/**
* The Search response class handles Fiber
* requests to render the JSON object for
@@ -16,14 +18,9 @@ namespace Kirby\Panel;
*/
class Search extends Json
{
protected static $key = '$search';
protected static string $key = '$search';
/**
* @param mixed $data
* @param array $options
* @return \Kirby\Http\Response
*/
public static function response($data, array $options = [])
public static function response($data, array $options = []): Response
{
if (is_array($data) === true) {
$data = [

View File

@@ -2,6 +2,9 @@
namespace Kirby\Panel;
use Kirby\Cms\File as CmsFile;
use Kirby\Filesystem\Asset;
/**
* Provides information about the site model for the Panel
* @since 3.6.0
@@ -14,17 +17,10 @@ namespace Kirby\Panel;
*/
class Site extends Model
{
/**
* @var \Kirby\Cms\Site
*/
protected $model;
/**
* Returns the setup for a dropdown option
* which is used in the changes dropdown
* for example.
*
* @return array
*/
public function dropdownOption(): array
{
@@ -38,11 +34,10 @@ class Site extends Model
* Returns the image file object based on provided query
*
* @internal
* @param string|null $query
* @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null
*/
protected function imageSource(string $query = null)
{
protected function imageSource(
string|null $query = null
): CmsFile|Asset|null {
if ($query === null) {
$query = 'site.image';
}
@@ -52,8 +47,6 @@ class Site extends Model
/**
* Returns the full path without leading slash
*
* @return string
*/
public function path(): string
{
@@ -65,8 +58,6 @@ class Site extends Model
* view's component props
*
* @internal
*
* @return array
*/
public function props(): array
{
@@ -86,8 +77,6 @@ class Site extends Model
* this model's Panel view
*
* @internal
*
* @return array
*/
public function view(): array
{

View File

@@ -2,7 +2,10 @@
namespace Kirby\Panel;
use Kirby\Cms\File as CmsFile;
use Kirby\Cms\Translation;
use Kirby\Cms\Url;
use Kirby\Filesystem\Asset;
use Kirby\Toolkit\I18n;
/**
@@ -17,15 +20,8 @@ use Kirby\Toolkit\I18n;
*/
class User extends Model
{
/**
* @var \Kirby\Cms\User
*/
protected $model;
/**
* Breadcrumb array
*
* @return array
*/
public function breadcrumb(): array
{
@@ -39,9 +35,6 @@ class User extends Model
/**
* Provides options for the user dropdown
*
* @param array $options
* @return array
*/
public function dropdown(array $options = []): array
{
@@ -104,8 +97,6 @@ class User extends Model
* Returns the setup for a dropdown option
* which is used in the changes dropdown
* for example.
*
* @return array
*/
public function dropdownOption(): array
{
@@ -115,10 +106,7 @@ class User extends Model
] + parent::dropdownOption();
}
/**
* @return string|null
*/
public function home(): ?string
public function home(): string|null
{
if ($home = ($this->model->blueprint()->home() ?? null)) {
$url = $this->model->toString($home);
@@ -130,8 +118,6 @@ class User extends Model
/**
* Default settings for the user's Panel image
*
* @return array
*/
protected function imageDefaults(): array
{
@@ -144,12 +130,11 @@ class User extends Model
/**
* Returns the image file object based on provided query
*
* @param string|null $query
* @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null
* @internal
*/
protected function imageSource(string $query = null)
{
protected function imageSource(
string|null $query = null
): CmsFile|Asset|null {
if ($query === null) {
return $this->model->avatar();
}
@@ -159,8 +144,6 @@ class User extends Model
/**
* Returns the full path without leading slash
*
* @return string
*/
public function path(): string
{
@@ -174,11 +157,8 @@ class User extends Model
/**
* Returns prepared data for the panel user picker
*
* @param array|null $params
* @return array
*/
public function pickerData(array $params = null): array
public function pickerData(array $params = []): array
{
$params['text'] ??= '{{ user.username }}';
@@ -193,8 +173,6 @@ class User extends Model
* previous and next user
*
* @internal
*
* @return array
*/
public function prevNext(): array
{
@@ -211,8 +189,6 @@ class User extends Model
* view's component props
*
* @internal
*
* @return array
*/
public function props(): array
{
@@ -244,10 +220,8 @@ class User extends Model
/**
* Returns the Translation object
* for the selected Panel language
*
* @return \Kirby\Cms\Translation
*/
public function translation()
public function translation(): Translation
{
$kirby = $this->model->kirby();
$lang = $this->model->language();
@@ -259,8 +233,6 @@ class User extends Model
* this model's Panel view
*
* @internal
*
* @return array
*/
public function view(): array
{

View File

@@ -2,11 +2,14 @@
namespace Kirby\Panel;
use Closure;
use Kirby\Cms\App;
use Kirby\Exception\Exception;
use Kirby\Http\Response;
use Kirby\Toolkit\A;
use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Str;
use Throwable;
/**
* The View response class handles Fiber
@@ -27,9 +30,6 @@ class View
* query parameters. Requests can return only
* certain data fields that way or globals can
* be injected on demand.
*
* @param array $data
* @return array
*/
public static function apply(array $data): array
{
@@ -55,12 +55,8 @@ class View
*
* A global request can be activated with the `X-Fiber-Globals` header or the
* `_globals` query parameter.
*
* @param array $data
* @param string|null $globals
* @return array
*/
public static function applyGlobals(array $data, ?string $globals = null): array
public static function applyGlobals(array $data, string|null $globals = null): array
{
// split globals string into an array of fields
$globalKeys = Str::split($globals, ',');
@@ -89,12 +85,8 @@ class View
*
* Such requests can fetch shared data or globals.
* Globals will be loaded on demand.
*
* @param array $data
* @param string|null $only
* @return array
*/
public static function applyOnly(array $data, ?string $only = null): array
public static function applyOnly(array $data, string|null $only = null): array
{
// split include string into an array of fields
$onlyKeys = Str::split($only, ',');
@@ -133,10 +125,6 @@ class View
* The full shared data is always sent on every JSON and
* full document request unless the `X-Fiber-Only` header or
* the `_only` query parameter is set.
*
* @param array $view
* @param array $options
* @return array
*/
public static function data(array $view = [], array $options = []): array
{
@@ -239,10 +227,6 @@ class View
/**
* Renders the error view with provided message
*
* @param string $message
* @param int $code
* @return array
*/
public static function error(string $message, int $code = 404)
{
@@ -265,8 +249,6 @@ class View
* is only requested once on the first page load.
* It can be loaded partially later if needed,
* but is otherwise not included in Fiber calls.
*
* @return array
*/
public static function globals(): array
{
@@ -323,13 +305,8 @@ class View
/**
* Creates the menu for the topbar
*
* @param array $areas
* @param array $permissions
* @param string|null $current
* @return array
*/
public static function menu(?array $areas = [], ?array $permissions = [], ?string $current = null): array
public static function menu(array|null $areas = [], array|null $permissions = [], string|null $current = null): array
{
$menu = [];
@@ -346,7 +323,7 @@ class View
$menuSetting = $area['menu'] ?? false;
// menu settings can be a callback that can return true, false or disabled
if (is_a($menuSetting, 'Closure') === true) {
if ($menuSetting instanceof Closure) {
$menuSetting = $menuSetting($areas, $permissions, $current);
}
@@ -391,23 +368,19 @@ class View
* Renders the main panel view either as
* JSON response or full HTML document based
* on the request header or query params
*
* @param mixed $data
* @param array $options
* @return \Kirby\Http\Response
*/
public static function response($data, array $options = [])
public static function response($data, array $options = []): Response
{
// handle redirects
if (is_a($data, 'Kirby\Panel\Redirect') === true) {
if ($data instanceof Redirect) {
return Response::redirect($data->location(), $data->code());
// handle Kirby exceptions
} elseif (is_a($data, 'Kirby\Exception\Exception') === true) {
} elseif ($data instanceof Exception) {
$data = static::error($data->getMessage(), $data->getHttpCode());
// handle regular exceptions
} elseif (is_a($data, 'Throwable') === true) {
} elseif ($data instanceof Throwable) {
$data = static::error($data->getMessage(), 500);
// only expect arrays from here on
@@ -437,7 +410,7 @@ class View
return Document::response($fiber);
}
public static function searches(array $areas, array $permissions)
public static function searches(array $areas, array $permissions): array
{
$searches = [];