Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/Form/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,11 @@ public static function factory(
): static|FieldClass {
$field = static::$types[$type] ?? null;

if (is_string($field) && class_exists($field) === true) {
$attrs['siblings'] = $siblings;
return new $field($attrs);
if (
is_string($field) &&
is_subclass_of($field, FieldClass::class) === true
) {
return $field::factory($attrs, $siblings);
}

return new static($type, $attrs, $siblings);
Expand Down
29 changes: 18 additions & 11 deletions src/Form/Field/BlocksField.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,27 @@ class BlocksField extends FieldClass
protected string|null $group;
protected mixed $value = [];

public function __construct(array $params = [])
{
public function __construct(
array|string|null $empty = null,
array|string|null $fieldsets = null,
string|null $group = null,
int|null $max = null,
int|null $min = null,
bool $pretty = false,
...$props
) {
$this->setFieldsets(
$params['fieldsets'] ?? null,
$params['model'] ?? App::instance()->site()
$fieldsets,
$props['model'] ?? App::instance()->site()
);

parent::__construct($params);
parent::__construct(...$props);

$this->setEmpty($params['empty'] ?? null);
$this->setGroup($params['group'] ?? 'blocks');
$this->setMax($params['max'] ?? null);
$this->setMin($params['min'] ?? null);
$this->setPretty($params['pretty'] ?? false);
$this->setEmpty($empty);
$this->setGroup($group);
$this->setMax($max);
$this->setMin($min);
$this->setPretty($pretty);
}

public function blocksToValues(
Expand Down Expand Up @@ -134,7 +141,7 @@ public function isEmpty(): bool

public function group(): string
{
return $this->group;
return $this->group ?? 'blocks';
}

/**
Expand Down
24 changes: 15 additions & 9 deletions src/Form/Field/EntriesField.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ class EntriesField extends FieldClass
protected Form $form;
protected mixed $value = [];

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 __construct(
array|string|null $empty = null,
array|string|null $field = null,
int|null $max = null,
int|null $min = null,
bool $sortable = true,
...$props
) {
parent::__construct(...$props);

$this->setEmpty($empty);
$this->setField($field);
$this->setMax($max);
$this->setMin($min);
$this->setSortable($sortable);
}

public function field(): array
Expand Down
24 changes: 14 additions & 10 deletions src/Form/Field/LayoutField.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Kirby\Cms\Fieldset;
use Kirby\Cms\Layout;
use Kirby\Cms\Layouts;
use Kirby\Cms\ModelWithContent;
use Kirby\Data\Data;
use Kirby\Data\Json;
use Kirby\Exception\InvalidArgumentException;
Expand All @@ -16,18 +17,21 @@

class LayoutField extends BlocksField
{
protected array|null $layouts;
protected array|null $selector;
protected Fieldset|null $settings;

public function __construct(array $params)
{
$this->setModel($params['model'] ?? App::instance()->site());
$this->setLayouts($params['layouts'] ?? ['1/1']);
$this->setSelector($params['selector'] ?? null);
$this->setSettings($params['settings'] ?? null);

parent::__construct($params);
public function __construct(
protected array $layouts = ['1/1'],
ModelWithContent|null $model = null,
protected array|null $selector = null,
array|string|null $settings = null,
...$props
) {
$this->setModel($model ?? App::instance()->site());
$this->setLayouts($layouts);
$this->setSelector($selector);
$this->setSettings($settings);

parent::__construct(...$props);
}

/**
Expand Down
35 changes: 17 additions & 18 deletions src/Form/Field/StatsField.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,26 @@
*/
class StatsField extends FieldClass
{
/**
* Array or query string for reports. Each report needs a `label` and `value` and can have additional `info`, `link`, `icon` and `theme` settings.
*/
protected array|string $reports;

/**
* The size of the report cards. Available sizes: `tiny`, `small`, `medium`, `large`
*/
protected string $size;

/**
* Cache for the Stats UI component
*/
protected Stats $stats;

public function __construct(array $params)
{
parent::__construct($params);

$this->reports = $params['reports'] ?? [];
$this->size = $params['size'] ?? 'large';
public function __construct(
/**
* Array or query string for reports.
* Each report needs a `label` and `value` and can have
* additional `info`, `link`, `icon` and `theme` settings.
*/
protected array|string $reports = [],
/**
* The size of the report cards.
* Available sizes: `tiny`, `small`, `medium`, `large`
*/
protected string $size = 'large',
...$props
) {
parent::__construct(...$props);
}

public function hasValue(): bool
Expand All @@ -58,9 +57,9 @@ public function size(): string
public function stats(): Stats
{
return $this->stats ??= Stats::from(
model: $this->model,
model: $this->model,
reports: $this->reports,
size: $this->size
size: $this->size
);
}

Expand Down
85 changes: 53 additions & 32 deletions src/Form/FieldClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Kirby\Form;

use Kirby\Cms\HasSiblings;
use Kirby\Cms\ModelWithContent;
use Kirby\Exception\NotFoundException;
use Kirby\Toolkit\HasI18n;

/**
Expand Down Expand Up @@ -39,40 +41,54 @@ abstract class FieldClass
use Mixin\When;
use Mixin\Width;

protected Fields $siblings;

public function __construct(
protected array $params = []
array|string|null $after = null,
bool $autofocus = false,
array|string|null $before = null,
mixed $default = null,
bool $disabled = false,
array|string|null $help = null,
string|null $icon = null,
array|string|null $label = null,
ModelWithContent|null $model = null,
string|null $name = null,
array|string|null $placeholder = null,
bool $required = false,
protected Fields|null $siblings = null,
bool $translate = true,
$value = null,
array|null $when = null,
string|null $width = null
) {
$this->setAfter($params['after'] ?? null);
$this->setAutofocus($params['autofocus'] ?? false);
$this->setBefore($params['before'] ?? null);
$this->setDefault($params['default'] ?? null);
$this->setDisabled($params['disabled'] ?? false);
$this->setHelp($params['help'] ?? null);
$this->setIcon($params['icon'] ?? null);
$this->setLabel($params['label'] ?? null);
$this->setModel($params['model'] ?? null);
$this->setName($params['name'] ?? null);
$this->setPlaceholder($params['placeholder'] ?? null);
$this->setRequired($params['required'] ?? false);
$this->setSiblings($params['siblings'] ?? null);
$this->setTranslate($params['translate'] ?? true);
$this->setWhen($params['when'] ?? null);
$this->setWidth($params['width'] ?? null);

if (array_key_exists('value', $params) === true) {
$this->fill($params['value']);
$this->setAfter($after);
$this->setAutofocus($autofocus);
$this->setBefore($before);
$this->setDefault($default);
$this->setDisabled($disabled);
$this->setHelp($help);
$this->setIcon($icon);
$this->setLabel($label);
$this->setModel($model);
$this->setName($name);
$this->setPlaceholder($placeholder);
$this->setRequired($required);
$this->setSiblings($siblings);
$this->setTranslate($translate);
$this->setWhen($when);
$this->setWidth($width);

if ($value !== null) {
$this->fill($value);
}
}

public function __call(string $param, array $args): mixed
{
if (isset($this->$param) === true) {
if (property_exists($this, $param) === true) {
return $this->$param;
}

return $this->params[$param] ?? null;
throw new NotFoundException(message: 'Method or option "' . $param . '" does not exist for field type "' . $this->type() . '"');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bastianallgeier I was asking the other day about the magic validate prop that's not really defined anywhere. I guess this change would cause a problem with our magic usage there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to bring back this undocumented option for input fields, we should really do that in a way that sets a validate property and gets rid of the magic anyway.

}

/**
Expand All @@ -91,6 +107,19 @@ public function drawers(): array
return [];
}

/**
* Creates a new field instance from a $props array
* @since 6.0.0
*/
public static function factory(
array $props,
Fields|null $siblings = null
): static {
$props['siblings'] = $siblings;
unset($props['type']);
return new static(...$props);
}

public function id(): string
{
return $this->name();
Expand All @@ -101,14 +130,6 @@ public function isHidden(): bool
return false;
}

/**
* Returns all original params for the field
*/
public function params(): array
{
return $this->params;
}

/**
* Define the props that will be sent to
* the Vue component
Expand Down
9 changes: 9 additions & 0 deletions src/Form/Mixin/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ protected function setRequired(bool $required): void
$this->required = $required;
}

/**
* Runs all validations
* @since 6.0.0
*/
public function validate(): void
{
$this->errors();
}

/**
* Defines all validation rules
*/
Expand Down
4 changes: 1 addition & 3 deletions tests/Form/Field/EntriesFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,7 @@ public static function validationsProvider(): array
public function testValidations($type, $value, $expected): void
{
$field = $this->field('entries', [
'value' => [
$value
],
'value' => [$value],
'field' => $type,
'required' => true
]);
Expand Down
Loading