Upgrade to 3.9.0

This commit is contained in:
Bastian Allgeier
2023-01-17 14:50:16 +01:00
parent 0ebe0c7b16
commit 6e5c9d1f48
132 changed files with 1664 additions and 1254 deletions

View File

@@ -8,7 +8,7 @@ use Kirby\Blueprint\NodeText;
use Kirby\Cms\ModelWithContent;
/**
* Option for select fields, radio fields, etc
* Option for select fields, radio fields, etc.
*
* @package Kirby Option
* @author Bastian Allgeier <bastian@getkirby.com>
@@ -19,7 +19,7 @@ use Kirby\Cms\ModelWithContent;
class Option
{
public function __construct(
public float|int|string|null $value,
public string|int|float|null $value,
public bool $disabled = false,
public NodeIcon|null $icon = null,
public NodeText|null $info = null,
@@ -28,7 +28,7 @@ class Option
$this->text ??= new NodeText(['en' => $this->value]);
}
public static function factory(float|int|string|null|array $props): static
public static function factory(string|int|float|null|array $props): static
{
if (is_array($props) === false) {
$props = ['value' => $props];

View File

@@ -6,7 +6,8 @@ use Kirby\Blueprint\Collection;
use Kirby\Cms\ModelWithContent;
/**
* Options
* Collection of possible options for
* select fields, radio fields, etc.
*
* @package Kirby Option
* @author Bastian Allgeier <bastian@getkirby.com>
@@ -30,6 +31,7 @@ class Options extends Collection
$collection = new static();
foreach ($items as $key => $option) {
// convert an associative value => text array into props;
// skip if option is already an array of option props
if (
is_array($option) === false ||

View File

@@ -88,8 +88,12 @@ class OptionsApi extends OptionsProvider
* Creates the actual options by loading
* data from the API and resolving it to
* the correct text-value entries
*
* @param bool $safeMode Whether to escape special HTML characters in
* the option text for safe output in the Panel;
* only set to `false` if the text is later escaped!
*/
public function resolve(ModelWithContent $model): Options
public function resolve(ModelWithContent $model, bool $safeMode = true): Options
{
// use cached options if present
// @codeCoverageIgnoreStart
@@ -101,25 +105,48 @@ class OptionsApi extends OptionsProvider
// apply property defaults
$this->defaults();
// load data from URL and narrow down to queried part
// load data from URL and convert from JSON to array
$data = $this->load($model);
if ($data === null) {
throw new NotFoundException('Options could not be loaded from API: ' . $model->toSafeString($this->url));
}
// turn data into Nest so that it can be queried
$data = Nest::create($data);
$data = Query::factory($this->query)->resolve($data);
// optionally query a substructure inside the data array
if ($this->query !== null) {
// turn data into Nest so that it can be queried
$data = Nest::create($data);
// actually apply the query and turn the result back into an array
$data = Query::factory($this->query)->resolve($data)->toArray();
}
// create options by resolving text and value query strings
// for each item from the data
$options = $data->toArray(fn ($item) => [
// value is always a raw string
'value' => $model->toString($this->value, ['item' => $item]),
// text is only a raw string when using {< >}
'text' => $model->toSafeString($this->text, ['item' => $item]),
]);
$options = array_map(
function ($item, $key) use ($model, $safeMode) {
// convert simple `key: value` API data
if (is_string($item) === true) {
$item = [
'key' => $key,
'value' => $item
];
}
$safeMethod = $safeMode === true ? 'toSafeString' : 'toString';
return [
// value is always a raw string
'value' => $model->toString($this->value, ['item' => $item]),
// text is only a raw string when using {< >}
// or when the safe mode is explicitly disabled (select field)
'text' => $model->$safeMethod($this->text, ['item' => $item])
];
},
// separately pass values and keys to have the keys available in the callback
$data,
array_keys($data)
);
// create Options object and render this subsequently
return $this->options = Options::factory($options);

View File

@@ -26,5 +26,13 @@ abstract class OptionsProvider
return $this->resolve($model)->render($model);
}
abstract public function resolve(ModelWithContent $model): Options;
/**
* Dynamically determines the actual options and resolves
* them to the correct text-value entries
*
* @param bool $safeMode Whether to escape special HTML characters in
* the option text for safe output in the Panel;
* only set to `false` if the text is later escaped!
*/
abstract public function resolve(ModelWithContent $model, bool $safeMode = true): Options;
}

View File

@@ -131,8 +131,12 @@ class OptionsQuery extends OptionsProvider
* Creates the actual options by running
* the query on the model and resolving it to
* the correct text-value entries
*
* @param bool $safeMode Whether to escape special HTML characters in
* the option text for safe output in the Panel;
* only set to `false` if the text is later escaped!
*/
public function resolve(ModelWithContent $model): Options
public function resolve(ModelWithContent $model, bool $safeMode = true): Options
{
// use cached options if present
// @codeCoverageIgnoreStart
@@ -159,7 +163,7 @@ class OptionsQuery extends OptionsProvider
}
// create options array
$options = $result->toArray(function ($item) use ($model) {
$options = $result->toArray(function ($item) use ($model, $safeMode) {
// get defaults based on item type
[$alias, $text, $value] = $this->itemToDefaults($item);
$data = ['item' => $item, $alias => $item];
@@ -167,9 +171,10 @@ class OptionsQuery extends OptionsProvider
// value is always a raw string
$value = $model->toString($this->value ?? $value, $data);
// text is only a raw string when HTML prop
// is explicitly set to true
$text = $model->toSafeString($this->text ?? $text, $data);
// text is only a raw string when using {< >}
// or when the safe mode is explicitly disabled (select field)
$safeMethod = $safeMode === true ? 'toSafeString' : 'toString';
$text = $model->$safeMethod($this->text ?? $text, $data);
return compact('text', 'value');
});