You are here

taxonomy_multidelete_term.module in Taxonomy Multi-delete Terms 7

Taxonomy multi delete module use to delete terms in bulk.

File

taxonomy_multidelete_term.module
View source
<?php

/**
 * @file
 * Taxonomy multi delete module use to delete terms in bulk.
 */

/**
 * Implements hook_help().
 */
function taxonomy_multidelete_term_help($path, $arg) {
  switch ($path) {
    case 'admin/help#taxonomy_multidelete_term':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>This module help to delete multiple term at one time.' . ' You just need to select terms and click on delete button.' . ' All seleted terms will be delete. You can also delete all terms at one time.</p>';
      return $output;
  }
}

/**
 * Alter theme register to override function.
 */
function taxonomy_multidelete_term_theme_registry_alter(&$theme_registry) {
  $theme_registry['taxonomy_overview_terms']['function'] = 'taxonomy_multidelete_term_theme_taxonomy_overview_terms';
}

/**
 * Returns HTML for a terms overview form as a sortable list of terms.
 */
function taxonomy_multidelete_term_theme_taxonomy_overview_terms($variables) {
  $form = $variables['form'];
  $page_entries = $form['#page_entries'];
  $back_step = $form['#back_step'];
  $forward_step = $form['#forward_step'];

  // Add drag and drop if parent fields are present in the form.
  if ($form['#parent_fields']) {
    drupal_add_tabledrag('taxonomy', 'match', 'parent', 'term-parent', 'term-parent', 'term-id', FALSE);
    drupal_add_tabledrag('taxonomy', 'depth', 'group', 'term-depth', NULL, NULL, FALSE);
    drupal_add_js(drupal_get_path('module', 'taxonomy') . '/taxonomy.js');
    drupal_add_js(array(
      'taxonomy' => array(
        'backStep' => $back_step,
        'forwardStep' => $forward_step,
      ),
    ), 'setting');
    drupal_add_css(drupal_get_path('module', 'taxonomy') . '/taxonomy.css');
  }
  drupal_add_js('misc/tableselect.js', 'file');
  drupal_add_tabledrag('taxonomy', 'order', 'sibling', 'term-weight');
  $errors = form_get_errors() != FALSE ? form_get_errors() : array();
  $rows = array();
  foreach (element_children($form) as $key) {
    if (isset($form[$key]['#term'])) {
      $term =& $form[$key];
      $row = array();
      $row[] = (isset($term['#term']['depth']) && $term['#term']['depth'] > 0 ? theme('indentation', array(
        'size' => $term['#term']['depth'],
      )) : '') . drupal_render($term['view']);
      if ($form['#parent_fields']) {
        $term['tid']['#attributes']['class'] = array(
          'term-id',
        );
        $term['parent']['#attributes']['class'] = array(
          'term-parent',
        );
        $term['depth']['#attributes']['class'] = array(
          'term-depth',
        );
        $row[0] .= drupal_render($term['parent']) . drupal_render($term['tid']) . drupal_render($term['depth']);
      }
      $term['weight']['#attributes']['class'] = array(
        'term-weight',
      );
      $row[] = drupal_render($term['weight']);
      $row[] = drupal_render($term['edit']);
      $row = array(
        'data' => $row,
      );
      $rows[$key] = $row;
    }
  }

  // Add necessary classes to rows.
  $row_position = 0;
  foreach ($rows as $key => $row) {
    $rows[$key]['class'] = array();
    if (isset($form['#parent_fields'])) {
      $rows[$key]['class'][] = 'draggable';
    }

    // Add classes that mark which terms belong to previous and next pages.
    if ($row_position < $back_step || $row_position >= $page_entries - $forward_step) {
      $rows[$key]['class'][] = 'taxonomy-term-preview';
    }
    if ($row_position !== 0 && $row_position !== count($rows) - 1) {
      if ($row_position == $back_step - 1 || $row_position == $page_entries - $forward_step - 1) {
        $rows[$key]['class'][] = 'taxonomy-term-divider-top';
      }
      elseif ($row_position == $back_step || $row_position == $page_entries - $forward_step) {
        $rows[$key]['class'][] = 'taxonomy-term-divider-bottom';
      }
    }

    // Add an error class if this row contains a form error.
    foreach ($errors as $error_key => $error) {
      if (strpos($error_key, $key) === 0) {
        $rows[$key]['class'][] = 'error';
      }
    }
    $row_position++;
  }
  if (empty($rows)) {
    $rows[] = array(
      array(
        'data' => $form['#empty_text'],
        'colspan' => '3',
      ),
    );
  }

  // Added checkbox in front of the name to select all terms.
  $header = array(
    array(
      'data' => t('&nbsp;Name'),
      'class' => array(
        'select-all',
      ),
      'style' => 'width:auto;',
    ),
    t('Weight'),
    t('Operations'),
  );
  $output = '';
  if ($form['#confirm_delete'] != 1) {
    $output = theme('table', array(
      'header' => $header,
      'rows' => $rows,
      'attributes' => array(
        'id' => 'taxonomy',
      ),
    ));
  }
  $output .= drupal_render_children($form);
  if ($form['#confirm_delete'] != 1) {
    $output .= theme('pager');
  }
  return $output;
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Alter taxonomy overview terms list.
 */
function taxonomy_multidelete_term_form_taxonomy_overview_terms_alter(&$form, &$form_state, $form_id) {
  $form['#confirm_delete'] = 0;
  $vocabulary = $form_state['build_info']['args'][0];

  // Check for confirmation delete forms.
  if (isset($form_state['confirm_delete_terms'])) {
    hide($form['actions']);
    $form[] = taxonomy_multidelete_term_confirm_delete_terms($form, $form_state, $form_id);
    $form['#confirm_delete'] = 1;
    return $form;
  }

  // Check for confirmation forms.
  if (!isset($form_state['confirm_reset_alphabetical']) && !isset($form_state['confirm_delete_terms'])) {
    $page = isset($_GET['page']) ? $_GET['page'] : 0;
    $page_increment = variable_get('taxonomy_terms_per_page_admin', 100);
    $page_entries = 0;
    $before_entries = 0;
    $after_entries = 0;
    $root_entries = 0;
    $complete_tree = TRUE;

    // Terms from previous and next pages are shown
    // if the term tree would have
    // been cut in the middle. Keep track of how many extra
    // terms we show on each page of terms.
    $back_step = NULL;
    $forward_step = 0;

    // An array of the terms to be displayed on this page.
    $current_page = array();
    $delta = 0;
    $term_deltas = array();
    $tree = taxonomy_get_tree($vocabulary->vid);
    $term = current($tree);
    do {

      // In case this tree is completely empty.
      if (empty($term)) {
        break;
      }
      $delta++;

      // Count entries before the current page.
      if ($page && $page * $page_increment > $before_entries && !isset($back_step)) {
        $before_entries++;
        continue;
      }
      elseif ($page_entries > $page_increment && isset($complete_tree)) {
        $after_entries++;
        continue;
      }

      // Do not let a term start the page that is not at the root.
      if (isset($term->depth) && $term->depth > 0 && !isset($back_step)) {
        $back_step = 0;
        while ($pterm = prev($tree)) {
          $before_entries--;
          $back_step++;
          if ($pterm->depth == 0) {
            prev($tree);
            continue 2;
          }
        }
      }
      $back_step = isset($back_step) ? $back_step : 0;

      // Continue rendering the tree until we reach the a new root item.
      if ($page_entries >= $page_increment + $back_step + 1 && $term->depth == 0 && $root_entries > 1) {
        $complete_tree = TRUE;

        // This new item at the root level is the first item on the next page.
        $after_entries++;
        continue;
      }
      if ($page_entries >= $page_increment + $back_step) {
        $forward_step++;
      }

      // Finally, if we've gotten down this far,
      // we're rendering a term on this page.
      $page_entries++;
      $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0;
      $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid];

      // Keep track of the first term displayed on this page.
      if ($page_entries == 1) {
        $form['#first_tid'] = $term->tid;
      }

      // Keep a variable to make sure at least 2 root elements are displayed.
      if ($term->parents[0] == 0) {
        $root_entries++;
      }
      $current_page[$key] = $term;
    } while ($term = next($tree));

    // Build the actual form.
    foreach ($current_page as $key => $term) {
      $form[$key]['view'] = array(
        '#type' => 'checkbox',
        '#title' => l($term->name, "taxonomy/term/{$term->tid}"),
      );
      $form['#parent_fields'] = TRUE;
      $form[$key]['tid'] = array(
        '#type' => 'hidden',
        '#value' => $term->tid,
      );
      $form[$key]['depth'] = array(
        '#type' => 'hidden',
        '#default_value' => $term->depth,
      );
      $form[$key]['weight'] = array(
        '#type' => 'weight',
        '#delta' => $delta,
        '#title_display' => 'invisible',
        '#title' => t('Weight for added term'),
        '#default_value' => $term->weight,
      );
    }
    if (count($tree) > 0) {
      $form['actions']['delete'] = array(
        '#type' => 'submit',
        '#value' => t('Delete'),
        '#submit' => array(
          'taxonomy_multidelete_term_taxonomy_overview_terms_submit',
        ),
      );
      $form['#validate'][] = 'taxonomy_multidelete_term_taxonomy_overview_terms_validate';
    }
  }
}

