function WidgetBase::flagErrors

Same name in other branches
  1. 9 core/lib/Drupal/Core/Field/WidgetBase.php \Drupal\Core\Field\WidgetBase::flagErrors()
  2. 8.9.x core/lib/Drupal/Core/Field/WidgetBase.php \Drupal\Core\Field\WidgetBase::flagErrors()
  3. 11.x core/lib/Drupal/Core/Field/WidgetBase.php \Drupal\Core\Field\WidgetBase::flagErrors()

Overrides WidgetBaseInterface::flagErrors

2 methods override WidgetBase::flagErrors()
FileWidget::flagErrors in core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php
Reports field-level validation errors against actual form elements.
LinkWidget::flagErrors in core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
Override the '%uri' message parameter, to ensure that 'internal:' URIs show a validation error message that doesn't mention that scheme.

File

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

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 (str_starts_with($error_path, $element_path)) {
                    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.