class FormState
Same name in other branches
- 8.9.x core/lib/Drupal/Core/Form/FormState.php \Drupal\Core\Form\FormState
- 10 core/lib/Drupal/Core/Form/FormState.php \Drupal\Core\Form\FormState
- 11.x core/lib/Drupal/Core/Form/FormState.php \Drupal\Core\Form\FormState
Stores information about the state of a form.
Hierarchy
- class \Drupal\Core\Form\FormState implements \Drupal\Core\Form\FormStateInterface uses \Drupal\Core\Form\FormStateValuesTrait
Expanded class hierarchy of FormState
77 files declare their use of FormState
- AggregatorPluginSettingsBaseTest.php in core/
modules/ aggregator/ tests/ src/ Unit/ Plugin/ AggregatorPluginSettingsBaseTest.php - AreaDisplayLinkTest.php in core/
modules/ views/ tests/ src/ Kernel/ Handler/ AreaDisplayLinkTest.php - AreaEntityTest.php in core/
modules/ views/ tests/ src/ Kernel/ Handler/ AreaEntityTest.php - ArgumentValidateTest.php in core/
modules/ user/ tests/ src/ Kernel/ Views/ ArgumentValidateTest.php - batch.inc in core/
includes/ batch.inc - Batch processing API for processes to run in multiple HTTP requests.
File
-
core/
lib/ Drupal/ Core/ Form/ FormState.php, line 12
Namespace
Drupal\Core\FormView source
class FormState implements FormStateInterface {
use FormStateValuesTrait;
/**
* Tracks if any errors have been set on any form.
*
* @var bool
*/
protected static $anyErrors = FALSE;
/**
* The complete form structure.
*
* #process, #after_build, #element_validate, and other handlers being invoked
* on a form element may use this reference to access other information in the
* form the element is contained in.
*
* @see self::getCompleteForm()
*
* This property is uncacheable.
*
* @var array
*/
protected $complete_form;
/**
* An associative array of information stored by Form API.
*
* This associative array is necessary to build and rebuild the form from
* cache when the original context may no longer be available:
* - callback: The actual callback to be used to retrieve the form array.
* Can be any callable. If none is provided $form_id is used as the name
* of a function to call instead.
* - args: A list of arguments to pass to the form constructor.
* - files: An optional array defining include files that need to be loaded
* for building the form. Each array entry may be the path to a file or
* another array containing values for the parameters 'type', 'module' and
* 'name' as needed by \Drupal::moduleHandler()->loadInclude(). The files
* listed here are automatically loaded by
* \Drupal::formBuilder()->getCache(). By default the current menu router
* item's 'file' definition is added, if any. Use self::loadInclude() to
* add include files from a form constructor.
* - form_id: Identification of the primary form being constructed and
* processed.
* - base_form_id: Identification for a base form, as declared in the form
* class's \Drupal\Core\Form\BaseFormIdInterface::getBaseFormId() method.
* - immutable: If this flag is set to TRUE, a new form build id is
* generated when the form is loaded from the cache. If it is subsequently
* saved to the cache again, it will have another cache id and therefore
* the original form and form-state will remain unaltered. This is
* important when page caching is enabled in order to prevent form state
* from leaking between anonymous users.
*
* @var array
*/
protected $build_info = [
'args' => [],
'files' => [],
];
/**
* Similar to self::$build_info.
*
* But pertaining to \Drupal\Core\Form\FormBuilderInterface::rebuildForm().
*
* This property is uncacheable.
*
* @var array
*/
protected $rebuild_info = [];
/**
* Determines whether the form is rebuilt.
*
* Normally, after the entire form processing is completed and submit handlers
* have run, a form is considered to be done and
* \Drupal\Core\Form\FormSubmitterInterface::redirectForm() will redirect the
* user to a new page using a GET request (so a browser refresh does not
* re-submit the form). However, if 'rebuild' has been set to TRUE, then a new
* copy of the form is immediately built and sent to the browser, instead of a
* redirect. This is used for multi-step forms, such as wizards and
* confirmation forms. Normally, self::$rebuild is set by a submit handler,
* since it is usually logic within a submit handler that determines whether a
* form is done or requires another step. However, a validation handler may
* already set self::$rebuild to cause the form processing to bypass submit
* handlers and rebuild the form instead, even if there are no validation
* errors.
*
* This property is uncacheable.
*
* @see self::setRebuild()
*
* @var bool
*/
protected $rebuild = FALSE;
/**
* Determines if only safe element value callbacks are called.
*
* If set to TRUE the form will skip calling form element value callbacks,
* except for a select list of callbacks provided by Drupal core that are
* known to be safe.
*
* This property is uncacheable.
*
* @see self::setInvalidToken()
*
* @var bool
*/
protected $invalidToken = FALSE;
/**
* The response object.
*
* Used when a form needs to return some kind of a
* \Symfony\Component\HttpFoundation\Response object, e.g., a
* \Symfony\Component\HttpFoundation\BinaryFileResponse when triggering a
* file download. If you use self::setRedirect() or self::setRedirectUrl(),
* it will be used to build a
* \Symfony\Component\HttpFoundation\RedirectResponse and will populate this
* key.
*
* @var \Symfony\Component\HttpFoundation\Response|null
*/
protected $response;
/**
* Used to redirect the form on submission.
*
* @see self::getRedirect()
*
* This property is uncacheable.
*
* @var \Drupal\Core\Url|\Symfony\Component\HttpFoundation\RedirectResponse|null
*/
protected $redirect;
/**
* If set to TRUE the form will NOT perform a redirect.
*
* Redirect will not be performed, even if self::$redirect is set.
*
* This property is uncacheable.
*
* @var bool
*/
protected $no_redirect;
/**
* The HTTP form method to use for finding the input for this form.
*
* May be 'POST' or 'GET'. Defaults to 'POST'. Note that 'GET' method forms do
* not use form ids so are always considered to be submitted, which can have
* unexpected effects. The 'GET' method should only be used on forms that do
* not change data, as that is exclusively the domain of 'POST.'
*
* This property is uncacheable.
*
* @var string
*/
protected $method = 'POST';
/**
* The HTTP method used by the request building or processing this form.
*
* May be any valid HTTP method. Defaults to 'GET', because even though
* $method is 'POST' for most forms, the form's initial build is usually
* performed as part of a GET request.
*
* This property is uncacheable.
*
* @var string
*/
protected $requestMethod = 'GET';
/**
* Determines if the unprocessed form structure is cached.
*
* If set to TRUE the original, unprocessed form structure will be cached,
* which allows the entire form to be rebuilt from cache. A typical form
* workflow involves two page requests; first, a form is built and rendered
* for the user to fill in. Then, the user fills the form in and submits it,
* triggering a second page request in which the form must be built and
* processed. By default, $form and $form_state are built from scratch during
* each of these page requests. Often, it is necessary or desired to persist
* the $form and $form_state variables from the initial page request to the
* one that processes the submission. 'cache' can be set to TRUE to do this.
* A prominent example is an Ajax-enabled form, in which
* \Drupal\Core\Render\Element\RenderElement::processAjaxForm()
* enables form caching for all forms that include an element with the #ajax
* property. (The Ajax handler has no way to build the form itself, so must
* rely on the cached version.) Note that the persistence of $form and
* $form_state happens automatically for (multi-step) forms having the
* self::$rebuild flag set, regardless of the value for self::$cache.
*
* @var bool
*/
protected $cache = FALSE;
/**
* If set to TRUE the form will NOT be cached, even if 'cache' is set.
*
* @var bool
*/
protected $no_cache;
/**
* An associative array of values submitted to the form.
*
* The validation functions and submit functions use this array for nearly all
* their decision making. (Note that #tree determines whether the values are a
* flat array or an array whose structure parallels the $form array. See
* \Drupal\Core\Render\Element\FormElement for more information.)
*
* This property is uncacheable.
*
* @var array
*/
protected $values = [];
/**
* An associative array of form value keys to be removed by cleanValues().
*
* Any values that are temporary but must still be displayed as values in
* the rendered form should be added to this array using addCleanValueKey().
* Initialized with internal Form API values.
*
* This property is uncacheable.
*
* @var array
*/
protected $cleanValueKeys = [
'form_id',
'form_token',
'form_build_id',
'op',
];
/**
* The array of values as they were submitted by the user.
*
* These are raw and unvalidated, so should not be used without a thorough
* understanding of security implications. In almost all cases, code should
* use the data in the 'values' array exclusively. The most common use of this
* key is for multi-step forms that need to clear some of the user input when
* setting 'rebuild'. The values correspond to \Drupal::request()->request or
* \Drupal::request()->query, depending on the 'method' chosen.
*
* This property is uncacheable.
*
* @var array|null
* The submitted user input array, or NULL if no input was submitted yet.
*/
protected $input;
/**
* If TRUE and the method is GET, a form_id is not necessary.
*
* This property is uncacheable.
*
* @var bool
*/
protected $always_process;
/**
* Indicates if a validation will be forced.
*
* Ordinarily, a form is only validated once, but there are times when a form
* is resubmitted internally and should be validated again. Setting this to
* TRUE will force that to happen. This is most likely to occur during Ajax
* operations.
*
* This property is uncacheable.
*
* @var bool
*/
protected $must_validate;
/**
* Indicates if the form was submitted programmatically.
*
* If TRUE, the form was submitted programmatically, usually invoked via
* \Drupal\Core\Form\FormBuilderInterface::submitForm(). Defaults to FALSE.
*
* @var bool
*/
protected $programmed = FALSE;
/**
* Indicates if programmatic form submissions bypasses #access check.
*
* If TRUE, programmatic form submissions are processed without taking #access
* into account. Set this to FALSE when submitting a form programmatically
* with values that may have been input by the user executing the current
* request; this will cause #access to be respected as it would on a normal
* form submission. Defaults to TRUE.
*
* @var bool
*/
protected $programmed_bypass_access_check = TRUE;
/**
* Indicates correct form submission.
*
* TRUE signifies correct form submission. This is always TRUE for programmed
* forms coming from \Drupal\Core\Form\FormBuilderInterface::submitForm() (see
* 'programmed' key), or if the form_id coming from the
* \Drupal::request()->request data is set and matches the current form_id.
*
* @var bool
*/
protected $process_input;
/**
* If TRUE, the form has been submitted. Defaults to FALSE.
*
* This property is uncacheable.
*
* @var bool
*/
protected $submitted = FALSE;
/**
* If TRUE, the form was submitted and has been processed and executed.
*
* This property is uncacheable.
*
* @var bool
*/
protected $executed = FALSE;
/**
* The form element that triggered submission.
*
* This may or may not be a button (in the case of Ajax forms). This key is
* often used to distinguish between various buttons in a submit handler, and
* is also used in Ajax handlers.
*
* This property is uncacheable.
*
* @var array|null
*/
protected $triggering_element;
/**
* Indicates a file element is present.
*
* If TRUE, there is a file element and Form API will set the appropriate
* 'enctype' HTML attribute on the form.
*
* @var bool
*/
protected $has_file_element;
/**
* Contains references to details elements to render them within vertical tabs.
*
* This property is uncacheable.
*
* @var array
*/
protected $groups = [];
/**
* The storage.
*
* This is not a special key, and no specific support is provided for it in
* the Form API. By tradition it was the location where application-specific
* data was stored for communication between the submit, validation, and form
* builder functions, especially in a multi-step-style form. Form
* implementations may use any key(s) within $form_state (other than the keys
* listed here and other reserved ones used by Form API internals) for this
* kind of storage. The recommended way to ensure that the chosen key doesn't
* conflict with ones used by the Form API or other modules is to use the
* module name as the key name or a prefix for the key name. For example, the
* entity form classes use $this->entity in entity forms, or
* $form_state->getFormObject()->getEntity() outside the controller, to store
* information about the entity being edited, and this information stays
* available across successive clicks of the "Preview" button (if available)
* as well as when the "Save" button is finally clicked.
*
* @var array
*/
protected $storage = [];
/**
* A list containing copies of all submit and button elements in the form.
*
* This property is uncacheable.
*
* @var array
*/
protected $buttons = [];
/**
* Holds temporary data accessible during the current page request only.
*
* All $form_state properties that are not reserved keys (see
* other properties marked as uncacheable) persist throughout a multistep form
* sequence. Form API provides this key for modules to communicate information
* across form-related functions during a single page request. It may be used
* to temporarily save data that does not need to or should not be cached
* during the whole form workflow; e.g., data that needs to be accessed during
* the current form build process only. There is no use-case for this
* functionality in Drupal core.
*
* This property is uncacheable.
*
* @var array
*/
protected $temporary = [];
/**
* Tracks if the form has finished validation.
*
* This property is uncacheable.
*
* @var bool
*/
protected $validation_complete = FALSE;
/**
* Contains errors for this form.
*
* This property is uncacheable.
*
* @var array
*/
protected $errors = [];
/**
* Stores which errors should be limited during validation.
*
* An array of "sections" within which user input must be valid. If the
* element is within one of these sections, the error must be recorded.
* Otherwise, it can be suppressed. self::$limit_validation_errors can be an
* empty array, in which case all errors are suppressed. For example, a
* "Previous" button might want its submit action to be triggered even if none
* of the submitted values are valid.
*
* This property is uncacheable.
*
* @var array|null
*/
protected $limit_validation_errors;
/**
* Stores the gathered validation handlers.
*
* This property is uncacheable.
*
* @var array
*/
protected $validate_handlers = [];
/**
* Stores the gathered submission handlers.
*
* This property is uncacheable.
*
* @var array
*/
protected $submit_handlers = [];
/**
* {@inheritdoc}
*/
public function setFormState(array $form_state_additions) {
foreach ($form_state_additions as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
else {
$this->set($key, $value);
}
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setAlwaysProcess($always_process = TRUE) {
$this->always_process = (bool) $always_process;
return $this;
}
/**
* {@inheritdoc}
*/
public function getAlwaysProcess() {
return $this->always_process;
}
/**
* {@inheritdoc}
*/
public function setButtons(array $buttons) {
$this->buttons = $buttons;
return $this;
}
/**
* {@inheritdoc}
*/
public function getButtons() {
return $this->buttons;
}
/**
* {@inheritdoc}
*/
public function setCached($cache = TRUE) {
// Persisting $form_state is a side-effect disallowed during a "safe" HTTP
// method.
if ($cache && $this->isRequestMethodSafe()) {
throw new \LogicException(sprintf('Form state caching on %s requests is not allowed.', $this->requestMethod));
}
$this->cache = (bool) $cache;
return $this;
}
/**
* {@inheritdoc}
*/
public function isCached() {
return empty($this->no_cache) && $this->cache;
}
/**
* {@inheritdoc}
*/
public function disableCache() {
$this->no_cache = TRUE;
return $this;
}
/**
* {@inheritdoc}
*/
public function setExecuted() {
$this->executed = TRUE;
return $this;
}
/**
* {@inheritdoc}
*/
public function isExecuted() {
return $this->executed;
}
/**
* {@inheritdoc}
*/
public function setGroups(array $groups) {
$this->groups = $groups;
return $this;
}
/**
* {@inheritdoc}
*/
public function &getGroups() {
return $this->groups;
}
/**
* {@inheritdoc}
*/
public function setHasFileElement($has_file_element = TRUE) {
$this->has_file_element = (bool) $has_file_element;
return $this;
}
/**
* {@inheritdoc}
*/
public function hasFileElement() {
return $this->has_file_element;
}
/**
* {@inheritdoc}
*/
public function setLimitValidationErrors($limit_validation_errors) {
$this->limit_validation_errors = $limit_validation_errors;
return $this;
}
/**
* {@inheritdoc}
*/
public function getLimitValidationErrors() {
return $this->limit_validation_errors;
}
/**
* {@inheritdoc}
*/
public function setMethod($method) {
$this->method = strtoupper($method);
return $this;
}
/**
* {@inheritdoc}
*/
public function isMethodType($method_type) {
return $this->method === strtoupper($method_type);
}
/**
* {@inheritdoc}
*/
public function setRequestMethod($method) {
$this->requestMethod = strtoupper($method);
return $this;
}
/**
* Checks whether the request method is a "safe" HTTP method.
*
* Link below defines GET and HEAD as "safe" methods, meaning they SHOULD NOT
* have side-effects, such as persisting $form_state changes.
*
* @return bool
*
* @see \Symfony\Component\HttpFoundation\Request::isMethodSafe()
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
*/
protected function isRequestMethodSafe() {
return in_array($this->requestMethod, [
'GET',
'HEAD',
]);
}
/**
* {@inheritdoc}
*/
public function setValidationEnforced($must_validate = TRUE) {
$this->must_validate = (bool) $must_validate;
return $this;
}
/**
* {@inheritdoc}
*/
public function isValidationEnforced() {
return $this->must_validate;
}
/**
* {@inheritdoc}
*/
public function disableRedirect($no_redirect = TRUE) {
$this->no_redirect = (bool) $no_redirect;
return $this;
}
/**
* {@inheritdoc}
*/
public function isRedirectDisabled() {
return $this->no_redirect;
}
/**
* {@inheritdoc}
*/
public function setProcessInput($process_input = TRUE) {
$this->process_input = (bool) $process_input;
return $this;
}
/**
* {@inheritdoc}
*/
public function isProcessingInput() {
return $this->process_input;
}
/**
* {@inheritdoc}
*/
public function setProgrammed($programmed = TRUE) {
$this->programmed = (bool) $programmed;
return $this;
}
/**
* {@inheritdoc}
*/
public function isProgrammed() {
return $this->programmed;
}
/**
* {@inheritdoc}
*/
public function setProgrammedBypassAccessCheck($programmed_bypass_access_check = TRUE) {
$this->programmed_bypass_access_check = (bool) $programmed_bypass_access_check;
return $this;
}
/**
* {@inheritdoc}
*/
public function isBypassingProgrammedAccessChecks() {
return $this->programmed_bypass_access_check;
}
/**
* {@inheritdoc}
*/
public function setRebuildInfo(array $rebuild_info) {
$this->rebuild_info = $rebuild_info;
return $this;
}
/**
* {@inheritdoc}
*/
public function getRebuildInfo() {
return $this->rebuild_info;
}
/**
* {@inheritdoc}
*/
public function addRebuildInfo($property, $value) {
$rebuild_info = $this->getRebuildInfo();
$rebuild_info[$property] = $value;
$this->setRebuildInfo($rebuild_info);
return $this;
}
/**
* {@inheritdoc}
*/
public function setStorage(array $storage) {
$this->storage = $storage;
return $this;
}
/**
* {@inheritdoc}
*/
public function &getStorage() {
return $this->storage;
}
/**
* {@inheritdoc}
*/
public function setSubmitHandlers(array $submit_handlers) {
$this->submit_handlers = $submit_handlers;
return $this;
}
/**
* {@inheritdoc}
*/
public function getSubmitHandlers() {
return $this->submit_handlers;
}
/**
* {@inheritdoc}
*/
public function setSubmitted() {
$this->submitted = TRUE;
return $this;
}
/**
* {@inheritdoc}
*/
public function isSubmitted() {
return $this->submitted;
}
/**
* {@inheritdoc}
*/
public function setTemporary(array $temporary) {
$this->temporary = $temporary;
return $this;
}
/**
* {@inheritdoc}
*/
public function getTemporary() {
return $this->temporary;
}
/**
* {@inheritdoc}
*/
public function &getTemporaryValue($key) {
$value =& NestedArray::getValue($this->temporary, (array) $key);
return $value;
}
/**
* {@inheritdoc}
*/
public function setTemporaryValue($key, $value) {
NestedArray::setValue($this->temporary, (array) $key, $value, TRUE);
return $this;
}
/**
* {@inheritdoc}
*/
public function hasTemporaryValue($key) {
$exists = NULL;
NestedArray::getValue($this->temporary, (array) $key, $exists);
return $exists;
}
/**
* {@inheritdoc}
*/
public function setTriggeringElement($triggering_element) {
$this->triggering_element = $triggering_element;
return $this;
}
/**
* {@inheritdoc}
*/
public function &getTriggeringElement() {
return $this->triggering_element;
}
/**
* {@inheritdoc}
*/
public function setValidateHandlers(array $validate_handlers) {
$this->validate_handlers = $validate_handlers;
return $this;
}
/**
* {@inheritdoc}
*/
public function getValidateHandlers() {
return $this->validate_handlers;
}
/**
* {@inheritdoc}
*/
public function setValidationComplete($validation_complete = TRUE) {
$this->validation_complete = (bool) $validation_complete;
return $this;
}
/**
* {@inheritdoc}
*/
public function isValidationComplete() {
return $this->validation_complete;
}
/**
* {@inheritdoc}
*/
public function loadInclude($module, $type, $name = NULL) {
if (!isset($name)) {
$name = $module;
}
$build_info = $this->getBuildInfo();
if (!isset($build_info['files']["{$module}:{$name}.{$type}"])) {
// Only add successfully included files to the form state.
if ($result = $this->moduleLoadInclude($module, $type, $name)) {
$build_info['files']["{$module}:{$name}.{$type}"] = [
'type' => $type,
'module' => $module,
'name' => $name,
];
$this->setBuildInfo($build_info);
return $result;
}
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function getCacheableArray() {
return [
'build_info' => $this->getBuildInfo(),
'response' => $this->getResponse(),
'programmed' => $this->isProgrammed(),
'programmed_bypass_access_check' => $this->isBypassingProgrammedAccessChecks(),
'process_input' => $this->isProcessingInput(),
'has_file_element' => $this->hasFileElement(),
'storage' => $this->getStorage(),
// Use the properties directly, since self::isCached() combines them and
// cannot be relied upon.
'cache' => $this->cache,
'no_cache' => $this->no_cache,
];
}
/**
* {@inheritdoc}
*/
public function setCompleteForm(array &$complete_form) {
$this->complete_form =& $complete_form;
return $this;
}
/**
* {@inheritdoc}
*/
public function &getCompleteForm() {
return $this->complete_form;
}
/**
* {@inheritdoc}
*/
public function &get($property) {
$value =& NestedArray::getValue($this->storage, (array) $property);
return $value;
}
/**
* {@inheritdoc}
*/
public function set($property, $value) {
NestedArray::setValue($this->storage, (array) $property, $value, TRUE);
return $this;
}
/**
* {@inheritdoc}
*/
public function has($property) {
$exists = NULL;
NestedArray::getValue($this->storage, (array) $property, $exists);
return $exists;
}
/**
* {@inheritdoc}
*/
public function setBuildInfo(array $build_info) {
$this->build_info = $build_info;
return $this;
}
/**
* {@inheritdoc}
*/
public function getBuildInfo() {
return $this->build_info;
}
/**
* {@inheritdoc}
*/
public function addBuildInfo($property, $value) {
$build_info = $this->getBuildInfo();
$build_info[$property] = $value;
$this->setBuildInfo($build_info);
return $this;
}
/**
* {@inheritdoc}
*/
public function &getUserInput() {
return $this->input;
}
/**
* {@inheritdoc}
*/
public function setUserInput(array $user_input) {
$this->input = $user_input;
return $this;
}
/**
* {@inheritdoc}
*/
public function &getValues() {
return $this->values;
}
/**
* {@inheritdoc}
*/
public function setResponse(Response $response) {
$this->response = $response;
return $this;
}
/**
* {@inheritdoc}
*/
public function getResponse() {
return $this->response;
}
/**
* {@inheritdoc}
*/
public function setRedirect($route_name, array $route_parameters = [], array $options = []) {
$url = new Url($route_name, $route_parameters, $options);
return $this->setRedirectUrl($url);
}
/**
* {@inheritdoc}
*/
public function setRedirectUrl(Url $url) {
$this->redirect = $url;
return $this;
}
/**
* {@inheritdoc}
*/
public function getRedirect() {
// Skip redirection for form submissions invoked via
// \Drupal\Core\Form\FormBuilderInterface::submitForm().
if ($this->isProgrammed()) {
return FALSE;
}
// Skip redirection if rebuild is activated.
if ($this->isRebuilding()) {
return FALSE;
}
// Skip redirection if it was explicitly disallowed.
if ($this->isRedirectDisabled()) {
return FALSE;
}
return $this->redirect;
}
/**
* Sets the global status of errors.
*
* @param bool $errors
* TRUE if any form has any errors, FALSE otherwise.
*/
protected static function setAnyErrors($errors = TRUE) {
static::$anyErrors = $errors;
}
/**
* {@inheritdoc}
*/
public static function hasAnyErrors() {
return static::$anyErrors;
}
/**
* {@inheritdoc}
*/
public function setErrorByName($name, $message = '') {
if ($this->isValidationComplete()) {
throw new \LogicException('Form errors cannot be set after form validation has finished.');
}
$errors = $this->getErrors();
if (!isset($errors[$name])) {
$record = TRUE;
$limit_validation_errors = $this->getLimitValidationErrors();
if ($limit_validation_errors !== NULL) {
$record = FALSE;
foreach ($limit_validation_errors as $section) {
// Exploding by '][' reconstructs the element's #parents. If the
// reconstructed #parents begin with the same keys as the specified
// section, then the element's values are within the part of
// $form_state->getValues() that the clicked button requires to be
// valid, so errors for this element must be recorded. As the exploded
// array will all be strings, we need to cast every value of the
// section array to string.
if (array_slice(explode('][', $name), 0, count($section)) === array_map('strval', $section)) {
$record = TRUE;
break;
}
}
}
if ($record) {
$errors[$name] = $message;
$this->errors = $errors;
static::setAnyErrors();
}
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setError(array &$element, $message = '') {
$this->setErrorByName(implode('][', $element['#parents']), $message);
return $this;
}
/**
* {@inheritdoc}
*/
public function clearErrors() {
$this->errors = [];
static::setAnyErrors(FALSE);
}
/**
* {@inheritdoc}
*/
public function getError(array $element) {
if ($errors = $this->getErrors()) {
$parents = [];
foreach ($element['#parents'] as $parent) {
$parents[] = $parent;
$key = implode('][', $parents);
if (isset($errors[$key])) {
return $errors[$key];
}
}
}
}
/**
* {@inheritdoc}
*/
public function getErrors() {
return $this->errors;
}
/**
* {@inheritdoc}
*/
public function setRebuild($rebuild = TRUE) {
$this->rebuild = $rebuild;
return $this;
}
/**
* {@inheritdoc}
*/
public function isRebuilding() {
return $this->rebuild;
}
/**
* {@inheritdoc}
*/
public function prepareCallback($callback) {
if (is_string($callback) && substr($callback, 0, 2) == '::') {
$callback = [
$this->getFormObject(),
substr($callback, 2),
];
}
return $callback;
}
/**
* {@inheritdoc}
*/
public function setFormObject(FormInterface $form_object) {
$this->addBuildInfo('callback_object', $form_object);
return $this;
}
/**
* {@inheritdoc}
*/
public function getFormObject() {
return $this->getBuildInfo()['callback_object'];
}
/**
* {@inheritdoc}
*/
public function getCleanValueKeys() {
return $this->cleanValueKeys;
}
/**
* {@inheritdoc}
*/
public function setCleanValueKeys(array $cleanValueKeys) {
$this->cleanValueKeys = $cleanValueKeys;
return $this;
}
/**
* {@inheritdoc}
*/
public function addCleanValueKey($cleanValueKey) {
$keys = $this->getCleanValueKeys();
$this->setCleanValueKeys(array_merge((array) $keys, [
$cleanValueKey,
]));
return $this;
}
/**
* {@inheritdoc}
*/
public function cleanValues() {
foreach ($this->getCleanValueKeys() as $value) {
$this->unsetValue($value);
}
// Remove button values.
// \Drupal::formBuilder()->doBuildForm() collects all button elements in a
// form. We remove the button value separately for each button element.
foreach ($this->getButtons() as $button) {
// Remove this button's value from the submitted form values by finding
// the value corresponding to this button.
// We iterate over the #parents of this button and move a reference to
// each parent in self::getValues(). For example, if #parents is:
// @code
// array('foo', 'bar', 'baz')
// @endcode
// then the corresponding self::getValues() part will look like this:
// @code
// array(
// 'foo' => array(
// 'bar' => array(
// 'baz' => 'button_value',
// ),
// ),
// )
// @endcode
// We start by (re)moving 'baz' to $last_parent, so we are able unset it
// at the end of the iteration. Initially, $values will contain a
// reference to self::getValues(), but in the iteration we move the
// reference to self::getValue('foo'), and finally to
// self::getValue(array('foo', 'bar')), which is the level where we
// can unset 'baz' (that is stored in $last_parent).
$parents = $button['#parents'];
$last_parent = array_pop($parents);
$key_exists = NULL;
$values =& NestedArray::getValue($this->getValues(), $parents, $key_exists);
if ($key_exists && is_array($values)) {
unset($values[$last_parent]);
}
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setInvalidToken($invalid_token) {
$this->invalidToken = (bool) $invalid_token;
return $this;
}
/**
* {@inheritdoc}
*/
public function hasInvalidToken() {
return $this->invalidToken;
}
/**
* Wraps ModuleHandler::loadInclude().
*/
protected function moduleLoadInclude($module, $type, $name = NULL) {
return \Drupal::moduleHandler()->loadInclude($module, $type, $name);
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
FormState::$always_process | protected | property | If TRUE and the method is GET, a form_id is not necessary. | |
FormState::$anyErrors | protected static | property | Tracks if any errors have been set on any form. | |
FormState::$build_info | protected | property | An associative array of information stored by Form API. | |
FormState::$buttons | protected | property | A list containing copies of all submit and button elements in the form. | |
FormState::$cache | protected | property | Determines if the unprocessed form structure is cached. | |
FormState::$cleanValueKeys | protected | property | An associative array of form value keys to be removed by cleanValues(). | |
FormState::$complete_form | protected | property | The complete form structure. | |
FormState::$errors | protected | property | Contains errors for this form. | |
FormState::$executed | protected | property | If TRUE, the form was submitted and has been processed and executed. | |
FormState::$groups | protected | property | Contains references to details elements to render them within vertical tabs. | |
FormState::$has_file_element | protected | property | Indicates a file element is present. | |
FormState::$input | protected | property | The array of values as they were submitted by the user. | |
FormState::$invalidToken | protected | property | Determines if only safe element value callbacks are called. | |
FormState::$limit_validation_errors | protected | property | Stores which errors should be limited during validation. | |
FormState::$method | protected | property | The HTTP form method to use for finding the input for this form. | |
FormState::$must_validate | protected | property | Indicates if a validation will be forced. | |
FormState::$no_cache | protected | property | If set to TRUE the form will NOT be cached, even if 'cache' is set. | |
FormState::$no_redirect | protected | property | If set to TRUE the form will NOT perform a redirect. | |
FormState::$process_input | protected | property | Indicates correct form submission. | |
FormState::$programmed | protected | property | Indicates if the form was submitted programmatically. | |
FormState::$programmed_bypass_access_check | protected | property | Indicates if programmatic form submissions bypasses #access check. | |
FormState::$rebuild | protected | property | Determines whether the form is rebuilt. | |
FormState::$rebuild_info | protected | property | Similar to self::$build_info. | |
FormState::$redirect | protected | property | Used to redirect the form on submission. | |
FormState::$requestMethod | protected | property | The HTTP method used by the request building or processing this form. | |
FormState::$response | protected | property | The response object. | |
FormState::$storage | protected | property | The storage. | |
FormState::$submitted | protected | property | If TRUE, the form has been submitted. Defaults to FALSE. | |
FormState::$submit_handlers | protected | property | Stores the gathered submission handlers. | |
FormState::$temporary | protected | property | Holds temporary data accessible during the current page request only. | |
FormState::$triggering_element | protected | property | The form element that triggered submission. | |
FormState::$validate_handlers | protected | property | Stores the gathered validation handlers. | |
FormState::$validation_complete | protected | property | Tracks if the form has finished validation. | |
FormState::$values | protected | property | An associative array of values submitted to the form. | |
FormState::addBuildInfo | public | function | Adds a value to the build info. | Overrides FormStateInterface::addBuildInfo |
FormState::addCleanValueKey | public | function | Adds a key to the array of form values that will be cleaned. | Overrides FormStateInterface::addCleanValueKey |
FormState::addRebuildInfo | public | function | Adds a value to the rebuild info. | Overrides FormStateInterface::addRebuildInfo |
FormState::cleanValues | public | function | Removes internal Form API elements and buttons from submitted form values. | Overrides FormStateInterface::cleanValues |
FormState::clearErrors | public | function | Clears all errors against all form elements made by self::setErrorByName(). | Overrides FormStateInterface::clearErrors |
FormState::disableCache | public | function | Prevents the form from being cached. | Overrides FormStateInterface::disableCache |
FormState::disableRedirect | public | function | Prevents the form from redirecting. | Overrides FormStateInterface::disableRedirect |
FormState::get | public | function | Gets any arbitrary property. | Overrides FormStateInterface::get |
FormState::getAlwaysProcess | public | function | Determines if this form should always be processed. | Overrides FormStateInterface::getAlwaysProcess |
FormState::getBuildInfo | public | function | Returns the build info for the form. | Overrides FormStateInterface::getBuildInfo |
FormState::getButtons | public | function | Returns the submit and button elements for the form. | Overrides FormStateInterface::getButtons |
FormState::getCacheableArray | public | function | Returns an array representation of the cacheable portion of the form state. | Overrides FormStateInterface::getCacheableArray |
FormState::getCleanValueKeys | public | function | Gets the keys of the form values that will be cleaned. | Overrides FormStateInterface::getCleanValueKeys |
FormState::getCompleteForm | public | function | Returns a reference to the complete form array. | Overrides FormStateInterface::getCompleteForm |
FormState::getError | public | function | Returns the error message filed against the given form element. | Overrides FormStateInterface::getError |
FormState::getErrors | public | function | Returns an associative array of all errors. | Overrides FormStateInterface::getErrors |
FormState::getFormObject | public | function | Returns the form object that is responsible for building this form. | Overrides FormStateInterface::getFormObject |
FormState::getGroups | public | function | Returns references to details elements to render them within vertical tabs. | Overrides FormStateInterface::getGroups |
FormState::getLimitValidationErrors | public | function | Retrieves the limited validation error sections. | Overrides FormStateInterface::getLimitValidationErrors |
FormState::getRebuildInfo | public | function | Gets the rebuild info. | Overrides FormStateInterface::getRebuildInfo |
FormState::getRedirect | public | function | Gets the value to use for redirecting after the form has been executed. | Overrides FormStateInterface::getRedirect |
FormState::getResponse | public | function | Gets a response for this form. | Overrides FormStateInterface::getResponse |
FormState::getStorage | public | function | Returns the entire set of arbitrary data. | Overrides FormStateInterface::getStorage |
FormState::getSubmitHandlers | public | function | Gets the submit handlers. | Overrides FormStateInterface::getSubmitHandlers |
FormState::getTemporary | public | function | Gets temporary data. | Overrides FormStateInterface::getTemporary |
FormState::getTemporaryValue | public | function | Gets an arbitrary value from temporary storage. | Overrides FormStateInterface::getTemporaryValue |
FormState::getTriggeringElement | public | function | Gets the form element that triggered submission. | Overrides FormStateInterface::getTriggeringElement |
FormState::getUserInput | public | function | Returns the form values as they were submitted by the user. | Overrides FormStateInterface::getUserInput |
FormState::getValidateHandlers | public | function | Gets the validate handlers. | Overrides FormStateInterface::getValidateHandlers |
FormState::getValues | public | function | Implements \Drupal\Core\Form\FormStateInterface::getValues() | Overrides FormStateValuesTrait::getValues |
FormState::has | public | function | Determines if an arbitrary property is present. | Overrides FormStateInterface::has |
FormState::hasAnyErrors | public static | function | Determines if any forms have any errors. | Overrides FormStateInterface::hasAnyErrors |
FormState::hasFileElement | public | function | Returns whether this form has a file element. | Overrides FormStateInterface::hasFileElement |
FormState::hasInvalidToken | public | function | Determines if the form has an invalid token. | Overrides FormStateInterface::hasInvalidToken |
FormState::hasTemporaryValue | public | function | Determines if a temporary value is present. | Overrides FormStateInterface::hasTemporaryValue |
FormState::isBypassingProgrammedAccessChecks | public | function | Determines if this form submission should bypass #access. | Overrides FormStateInterface::isBypassingProgrammedAccessChecks |
FormState::isCached | public | function | Determines if the form should be cached. | Overrides FormStateInterface::isCached |
FormState::isExecuted | public | function | Determines if the form was submitted and has been processed and executed. | Overrides FormStateInterface::isExecuted |
FormState::isMethodType | public | function | Returns the HTTP form method. | Overrides FormStateInterface::isMethodType |
FormState::isProcessingInput | public | function | Determines if the form input will be processed. | Overrides FormStateInterface::isProcessingInput |
FormState::isProgrammed | public | function | Returns if this form was submitted programmatically. | Overrides FormStateInterface::isProgrammed |
FormState::isRebuilding | public | function | Determines if the form should be rebuilt after processing. | Overrides FormStateInterface::isRebuilding |
FormState::isRedirectDisabled | public | function | Determines if redirecting has been prevented. | Overrides FormStateInterface::isRedirectDisabled |
FormState::isRequestMethodSafe | protected | function | Checks whether the request method is a "safe" HTTP method. | |
FormState::isSubmitted | public | function | Determines if the form has been submitted. | Overrides FormStateInterface::isSubmitted |
FormState::isValidationComplete | public | function | Determines if validation has been completed. | Overrides FormStateInterface::isValidationComplete |
FormState::isValidationEnforced | public | function | Checks if validation is enforced. | Overrides FormStateInterface::isValidationEnforced |
FormState::loadInclude | public | function | Ensures an include file is loaded whenever the form is processed. | Overrides FormStateInterface::loadInclude |
FormState::moduleLoadInclude | protected | function | Wraps ModuleHandler::loadInclude(). | |
FormState::prepareCallback | public | function | Converts support notations for a form callback to a valid callable. | Overrides FormStateInterface::prepareCallback |
FormState::set | public | function | Sets a value to an arbitrary property. | Overrides FormStateInterface::set |
FormState::setAlwaysProcess | public | function | Sets this form to always be processed. | Overrides FormStateInterface::setAlwaysProcess |
FormState::setAnyErrors | protected static | function | Sets the global status of errors. | |
FormState::setBuildInfo | public | function | Sets the build info for the form. | Overrides FormStateInterface::setBuildInfo |
FormState::setButtons | public | function | Stores the submit and button elements for the form. | Overrides FormStateInterface::setButtons |
FormState::setCached | public | function | Sets this form to be cached. | Overrides FormStateInterface::setCached |
FormState::setCleanValueKeys | public | function | Sets the keys of the form values that will be cleaned. | Overrides FormStateInterface::setCleanValueKeys |
FormState::setCompleteForm | public | function | Stores the complete form array. | Overrides FormStateInterface::setCompleteForm |
FormState::setError | public | function | Flags an element as having an error. | Overrides FormStateInterface::setError |
FormState::setErrorByName | public | function | Files an error against a form element. | Overrides FormStateInterface::setErrorByName |
FormState::setExecuted | public | function | Sets that the form was submitted and has been processed and executed. | Overrides FormStateInterface::setExecuted |
FormState::setFormObject | public | function | Sets the form object that is responsible for building this form. | Overrides FormStateInterface::setFormObject |
FormState::setFormState | public | function | Sets the value of the form state. | Overrides FormStateInterface::setFormState |
FormState::setGroups | public | function | Sets references to details elements to render them within vertical tabs. | Overrides FormStateInterface::setGroups |
FormState::setHasFileElement | public | function | Sets that this form has a file element. | Overrides FormStateInterface::setHasFileElement |
FormState::setInvalidToken | public | function | Flags the form state as having or not an invalid token. | Overrides FormStateInterface::setInvalidToken |
FormState::setLimitValidationErrors | public | function | Sets the limited validation error sections. | Overrides FormStateInterface::setLimitValidationErrors |
FormState::setMethod | public | function | Sets the HTTP method to use for the form's submission. | Overrides FormStateInterface::setMethod |
FormState::setProcessInput | public | function | Sets that the form should process input. | Overrides FormStateInterface::setProcessInput |
FormState::setProgrammed | public | function | Sets that this form was submitted programmatically. | Overrides FormStateInterface::setProgrammed |
FormState::setProgrammedBypassAccessCheck | public | function | Sets if this form submission should bypass #access. | Overrides FormStateInterface::setProgrammedBypassAccessCheck |
FormState::setRebuild | public | function | Sets the form to be rebuilt after processing. | Overrides FormStateInterface::setRebuild |
FormState::setRebuildInfo | public | function | Sets the rebuild info. | Overrides FormStateInterface::setRebuildInfo |
FormState::setRedirect | public | function | Sets the redirect for the form. | Overrides FormStateInterface::setRedirect |
FormState::setRedirectUrl | public | function | Sets the redirect URL for the form. | Overrides FormStateInterface::setRedirectUrl |
FormState::setRequestMethod | public | function | Sets the HTTP method used by the request that is building the form. | Overrides FormStateInterface::setRequestMethod |
FormState::setResponse | public | function | Sets a response for this form. | Overrides FormStateInterface::setResponse |
FormState::setStorage | public | function | Sets the entire set of arbitrary data. | Overrides FormStateInterface::setStorage |
FormState::setSubmitHandlers | public | function | Sets the submit handlers. | Overrides FormStateInterface::setSubmitHandlers |
FormState::setSubmitted | public | function | Sets that the form has been submitted. | Overrides FormStateInterface::setSubmitted |
FormState::setTemporary | public | function | Sets temporary data. | Overrides FormStateInterface::setTemporary |
FormState::setTemporaryValue | public | function | Sets an arbitrary value in temporary storage. | Overrides FormStateInterface::setTemporaryValue |
FormState::setTriggeringElement | public | function | Sets the form element that triggered submission. | Overrides FormStateInterface::setTriggeringElement |
FormState::setUserInput | public | function | Sets the form values as though they were submitted by a user. | Overrides FormStateInterface::setUserInput |
FormState::setValidateHandlers | public | function | Sets the validate handlers. | Overrides FormStateInterface::setValidateHandlers |
FormState::setValidationComplete | public | function | Sets that validation has been completed. | Overrides FormStateInterface::setValidationComplete |
FormState::setValidationEnforced | public | function | Enforces that validation is run. | Overrides FormStateInterface::setValidationEnforced |
FormStateValuesTrait::getValue | public | function | Implements \Drupal\Core\Form\FormStateInterface::getValue() | |
FormStateValuesTrait::hasValue | public | function | Implements \Drupal\Core\Form\FormStateInterface::hasValue() | |
FormStateValuesTrait::isValueEmpty | public | function | Implements \Drupal\Core\Form\FormStateInterface::isValueEmpty() | |
FormStateValuesTrait::setValue | public | function | Implements \Drupal\Core\Form\FormStateInterface::setValue() | |
FormStateValuesTrait::setValueForElement | public | function | Implements \Drupal\Core\Form\FormStateInterface::setValueForElement() | |
FormStateValuesTrait::setValues | public | function | Implements \Drupal\Core\Form\FormStateInterface::setValues() | |
FormStateValuesTrait::unsetValue | public | function | Implements \Drupal\Core\Form\FormStateInterface::unsetValue() |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.