You are here

taxonomy_dupecheck.module in Taxonomy dupecheck 6

Same filename and directory in other branches
  1. 7 taxonomy_dupecheck.module

Module file for the Taxonomy dupecheck module.

File

taxonomy_dupecheck.module
View source
<?php

// $Id$

/**
 * @file
 * Module file for the Taxonomy dupecheck module.
 */

/**
 * Implements hook_help().
 */
function taxonomy_dupecheck_help($path, $arg) {
  if ($path == 'admin/help/taxonomy_dupecheck') {
    $output = '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t("The Taxonomy dupecheck module prevents Drupal administrators from adding duplicate taxonomy vocabularies and/or terms. It's helpful when entering large amounts of terms or vocabularies in situations where each value must be unique. This saves time by preventing administrators from enforcing a unique value policy through later cleanup.") . '</p>';
    $output .= '<p>' . t("The module provides a configuration screen allowing administrators to choose which should be unique: taxonomy terms, vocabularies or both. It defaults to case-insensitive comparisons, with an option to change to case-sensitive. Based on the settings, the user will see an error message when adding a duplicate value.") . '</p>';
    return $output;
  }
}

/**
 * Implements hook_menu().
 */
function taxonomy_dupecheck_menu() {
  $items = array();
  $items['admin/settings/taxonomy_dupecheck'] = array(
    'title' => 'Taxonomy dupecheck',
    'description' => 'Configuration for the Taxonomy dupecheck module.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'taxonomy_dupecheck_settings',
    ),
    'access arguments' => array(
      'administer taxonomy',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Form builder; creates and displays the Taxonomy dupecheck
 * configuration settings form.
 */
function taxonomy_dupecheck_settings() {

  // Checkboxes to choose what should be checked for dupes (vocab, terms, both)
  $form['taxonomy_dupecheck_types'] = array(
    '#type' => 'checkboxes',
    '#title' => 'Check for duplicate',
    '#default_value' => variable_get('taxonomy_dupecheck_types', array()),
    '#options' => array(
      'vocab' => t('Vocabularies'),
      'term' => t('Terms (within a vocabulary)'),
    ),
  );

  // Checkbox to indicate whether the check should be case-sensitive
  $form['taxonomy_dupecheck_case_sensitive'] = array(
    '#type' => 'checkbox',
    '#title' => "Case-sensitive comparison (e.g. 'Foo' and 'foo' are not duplicates if checked).",
    '#default_value' => variable_get('taxonomy_dupecheck_case_sensitive', 0),
  );
  return system_settings_form($form);
}

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

  // Get the types of taxonomy objects we will validate against
  $types = variable_get('taxonomy_dupecheck_types', array());

  // Add the validator if 1) we're checking terms for dupes and 2) we're not deleting the term.
  // This handles the problem of validators running during the delete process.
  if ($types['term'] && (!isset($form_state['post']['op']) || $form_state['post']['op'] != 'Delete')) {
    $form['#validate'][] = 'taxonomy_dupecheck_term_validate';
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for taxonomy_form_vocabulary().
 */
function taxonomy_dupecheck_form_taxonomy_form_vocabulary_alter(&$form, &$form_state) {

  // Get the types of taxonomy objects we will validate against
  $types = variable_get('taxonomy_dupecheck_types', array());

  // Add the validator if 1) we're checking terms for dupes and 2) we're not deleting the term.
  // This handles the problem of validators running during the delete process.
  if ($types['vocab'] && (!isset($form_state['post']['op']) || $form_state['post']['op'] != 'Delete')) {
    $form['#validate'][] = 'taxonomy_dupecheck_vocabulary_validate';
  }
}

/**
 * Implements _form_validate() for taxonomy_form_term().
 */
function taxonomy_dupecheck_term_validate($form, &$form_state) {
  $term = $form_state['values']['name'];
  $vid = $form_state['values']['vid'];
  $tid = $form_state['values']['tid'];
  if (taxonomy_dupecheck_is_dupe_term($term, $vid, $tid)) {
    form_set_error('name', t('The term %term already exists in this vocabulary.', array(
      '%term' => check_plain($term),
    )));
  }
}

/**
 * Implements _form_validate() for taxonomy_form_vocabulary().
 */
function taxonomy_dupecheck_vocabulary_validate($form, &$form_state) {
  $vocab = $form_state['values']['name'];
  $vid = isset($form_state['values']['vid']) ? $form_state['values']['vid'] : 0;
  if (taxonomy_dupecheck_is_dupe_vocabulary($vocab, $vid)) {
    form_set_error('name', t('The vocabulary %term already exists.', array(
      '%term' => check_plain($vocab),
    )));
  }
}

/**
 * Checks whether a term is a duplicate, based on the module preferences.
 *
 * @param $term
 *   Name of the new term to check
 *
 * @param int $vid
 *   ID of the vocabulary the new term belongs to
 *
 * @param int $tid
 *   Term ID of the new term (used when updating an existing term name)
 *
 * @return
 *   TRUE if the term is a duplicate, FALSE if not
 */
function taxonomy_dupecheck_is_dupe_term($term, $vid, $tid = 0) {

  // Get case-sensitivity preference
  $case_sensitive = variable_get('taxonomy_dupecheck_case_sensitive', 0);

  // Get the terms via SQL instead of taxonomy_get_tree, which helps with large vocabs
  $sql = "SELECT TRIM(name) AS trimmed_name FROM {term_data} WHERE vid = %d AND name = TRIM('%s') AND tid <> '%d'";
  $result = db_query($sql, $vid, $term, $tid);
  while ($found_term = db_fetch_object($result)) {

    // Do case (in)sensitive comparison
    if ($case_sensitive && !strcmp($found_term->trimmed_name, $term) || !$case_sensitive && !strcasecmp($found_term->trimmed_name, $term)) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Checks whether a vocabulary is a duplicate, based on the module preferences.
 *
 * @param $vocab
 *   Name of the new vocabulary to check
 *
 * @param int $vid
 *   ID of the vocabulary the new term belongs to (used when updating an existing vocabulary)
 *
 * @return
 *   TRUE if the vocabulary is a duplicate, FALSE if not
 */
function taxonomy_dupecheck_is_dupe_vocabulary($vocab, $vid = 0) {

  // Clean up the vocabulary to check
  $vocab = trim($vocab);

  // Get all vocabularies
  $vocabs = taxonomy_get_vocabularies();

  // Look for a vocabulary with the same name based on case-sensitivity preferences
  $case_sensitive = variable_get('taxonomy_dupecheck_case_sensitive', 0);
  foreach ($vocabs as $found_vocab) {

    // Skip the check if the current found vocabulary is the same one we're comparing.
    // This will happen on updates to an existing vocabulary.
    if ($vid == $found_vocab->vid) {
      continue;
    }

    // Clean up the stored vocabulary. This helps for systems that
    // don't trim their vocabulary names before entry.
    $found_vocab_name = trim($found_vocab->name);
    if ($case_sensitive && !strcmp($found_vocab_name, $vocab) || !$case_sensitive && !strcasecmp($found_vocab_name, $vocab)) {
      return TRUE;
    }
  }
  return FALSE;
}

Functions

Namesort descending Description
taxonomy_dupecheck_form_taxonomy_form_term_alter Implements hook_form_FORM_ID_alter() for taxonomy_form_term().
taxonomy_dupecheck_form_taxonomy_form_vocabulary_alter Implements hook_form_FORM_ID_alter() for taxonomy_form_vocabulary().
taxonomy_dupecheck_help Implements hook_help().
taxonomy_dupecheck_is_dupe_term Checks whether a term is a duplicate, based on the module preferences.
taxonomy_dupecheck_is_dupe_vocabulary Checks whether a vocabulary is a duplicate, based on the module preferences.
taxonomy_dupecheck_menu Implements hook_menu().
taxonomy_dupecheck_settings Form builder; creates and displays the Taxonomy dupecheck configuration settings form.
taxonomy_dupecheck_term_validate Implements _form_validate() for taxonomy_form_term().
taxonomy_dupecheck_vocabulary_validate Implements _form_validate() for taxonomy_form_vocabulary().