public static function EntityAutocomplete::validateEntityAutocomplete

public static EntityAutocomplete::validateEntityAutocomplete(array &$element, FormStateInterface $form_state, array &$complete_form)

Form element validation handler for entity_autocomplete elements.

File

core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php, line 151

Class

EntityAutocomplete
Provides an entity autocomplete form element.

Namespace

Drupal\Core\Entity\Element

Code

public static function validateEntityAutocomplete(array &$element, FormStateInterface $form_state, array &$complete_form) {
  $value = NULL;

  if (!empty($element['#value'])) {
    $options = array(
      'target_type' => $element['#target_type'],
      'handler' => $element['#selection_handler'],
      'handler_settings' => $element['#selection_settings'],
    );
    /** @var /Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler */
    $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($options);
    $autocreate = (bool) $element['#autocreate'] && $handler instanceof SelectionWithAutocreateInterface;

    // GET forms might pass the validated data around on the next request, in
    // which case it will already be in the expected format.
    if (is_array($element['#value'])) {
      $value = $element['#value'];
    }
    else {
      $input_values = $element['#tags'] ? Tags::explode($element['#value']) : array($element['#value']);

      foreach ($input_values as $input) {
        $match = static::extractEntityIdFromAutocompleteInput($input);
        if ($match === NULL) {
          // Try to get a match from the input string when the user didn't use
          // the autocomplete but filled in a value manually.
          $match = static::matchEntityByTitle($handler, $input, $element, $form_state, !$autocreate);
        }

        if ($match !== NULL) {
          $value[] = array(
            'target_id' => $match,
          );
        }
        elseif ($autocreate) {
          /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface $handler */
          // Auto-create item. See an example of how this is handled in
          // \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::presave().
          $value[] = array(
            'entity' => $handler->createNewEntity($element['#target_type'], $element['#autocreate']['bundle'], $input, $element['#autocreate']['uid']),
          );
        }
      }
    }

    // Check that the referenced entities are valid, if needed.
    if ($element['#validate_reference'] && !empty($value)) {
      // Validate existing entities.
      $ids = array_reduce($value, function($return, $item) {
        if (isset($item['target_id'])) {
          $return[] = $item['target_id'];
        }
        return $return;
      });

      if ($ids) {
        $valid_ids = $handler->validateReferenceableEntities($ids);
        if ($invalid_ids = array_diff($ids, $valid_ids)) {
          foreach ($invalid_ids as $invalid_id) {
            $form_state->setError($element, t('The referenced entity (%type: %id) does not exist.', array('%type' => $element['#target_type'], '%id' => $invalid_id)));
          }
        }
      }

      // Validate newly created entities.
      $new_entities = array_reduce($value, function($return, $item) {
        if (isset($item['entity'])) {
          $return[] = $item['entity'];
        }
        return $return;
      });

      if ($new_entities) {
        if ($autocreate) {
          $valid_new_entities = $handler->validateReferenceableNewEntities($new_entities);
          $invalid_new_entities = array_diff_key($new_entities, $valid_new_entities);
        }
        else {
          // If the selection handler does not support referencing newly
          // created entities, all of them should be invalidated.
          $invalid_new_entities = $new_entities;
        }

        foreach ($invalid_new_entities as $entity) {
          /** @var \Drupal\Core\Entity\EntityInterface $entity */
          $form_state->setError($element, t('This entity (%type: %label) cannot be referenced.', array('%type' => $element['#target_type'], '%label' => $entity->label())));
        }
      }
    }

    // Use only the last value if the form element does not support multiple
    // matches (tags).
    if (!$element['#tags'] && !empty($value)) {
      $last_value = $value[count($value) - 1];
      $value = isset($last_value['target_id']) ? $last_value['target_id'] : $last_value;
    }
  }

  $form_state->setValueForElement($element, $value);
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!Element!EntityAutocomplete.php/function/EntityAutocomplete::validateEntityAutocomplete/8.1.x