function WidgetBase::flagErrors

Same name and namespace in other branches
  1. 11.x core/lib/Drupal/Core/Field/WidgetBase.php \Drupal\Core\Field\WidgetBase::flagErrors()
  2. 10 core/lib/Drupal/Core/Field/WidgetBase.php \Drupal\Core\Field\WidgetBase::flagErrors()
  3. 8.9.x core/lib/Drupal/Core/Field/WidgetBase.php \Drupal\Core\Field\WidgetBase::flagErrors()
1 method overrides WidgetBase::flagErrors()
FileWidget::flagErrors in core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php
Reports field-level validation errors against actual form elements.

File

core/lib/Drupal/Core/Field/WidgetBase.php, line 419

Class

WidgetBase
Base class for 'Field widget' plugin implementations.

Namespace

Drupal\Core\Field

Code

public function flagErrors(FieldItemListInterface $items, ConstraintViolationListInterface $violations, array $form, FormStateInterface $form_state) {
  $field_name = $this->fieldDefinition
    ->getName();
  $field_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
  if ($violations->count()) {
    // Locate the correct element in the form.
    $element = NestedArray::getValue($form_state->getCompleteForm(), $field_state['array_parents']);
    // Do not report entity-level validation errors if Form API errors have
    // already been reported for the field.
    // @todo Field validation should not be run on fields with FAPI errors to
    //   begin with. See https://www.drupal.org/node/2070429.
    $element_path = implode('][', $element['#parents']);
    if ($reported_errors = $form_state->getErrors()) {
      foreach (array_keys($reported_errors) as $error_path) {
        if (strpos($error_path, $element_path) === 0) {
          return;
        }
      }
    }
    // Only set errors if the element is visible.
    if (Element::isVisibleElement($element)) {
      $handles_multiple = $this->handlesMultipleValues();
      $violations_by_delta = $item_list_violations = [];
      foreach ($violations as $violation) {
        $violation = new InternalViolation($violation);
        // Separate violations by delta.
        $property_path = explode('.', $violation->getPropertyPath());
        $delta = array_shift($property_path);
        if (is_numeric($delta)) {
          $violations_by_delta[$delta][] = $violation;
        }
        else {
          $item_list_violations[] = $violation;
        }
        // @todo Remove BC layer https://www.drupal.org/i/3307859 on PHP 8.2.
        $violation->arrayPropertyPath = $property_path;
      }
      /** @var \Symfony\Component\Validator\ConstraintViolationInterface[] $delta_violations */
      foreach ($violations_by_delta as $delta => $delta_violations) {
        // Pass violations to the main element if this is a multiple-value
        // widget.
        if ($handles_multiple) {
          $delta_element = $element;
        }
        else {
          $original_delta = $field_state['original_deltas'][$delta];
          $delta_element = $element[$original_delta];
        }
        foreach ($delta_violations as $violation) {
          $error_element = $this->errorElement($delta_element, $violation, $form, $form_state);
          if ($error_element !== FALSE) {
            $form_state->setError($error_element, $violation->getMessage());
          }
        }
      }
      /** @var \Symfony\Component\Validator\ConstraintViolationInterface[] $item_list_violations */
      // Pass violations to the main element without going through
      // errorElement() if the violations are at the ItemList level.
      foreach ($item_list_violations as $violation) {
        $form_state->setError($element, $violation->getMessage());
      }
    }
  }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.