1
0

downgrade to kirby v3

This commit is contained in:
Philip Wagner
2024-09-01 10:47:15 +02:00
parent a4b2aece7b
commit af86acb7a1
1085 changed files with 54743 additions and 65042 deletions

View File

@@ -1,145 +0,0 @@
<?php
use Kirby\Exception\InvalidArgumentException;
use Kirby\Field\FieldOptions;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Escape;
use Kirby\Toolkit\Str;
return [
'props' => [
/**
* Unset inherited props
*/
'after' => null,
'before' => null,
/**
* Whether to allow alpha transparency in the color
*/
'alpha' => function (bool $alpha = false) {
return $alpha;
},
/**
* The CSS format (hex, rgb, hsl) to display and store the value
*/
'format' => function (string $format = 'hex'): string {
if (in_array($format, ['hex', 'hsl', 'rgb']) === false) {
throw new InvalidArgumentException('Unsupported format for color field (supported: hex, rgb, hsl)');
}
return $format;
},
/**
* Change mode to disable the color picker (`input`) or to only
* show the `options` as toggles
*/
'mode' => function (string $mode = 'picker'): string {
if (in_array($mode, ['picker', 'input', 'options']) === false) {
throw new InvalidArgumentException('Unsupported mode for color field (supported: picker, input, options)');
}
return $mode;
},
/**
* List of colors that will be shown as buttons
* to directly select them
*/
'options' => function (array $options = []): array {
return $options;
}
],
'computed' => [
'default' => function (): string {
return Str::lower($this->default);
},
'options' => function (): array {
// resolve options to support manual arrays
// alongside api and query options
$props = FieldOptions::polyfill($this->props);
$options = FieldOptions::factory([
'text' => '{{ item.value }}',
'value' => '{{ item.key }}',
...$props['options']
]);
$options = $options->render($this->model());
if (empty($options) === true) {
return [];
}
$options = match (true) {
// simple array of values
// or value=text (from Options class)
is_numeric($options[0]['value']) ||
$options[0]['value'] === $options[0]['text']
=> A::map($options, fn ($option) => [
'value' => $option['text']
]),
// deprecated: name => value, flipping
// TODO: start throwing in warning in v5
$this->isColor($options[0]['text'])
=> A::map($options, fn ($option) => [
'value' => $option['text'],
// ensure that any HTML in the new text is escaped
'text' => Escape::html($option['value'])
]),
default
=> A::map($options, fn ($option) => [
'value' => $option['value'],
'text' => $option['text']
]),
};
return $options;
}
],
'methods' => [
'isColor' => function (string $value): bool {
return
$this->isHex($value) ||
$this->isRgb($value) ||
$this->isHsl($value);
},
'isHex' => function (string $value): bool {
return preg_match('/^#([\da-f]{3,4}){1,2}$/i', $value) === 1;
},
'isHsl' => function (string $value): bool {
return preg_match('/^hsla?\(\s*(\d{1,3}\.?\d*)(deg|rad|grad|turn)?(?:,|\s)+(\d{1,3})%(?:,|\s)+(\d{1,3})%(?:,|\s|\/)*(\d*(?:\.\d+)?)(%?)\s*\)?$/i', $value) === 1;
},
'isRgb' => function (string $value): bool {
return preg_match('/^rgba?\(\s*(\d{1,3})(%?)(?:,|\s)+(\d{1,3})(%?)(?:,|\s)+(\d{1,3})(%?)(?:,|\s|\/)*(\d*(?:\.\d+)?)(%?)\s*\)?$/i', $value) === 1;
},
],
'validations' => [
'color' => function ($value) {
if (empty($value) === true) {
return true;
}
if ($this->format === 'hex' && $this->isHex($value) === false) {
throw new InvalidArgumentException([
'key' => 'validation.color',
'data' => ['format' => 'hex']
]);
}
if ($this->format === 'rgb' && $this->isRgb($value) === false) {
throw new InvalidArgumentException([
'key' => 'validation.color',
'data' => ['format' => 'rgb']
]);
}
if ($this->format === 'hsl' && $this->isHsl($value) === false) {
throw new InvalidArgumentException([
'key' => 'validation.color',
'data' => ['format' => 'hsl']
]);
}
}
]
];