/**
 * Confirm form to delete terms.
 */
function taxonomy_multidelete_term_confirm_delete_terms($form, &$form_state, $form_id) {
  $tree = taxonomy_get_tree($form_state['build_info']['args'][0]->vid);
  $deleted_term_array = taxonomy_multidelete_term_get_deleted_term_names($tree, $form_state);
  $deleted_terms = implode(', ', $deleted_term_array);
  $deleted_terms = truncate_utf8($deleted_terms, 200, TRUE, TRUE);
  $seleted_tid = array();
  $term_deltas = array();
  foreach ($tree as $term) {
    $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0;
    $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid];
    if (!empty($form_state['values'][$key]['view'])) {
      $seleted_tid[] = $term->tid;
    }
  }
  $form_build_id = $form['#vocabulary'];
  $form = array();
  $form['#form_build_id'] = $form_build_id;
  $form['#form_id'] = $form_id;
  $form['#term_data'] = $seleted_tid;
  $form['delete'] = array(
    '#type' => 'value',
    '#value' => TRUE,
  );
  $confirm_form = confirm_form($form, t('Are you sure you want to delete the term %title?', array(
    '%title' => $deleted_terms,
  )), 'admin/structure/taxonomy/' . $form_state['build_info']['args'][0]->machine_name, t('Deleting a terms will delete all its children if there are any. This action cannot be undone.'), t('Delete'), t('Cancel'));
  $confirm_form['actions']['submit']['#submit'] = array(
    'taxonomy_multidelete_term_confirm_delete_terms_submit',
  );
  return $confirm_form;
}

