You are here

taxonomy_unique.module in Taxonomy unique 7

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

Module file for the Taxonomy unique module.

File

taxonomy_unique.module
View source
<?php

/**
 * @file
 * Module file for the Taxonomy unique module.
 */
define('TAXONOMY_UNIQUE_DEFAULT_MESSAGE', 'Term %term already exists in vocabulary %vocabulary.');
define('TAXONOMY_UNIQUE_TAXONOMY_MANAGER_ADD_MESSAGE', 'Term %term listed more than once in the input');

/**
 * Implements hook_form_FORM_ID_alter() for taxonomy_form_vocabulary().
 */
function taxonomy_unique_form_taxonomy_form_vocabulary_alter(&$form, &$form_state, $form_id) {
  $form['unique_container'] = array(
    '#type' => 'fieldset',
    '#title' => t('Taxonomy unique'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['unique_container']['unique'] = array(
    '#type' => 'checkbox',
    '#title' => t('Terms should be unique.'),
    '#default_value' => variable_get('taxonomy_unique_' . $form['#vocabulary']->machine_name, ''),
  );
  $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' => variable_get('taxonomy_unique_' . $form['#vocabulary']->machine_name . '_message', TAXONOMY_UNIQUE_DEFAULT_MESSAGE),
  );

  // Attach custom submit handler to the form.
  $form['#submit'][] = 'taxonomy_unique_taxonomy_form_vocabulary_submit';
}

/**
 * Form submission handler for taxonomy_form_vocabulary().
 */
function taxonomy_unique_taxonomy_form_vocabulary_submit($form, &$form_state) {

  // Save custom fields to variables.
  variable_set('taxonomy_unique_' . $form_state['values']['machine_name'], $form_state['values']['unique']);
  variable_set('taxonomy_unique_' . $form_state['values']['machine_name'] . '_message', $form_state['values']['unique_message']);
}

/**
 * Implements hook_form_FORM_ID_alter() for taxonomy_form_term().
 */
function taxonomy_unique_form_taxonomy_form_term_alter(&$form, &$form_state, $form_id) {

  // If the terms in this vocabulary should be unique,
  // attach custom validate function to the form.
  if (variable_get('taxonomy_unique_' . $form['vocabulary_machine_name']['#value'], FALSE)) {
    $form['#validate'][] = 'taxonomy_unique_term_name_validate';
  }
}

/**
 * Implements _form_validate() for taxonomy_form_term().
 */
function taxonomy_unique_term_name_validate($form, &$form_state) {

  // If we don't want to save, don't validate the term name.
  if ($form_state['values']['op'] != t('Save')) {
    return;
  }

  // Get the needed variables from $form_state.
  $name = $form_state['values']['name'];
  $vocabulary_machine_name = $form_state['values']['vocabulary_machine_name'];
  $tid = !empty($form_state['values']['tid']) ? $form_state['values']['tid'] : NULL;

  // 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 = variable_get('taxonomy_unique_' . $vocabulary_machine_name . '_message', TAXONOMY_UNIQUE_DEFAULT_MESSAGE);
    form_set_error('name', filter_xss(format_string($error_message, array(
      '%term' => $name,
      '%vocabulary' => $vocabulary_machine_name,
    ))));
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for taxonomy_manager_form().
 *
 * (Support for taxonomy_manager.module)
 */
function taxonomy_unique_form_taxonomy_manager_form_alter(&$form, &$form_state, $form_id) {
  $vocabulary_machine_name = $form['voc']['#value']->machine_name;
  if (variable_get('taxonomy_unique_' . $vocabulary_machine_name, FALSE)) {
    $form['add']['add']['#validate'] = array(
      'taxonomy_unique_form_taxonomy_manager_form_add_validate',
    );
  }
}

/**
 * Validation handler for taxonomy_manager_form() 'add' button.
 *
 * (Support for taxonomy_manager.module)
 */
function taxonomy_unique_form_taxonomy_manager_form_add_validate($form, &$form_state) {

  // Get the needed variables from $form_state.
  if (isset($form_state['values']['add']['mass_add'])) {
    $input = $form_state['values']['add']['mass_add'];

    // taxonomy_manager_mass_add_terms() splits the string this way.
    $names = explode("\n", str_replace("\r", '', $input));
    $names = array_filter($names);
  }
  if (empty($names)) {
    return;
  }
  $vocabulary_machine_name = $form_state['values']['voc']->machine_name;
  $db_duplicates = array();
  $input_duplicates = array();
  while ($name = array_shift($names)) {
    if (in_array($name, $names, TRUE)) {
      $input_duplicates[$name] = TRUE;
    }
    elseif (!taxonomy_unique_is_term_unique($name, $vocabulary_machine_name)) {
      $db_duplicates[$name] = TRUE;
    }
  }

  // Assigning multiple errors to a form field is problematic; so for
  // simplicity we only report on $input_duplicates if there are no
  // $db_duplicates.  In practice input duplicates should be uncommon,
  // so this isn't likely to be a problem.
  if ($db_duplicates) {
    $error_message = variable_get('taxonomy_unique_' . $vocabulary_machine_name . '_message', TAXONOMY_UNIQUE_DEFAULT_MESSAGE);
    $args = array(
      '%term' => implode(', ', array_keys($db_duplicates)),
      '%vocabulary' => $vocabulary_machine_name,
    );
    form_set_error('add', filter_xss(t($error_message, $args)));
  }
  elseif ($input_duplicates) {
    $error_message = variable_get('taxonomy_unique_taxonomy_manager_add_message', TAXONOMY_UNIQUE_TAXONOMY_MANAGER_ADD_MESSAGE);
    $args = array(
      '%term' => implode(', ', array_keys($input_duplicates)),
    );
    form_set_error('add', filter_xss(t($error_message, $args)));
  }
}

/**
 * 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 = taxonomy_get_term_by_name($term_name, $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->tid == $tid) {
    return TRUE;
  }
  return FALSE;
}