You are here

function entity_translation_taxonomy_autocomplete_validate in Entity Translation 7

Form element validate handler for taxonomy term autocomplete element.

See also

taxonomy_autocomplete_validate()

1 string reference to 'entity_translation_taxonomy_autocomplete_validate'
entity_translation_field_widget_taxonomy_autocomplete_form_alter in ./entity_translation.taxonomy.inc
Implements hook_field_widget_WIDGET_TYPE_form_alter().

File

./entity_translation.taxonomy.inc, line 406
The taxonomy specific translation functions and hook implementations.

Code

function entity_translation_taxonomy_autocomplete_validate($element, &$form_state) {
  $value = array();
  list($id) = entity_extract_ids($element['#entity_type'], $element['#entity']);
  $is_new = !isset($id);

  // This is the language of the parent entity, that we will be applying to new
  // terms.
  $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
  $langcode = !empty($form_state['entity_translation']['form_langcode']) ? $form_state['entity_translation']['form_langcode'] : $parent_handler
    ->getActiveLanguage();

  // Handle in-place translation.
  if (_entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state)) {

    // The referenced terms cannot change, so we just need to collect their term
    // identifiers. We also build a map of the corresponding deltas for later
    // use.
    $deltas = array();
    foreach (element_children($element) as $delta) {
      $tid = $element[$delta]['#tid'];
      $deltas[$tid] = $delta;
      $value[$delta]['tid'] = $tid;
    }

    // Save term translations.
    $entity_type = 'taxonomy_term';
    $name_field = 'name_field';
    $source_langcode = $parent_handler
      ->getSourceLanguage();

    // This is a validation handler, so we must defer the actual save to the
    // submit phase.
    $terms_to_save =& $form_state['entity_translation']['taxonomy_autocomplete'][$element['#entity_type']][$id][$element['#field_name']];
    foreach (taxonomy_term_load_multiple(array_keys($deltas)) as $term) {

      // This is also the right context to perform validation.
      $term_translation = $element[$deltas[$term->tid]]['#value'];
      if (!$term_translation) {
        $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
        drupal_set_message(t('The translations for %field_label cannot be empty.', array(
          '%field_label' => $instance['label'],
        )), 'error', FALSE);
        continue;
      }
      $handler = entity_translation_get_handler($entity_type, $term);
      $translations = $handler
        ->getTranslations();
      $term_langcode = $handler
        ->getLanguage();
      $typed_langcode = $term_langcode != LANGUAGE_NONE ? $langcode : $term_langcode;

      // Create a new translation in the active language, if it is missing.
      if (!isset($translations->data[$typed_langcode]) && $typed_langcode != LANGUAGE_NONE) {
        $translation = array(
          'language' => $typed_langcode,
          'source' => $source_langcode,
          'uid' => $GLOBALS['user']->uid,
          'status' => 1,
          'created' => REQUEST_TIME,
          'changed' => REQUEST_TIME,
        );
        $translation_values = array(
          $name_field => array(
            $typed_langcode => array(
              array(
                'value' => $term_translation,
              ),
            ),
          ),
        );
        $handler
          ->setTranslation($translation, $translation_values);
        $terms_to_save[] = $term;
      }
      elseif ($term_translation != _entity_translation_taxonomy_label($term, $typed_langcode)) {
        $term->{$name_field}[$typed_langcode][0]['value'] = $term_translation;
        $terms_to_save[] = $term;
      }
    }
  }
  elseif ($tags = $element['#value']) {
    $entity_type = 'taxonomy_term';
    $field = field_widget_field($element, $form_state);
    $vocabulary = _entity_translation_taxonomy_reference_get_vocabulary($field);
    $typed_tags = drupal_explode_tags($tags);

    // Collect existing terms by name.
    $existing_terms = array();
    foreach (_entity_translation_taxonomy_autocomplete_widget_get_terms($element) as $term) {
      $name = _entity_translation_taxonomy_label($term, $langcode);
      $existing_terms[$name] = $term;
    }

    // Select terms that match by the (translated) name.
    $query = new EntityFieldQuery();
    $query
      ->addTag('taxonomy_term_access');
    $query
      ->entityCondition('entity_type', $entity_type);
    $query
      ->propertyCondition('vid', $vocabulary->vid);
    if ($langcode != LANGUAGE_NONE && module_invoke('title', 'field_replacement_enabled', $entity_type, $vocabulary->machine_name, 'name')) {
      $language_group = 0;

      // Do not select already entered terms.
      $name_field = 'name_field';
      $column = 'value';
      $query
        ->fieldCondition($name_field, $column, $typed_tags, NULL, NULL, $language_group);

      // When we are creating a new entity, we cannot filter by active language,
      // as that may have not be applied to the autocomplete query.
      if (!$is_new) {
        $query
          ->fieldLanguageCondition($name_field, array(
          $langcode,
          LANGUAGE_NONE,
        ), NULL, NULL, $language_group);
      }
    }
    else {
      $query
        ->propertyCondition('name', $typed_tags);
    }
    $result = $query
      ->execute();

    // When we are creating a new entity, the language used for the autocomplete
    // query is the current content language, so we should use that to update
    // the map of existing terms.
    if (!empty($result[$entity_type])) {
      $typed_langcode = !$is_new ? $langcode : $GLOBALS['language_content']->language;
      foreach (taxonomy_term_load_multiple(array_keys($result[$entity_type])) as $term) {
        $name = _entity_translation_taxonomy_label($term, $typed_langcode);
        $existing_terms[$name] = $term;
      }
    }

    // Now collect the identifiers for the various terms and update the taxonomy
    // reference field values.
    foreach ($typed_tags as $delta => $typed_tag) {

      // See if the term exists in the chosen vocabulary and return the tid.
      // Otherwise create a new 'autocreate' term for insert/update.
      if (isset($existing_terms[$typed_tag])) {
        $term = $existing_terms[$typed_tag];
      }
      else {
        $term = (object) array(
          'tid' => 'autocreate',
          'vid' => $vocabulary->vid,
          'name' => $typed_tag,
          'vocabulary_machine_name' => $vocabulary->machine_name,
        );
        $handler = entity_translation_get_handler($entity_type, $term);
        $handler
          ->setOriginalLanguage($langcode);
        $handler
          ->initTranslations();
      }
      $value[] = (array) $term;
    }
  }
  form_set_value($element, $value, $form_state);
}