diff core/lib/Drupal/Core/Field/WidgetBase.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 4c8ae668cc8c
children
line wrap: on
line diff
--- a/core/lib/Drupal/Core/Field/WidgetBase.php	Mon Apr 23 09:33:26 2018 +0100
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php	Mon Apr 23 09:46:53 2018 +0100
@@ -104,6 +104,19 @@
       $elements = $this->formMultipleElements($items, $form, $form_state);
     }
 
+    // Allow modules to alter the field multi-value widget form element.
+    // This hook can also be used for single-value fields.
+    $context = [
+      'form' => $form,
+      'widget' => $this,
+      'items' => $items,
+      'default' => $this->isDefaultValueWidget($form_state),
+    ];
+    \Drupal::moduleHandler()->alter([
+      'field_widget_multivalue_form',
+      'field_widget_multivalue_' . $this->getPluginId() . '_form',
+    ], $elements, $form_state, $context);
+
     // Populate the 'array_parents' information in $form_state->get('field')
     // after the form is built, so that we catch changes in the form structure
     // performed in alter() hooks.
@@ -410,21 +423,26 @@
       if (Element::isVisibleElement($element)) {
         $handles_multiple = $this->handlesMultipleValues();
 
-        $violations_by_delta = [];
+        $violations_by_delta = $item_list_violations = [];
         foreach ($violations as $violation) {
           // Separate violations by delta.
           $property_path = explode('.', $violation->getPropertyPath());
           $delta = array_shift($property_path);
-          $violations_by_delta[$delta][] = $violation;
+          if (is_numeric($delta)) {
+            $violations_by_delta[$delta][] = $violation;
+          }
+          // Violations at the ItemList level are not associated to any delta.
+          else {
+            $item_list_violations[] = $violation;
+          }
           $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,
-          // - or if the violations are at the ItemList level.
-          if ($handles_multiple || !is_numeric($delta)) {
+          // Pass violations to the main element if this is a multiple-value
+          // widget.
+          if ($handles_multiple) {
             $delta_element = $element;
           }
           // Otherwise, pass errors by delta to the corresponding sub-element.
@@ -440,6 +458,13 @@
             }
           }
         }
+
+        /** @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());
+        }
       }
     }
   }