Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.346
diff -u -r1.346 taxonomy.module
--- modules/taxonomy/taxonomy.module	6 Apr 2007 13:27:22 -0000	1.346
+++ modules/taxonomy/taxonomy.module	10 Apr 2007 13:07:56 -0000
@@ -21,6 +21,9 @@
     'taxonomy_term_select' => array(
       'arguments' => array('element' => NULL),
     ),
+    'taxonomy_overview_terms' => array(
+      'arguments' => array('form' => NULL),
+    ),
   );
 }
 
@@ -131,8 +134,8 @@
   );
   $items['admin/content/taxonomy/%taxonomy_vocabulary'] = array(
     'title' => t('List terms'),
-    'page callback' => 'taxonomy_overview_terms',
-    'page arguments' => array(3),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('taxonomy_overview_terms', 3),
     'access arguments' => array('administer taxonomy'),
     'type' => MENU_CALLBACK,
   );
@@ -182,42 +185,166 @@
 }
 
 /**
- * Display a tree of all the terms in a vocabulary, with options to edit
- * each one.
- */
-function taxonomy_overview_terms($vocabulary) {
-  $destination = drupal_get_destination();
+ * Manage vocabulary terms.
+ * 
+ * @param $vocabulary
+ *   The vocabulary (object) whose terms are to be managed.
+ * @param $form_values
+ *   $form_values for the multi-step form. This parameter is automatically added
+ * by the forms API.
+ * 
+ * @return $form
+ *   A multi-step form array.
+ */
+function taxonomy_overview_terms($vocabulary, $form_values = NULL) {
+  $form = array();
+
+  if (isset($form_values)) {
+    $step = $form_values['step'] + 1;
+    // Forward essential values from step 1 to subsequent steps.
+    $form['operation'] = array('#type' => 'value', '#value' => $form_values['operation']);
+    $form['terms'] = array('#type' => 'value', '#value' => $form_values['terms']);
+    $form['vid'] = array('#type' => 'value', '#value' => $vocabulary->vid);
+  }
+  else {
+    $step = 1;
+  }
 
-  $header = array(t('Name'), t('Operations'));
+  $form['step'] = array('#type' => 'hidden', '#value' => $step);
 
-  drupal_set_title(check_plain($vocabulary->name));
-  $start_from      = isset($_GET['page']) ? $_GET['page'] : 0;
-  $total_entries   = 0;  // total count for pager
-  $page_increment  = 25; // number of tids per page
-  $displayed_count = 0;  // number of tids shown
-
-  $tree = taxonomy_get_tree($vocabulary->vid);
-  foreach ($tree as $term) {
-    $total_entries++; // we're counting all-totals, not displayed
-    if (($start_from && ($start_from * $page_increment) >= $total_entries) || ($displayed_count == $page_increment)) {
-      continue;
-    }
-    $rows[] = array(str_repeat('--', $term->depth) . ' ' . l($term->name, "taxonomy/term/$term->tid"), l(t('edit'), "admin/content/taxonomy/edit/term/$term->tid", array('query' => $destination)));
-    $displayed_count++; // we're counting tids displayed
+  switch ($step) {
+    case 1:
+      drupal_set_title(check_plain($vocabulary->name));
+
+      $start_from = isset($_GET['page']) ? $_GET['page'] : 0;
+      // Total count for pager.
+      $total_entries = 0;
+      // Number of terms per page.
+      $page_increment = 50;
+      // Number of terms shown.
+      $displayed_count = 0;
+
+      $destination = drupal_get_destination();
+
+      $tree = taxonomy_get_tree($vocabulary->vid);
+      $terms = array();
+      foreach ($tree as $term) {
+        // Count all tids.
+        $total_entries++;
+        if (($start_from && ($start_from * $page_increment) >= $total_entries) || ($displayed_count >= $page_increment)) {
+          continue;
+        }
+
+        $terms[$term->tid] = '';
+        $form['name'][$term->tid] = array('#value' => l($term->name, "taxonomy/term/$term->tid"));
+        // Forward depth for use in the theme function.
+        // @see theme_taxonomy_overview_terms.
+        $form['depth'][$term->tid] = array('#type' => 'value', '#value' => $term->depth);
+        $form['operations'][$term->tid] = array('#value' => l(t('Edit'), "admin/content/taxonomy/edit/term/$term->tid", array(), $destination));
+
+        // Count the tids displayed.
+        $displayed_count++;
+      }
+      $form['terms'] = array('#type' => 'checkboxes', '#options' => $terms);
+
+      $GLOBALS['pager_page_array'][] = $start_from;  // FIXME
+      $GLOBALS['pager_total'][] = ceil($total_entries / $page_increment); // FIXME
+      if ($total_entries >= $page_increment) {
+        $form['pager'] = array('#value' => theme('pager', NULL, $page_increment));
+      }
+
+      $options = array('delete' => t('Delete'));
+
+      $form['perform'] = array('#type' => 'fieldset', '#title' => t('Update selected terms'));
+      $form['perform']['operation'] = array(
+        '#type' => 'select',
+        '#options' => $options,
+        '#default_value' => 'delete',
+        '#prefix' => '<div class="container-inline">'
+      );
+      $form['perform']['submit'] = array(
+        '#type' => 'submit',
+        '#value' => t('Update'),
+        '#suffix' => '</div>'
+      );
+      break;
+    case 2:
+      // Use the $form element rather than $form_values for consistency with
+      // other modules that might hook in. 
+      if ($form['operation']['#value'] == 'delete') {
+        $form = confirm_form(
+          $form,
+          t('Are you sure you want to delete the selected terms?'),
+          'admin/content/taxonomy/'. $vocabulary->vid,
+          t('This will delete all selected terms. This action cannot be undone.'),
+          t('Delete terms')
+        );
+      }
   }
 
-  if (empty($rows)) {
-    $rows[] = array(array('data' => t('No terms available.'), 'colspan' => '2'));
+  $form['#multistep'] = TRUE;
+  $form['#redirect'] = FALSE;
+
+  return $form;
+}
+
+/**
+ * Process the taxonomy_overview_terms form submission.
+ * @todo Avoid the drupal_goto.
+ */
+function taxonomy_overview_terms_submit($form, $form_values) {
+  if ($form_values['step'] == 2 && $form_values['operation'] == 'delete' && $form_values['confirm'] == 1) {
+    foreach ($form_values['terms'] as $tid) {
+      taxonomy_del_term($tid);
+    }
+    // Ideally, an entry would be made for each term deleted.
+    drupal_set_message(t('The terms have been deleted.'));
+    watchdog('taxonomy', t('Mass term deletion operation performed.'));
+
+    // Rather than toggling the #redirect of the multi-step form, just use a
+    // goto.
+    drupal_goto('admin/content/taxonomy/'. $form_values['vid']);
   }
+}
+
+/**
+ * Theme the taxonomy_overview_terms form.
+ */
+function theme_taxonomy_overview_terms($form) {
+  $output = '';
 
-  $GLOBALS['pager_page_array'][] = $start_from;  // FIXME
-  $GLOBALS['pager_total'][] = intval($total_entries / $page_increment) + 1; // FIXME
+  // This form is only displayed during step 1 of the multi-step form.
+  if ($form['step']['#value'] == 1) {
+    // Overview table.
+    $header = array(theme('table_select_header_cell'), t('Name'), t('Operations'));
+    $output .= drupal_render($form['perform']);
 
-  if ($total_entries >= $page_increment) {
-    $rows[] = array(array('data' => theme('pager', NULL, $page_increment), 'colspan' => '2'));
+    if (isset($form['name']) && is_array($form['name'])) {
+      foreach (element_children($form['name']) as $key) {
+        $row = array();
+        $form['name'][$key]['#value'] = str_repeat('--', $form['depth'][$key]['#value']) .' '. $form['name'][$key]['#value']; 
+        $row[] = drupal_render($form['terms'][$key]);
+        $row[] = drupal_render($form['name'][$key]);
+        $row[] = drupal_render($form['operations'][$key]);
+        $rows[] = $row;
+      }
+    }
+    else  {
+      $rows[] = array(array('data' => t('No terms available.'), 'colspan' => '3'));
+    }
+
+    $output .= theme('table', $header, $rows);
+
+    if (isset($form['pager']['#value'])) {
+      $output .= drupal_render($form['pager']);
+    }
   }
+  // The depth element is no longer required.
+  unset($form['depth']);
 
-  return theme('table', $header, $rows, array('id' => 'taxonomy'));
+  $output .= drupal_render($form);
+
+  return $output;
 }
 
 /**
