Add landing page
This commit is contained in:
parent
9439de0603
commit
aaf1aa7890
603 changed files with 637 additions and 1 deletions
61
private/kirby/config/fields/checkboxes.php
Normal file
61
private/kirby/config/fields/checkboxes.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'options'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Arranges the checkboxes in the given number of columns
|
||||
*/
|
||||
'columns' => function (int $columns = 1) {
|
||||
return $columns;
|
||||
},
|
||||
/**
|
||||
* Default value for the field, which will be used when a page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return Str::split($default, ',');
|
||||
},
|
||||
/**
|
||||
* Maximum number of checked boxes
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Minimum number of checked boxes
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return Str::split($value, ',');
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->sanitizeOptions($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->sanitizeOptions($this->value);
|
||||
},
|
||||
],
|
||||
'save' => function ($value): string {
|
||||
return A::join($value, ', ');
|
||||
},
|
||||
'validations' => [
|
||||
'options',
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
||||
129
private/kirby/config/fields/date.php
Normal file
129
private/kirby/config/fields/date.php
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\Exception;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Default date when a new page/file/user gets created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a custom format that is used when the field is saved
|
||||
*/
|
||||
'format' => function (string $format = null) {
|
||||
return $format;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the calendar icon to something custom
|
||||
*/
|
||||
'icon' => function (string $icon = 'calendar') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Youngest date, which can be selected/saved
|
||||
*/
|
||||
'max' => function (string $max = null) {
|
||||
return $this->toDate($max);
|
||||
},
|
||||
/**
|
||||
* Oldest date, which can be selected/saved
|
||||
*/
|
||||
'min' => function (string $min = null) {
|
||||
return $this->toDate($min);
|
||||
},
|
||||
/**
|
||||
* The placeholder is not available
|
||||
*/
|
||||
'placeholder' => null,
|
||||
/**
|
||||
* Pass `true` or an array of time field options to show the time selector.
|
||||
*/
|
||||
'time' => function ($time = false) {
|
||||
return $time;
|
||||
},
|
||||
/**
|
||||
* Must be a parseable date string
|
||||
*/
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toDate($this->default);
|
||||
},
|
||||
'format' => function () {
|
||||
return $this->props['format'] ?? ($this->time() === false ? 'Y-m-d' : 'Y-m-d H:i');
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toDate($this->value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'toDate' => function ($value) {
|
||||
if ($timestamp = timestamp($value, $this->time['step'] ?? 5)) {
|
||||
return date('Y-m-d H:i:s', $timestamp);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
],
|
||||
'save' => function ($value) {
|
||||
if ($value !== null && $date = strtotime($value)) {
|
||||
return date($this->format(), $date);
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
'validations' => [
|
||||
'date',
|
||||
'minMax' => function ($value) {
|
||||
$min = $this->min ? strtotime($this->min) : null;
|
||||
$max = $this->max ? strtotime($this->max) : null;
|
||||
$value = strtotime($this->value());
|
||||
$format = 'd.m.Y';
|
||||
$errors = [];
|
||||
|
||||
if ($value && $min && $value < $min) {
|
||||
$errors['min'] = $min;
|
||||
}
|
||||
|
||||
if ($value && $max && $value > $max) {
|
||||
$errors['max'] = $max;
|
||||
}
|
||||
|
||||
if (empty($errors) === false) {
|
||||
if ($min && $max) {
|
||||
throw new Exception([
|
||||
'key' => 'validation.date.between',
|
||||
'data' => [
|
||||
'min' => date($format, $min),
|
||||
'max' => date($format, $max)
|
||||
]
|
||||
]);
|
||||
} elseif ($min) {
|
||||
throw new Exception([
|
||||
'key' => 'validation.date.after',
|
||||
'data' => [
|
||||
'date' => date($format, $min),
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
throw new Exception([
|
||||
'key' => 'validation.date.before',
|
||||
'data' => [
|
||||
'date' => date($format, $max),
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
]
|
||||
];
|
||||
40
private/kirby/config/fields/email.php
Normal file
40
private/kirby/config/fields/email.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete mode for the input
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'email') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the email icon to something custom
|
||||
*/
|
||||
'icon' => function (string $icon = 'email') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom placeholder text, when the field is empty.
|
||||
*/
|
||||
'placeholder' => function ($value = null) {
|
||||
return I18n::translate($value, $value) ?? I18n::translate('email.placeholder');
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'email'
|
||||
]
|
||||
];
|
||||
138
private/kirby/config/fields/files.php
Normal file
138
private/kirby/config/fields/files.php
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'mixins' => [
|
||||
'picker',
|
||||
'filepicker',
|
||||
'min',
|
||||
'upload'
|
||||
],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'autofocus' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Sets the file(s), which are selected by default when a new page is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the layout of the selected files. Available layouts: `list`, `cards`
|
||||
*/
|
||||
'layout' => function (string $layout = 'list') {
|
||||
return $layout;
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge`
|
||||
*/
|
||||
'size' => function (string $size = 'auto') {
|
||||
return $size;
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'parentModel' => function () {
|
||||
if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
return $this->model();
|
||||
},
|
||||
'parent' => function () {
|
||||
return $this->parentModel->apiUrl(true);
|
||||
},
|
||||
'query' => function () {
|
||||
return $this->query ?? $this->parentModel::CLASS_ALIAS . '.files';
|
||||
},
|
||||
'default' => function () {
|
||||
return $this->toFiles($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toFiles($this->value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'fileResponse' => function ($file) {
|
||||
return $file->panelPickerData([
|
||||
'image' => $this->image,
|
||||
'info' => $this->info ?? false,
|
||||
'model' => $this->model(),
|
||||
'text' => $this->text,
|
||||
]);
|
||||
},
|
||||
'toFiles' => function ($value = null) {
|
||||
$files = [];
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) {
|
||||
$files[] = $this->fileResponse($file);
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
|
||||
return $field->filepicker([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'limit' => $field->limit(),
|
||||
'page' => $this->requestQuery('page'),
|
||||
'query' => $field->query(),
|
||||
'search' => $this->requestQuery('search'),
|
||||
'text' => $field->text()
|
||||
]);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'upload',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$uploads = $field->uploads();
|
||||
|
||||
return $field->upload($this, $uploads, function ($file, $parent) use ($field) {
|
||||
return $file->panelPickerData([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'model' => $field->model(),
|
||||
'text' => $field->text(),
|
||||
]);
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'uuid');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
||||
27
private/kirby/config/fields/headline.php
Normal file
27
private/kirby/config/fields/headline.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => false,
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'default' => null,
|
||||
'disabled' => null,
|
||||
'help' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
'required' => null,
|
||||
'translate' => null,
|
||||
|
||||
/**
|
||||
* If `false`, the prepended number will be hidden
|
||||
*/
|
||||
'numbered' => function (bool $numbered = true) {
|
||||
return $numbered;
|
||||
}
|
||||
]
|
||||
];
|
||||
3
private/kirby/config/fields/hidden.php
Normal file
3
private/kirby/config/fields/hidden.php
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
return [];
|
||||
24
private/kirby/config/fields/info.php
Normal file
24
private/kirby/config/fields/info.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Text to be displayed
|
||||
*/
|
||||
'text' => function ($value = null) {
|
||||
return I18n::translate($value, $value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'text' => function () {
|
||||
if ($text = $this->text) {
|
||||
$text = $this->model()->toString($text);
|
||||
$text = $this->kirby()->kirbytext($text);
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
],
|
||||
'save' => false,
|
||||
];
|
||||
5
private/kirby/config/fields/line.php
Normal file
5
private/kirby/config/fields/line.php
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => false
|
||||
];
|
||||
14
private/kirby/config/fields/mixins/filepicker.php
Normal file
14
private/kirby/config/fields/mixins/filepicker.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\FilePicker;
|
||||
|
||||
return [
|
||||
'methods' => [
|
||||
'filepicker' => function (array $params = []) {
|
||||
// fetch the parent model
|
||||
$params['model'] = $this->model();
|
||||
|
||||
return (new FilePicker($params))->toArray();
|
||||
}
|
||||
]
|
||||
];
|
||||
22
private/kirby/config/fields/mixins/min.php
Normal file
22
private/kirby/config/fields/mixins/min.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'computed' => [
|
||||
'min' => function () {
|
||||
// set min to at least 1, if required
|
||||
if ($this->required === true) {
|
||||
return $this->min ?? 1;
|
||||
}
|
||||
|
||||
return $this->min;
|
||||
},
|
||||
'required' => function () {
|
||||
// set required to true if min is set
|
||||
if ($this->min) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->required;
|
||||
}
|
||||
]
|
||||
];
|
||||
48
private/kirby/config/fields/mixins/options.php
Normal file
48
private/kirby/config/fields/mixins/options.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Form\Options;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* API settings for options requests. This will only take affect when `options` is set to `api`.
|
||||
*/
|
||||
'api' => function ($api = null) {
|
||||
return $api;
|
||||
},
|
||||
/**
|
||||
* An array with options
|
||||
*/
|
||||
'options' => function ($options = []) {
|
||||
return $options;
|
||||
},
|
||||
/**
|
||||
* Query settings for options queries. This will only take affect when `options` is set to `query`.
|
||||
*/
|
||||
'query' => function ($query = null) {
|
||||
return $query;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'options' => function (): array {
|
||||
return $this->getOptions();
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'getOptions' => function () {
|
||||
return Options::factory(
|
||||
$this->options(),
|
||||
$this->props,
|
||||
$this->model()
|
||||
);
|
||||
},
|
||||
'sanitizeOption' => function ($option) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return in_array($option, $allowed, true) === true ? $option : null;
|
||||
},
|
||||
'sanitizeOptions' => function ($options) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return array_intersect($options, $allowed);
|
||||
},
|
||||
]
|
||||
];
|
||||
14
private/kirby/config/fields/mixins/pagepicker.php
Normal file
14
private/kirby/config/fields/mixins/pagepicker.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\PagePicker;
|
||||
|
||||
return [
|
||||
'methods' => [
|
||||
'pagepicker' => function (array $params = []) {
|
||||
// inject the current model
|
||||
$params['model'] = $this->model();
|
||||
|
||||
return (new PagePicker($params))->toArray();
|
||||
}
|
||||
]
|
||||
];
|
||||
78
private/kirby/config/fields/mixins/picker.php
Normal file
78
private/kirby/config/fields/mixins/picker.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* The placeholder text if none have been selected yet
|
||||
*/
|
||||
'empty' => function ($empty = null) {
|
||||
return I18n::translate($empty, $empty);
|
||||
},
|
||||
|
||||
/**
|
||||
* Image settings for each item
|
||||
*/
|
||||
'image' => function ($image = null) {
|
||||
return $image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Info text for each item
|
||||
*/
|
||||
'info' => function (string $info = null) {
|
||||
return $info;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether each item should be clickable
|
||||
*/
|
||||
'link' => function (bool $link = true) {
|
||||
return $link;
|
||||
},
|
||||
|
||||
/**
|
||||
* The minimum number of required selected
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
|
||||
/**
|
||||
* The maximum number of allowed selected
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
|
||||
/**
|
||||
* If `false`, only a single one can be selected
|
||||
*/
|
||||
'multiple' => function (bool $multiple = true) {
|
||||
return $multiple;
|
||||
},
|
||||
|
||||
/**
|
||||
* Query for the items to be included in the picker
|
||||
*/
|
||||
'query' => function (string $query = null) {
|
||||
return $query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable/disable the search field in the picker
|
||||
*/
|
||||
'search' => function (bool $search = true) {
|
||||
return $search;
|
||||
},
|
||||
|
||||
/**
|
||||
* Main text for each item
|
||||
*/
|
||||
'text' => function (string $text = null) {
|
||||
return $text;
|
||||
},
|
||||
|
||||
],
|
||||
];
|
||||
72
private/kirby/config/fields/mixins/upload.php
Normal file
72
private/kirby/config/fields/mixins/upload.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Api;
|
||||
use Kirby\Cms\File;
|
||||
use Kirby\Exception\Exception;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Sets the upload options for linked files (since 3.2.0)
|
||||
*/
|
||||
'uploads' => function ($uploads = []) {
|
||||
if ($uploads === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_string($uploads) === true) {
|
||||
$uploads = ['template' => $uploads];
|
||||
}
|
||||
|
||||
if (is_array($uploads) === false) {
|
||||
$uploads = [];
|
||||
}
|
||||
|
||||
$template = $uploads['template'] ?? null;
|
||||
|
||||
if ($template) {
|
||||
$file = new File([
|
||||
'filename' => 'tmp',
|
||||
'template' => $template
|
||||
]);
|
||||
|
||||
$uploads['accept'] = $file->blueprint()->accept()['mime'] ?? '*';
|
||||
} else {
|
||||
$uploads['accept'] = '*';
|
||||
}
|
||||
|
||||
return $uploads;
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'upload' => function (Api $api, $params, Closure $map) {
|
||||
if ($params === false) {
|
||||
throw new Exception('Uploads are disabled for this field');
|
||||
}
|
||||
|
||||
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) {
|
||||
$file = $parent->createFile([
|
||||
'source' => $source,
|
||||
'template' => $params['template'] ?? null,
|
||||
'filename' => $filename,
|
||||
]);
|
||||
|
||||
if (is_a($file, 'Kirby\Cms\File') === false) {
|
||||
throw new Exception('The file could not be uploaded');
|
||||
}
|
||||
|
||||
return $map($file, $parent);
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
13
private/kirby/config/fields/mixins/userpicker.php
Normal file
13
private/kirby/config/fields/mixins/userpicker.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\UserPicker;
|
||||
|
||||
return [
|
||||
'methods' => [
|
||||
'userpicker' => function (array $params = []) {
|
||||
$params['model'] = $this->model();
|
||||
|
||||
return (new UserPicker($params))->toArray();
|
||||
}
|
||||
]
|
||||
];
|
||||
32
private/kirby/config/fields/multiselect.php
Normal file
32
private/kirby/config/fields/multiselect.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'tags',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'accept' => null,
|
||||
/**
|
||||
* Custom icon to replace the arrow down.
|
||||
*/
|
||||
'icon' => function (string $icon = null) {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* 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;
|
||||
},
|
||||
]
|
||||
];
|
||||
48
private/kirby/config/fields/number.php
Normal file
48
private/kirby/config/fields/number.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Default number that will be saved when a new page/user/file is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->toNumber($default);
|
||||
},
|
||||
/**
|
||||
* The lowest allowed number
|
||||
*/
|
||||
'min' => function (float $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* The highest allowed number
|
||||
*/
|
||||
'max' => function (float $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Allowed incremental steps between numbers (i.e `0.5`)
|
||||
*/
|
||||
'step' => function ($step = null) {
|
||||
return $this->toNumber($step);
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $this->toNumber($value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toNumber' => function ($value) {
|
||||
if ($this->isEmpty($value) === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return is_float($value) === true ? $value : (float)Str::float($value);
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
||||
117
private/kirby/config/fields/pages.php
Normal file
117
private/kirby/config/fields/pages.php
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'pagepicker', 'picker'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default selected page(s) when a new page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->toPages($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the layout of the selected files. Available layouts: `list`, `cards`
|
||||
*/
|
||||
'layout' => function (string $layout = 'list') {
|
||||
return $layout;
|
||||
},
|
||||
|
||||
/**
|
||||
* Optional query to select a specific set of pages
|
||||
*/
|
||||
'query' => function (string $query = null) {
|
||||
return $query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge`
|
||||
*/
|
||||
'size' => function (string $size = 'auto') {
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Optionally include subpages of pages
|
||||
*/
|
||||
'subpages' => function (bool $subpages = true) {
|
||||
return $subpages;
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $this->toPages($value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
/**
|
||||
* Unset inherited computed
|
||||
*/
|
||||
'default' => null
|
||||
],
|
||||
'methods' => [
|
||||
'pageResponse' => function ($page) {
|
||||
return $page->panelPickerData([
|
||||
'image' => $this->image,
|
||||
'info' => $this->info,
|
||||
'text' => $this->text,
|
||||
]);
|
||||
},
|
||||
'toPages' => function ($value = null) {
|
||||
$pages = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if ($id !== null && ($page = $kirby->page($id))) {
|
||||
$pages[] = $this->pageResponse($page);
|
||||
}
|
||||
}
|
||||
|
||||
return $pages;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
|
||||
return $field->pagepicker([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'limit' => $field->limit(),
|
||||
'page' => $this->requestQuery('page'),
|
||||
'parent' => $this->requestQuery('parent'),
|
||||
'query' => $field->query(),
|
||||
'search' => $this->requestQuery('search'),
|
||||
'subpages' => $field->subpages(),
|
||||
'text' => $field->text()
|
||||
]);
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'id');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
||||
29
private/kirby/config/fields/radio.php
Normal file
29
private/kirby/config/fields/radio.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'mixins' => ['options'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Arranges the radio buttons in the given number of columns
|
||||
*/
|
||||
'columns' => function (int $columns = 1) {
|
||||
return $columns;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->sanitizeOption($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->sanitizeOption($this->value) ?? '';
|
||||
}
|
||||
]
|
||||
];
|
||||
24
private/kirby/config/fields/range.php
Normal file
24
private/kirby/config/fields/range.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'number',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* The maximum value on the slider
|
||||
*/
|
||||
'max' => function (float $max = 100) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Enables/disables the tooltip and set the before and after values
|
||||
*/
|
||||
'tooltip' => function ($tooltip = true) {
|
||||
return $tooltip;
|
||||
},
|
||||
]
|
||||
];
|
||||
24
private/kirby/config/fields/select.php
Normal file
24
private/kirby/config/fields/select.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'radio',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'columns' => null,
|
||||
|
||||
/**
|
||||
* Custom icon to replace the arrow down.
|
||||
*/
|
||||
'icon' => function (string $icon = null) {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Custom placeholder string for empty option.
|
||||
*/
|
||||
'placeholder' => function (string $placeholder = '—') {
|
||||
return $placeholder;
|
||||
},
|
||||
]
|
||||
];
|
||||
193
private/kirby/config/fields/structure.php
Normal file
193
private/kirby/config/fields/structure.php
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Form;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'mixins' => ['min'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'autofocus' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Optional columns definition to only show selected fields in the structure table.
|
||||
*/
|
||||
'columns' => function (array $columns = []) {
|
||||
// lower case all keys, because field names will
|
||||
// be lowercase as well.
|
||||
return array_change_key_case($columns);
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles duplicating rows for the structure
|
||||
*/
|
||||
'duplicate' => function (bool $duplicate = true) {
|
||||
return $duplicate;
|
||||
},
|
||||
|
||||
/**
|
||||
* The placeholder text if no items have been added yet
|
||||
*/
|
||||
'empty' => function ($empty = null) {
|
||||
return I18n::translate($empty, $empty);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the default rows for the structure
|
||||
*/
|
||||
'default' => function (array $default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fields setup for the structure form. Works just like fields in regular forms.
|
||||
*/
|
||||
'fields' => function (array $fields) {
|
||||
return $fields;
|
||||
},
|
||||
/**
|
||||
* The number of entries that will be displayed on a single page. Afterwards pagination kicks in.
|
||||
*/
|
||||
'limit' => function (int $limit = null) {
|
||||
return $limit;
|
||||
},
|
||||
/**
|
||||
* Maximum allowed entries in the structure. Afterwards the "Add" button will be switched off.
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Minimum required entries in the structure
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* Toggles adding to the top or bottom of the list
|
||||
*/
|
||||
'prepend' => function (bool $prepend = null) {
|
||||
return $prepend;
|
||||
},
|
||||
/**
|
||||
* Toggles drag & drop sorting
|
||||
*/
|
||||
'sortable' => function (bool $sortable = null) {
|
||||
return $sortable;
|
||||
},
|
||||
/**
|
||||
* Sorts the entries by the given field and order (i.e. `title desc`)
|
||||
* Drag & drop is disabled in this case
|
||||
*/
|
||||
'sortBy' => function (string $sort = null) {
|
||||
return $sort;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->rows($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->rows($this->value);
|
||||
},
|
||||
'fields' => function () {
|
||||
if (empty($this->fields) === true) {
|
||||
throw new Exception('Please provide some fields for the structure');
|
||||
}
|
||||
|
||||
return $this->form()->fields()->toArray();
|
||||
},
|
||||
'columns' => function () {
|
||||
$columns = [];
|
||||
|
||||
if (empty($this->columns)) {
|
||||
foreach ($this->fields as $field) {
|
||||
|
||||
// Skip hidden fields.
|
||||
// They should never be included as column
|
||||
if ($field['type'] === 'hidden') {
|
||||
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 = [];
|
||||
}
|
||||
|
||||
$field = $this->fields[$columnName] ?? null;
|
||||
|
||||
if (empty($field) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns[$columnName] = array_merge($columnProps, [
|
||||
'type' => $field['type'],
|
||||
'label' => $field['label'] ?? $field['name']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'rows' => function ($value) {
|
||||
$rows = Data::decode($value, 'yaml');
|
||||
$value = [];
|
||||
|
||||
foreach ($rows as $index => $row) {
|
||||
if (is_array($row) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value[] = $this->form($row)->values();
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
'form' => function (array $values = []) {
|
||||
return new Form([
|
||||
'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) {
|
||||
$data[] = $this->form($row)->data();
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
||||
96
private/kirby/config/fields/tags.php
Normal file
96
private/kirby/config/fields/tags.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Toolkit\V;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'options'],
|
||||
'props' => [
|
||||
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* If set to `all`, any type of input is accepted. If set to `options` only the predefined options are accepted as input.
|
||||
*/
|
||||
'accept' => function ($value = 'all') {
|
||||
return V::in($value, ['all', 'options']) ? $value : 'all';
|
||||
},
|
||||
/**
|
||||
* Changes the tag icon
|
||||
*/
|
||||
'icon' => function ($icon = 'tag') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Minimum number of required entries/tags
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* Maximum number of allowed entries/tags
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Custom tags separator, which will be used to store tags in the content file
|
||||
*/
|
||||
'separator' => function (string $separator = ',') {
|
||||
return $separator;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function (): array {
|
||||
return $this->toTags($this->default);
|
||||
},
|
||||
'value' => function (): array {
|
||||
return $this->toTags($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toTags' => function ($value) {
|
||||
if (is_null($value) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$options = $this->options();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
$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(
|
||||
A::pluck($value, 'value'),
|
||||
$this->separator() . ' '
|
||||
);
|
||||
},
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
||||
27
private/kirby/config/fields/tel.php
Normal file
27
private/kirby/config/fields/tel.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
'spellcheck' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete attribute
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'tel') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the phone icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'phone') {
|
||||
return $icon;
|
||||
}
|
||||
]
|
||||
];
|
||||
103
private/kirby/config/fields/text.php
Normal file
103
private/kirby/config/fields/text.php
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
|
||||
/**
|
||||
* 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 && in_array($value, array_keys($this->converters())) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'field.converter.invalid',
|
||||
'data' => ['converter' => $value]
|
||||
]);
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows or hides the character counter in the top right corner
|
||||
*/
|
||||
'counter' => function (bool $counter = true) {
|
||||
return $counter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
'maxlength' => function (int $maxlength = null) {
|
||||
return $maxlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required characters
|
||||
*/
|
||||
'minlength' => function (int $minlength = null) {
|
||||
return $minlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* A regular expression, which will be used to validate the input
|
||||
*/
|
||||
'pattern' => function (string $pattern = null) {
|
||||
return $pattern;
|
||||
},
|
||||
|
||||
/**
|
||||
* If `false`, spellcheck will be switched off
|
||||
*/
|
||||
'spellcheck' => function (bool $spellcheck = false) {
|
||||
return $spellcheck;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->convert($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return (string)$this->convert($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'convert' => function ($value) {
|
||||
if ($this->converter() === null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
$converter = $this->converters()[$this->converter()];
|
||||
|
||||
if (is_array($value) === true) {
|
||||
return array_map($converter, $value);
|
||||
}
|
||||
|
||||
return call_user_func($converter, $value);
|
||||
},
|
||||
'converters' => function (): array {
|
||||
return [
|
||||
'lower' => function ($value) {
|
||||
return Str::lower($value);
|
||||
},
|
||||
'slug' => function ($value) {
|
||||
return Str::slug($value);
|
||||
},
|
||||
'ucfirst' => function ($value) {
|
||||
return Str::ucfirst($value);
|
||||
},
|
||||
'upper' => function ($value) {
|
||||
return Str::upper($value);
|
||||
},
|
||||
];
|
||||
},
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'pattern'
|
||||
]
|
||||
];
|
||||
122
private/kirby/config/fields/textarea.php
Normal file
122
private/kirby/config/fields/textarea.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'mixins' => ['filepicker', 'upload'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
|
||||
/**
|
||||
* Enables/disables the format buttons. Can either be `true`/`false` or a list of allowed buttons. Available buttons: `headlines`, `italic`, `bold`, `link`, `email`, `file`, `code`, `ul`, `ol` (as well as `|` for a divider)
|
||||
*/
|
||||
'buttons' => function ($buttons = true) {
|
||||
return $buttons;
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables/disables the character counter in the top right corner
|
||||
*/
|
||||
'counter' => function (bool $counter = true) {
|
||||
return $counter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the default text when a new page/file/user is created
|
||||
*/
|
||||
'default' => function (string $default = null) {
|
||||
return trim($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the options for the files picker
|
||||
*/
|
||||
'files' => function ($files = []) {
|
||||
if (is_string($files) === true) {
|
||||
return ['query' => $files];
|
||||
}
|
||||
|
||||
if (is_array($files) === false) {
|
||||
$files = [];
|
||||
}
|
||||
|
||||
return $files;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the font family (sans or monospace)
|
||||
*/
|
||||
'font' => function (string $font = null) {
|
||||
return $font === 'monospace' ? 'monospace' : 'sans-serif';
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
'maxlength' => function (int $maxlength = null) {
|
||||
return $maxlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required characters
|
||||
*/
|
||||
'minlength' => function (int $minlength = null) {
|
||||
return $minlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the size of the textarea. Available sizes: `small`, `medium`, `large`, `huge`
|
||||
*/
|
||||
'size' => function (string $size = null) {
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* If `false`, spellcheck will be switched off
|
||||
*/
|
||||
'spellcheck' => function (bool $spellcheck = true) {
|
||||
return $spellcheck;
|
||||
},
|
||||
|
||||
'value' => function (string $value = null) {
|
||||
return trim($value);
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => 'files',
|
||||
'action' => function () {
|
||||
$params = array_merge($this->field()->files(), [
|
||||
'page' => $this->requestQuery('page'),
|
||||
'search' => $this->requestQuery('search')
|
||||
]);
|
||||
|
||||
return $this->field()->filepicker($params);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'upload',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$uploads = $field->uploads();
|
||||
|
||||
return $this->field()->upload($this, $uploads, function ($file, $parent) use ($field) {
|
||||
$absolute = $field->model()->is($parent) === false;
|
||||
|
||||
return [
|
||||
'filename' => $file->filename(),
|
||||
'dragText' => $file->dragText('auto', $absolute),
|
||||
];
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength'
|
||||
]
|
||||
];
|
||||
68
private/kirby/config/fields/time.php
Normal file
68
private/kirby/config/fields/time.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Sets the default time when a new page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
/**
|
||||
* Changes the clock icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'clock') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* `12` or `24` hour notation. If `12`, an AM/PM selector will be shown.
|
||||
*/
|
||||
'notation' => function (int $value = 24) {
|
||||
return $value === 24 ? 24 : 12;
|
||||
},
|
||||
/**
|
||||
* The interval between minutes in the minutes select dropdown.
|
||||
*/
|
||||
'step' => function (int $step = 5) {
|
||||
return $step;
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toTime($this->default);
|
||||
},
|
||||
'format' => function () {
|
||||
return $this->notation === 24 ? 'H:i' : 'h:i a';
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toTime($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toTime' => function ($value) {
|
||||
if ($timestamp = timestamp($value, $this->step)) {
|
||||
return date('H:i', $timestamp);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
],
|
||||
'save' => function ($value): string {
|
||||
if ($timestamp = strtotime($value)) {
|
||||
return date($this->format, $timestamp);
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
'validations' => [
|
||||
'time',
|
||||
]
|
||||
];
|
||||
68
private/kirby/config/fields/toggle.php
Normal file
68
private/kirby/config/fields/toggle.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default value which will be saved when a new page/user/file is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->default = $default;
|
||||
},
|
||||
/**
|
||||
* Sets the text next to the toggle. The text can be a string or an array of two options. The first one is the negative text and the second one the positive. The text will automatically switch when the toggle is triggered.
|
||||
*/
|
||||
'text' => function ($value = null) {
|
||||
if (is_array($value) === true) {
|
||||
if (A::isAssociative($value) === true) {
|
||||
return I18n::translate($value, $value);
|
||||
}
|
||||
|
||||
foreach ($value as $key => $val) {
|
||||
$value[$key] = I18n::translate($val, $val);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
return I18n::translate($value, $value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toBool($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
if ($this->props['value'] === null) {
|
||||
return $this->default();
|
||||
} else {
|
||||
return $this->toBool($this->props['value']);
|
||||
}
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toBool' => function ($value) {
|
||||
return in_array($value, [true, 'true', 1, '1', 'on'], true) === true;
|
||||
}
|
||||
],
|
||||
'save' => function (): string {
|
||||
return $this->value() === true ? 'true' : 'false';
|
||||
},
|
||||
'validations' => [
|
||||
'boolean',
|
||||
'required' => function ($value) {
|
||||
if ($this->isRequired() && ($value === false || $this->isEmpty($value))) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'form.field.required'
|
||||
]);
|
||||
}
|
||||
},
|
||||
]
|
||||
];
|
||||
41
private/kirby/config/fields/url.php
Normal file
41
private/kirby/config/fields/url.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
'spellcheck' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete attribute
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'url') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the link icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'url') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets custom placeholder text, when the field is empty
|
||||
*/
|
||||
'placeholder' => function ($value = null) {
|
||||
return I18n::translate($value, $value) ?? 'https://example.com';
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'url'
|
||||
],
|
||||
];
|
||||
97
private/kirby/config/fields/users.php
Normal file
97
private/kirby/config/fields/users.php
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'picker', 'userpicker'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default selected user(s) when a new page/file/user is created
|
||||
*/
|
||||
'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) {
|
||||
return $this->toUsers($value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
/**
|
||||
* Unset inherited computed
|
||||
*/
|
||||
'default' => null
|
||||
],
|
||||
'methods' => [
|
||||
'userResponse' => function ($user) {
|
||||
return $user->panelPickerData([
|
||||
'info' => $this->info,
|
||||
'image' => $this->image,
|
||||
'text' => $this->text,
|
||||
]);
|
||||
},
|
||||
'toUsers' => function ($value = null) {
|
||||
$users = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $email) {
|
||||
if (is_array($email) === true) {
|
||||
$email = $email['email'] ?? null;
|
||||
}
|
||||
|
||||
if ($email !== null && ($user = $kirby->user($email))) {
|
||||
$users[] = $this->userResponse($user);
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
|
||||
return $field->userpicker([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'limit' => $field->limit(),
|
||||
'page' => $this->requestQuery('page'),
|
||||
'query' => $field->query(),
|
||||
'search' => $this->requestQuery('search'),
|
||||
'text' => $field->text()
|
||||
]);
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'id');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
||||
Loading…
Add table
Add a link
Reference in a new issue