/**
 * Validate delete term action.
 */
function taxonomy_multidelete_term_taxonomy_overview_terms_validate($form, &$form_state) {
  if ($form_state['values']['op'] === t("Delete")) {
    $tree = taxonomy_get_tree($form_state['build_info']['args'][0]->vid);
    $deleted_term_array = taxonomy_multidelete_term_get_deleted_term_names($tree, $form_state);
    if (count($deleted_term_array) === 0) {
      form_set_error('', t('Please select term(s) to delete.'));
    }
  }
}

/**
 * Deleted the selected term name.
 */
function taxonomy_multidelete_term_taxonomy_overview_terms_submit($form, &$form_state) {

  // Rebuild the form to confirm the reset action.
  $form_state['rebuild'] = TRUE;
  $form_state['confirm_delete_terms'] = TRUE;
}

/**
 * Delete terms after confirmation.
 */
function taxonomy_multidelete_term_confirm_delete_terms_submit($form, &$form_state) {
  $delete_terms = $form[0]['#term_data'];
  $total_tids = array();
  $name = array();
  foreach ($delete_terms as $term) {
    $total_tids[] = $term;
    $name[] = taxonomy_multidelete_term_term_name_by_id($term);
  }
  rsort($total_tids);
  $limit = 10;
  $chunks = array_chunk($total_tids, $limit);
  $operations = array();
  foreach ($chunks as $chunksids) {
    $chunk['tids'] = $chunksids;
    $chunk['terms-name'] = $name;
    $operations[] = array(
      'taxonomy_multidelete_term_processor',
      array(
        $chunk,
      ),
    );
  }
  $batch = array(
    'operations' => $operations,
    'finished' => 'taxonomy_multidelete_term_finished',
    'title' => 'Please wait we are deleting seleted terms ..',
  );
  batch_set($batch);
}

