Drupal предоставляет базовый объект Drupal\Core\Form\FormBase
, который можно использовать для создания всевозможных форм.
FormBase
используется по-разному, например, можно наследоваться напрямую от данного объекта для создания своей формы, либо создавать новые базовые объекты форм, которые имеют дополнительный функционал или возможности.
Например, в ядре можно выделить:
-
Drupal\Core\Form\FormBase
: Описан выше, общий объект для создания любых форм. -
Drupal\Core\Form\ConfigFormBase
: Предназначен для форм редактирования каких-либо настроек. В основном подходит для административного интерфейса и подразумевает что данные будут храниться в конфигурациях. -
Drupal\Core\Form\ConfirmFormBase
: Форма подтверждения какого-либо действия, например, удаления содержимого. -
Drupal\Core\Entity\EntityForm
: Базовый объект для создания форм редактирования, добавления и прочих, связанных с какой-то сущностью.
и т.д.
¶Структура FormBase
FormBase
является базовым объектом всех возможных форм в Drupal, следовательно, весь его функционал доступен в любой другой форме.
FormBase
предоставляет следующие методы, которые вы можете переопределять в своих формах:
-
create()
: Позволяет внедрять сервисы в качестве зависимостей. Для более подробного описания поведения смотрите Dependency Injection. -
config()
: Получает объект конфигурации по её названию. Данная конфигурация будет в режиме чтения. -
getRequest()
: Возвращает текущей объект запроса. -
getRouteMatch()
: Возвращает объектRouteMatchInterface
. -
currentUser()
: Возвращает объектAccountInterface
содержащий информацию о текущем пользователе.
Это лишь методы, которые могут быть полезны и интересны, объект также содержит и другие методы.
FormBase
реализует интерфейс Drupal\Core\Form\FormInterface
, который требует создания некоторых методов:
-
getFormId()
: Возвращает строку с уникальным идентификатором формы. -
buildForm()
: Возвращает рендер массив в котором и описана форма. -
validatedForm()
: (опционально) Метод производящий валидацию формы. -
submitForm()
: Производит обработку отправленных данных формой.
¶FormState
Во всех формах созданных при помощи Drupal Form API активно используется Drupal\Core\Form\FormState
.
Экземпляр данного объекта передается в качестве аргумента на все этапы формы: построение, валидацию, отправку. Он хранит всю необходимую информацию о текущем состоянии формы.
При помощи данного объекта, можно получать и влиять на данные формы, хранить информацию между состояниями и многое другое.
Объект имеет множество различных методов, и лучше всего с ними ознакомиться в интерфейсе.
¶Значения формы
Для работы с обработанными значениями формы используются следующие методы:
-
&getValues()
: Возвращает массив значений формы. -
&getValue($key, $default = NULL)
: Получает конкретное значение формы с возможностью задать значение по умолчанию.$key
может быть либо строкой с конкретным ключом, либо массивом с ключами иерархии значений. Например, если значение находится в$values['foo']['bar']
, и вы хотите получить только данное значение, вы можете запросить его поgetValue(['foo', 'bar'])
. -
setValues(array $values)
: Устанавливает массив в качестве значений формы, полностью заменяя те что имеются. -
setValue($key, $value)
: Устанавливает конкретное значение формы.$key
имеет поведение как уgetValue()
. -
unsetValue($key)
: Удаляет конкретное значение формы.$key
имеет поведение как уgetValue()
. -
hasValue($key)
: Проверяет при помощиisset()
, имеется ли значение в форме.$key
имеет поведение как уgetValue()
. -
isValueEmpty($key)
: Проверяет при помощиempty()
, имеется ли значение в форме.$key
имеет поведение как уgetValue()
.
¶Ошибки
Для работы с ошибками формы используются следующие методы:
-
hasAnyErrors()
: Возвращает логическое значение, есть ли в форме на текущей момент ошибки или нет. -
setErrorByName($name, $message = '')
: Устанавливает ошибку на элемент по его названию. -
setError(array &$element, $message = '')
: Устанавливает ошибку на элемент по его ссылке. -
clearErrors()
: Очищает информацию о всех ошибках на данный момент. -
getErrors()
: Возвращает ассоциативный массив с информацией о всех ошибках на данный момент. -
getError(array $element)
: Получает информацию об ошибке для конкретного элемента.
¶Построение формы
Построение формы — процесс, в котором описываются элементы формы.
Формы являются рендер массивами, следовательно, описываются в виде специально оформленных PHP массивов. В форме могут быть как RenderElement
, так и FormElement
. RenderElement
будут обрабатываться, как обычно, и могут использоваться для вывода какой-то разметки или данных. Данные поступившие с FormElement
будут обрабатываться и передаваться на валидацию и отправку формы.
Построение формы производится в buildForm()
методе, который и должен возвращать рендер массив формы. Например:
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['message'] = [
'#type' => 'textarea',
'#title' => $this->t('Message'),
'#required' => TRUE,
'#default_value' => $this->t('Hello World'),
];
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Send'),
];
return $form;
}
¶Валидация формы
После отправки формы, запускается её валидация. Процесс валидации отвечает за проверку данных, отправленных формой.
Цель валидации — приостановить дальнейшую обработку формы. Любая ошибка в форме обнаруженная в момент валидации, прекращает обработку, и возвращает пользователю ошибку(и) и подсвечивает проблемные элементы.
На данном этапе не должно быть никакой логики, которая не имеет прямого отношения к валидации. Вы должны установить ошибки на все проблемные элементы с указанием ошибок.
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if (mb_strlen($form_state->getValue('message')) < 10) {
$form_state->setErrorByName('name', $this->t('Message should be at least 10 characters.'));
}
}
¶Обработка формы
Финальный этап отправки формы — обработка. На данном этапе принимается решение что делать дальше с данными формы:
- Обработать данные и отправить успешное сообщение пользователю.
- Обработать данные и перенаправить пользователя в другое место.
- и т.д.
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->messenger()->addStatus($this->t('The message has been sent.'));
$form_state->setRedirect('<front>');
}
¶Ссылки
- Drupal 8: Form API что изменилось и как использовать, Niklan, 2015