You are here

taxonomy_unique.module in Taxonomy unique 8

Same filename and directory in other branches
  1. 8.2 taxonomy_unique.module
  2. 7 taxonomy_unique.module

File

taxonomy_unique.module
View source
<?php

define('TAXONOMY_UNIQUE_DEFAULT_MESSAGE', 'Term @term already exists in vocabulary @vocabulary.');
function taxonomy_unique_form_taxonomy_vocabulary_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['unique_container'] = array(
    '#type' => 'fieldset',
    '#title' => t('Taxonomy unique'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $unique_default_value = \Drupal::config('taxonomy_unique.settings')
    ->get($form_state
    ->getFormObject()
    ->getEntity()
    ->id());
  if (is_array($unique_default_value) || empty($unique_default_value)) {
    $unique_default_value = FALSE;
  }
  $form['unique_container']['unique'] = array(
    '#type' => 'checkbox',
    '#title' => t('Terms should be unique.'),
    '#default_value' => $unique_default_value,
  );
  $unique_message_default_value = \Drupal::config('taxonomy_unique.settings')
    ->get($form_state
    ->getFormObject()
    ->getEntity()
    ->id() . '_message');
  if (empty($unique_message_default_value)) {
    $unique_message_default_value = TAXONOMY_UNIQUE_DEFAULT_MESSAGE;
  }
  $form['unique_container']['unique_message'] = array(
    '#type' => 'textfield',
    '#title' => t('Message to show if term already exists'),
    '#description' => t('Placeholders: %term and %vocabulary'),
    '#default_value' => $unique_message_default_value,
  );
  $form['actions']['submit']['#submit'][] = 'taxonomy_unique_taxonomy_form_vocabulary_submit';
}
function taxonomy_unique_taxonomy_form_vocabulary_submit($form, \Drupal\Core\Form\FormStateInterface $form_state) {

  // Save custom fields to variables.
  \Drupal::configFactory()
    ->getEditable('taxonomy_unique.settings')
    ->set($form_state
    ->getFormObject()
    ->getEntity()
    ->id(), $form_state
    ->getValue('unique'))
    ->set($form_state
    ->getFormObject()
    ->getEntity()
    ->id() . '_message', $form_state
    ->getValue('unique_message'))
    ->save();
}
function taxonomy_unique_form_taxonomy_term_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  // If the terms in this vocabulary should be unique,
  // attach custom validate function to the form.
  if (\Drupal::config('taxonomy_unique.settings')
    ->get($form_state
    ->getFormObject()
    ->getEntity()
    ->getVocabularyId())) {
    $form['#validate'][] = 'taxonomy_unique_term_name_validate';
  }
}

/**
 * Implements _form_validate() for taxonomy_form_term().
 */
function taxonomy_unique_term_name_validate($form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $triggering_element = $form_state
    ->getTriggeringElement();

  // If we don't want to save, don't validate the term name.
  if ($triggering_element['#button_type'] != 'primary') {
    return;
  }

  // Get the needed variables from $form_state.
  $name = $form_state
    ->getValue('name');
  $name = $name[0]['value'];
  $vocabulary_machine_name = $form_state
    ->getFormObject()
    ->getEntity()
    ->getVocabularyId();
  $tid = $form_state
    ->getFormObject()
    ->getEntity()
    ->id();

  // If the name isn't empty and unique check failed, mark field as invalid.
  if ($name != '' && !taxonomy_unique_is_term_unique($name, $vocabulary_machine_name, $tid)) {
    $error_message = \Drupal::config('taxonomy_unique.settings')
      ->get($form_state
      ->getFormObject()
      ->getEntity()
      ->getVocabularyId() . '_message');
    if (empty($error_message)) {
      $error_message = TAXONOMY_UNIQUE_DEFAULT_MESSAGE;
    }
    $form_state
      ->setErrorByName('name', \Drupal\Component\Utility\Xss::filter(\Drupal\Component\Utility\SafeMarkup::format($error_message, array(
      '@term' => $name,
      '@vocabulary' => $vocabulary_machine_name,
    ))));
  }
}

/**
 * Checks if term name already exists in vocabulary.
 *
 * @param string $term_name
 *   Name to check
 *
 * @param string $vocabulary_machine_name
 *   Machine name of the vocabulary the term belongs to
 *
 * @param int $tid
 *   The term ID when updating an existing term
 *
 * @return bool
 *   TRUE when term name is unique, FALSE if not
 */
function taxonomy_unique_is_term_unique($term_name, $vocabulary_machine_name, $tid = NULL) {
  $terms = \Drupal::entityTypeManager()
    ->getStorage('taxonomy_term')
    ->loadByProperties([
    'name' => $term_name,
    'vid' => $vocabulary_machine_name,
  ]);
  $term = current($terms);

  // If no terms are found, or only one term is found which has
  // the same tid as the one we're trying to save, the name must be unique.
  if (empty($terms) || count($terms) == 1 && $term
    ->id() == $tid) {
    return TRUE;
  }
  return FALSE;
}