Files
lichterei-web/kirby/src/Cms/Form.php
Bastian Allgeier c378376bc9 Upgrade to rc5
2020-12-15 12:21:38 +01:00

131 lines
3.7 KiB
PHP
Executable File

<?php
namespace Kirby\Cms;
use Kirby\Exception\NotFoundException;
use Kirby\Form\Form as BaseForm;
use Kirby\Toolkit\Str;
/**
* Extension of `Kirby\Form\Form` that introduces
* a Form::for method that creates a proper form
* definition for any Cms Model.
*
* @package Kirby Cms
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://getkirby.com/license
*/
class Form extends BaseForm
{
protected $errors;
protected $fields;
protected $values = [];
/**
* Form constructor.
*
* @param array $props
*/
public function __construct(array $props)
{
$kirby = App::instance();
if ($kirby->multilang() === true) {
$fields = $props['fields'] ?? [];
$languageCode = $props['language'] ?? $kirby->language()->code();
$isDefaultLanguage = $languageCode === $kirby->defaultLanguage()->code();
foreach ($fields as $fieldName => $fieldProps) {
// switch untranslatable fields to readonly
if (($fieldProps['translate'] ?? true) === false && $isDefaultLanguage === false) {
$fields[$fieldName]['unset'] = true;
$fields[$fieldName]['disabled'] = true;
}
}
$props['fields'] = $fields;
}
parent::__construct($props);
}
/**
* Get the field object by name
* and handle nested fields correctly
*
* @param string $name
* @throws \Kirby\Exception\NotFoundException
* @return \Kirby\Form\Field
*/
public function field(string $name)
{
$form = $this;
$fieldNames = Str::split($name, '+');
$index = 0;
$count = count($fieldNames);
$field = null;
foreach ($fieldNames as $fieldName) {
$index++;
if ($field = $form->fields()->get($fieldName)) {
if ($count !== $index) {
$form = $field->form();
}
} else {
throw new NotFoundException('The field "' . $fieldName . '" could not be found');
}
}
// it can get this error only if $name is an empty string as $name = ''
if ($field === null) {
throw new NotFoundException('No field could be loaded');
}
return $field;
}
/**
* @param \Kirby\Cms\Model $model
* @param array $props
* @return self
*/
public static function for(Model $model, array $props = [])
{
// get the original model data
$original = $model->content($props['language'] ?? null)->toArray();
$values = $props['values'] ?? [];
// convert closures to values
foreach ($values as $key => $value) {
if (is_a($value, 'Closure') === true) {
$values[$key] = $value($original[$key] ?? null);
}
}
// set a few defaults
$props['values'] = array_merge($original, $values);
$props['fields'] = $props['fields'] ?? [];
$props['model'] = $model;
// search for the blueprint
if (method_exists($model, 'blueprint') === true && $blueprint = $model->blueprint()) {
$props['fields'] = $blueprint->fields();
}
$ignoreDisabled = $props['ignoreDisabled'] ?? false;
// REFACTOR: this could be more elegant
if ($ignoreDisabled === true) {
$props['fields'] = array_map(function ($field) {
$field['disabled'] = false;
return $field;
}, $props['fields']);
}
return new static($props);
}
}