Initial commit
This commit is contained in:
commit
efa5624dab
687 changed files with 162710 additions and 0 deletions
211
kirby/src/Form/Field/EntriesField.php
Normal file
211
kirby/src/Form/Field/EntriesField.php
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Form\Field;
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Form\FieldClass;
|
||||
use Kirby\Form\Form;
|
||||
use Kirby\Form\Mixin\EmptyState;
|
||||
use Kirby\Form\Mixin\Max;
|
||||
use Kirby\Form\Mixin\Min;
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* Main class file of the entries field
|
||||
*
|
||||
* @package Kirby Field
|
||||
* @author Ahmet Bora <ahmet@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license https://getkirby.com/license
|
||||
* @since 5.0.0
|
||||
*/
|
||||
class EntriesField extends FieldClass
|
||||
{
|
||||
use EmptyState;
|
||||
use Max;
|
||||
use Min;
|
||||
|
||||
protected array $field;
|
||||
protected Form $form;
|
||||
protected bool $sortable = true;
|
||||
|
||||
public function __construct(array $params = [])
|
||||
{
|
||||
parent::__construct($params);
|
||||
|
||||
$this->setEmpty($params['empty'] ?? null);
|
||||
$this->setField($params['field'] ?? null);
|
||||
$this->setMax($params['max'] ?? null);
|
||||
$this->setMin($params['min'] ?? null);
|
||||
$this->setSortable($params['sortable'] ?? true);
|
||||
}
|
||||
|
||||
public function field(): array
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
public function fieldProps(): array
|
||||
{
|
||||
return $this->form()->fields()->first()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MethodSignatureMismatch
|
||||
* @todo Remove psalm suppress after https://github.com/vimeo/psalm/issues/8673 is fixed
|
||||
*/
|
||||
public function fill(mixed $value): static
|
||||
{
|
||||
$this->value = Data::decode($value ?? '', 'yaml');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
return $this->form ??= new Form(
|
||||
fields: [$this->field()],
|
||||
model: $this->model
|
||||
);
|
||||
}
|
||||
|
||||
public function props(): array
|
||||
{
|
||||
return [
|
||||
...parent::props(),
|
||||
'empty' => $this->empty(),
|
||||
'field' => $this->fieldProps(),
|
||||
'max' => $this->max(),
|
||||
'min' => $this->min(),
|
||||
'sortable' => $this->sortable(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function setField(array|string|null $attrs = null): void
|
||||
{
|
||||
if (is_string($attrs) === true) {
|
||||
$attrs = ['type' => $attrs];
|
||||
}
|
||||
|
||||
$attrs ??= ['type' => 'text'];
|
||||
|
||||
if (in_array($attrs['type'], $this->supports()) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
key: 'entries.supports',
|
||||
data: ['type' => $attrs['type']]
|
||||
);
|
||||
}
|
||||
|
||||
// remove the unsupported props from the entry field
|
||||
unset($attrs['counter'], $attrs['label']);
|
||||
|
||||
$this->field = $attrs;
|
||||
}
|
||||
|
||||
protected function setSortable(bool|null $sortable = true): void
|
||||
{
|
||||
$this->sortable = $sortable;
|
||||
}
|
||||
|
||||
public function sortable(): bool
|
||||
{
|
||||
return $this->sortable;
|
||||
}
|
||||
|
||||
public function supports(): array
|
||||
{
|
||||
return [
|
||||
'color',
|
||||
'date',
|
||||
'email',
|
||||
'number',
|
||||
'select',
|
||||
'slug',
|
||||
'tel',
|
||||
'text',
|
||||
'time',
|
||||
'url'
|
||||
];
|
||||
}
|
||||
|
||||
public function toFormValue(): mixed
|
||||
{
|
||||
$form = $this->form();
|
||||
$value = parent::toFormValue() ?? [];
|
||||
|
||||
return A::map(
|
||||
$value,
|
||||
fn ($value) => $form
|
||||
->reset()
|
||||
->fill(input: [$value])
|
||||
->fields()
|
||||
->first()
|
||||
->toFormValue()
|
||||
);
|
||||
}
|
||||
|
||||
public function toStoredValue(): mixed
|
||||
{
|
||||
$form = $this->form();
|
||||
$value = parent::toStoredValue();
|
||||
|
||||
return A::map(
|
||||
$value,
|
||||
fn ($value) => $form
|
||||
->reset()
|
||||
->submit(input: [$value])
|
||||
->fields()
|
||||
->first()
|
||||
->toStoredValue()
|
||||
);
|
||||
}
|
||||
|
||||
public function validations(): array
|
||||
{
|
||||
return [
|
||||
'entries' => function ($value) {
|
||||
if ($this->min && count($value) < $this->min) {
|
||||
throw new InvalidArgumentException(
|
||||
key: match ($this->min) {
|
||||
1 => 'entries.min.singular',
|
||||
default => 'entries.min.plural'
|
||||
},
|
||||
data: ['min' => $this->min]
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->max && count($value) > $this->max) {
|
||||
throw new InvalidArgumentException(
|
||||
key: match ($this->max) {
|
||||
1 => 'entries.max.singular',
|
||||
default => 'entries.max.plural'
|
||||
},
|
||||
data: ['max' => $this->max]
|
||||
);
|
||||
}
|
||||
|
||||
$form = $this->form();
|
||||
|
||||
foreach ($value as $index => $val) {
|
||||
$form->reset()->submit(input: [$val]);
|
||||
|
||||
foreach ($form->fields() as $field) {
|
||||
$errors = $field->errors();
|
||||
|
||||
if ($errors !== []) {
|
||||
throw new InvalidArgumentException(
|
||||
key: 'entries.validation',
|
||||
data: [
|
||||
'field' => $this->label() ?? Str::ucfirst($this->name()),
|
||||
'index' => $index + 1
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue