You are here

public static function FieldCollectionEmbedWidget::validate in Field collection 8

Same name and namespace in other branches
  1. 8.3 src/Plugin/Field/FieldWidget/FieldCollectionEmbedWidget.php \Drupal\field_collection\Plugin\Field\FieldWidget\FieldCollectionEmbedWidget::validate()

FAPI validation of an individual field collection element.

File

src/Plugin/Field/FieldWidget/FieldCollectionEmbedWidget.php, line 175

Class

FieldCollectionEmbedWidget
Plugin implementation of the 'field_collection_embed' widget.

Namespace

Drupal\field_collection\Plugin\Field\FieldWidget

Code

public static function validate($element, FormStateInterface $form_state, $form) {
  $field_parents = $element['#field_parents'];
  $field_name = $element['#field_name'];
  $field_state = static::getWidgetState($field_parents, $field_name, $form_state);
  $field_collection_item = $field_state['field_collection_item'][$element['#delta']];
  $display = entity_get_form_display('field_collection_item', $field_name, 'default');
  $display
    ->extractFormValues($field_collection_item, $element, $form_state);

  // Now validate required elements if the entity is not empty.
  if (!$field_collection_item
    ->isEmpty() && !empty($element['#field_collection_required_elements'])) {
    foreach ($element['#field_collection_required_elements'] as &$elements) {

      // Copied from \Drupal\Core\Form\FormValidator::doValidateForm().
      // #1676206: Modified to support options widget.
      if (isset($elements['#needs_validation'])) {
        $is_countable = is_array($elements['#value']) || $elements['#value'] instanceof \Countable;
        $is_empty_multiple = $is_countable && count($elements['#value']) == 0;

        // @todo: replace Unicode::strlen() with mb_substr() per
        // https://www.drupal.org/project/drupal/issues/2849669
        $is_empty_string = is_string($elements['#value']) && Unicode::strlen(trim($elements['#value'])) == 0;
        $is_empty_value = $elements['#value'] === 0;
        $is_empty_option = isset($elements['#options']['_none']) && $elements['#value'] == '_none';
        if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_option) {
          if (isset($elements['#required_error'])) {
            $form_state
              ->setError($elements, $elements['#required_error']);
          }
          else {
            if (isset($elements['#title'])) {
              $form_state
                ->setError($elements, t('@name field is required.', [
                '@name' => $elements['#title'],
              ]));
            }
            else {
              $form_state
                ->setError($elements);
            }
          }
        }
      }
    }
  }

  // Only if the form is being submitted, finish the collection entity and
  // prepare it for saving.
  if ($form_state
    ->isSubmitted() && !$form_state
    ->hasAnyErrors()) {

    // Load initial form values into $item, so any other form values below the
    // same parents are kept.
    $field = NestedArray::getValue($form_state
      ->getValues(), $element['#parents']);

    // Set the _weight if it is a multiple field.
    $element_widget = NestedArray::getValue($form, array_slice($element['#array_parents'], 0, -1));
    if (isset($element['_weight']) && $element_widget['#cardinality_multiple']) {
      $field['_weight'] = $element['_weight']['#value'];
    }

    // Put the field collection field in $field['field_collection_item'], so
    // it is saved with the host entity via FieldCollection->preSave() / field
    // API if it is not empty.
    $field['field_collection_item'] = $field_collection_item;
    $form_state
      ->setValue($element['#parents'], $field);
  }
}