/**
 * Batch processor function to delete terms.
 */
function taxonomy_multidelete_term_processor($chunk, &$context) {
  foreach ($chunk['tids'] as $tid) {
    taxonomy_term_delete($tid);
  }
  $context['results']['terms'] = $chunk['terms-name'];
}

/**
 * Batch 'finished' callback.
 */
function taxonomy_multidelete_term_finished($success, $results, $operations) {
  if ($success) {
    $delete_terms = $results['terms'];
    $deleted_terms_name = implode(', ', $delete_terms);
    drupal_set_message(t('Deleted term(s) %name.', array(
      '%name' => $deleted_terms_name,
    )));
    watchdog('taxonomy', 'Deleted term(s) %name.', array(
      '%name' => $deleted_terms_name,
    ), WATCHDOG_NOTICE);
    cache_clear_all();
  }
  else {

    // An error occurred.
    // $operations contains the operations that remained unprocessed.
    $error_operation = reset($operations);
    drupal_set_message(t('An error occurred while processing @operation with arguments : @args', array(
      '@operation' => $error_operation[0],
      '@args' => print_r($error_operation[0], TRUE),
    )));
  }
}

/**
 * It will return Term Name.
 */
function taxonomy_multidelete_term_term_name_by_id($tid) {
  return db_select('taxonomy_term_data', 't')
    ->fields('t', array(
    'name',
  ))
    ->condition('tid', $tid)
    ->execute()
    ->fetchField();
}

/**
 * It will retrun name of the term name Which are deleted.
 */
function taxonomy_multidelete_term_get_deleted_term_names($tree, $form_state = NULL, $preseleted = NULL) {
  $name = array();
  if (!empty($preseleted)) {
    foreach ($tree as $term) {
      $name[] = taxonomy_multidelete_term_term_name_by_id($term);
    }
  }
  else {
    $term_deltas = array();
    foreach ($tree as $key => $term) {
      $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0;
      $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid];
      if (!empty($form_state['values'][$key]['view'])) {
        $seleted_tid = $term->tid;
        $name[] = taxonomy_multidelete_term_term_name_by_id($seleted_tid);
      }
    }
  }
  return $name;
}

Functions

Namesort descending Description
taxonomy_multidelete_term_confirm_delete_terms Confirm form to delete terms.
taxonomy_multidelete_term_confirm_delete_terms_submit Delete terms after confirmation.
taxonomy_multidelete_term_finished Batch 'finished' callback.
taxonomy_multidelete_term_form_taxonomy_overview_terms_alter Implements hook_form_FORM_ID_alter().
taxonomy_multidelete_term_get_deleted_term_names It will retrun name of the term name Which are deleted.
taxonomy_multidelete_term_help Implements hook_help().
taxonomy_multidelete_term_processor Batch processor function to delete terms.
taxonomy_multidelete_term_taxonomy_overview_terms_submit Deleted the selected term name.
taxonomy_multidelete_term_taxonomy_overview_terms_validate Validate delete term action.
taxonomy_multidelete_term_term_name_by_id It will return Term Name.
taxonomy_multidelete_term_theme_registry_alter Alter theme register to override function.
taxonomy_multidelete_term_theme_taxonomy_overview_terms Returns HTML for a terms overview form as a sortable list of terms.