View File

@@ -46,13 +46,13 @@ return [
/**
* Latest date, which can be selected/saved (Y-m-d)
*/
'max' => function (string $max = null): string|null {
'max' => function (string $max = null): ?string {
return Date::optional($max);
},
/**
* Earliest date, which can be selected/saved (Y-m-d)
*/
'min' => function (string $min = null): string|null {
'min' => function (string $min = null): ?string {
return Date::optional($min);
},
@@ -129,7 +129,7 @@ return [
'key' => 'validation.date.between',
'data' => [
'min' => $min->format($format),
'max' => $max->format($format)
'max' => $min->format($format)
]
]);
} elseif ($min && $value->isMin($min) === false) {

View File

@@ -1,6 +1,5 @@
<?php
use Kirby\Cms\ModelWithContent;
use Kirby\Data\Data;
use Kirby\Toolkit\A;
@@ -35,13 +34,7 @@ return [
],
'computed' => [
'parentModel' => function () {
if (
is_string($this->parent) === true &&
$model = $this->model()->query(
$this->parent,
ModelWithContent::class
)
) {
if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) {
return $model;
}
@@ -75,13 +68,10 @@ return [
foreach (Data::decode($value, 'yaml') as $id) {
if (is_array($id) === true) {
$id = $id['uuid'] ?? $id['id'] ?? null;
$id = $id['id'] ?? null;
}
if (
$id !== null &&
($file = $this->kirby()->file($id, $this->model()))
) {
if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) {
$files[] = $this->fileResponse($file);
}
}
@@ -132,7 +122,7 @@ return [
];
},
'save' => function ($value = null) {
return A::pluck($value, $this->store);
return A::pluck($value, 'uuid');
},
'validations' => [
'max',

View File

@@ -14,6 +14,13 @@ return [
'icon' => null,
'placeholder' => null,
'required' => null,
'translate' => null
'translate' => null,
/**
* If `false`, the prepended number will be hidden
*/
'numbered' => function (bool $numbered = true) {
return $numbered;
}
]
];

View File

@@ -1,5 +1,3 @@
<?php
return [
'hidden' => true
];
return [];

View File

@@ -12,6 +12,7 @@ return [
'before' => null,
'default' => null,
'disabled' => null,
'icon' => null,
'placeholder' => null,
'required' => null,
'translate' => null,

View File

@@ -1,155 +0,0 @@
<?php
use Kirby\Exception\InvalidArgumentException;
use Kirby\Http\Url;
use Kirby\Toolkit\Str;
use Kirby\Toolkit\V;
return [
'props' => [
'after' => null,
'before' => null,
'icon' => null,
'placeholder' => null,
/**
* @values 'anchor', 'url, 'page, 'file', 'email', 'tel', 'custom'
*/
'options' => function (array|null $options = null): array {
return $options ?? [
'url',
'page',
'file',
'email',
'tel',
'anchor'
];
},
'value' => function (string|null $value = null) {
return $value ?? '';
}
],
'methods' => [
'activeTypes' => function () {
return array_filter($this->availableTypes(), function (string $type) {
return in_array($type, $this->props['options']) === true;
}, ARRAY_FILTER_USE_KEY);
},
'availableTypes' => function () {
return [
'anchor' => [
'detect' => function (string $value): bool {
return Str::startsWith($value, '#') === true;
},
'link' => function (string $value): string {
return $value;
},
'validate' => function (string $value): bool {
return Str::startsWith($value, '#') === true;
},
],
'email' => [
'detect' => function (string $value): bool {
return Str::startsWith($value, 'mailto:') === true;
},
'link' => function (string $value): string {
return str_replace('mailto:', '', $value);
},
'validate' => function (string $value): bool {
return V::email($value);
},
],
'file' => [
'detect' => function (string $value): bool {
return Str::startsWith($value, 'file://') === true;
},
'link' => function (string $value): string {
return $value;
},
'validate' => function (string $value): bool {
return V::uuid($value, 'file');
},
],
'page' => [
'detect' => function (string $value): bool {
return Str::startsWith($value, 'page://') === true;
},
'link' => function (string $value): string {
return $value;
},
'validate' => function (string $value): bool {
return V::uuid($value, 'page');
},
],
'tel' => [
'detect' => function (string $value): bool {
return Str::startsWith($value, 'tel:') === true;
},
'link' => function (string $value): string {
return str_replace('tel:', '', $value);
},
'validate' => function (string $value): bool {
return V::tel($value);
},
],
'url' => [
'detect' => function (string $value): bool {
return Str::startsWith($value, 'http://') === true || Str::startsWith($value, 'https://') === true;
},
'link' => function (string $value): string {
return $value;
},
'validate' => function (string $value): bool {
return V::url($value);
},
],
// needs to come last
'custom' => [
'detect' => function (string $value): bool {
return true;
},
'link' => function (string $value): string {
return $value;
},
'validate' => function (): bool {
return true;
},
]
];
},
],
'validations' => [
'value' => function (string|null $value) {
if (empty($value) === true) {
return true;
}
$detected = false;
foreach ($this->activeTypes() as $type => $options) {
if ($options['detect']($value) !== true) {
continue;
}
$link = $options['link']($value);
$detected = true;
if ($options['validate']($link) === false) {
throw new InvalidArgumentException([
'key' => 'validation.' . $type
]);
}
}
// none of the configured types has been detected
if ($detected === false) {
throw new InvalidArgumentException([
'key' => 'validation.linkType'
]);
}
return true;
},
]
];

View File

@@ -7,12 +7,6 @@ return [
*/
'marks' => function ($marks = true) {
return $marks;
},
/**
* Sets the allowed nodes. Available nodes: `bulletList`, `orderedList`
*/
'nodes' => function ($nodes = null) {
return $nodes;
}
],
'computed' => [

View File

@@ -12,7 +12,7 @@ return [
},
/**
* Layout size for cards: `tiny`, `small`, `medium`, `large`, `huge`, `full`
* Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge`
*/
'size' => function (string $size = 'auto') {
return $size;

View File

@@ -1,6 +1,6 @@
<?php
use Kirby\Field\FieldOptions;
use Kirby\Form\Options;
return [
'props' => [
@@ -30,18 +30,19 @@ return [
],
'methods' => [
'getOptions' => function () {
$props = FieldOptions::polyfill($this->props);
$options = FieldOptions::factory($props['options']);
return $options->render($this->model());
return Options::factory(
$this->options(),
$this->props,
$this->model()
);
},
'sanitizeOption' => function ($value) {
$options = array_column($this->options(), 'value');
return in_array($value, $options) === true ? $value : null;
'sanitizeOption' => function ($option) {
$allowed = array_column($this->options(), 'value');
return in_array($option, $allowed, true) === true ? $option : null;
},
'sanitizeOptions' => function ($values) {
$options = array_column($this->options(), 'value');
$options = array_intersect($values, $options);
return array_values($options);
'sanitizeOptions' => function ($options) {
$allowed = array_column($this->options(), 'value');
return array_intersect($options, $allowed);
},
]
];

View File

@@ -1,7 +1,6 @@
<?php
use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Str;
return [
'props' => [
@@ -68,21 +67,12 @@ return [
return $search;
},
/**
* Whether to store UUID or ID in the
* content file of the model
*
* @param string $store 'uuid'|'id'
*/
'store' => function (string $store = 'uuid') {
return Str::lower($store);
},
/**
* Main text for each item
*/
'text' => function (string $text = null) {
return $text;
},
],
];

View File

@@ -3,7 +3,6 @@
use Kirby\Cms\Api;
use Kirby\Cms\File;
use Kirby\Exception\Exception;
use Kirby\Exception\InvalidArgumentException;
return [
'props' => [
@@ -23,23 +22,18 @@ return [
$uploads = [];
}
$uploads['accept'] = '*';
if ($template = $uploads['template'] ?? null) {
// get parent object for upload target
$parent = $this->uploadParent($uploads['parent'] ?? null);
if ($parent === null) {
throw new InvalidArgumentException('"' . $uploads['parent'] . '" could not be resolved as a valid parent for the upload');
}
$template = $uploads['template'] ?? null;
if ($template) {
$file = new File([
'filename' => 'tmp',
'parent' => $parent,
'parent' => $this->model(),
'template' => $template
]);
$uploads['accept'] = $file->blueprint()->acceptAttribute();
$uploads['accept'] = $file->blueprint()->acceptMime();
} else {
$uploads['accept'] = '*';
}
return $uploads;
@@ -51,37 +45,29 @@ return [
throw new Exception('Uploads are disabled for this field');
}
$parent = $this->uploadParent($params['parent'] ?? null);
if ($parentQuery = ($params['parent'] ?? null)) {
$parent = $this->model()->query($parentQuery);
} else {
$parent = $this->model();
}
if (is_a($parent, 'Kirby\Cms\File') === true) {
$parent = $parent->parent();
}
return $api->upload(function ($source, $filename) use ($parent, $params, $map) {
$props = [
$file = $parent->createFile([
'source' => $source,
'template' => $params['template'] ?? null,
'filename' => $filename,
];
]);
// move the source file from the temp dir
$file = $parent->createFile($props, true);
if ($file instanceof File === false) {
if (is_a($file, 'Kirby\Cms\File') === false) {
throw new Exception('The file could not be uploaded');
}
return $map($file, $parent);
});
},
'uploadParent' => function (string $parentQuery = null) {
$parent = $this->model();
if ($parentQuery) {
$parent = $parent->query($parentQuery);
}
if ($parent instanceof File) {
$parent = $parent->parent();
}
return $parent;
}
]
];

View File

@@ -1,35 +1,32 @@
<?php
use Kirby\Toolkit\Str;
use Kirby\Toolkit\V;
return [
'extends' => 'tags',
'props' => [
/**
* If set to `all`, any type of input is accepted. If set to `options` only the predefined options are accepted as input.
* Unset inherited props
*/
'accept' => function ($value = 'options') {
return V::in($value, ['all', 'options']) ? $value : 'all';
},
'accept' => null,
/**
* Custom icon to replace the arrow down.
*/
'icon' => function (string $icon = 'checklist') {
'icon' => function (string $icon = null) {
return $icon;
},
],
'methods' => [
'toValues' => function ($value) {
if (is_null($value) === true) {
return [];
}
if (is_array($value) === false) {
$value = Str::split($value, $this->separator());
}
return $this->sanitizeOptions($value);
}
],
/**
* Enable/disable the search in the dropdown
* Also limit displayed items (display: 20)
* and set minimum number of characters to search (min: 3)
*/
'search' => function ($search = true) {
return $search;
},
/**
* If `true`, selected entries will be sorted
* according to their position in the dropdown
*/
'sort' => function (bool $sort = false) {
return $sort;
},
]
];

View File

@@ -8,7 +8,7 @@ return [
* Default number that will be saved when a new page/user/file is created
*/
'default' => function ($default = null) {
return $this->toNumber($default) ?? '';
return $this->toNumber($default);
},
/**
* The lowest allowed number
@@ -26,10 +26,10 @@ return [
* Allowed incremental steps between numbers (i.e `0.5`)
*/
'step' => function ($step = null) {
return $this->toNumber($step) ?? '';
return $this->toNumber($step);
},
'value' => function ($value = null) {
return $this->toNumber($value) ?? '';
return $this->toNumber($value);
}
],
'methods' => [

View File

@@ -1,104 +0,0 @@
<?php
use Kirby\Data\Data;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Form\Form;
use Kirby\Toolkit\I18n;
return [
'props' => [
/**
* Unset inherited props
*/
'after' => null,
'before' => null,
'autofocus' => null,
'icon' => null,
'placeholder' => null,
/**
* Set the default values for the object
*/
'default' => function ($default = null) {
return $default;
},
/**
* The placeholder text if no information has been added yet
*/
'empty' => function ($empty = null) {
return I18n::translate($empty, $empty);
},
/**
* Fields setup for the object form. Works just like fields in regular forms.
*/
'fields' => function (array $fields = []) {
return $fields;
}
],
'computed' => [
'default' => function () {
if (empty($this->default) === true) {
return '';
}
return $this->form($this->default)->values();
},
'fields' => function () {
if (empty($this->fields) === true) {
return [];
}
return $this->form()->fields()->toArray();
},
'value' => function () {
$data = Data::decode($this->value, 'yaml');
if (empty($data) === true) {
return '';
}
return $this->form($data)->values();
}
],
'methods' => [
'form' => function (array $values = []) {
return new Form([
'fields' => $this->attrs['fields'],
'values' => $values,
'model' => $this->model
]);
},
],
'save' => function ($value) {
if (empty($value) === true) {
return '';
}
return $this->form($value)->content();
},
'validations' => [
'object' => function ($value) {
if (empty($value) === true) {
return true;
}
$errors = $this->form($value)->errors();
if (empty($errors) === false) {
// use the first error for details
$name = array_key_first($errors);
$error = $errors[$name];
throw new InvalidArgumentException([
'key' => 'object.validation',
'data' => [
'label' => $error['label'] ?? $name,
'message' => implode("\n", $error['message'])
]
]);
}
}
]
];

View File

@@ -67,7 +67,7 @@ return [
foreach (Data::decode($value, 'yaml') as $id) {
if (is_array($id) === true) {
$id = $id['uuid'] ?? $id['id'] ?? null;
$id = $id['id'] ?? null;
}
if ($id !== null && ($page = $kirby->page($id))) {
@@ -102,7 +102,7 @@ return [
];
},
'save' => function ($value = null) {
return A::pluck($value, $this->store);
return A::pluck($value, 'id');
},
'validations' => [
'max',

View File

@@ -1,7 +1,5 @@
<?php
use Kirby\Toolkit\I18n;
return [
'extends' => 'number',
'props' => [
@@ -20,13 +18,6 @@ return [
* Enables/disables the tooltip and set the before and after values
*/
'tooltip' => function ($tooltip = true) {
if (is_array($tooltip) === true) {
$after = $tooltip['after'] ?? null;
$before = $tooltip['before'] ?? null;
$tooltip['after'] = I18n::translate($after, $after);
$tooltip['before'] = I18n::translate($before, $before);
}
return $tooltip;
},
]

View File

@@ -1,7 +1,5 @@
<?php
use Kirby\Field\FieldOptions;
return [
'extends' => 'radio',
'props' => [
@@ -22,16 +20,5 @@ return [
'placeholder' => function (string $placeholder = '—') {
return $placeholder;
},
],
'methods' => [
'getOptions' => function () {
$props = FieldOptions::polyfill($this->props);
// disable safe mode as the select field does not
// render HTML for the option text
$options = FieldOptions::factory($props['options'], false);
return $options->render($this->model());
}
]
];

View File

@@ -1,11 +1,8 @@
<?php
use Kirby\Data\Data;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Form\Form;
use Kirby\Toolkit\A;
use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Str;
return [
'mixins' => ['min'],
@@ -52,7 +49,7 @@ return [
/**
* Fields setup for the structure form. Works just like fields in regular forms.
*/
'fields' => function (array $fields = []) {
'fields' => function (array $fields) {
return $fields;
},
/**
@@ -102,54 +99,54 @@ return [
},
'fields' => function () {
if (empty($this->fields) === true) {
return [];
throw new Exception('Please provide some fields for the structure');
}
return $this->form()->fields()->toArray();
},
'columns' => function () {
$columns = [];
$blueprint = $this->columns;
$columns = [];
$mobile = 0;
// if no custom columns have been defined,
// gather all fields as columns
if (empty($blueprint) === true) {
// skip hidden fields
$fields = array_filter(
$this->fields,
fn ($field) =>
$field['type'] !== 'hidden' && $field['hidden'] !== true
);
$fields = array_column($fields, 'name');
$blueprint = array_fill_keys($fields, true);
}
if (empty($this->columns)) {
foreach ($this->fields as $field) {
// Skip hidden and unsaveable fields
// They should never be included as column
if ($field['type'] === 'hidden' || $field['saveable'] === false) {
continue;
}
foreach ($blueprint as $name => $column) {
$field = $this->fields[$name] ?? null;
// Skip empty and unsaveable fields
// They should never be included as column
if (
empty($field) === true ||
$field['saveable'] === false
) {
continue;
$columns[$field['name']] = [
'type' => $field['type'],
'label' => $field['label'] ?? $field['name']
];
}
} else {
foreach ($this->columns as $columnName => $columnProps) {
if (is_array($columnProps) === false) {
$columnProps = [];
}
if (is_array($column) === false) {
$column = [];
$field = $this->fields[$columnName] ?? null;
if (empty($field) === true || $field['saveable'] === false) {
continue;
}
if (($columnProps['mobile'] ?? false) === true) {
$mobile++;
}
$columns[$columnName] = array_merge($columnProps, [
'type' => $field['type'],
'label' => $field['label'] ?? $field['name']
]);
}
$column['type'] ??= $field['type'];
$column['label'] ??= $field['label'] ?? $name;
$column['label'] = I18n::translate($column['label'], $column['label']);
$columns[$name] = $column;
}
// make the first column visible on mobile
// if no other mobile columns are defined
if (in_array(true, array_column($columns, 'mobile')) === false) {
if ($mobile === 0) {
$columns[array_key_first($columns)]['mobile'] = true;
}
@@ -173,53 +170,34 @@ return [
},
'form' => function (array $values = []) {
return new Form([
'fields' => $this->attrs['fields'] ?? [],
'fields' => $this->attrs['fields'],
'values' => $values,
'model' => $this->model
]);
},
],
'api' => function () {
return [
[
'pattern' => 'validate',
'method' => 'ALL',
'action' => function () {
return array_values($this->field()->form($this->requestBody())->errors());
}
]
];
},
'save' => function ($value) {
$data = [];
foreach ($value as $row) {
$row = $this->form($row)->content();
// remove frontend helper id
unset($row['_id']);
$data[] = $row;
$data[] = $this->form($row)->content();
}
return $data;
},
'validations' => [
'min',
'max',
'structure' => function ($value) {
if (empty($value) === true) {
return true;
}
$values = A::wrap($value);
foreach ($values as $index => $value) {
$form = $this->form($value);
foreach ($form->fields() as $field) {
$errors = $field->errors();
if (empty($errors) === false) {
throw new InvalidArgumentException([
'key' => 'structure.validation',
'data' => [
'field' => $field->label() ?? Str::ucfirst($field->name()),
'index' => $index + 1
]
]);
}
}
}
}
'max'
]
];

View File

@@ -31,7 +31,7 @@ return [
* Set to `list` to display each tag with 100% width,
* otherwise the tags are displayed inline
*/
'layout' => function (string|null $layout = null) {
'layout' => function (?string $layout = null) {
return $layout;
},
/**
@@ -46,56 +46,52 @@ return [
'max' => function (int $max = null) {
return $max;
},
/**
* Enable/disable the search in the dropdown
* Also limit displayed items (display: 20)
* and set minimum number of characters to search (min: 3)
*/
'search' => function (bool|array $search = true) {
return $search;
},
/**
* Custom tags separator, which will be used to store tags in the content file
*/
'separator' => function (string $separator = ',') {
return $separator;
},
/**
* If `true`, selected entries will be sorted
* according to their position in the dropdown
*/
'sort' => function (bool $sort = false) {
return $sort;
},
],
'computed' => [
'default' => function (): array {
return $this->toValues($this->default);
return $this->toTags($this->default);
},
'value' => function (): array {
return $this->toValues($this->value);
return $this->toTags($this->value);
}
],
'methods' => [
'toValues' => function ($value) {
'toTags' => function ($value) {
if (is_null($value) === true) {
return [];
}
if (is_array($value) === false) {
$value = Str::split($value, $this->separator());
}
$options = $this->options();
if ($this->accept === 'options') {
$value = $this->sanitizeOptions($value);
}
// transform into value-text objects
return array_map(function ($option) use ($options) {
// already a valid object
if (is_array($option) === true && isset($option['value'], $option['text']) === true) {
return $option;
}
return $value;
$index = array_search($option, array_column($options, 'value'));
if ($index !== false) {
return $options[$index];
}
return [
'value' => $option,
'text' => $option,
];
}, Str::split($value, $this->separator()));
}
],
'save' => function (array $value = null): string {
return A::join(
$value,
A::pluck($value, 'value'),
$this->separator() . ' '
);
},

View File

@@ -10,7 +10,7 @@ return [
* The field value will be converted with the selected converter before the value gets saved. Available converters: `lower`, `upper`, `ucfirst`, `slug`
*/
'converter' => function ($value = null) {
if ($value !== null && array_key_exists($value, $this->converters()) === false) {
if ($value !== null && in_array($value, array_keys($this->converters())) === false) {
throw new InvalidArgumentException([
'key' => 'field.converter.invalid',
'data' => ['converter' => $value]
@@ -27,13 +27,6 @@ return [
return $counter;
},
/**
* Sets the font family (sans or monospace)
*/
'font' => function (string $font = null) {
return $font === 'monospace' ? 'monospace' : 'sans-serif';
},
/**
* Maximum number of allowed characters
*/

View File

@@ -15,7 +15,7 @@ return [
/**
* Sets the default time when a new page/file/user is created
*/
'default' => function ($default = null): string|null {
'default' => function ($default = null): ?string {
return $default;
},
@@ -36,13 +36,13 @@ return [
/**
* Latest time, which can be selected/saved (H:i or H:i:s)
*/
'max' => function (string $max = null): string|null {
'max' => function (string $max = null): ?string {
return Date::optional($max);
},
/**
* Earliest time, which can be selected/saved (H:i or H:i:s)
*/
'min' => function (string $min = null): string|null {
'min' => function (string $min = null): ?string {
return Date::optional($min);
},
@@ -62,7 +62,7 @@ return [
'unit' => 'minute',
]);
},
'value' => function ($value = null): string|null {
'value' => function ($value = null): ?string {
return $value;
}
],
@@ -80,7 +80,7 @@ return [
'format' => function () {
return $this->props['format'] ?? 'H:i:s';
},
'value' => function (): string|null {
'value' => function (): ?string {
return $this->toDatetime($this->value, 'H:i:s') ?? '';
}
],

View File

@@ -49,9 +49,9 @@ return [
'value' => function () {
if ($this->props['value'] === null) {
return $this->default();
} else {
return $this->toBool($this->props['value']);
}
return $this->toBool($this->props['value']);
}
],
'methods' => [

View File

@@ -24,8 +24,18 @@ return [
/**
* Default selected user(s) when a new page/file/user is created
*/
'default' => function (string|array|bool|null $default = null) {
return $default;
'default' => function ($default = null) {
if ($default === false) {
return [];
}
if ($default === null && $user = $this->kirby()->user()) {
return [
$this->userResponse($user)
];
}
return $this->toUsers($default);
},
'value' => function ($value = null) {
@@ -33,22 +43,10 @@ return [
},
],
'computed' => [
'default' => function (): array {
if ($this->default === false) {
return [];
}
if (
$this->default === true &&
$user = $this->kirby()->user()
) {
return [
$this->userResponse($user)
];
}
return $this->toUsers($this->default);
}
/**
* Unset inherited computed
*/
'default' => null
],
'methods' => [
'userResponse' => function ($user) {
@@ -59,7 +57,7 @@ return [
'text' => $this->text,
]);
},
'toUsers' => function ($value = null): array {
'toUsers' => function ($value = null) {
$users = [];
$kirby = App::instance();
@@ -98,7 +96,7 @@ return [
];
},
'save' => function ($value = null) {
return A::pluck($value, $this->store);
return A::pluck($value, 'id');
},
'validations' => [
'max',

View File

@@ -1,23 +1,9 @@
<?php
use Kirby\Exception\InvalidArgumentException;
use Kirby\Sane\Sane;
use Kirby\Toolkit\V;
return [
'props' => [
/**
* Enables/disables the character counter in the top right corner
*/
'counter' => function (bool $counter = true) {
return $counter;
},
/**
* Available heading levels
*/
'headings' => function (array|null $headings = null) {
return array_intersect($headings ?? range(1, 6), range(1, 6));
},
/**
* Enables inline mode, which will not wrap new lines in paragraphs and creates hard breaks instead.
*
@@ -27,37 +13,18 @@ return [
return $inline;
},
/**
* Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`, `email`. Activate/deactivate them all by passing `true`/`false`. Default marks are `bold`, `italic`, `underline`, `strike`, `link`, `email`
* Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`, `email`. Activate them all by passing `true`. Deactivate them all by passing `false`
* @param array|bool $marks
*/
'marks' => function ($marks = null) {
'marks' => function ($marks = true) {
return $marks;
},
/**
* Maximum number of allowed characters
*/
'maxlength' => function (int $maxlength = null) {
return $maxlength;
},
/**
* Minimum number of required characters
*/
'minlength' => function (int $minlength = null) {
return $minlength;
},
/**
* Sets the allowed nodes. Available nodes: `paragraph`, `heading`, `bulletList`, `orderedList`, `quote`. Activate/deactivate them all by passing `true`/`false`. Default nodes are `paragraph`, `heading`, `bulletList`, `orderedList`.
* Sets the allowed nodes. Available nodes: `paragraph`, `heading`, `bulletList`, `orderedList`. Activate/deactivate them all by passing `true`/`false`. Default nodes are `paragraph`, `heading`, `bulletList`, `orderedList`.
* @param array|bool|null $nodes
*/
'nodes' => function ($nodes = null) {
return $nodes;
},
/**
* Toolbar options, incl. `marks` (to narrow down which marks should have toolbar buttons), `nodes` (to narrow down which nodes should have toolbar dropdown entries) and `inline` to set the position of the toolbar (false = sticking on top of the field)
*/
'toolbar' => function ($toolbar = null) {
return $toolbar;
}
],
'computed' => [
@@ -66,28 +33,4 @@ return [
return Sane::sanitize($value, 'html');
}
],
'validations' => [
'minlength' => function ($value) {
if (
$this->minlength &&
V::minLength(strip_tags($value), $this->minlength) === false
) {
throw new InvalidArgumentException([
'key' => 'validation.minlength',
'data' => ['min' => $this->minlength]
]);
}
},
'maxlength' => function ($value) {
if (
$this->maxlength &&
V::maxLength(strip_tags($value), $this->maxlength) === false
) {
throw new InvalidArgumentException([
'key' => 'validation.maxlength',
'data' => ['max' => $this->maxlength]
]);
}
},
]
];