131 lines
3.7 KiB
PHP
Executable File
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);
|
|
}
|
|
}
|