phplibrary/src/Form/Form.php

201 lines
5.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* При рендеринге каждому классу соответствует шаблон (см. themes/maxim/templates/macros.html)
*/
namespace ctiso\Form;
use ctiso\Form\Field;
use ctiso\Form\Select;
use ctiso\Form\Input;
use ctiso\Validator\Validator;
use ctiso\HttpRequest;
/**
* Форма для ввода
*/
class Form {
/** @var array */
public $field = []; //Поля формы
/** @var array */
public $fieldsets = []; //Группы полей (fieldset). Некоторые поля могут не принадлежать никаким группам
/** @var string */
public $action = "";
/** @var string */
public $method = 'post';
/** @var string */
public $header;
protected $replace;
protected $before;
/** @var array<string> */
public $_title = [];
/** @var array */
public $alias = [];
/** @var class-string<Field>[] */
private $constructor = [];
/**
* Строим форму по ее структуре. Каждому типу соответствует определенный класс.
*/
public function __construct()
{
$this->constructor = [
'input' => Input::class,
// input с проверкой на заполненность
'inputreq' => Input::class,
'date' => Date::class,
'datereq' => Date::class,
'datetime' => DateTime::class,
'color' => Color::class,
'textarea' => TextArea::class,
'text' => TextArea::class,
'multiselect' => SelectMany::class,
'select1' => SelectOne::class,
'select' => SelectOne::class,
'questiontype'=> QuestionType::class,
'secret' => Secret::class,
'upload' => Upload::class,
'image' => Upload::class,
'checkbox' => CheckBox::class,
'checkmany' => SelectMany::class,
'hidden' => Hidden::class,
'radio' => SelectOne::class,
'filebrowser' => BrowserInput::class,
'documents' => BrowserInput::class,
'chooser' => Input::class,
'select_chooser' => SelectOne::class,
'html_text' => HtmlText::class
];
}
function getId(): string
{
return '_form_edit';
}
/**
* Добавление конструкторя для поля формы
* @param string $name Краткое название поля
* @param class-string<Field> $class
*/
public function addFieldClass($name, $class): void
{
$this->constructor [$name] = $class;
}
/**
* Добавляет одно поле ввода на форму
* @param array{ type: string, name: string, hint?: string } $init
* @param OptionsFactory|null $factory
*/
public function addField(array $init, $factory = null): Field
{
assert(isset($init['type']));
assert(isset($init['name']));
$constructor = $this->constructor[$init['type']];
$el = new $constructor($init, $factory);
if (!$el->type) {
$el->type = $init['type'];
}
if(isset($init['hint'])) {
$el->hint = $init['hint'];
}
$this->field[$init['name']] = $el;
return $el;
}
/**
* Добавление fieldset на форму
*/
public function addFieldSet(array $fieldset): void
{
$this->fieldsets[$fieldset['name']] = $fieldset;
}
/**
* Добавление массива fieldset на форму
*/
public function addFieldSetList(array $list): void
{
foreach ($list as $fieldset) {
$this->addFieldSet($fieldset);
}
}
/**
* Добавляет список полей для формы
* @param array $list
*/
public function addFieldList(array $list, $factory = null): void
{
foreach ($list as $init) {
$this->addField($init, $factory);
}
}
/**
* Устанавливает ошибки после проверки
*/
function setError(Validator $validator): void
{
foreach ($validator->getErrorMsg() as $name => $error)
{
$this->field[$name]->error = true;
$this->field[$name]->error_msg = $error;
}
}
/**
* Устанавливает ошибку для поля
* @param string $name
* @param string $message
*/
function setFieldError($name, $message): void
{
$this->field[$name]->error = true;
$this->field[$name]->error_msg = $message;
}
/**
* Устанавливает значения из масива
*/
function setValues(HttpRequest $request): void {
foreach ($this->field as $key => $_) {
$value = $request->getRawData($this->method, $key);
$this->field[$key]->setValue($value);
}
}
/**
* Заполняет форму данными из обьекта
* @param object $data
* @param array $schema Связь между элементами формы и свойствами обьекта
*/
public function fill($data, array $schema): void
{
foreach ($schema as $key => $conv) {
list($value, $type) = $conv;
$this->field [$key]->setValue(call_user_func([\ctiso\Primitive::class, 'from_' . $type], $data->$value));
}
}
public function set($name, $value): void
{
$this->field[$name]->setValue($value);
}
function execute(): self
{
return $this;
}
}