--- taxonomy_access.module	2010-02-26 15:21:24.000000000 -0600
+++ taxonomy_access.module.new	2010-02-26 15:25:45.000000000 -0600
@@ -213,6 +213,95 @@ function taxonomy_access_form_alter(&$fo
   }
 }
 
+
+/**
+ * Implements hook_form_FORM_ID_alter() for taxonomy-form-term.
+ * Overriding the term deletion form's submit handler allows us to update the
+ * appropriate {node_access} entries before {term_node} records are deleted 
+ * from the database.
+ */
+function taxonomy_access_form_taxonomy_form_term_alter(&$form,&$form_state) {
+  $form['#submit'] = array('taxonomy_access_term_delete_submit');
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for taxonomy-vocabulary-confirm-delete.
+ * Overriding the term deletion form's submit handler allows us to update the
+ * appropriate {node_access} entries before the {term_data} and {term_node} 
+ * records are deleted from the database.
+ */
+function taxonomy_access_form_taxonomy_vocabulary_confirm_delete_alter(&$form,&$form_state) {
+  $form['#submit'] = array('taxonomy_access_vocabulary_delete_submit');
+}
+
+
+/**
+ * Submit handler for term deletions.
+ * Overrides handling of term deletion to update relevant grants.
+ */
+function taxonomy_access_term_delete_submit(&$form,&$form_state) {
+  // If we are deleting a term, override the default behavior.
+  if ($form_state['clicked_button']['#value'] == t('Delete')) {
+    if ($form_state['values']['delete'] === TRUE) {
+
+      $tid = $form_state['values']['tid'];
+      // First, remove our data for the term.
+      $affected_nodes = _taxonomy_access_get_nodes_for_term($tid);
+      db_query("DELETE FROM {term_access} WHERE tid = '%d'", $tid);
+
+      // Delete entries from {term_node} now, before updating grants.
+      // Otherwise, terms may inherit default grants for vocabularies 
+      // that they no longer belong to.
+      db_query('DELETE FROM {term_node} WHERE tid = %d', $tid);
+
+      // Now, update grants for the affected nodes.
+      _taxonomy_access_node_access_update($affected_nodes);
+      
+      // Finally, proceed with term deletion.
+      return taxonomy_term_confirm_delete_submit($form, $form_state);
+    }
+    // Rebuild the form to confirm term deletion.
+    $form_state['rebuild'] = TRUE;
+    $form_state['confirm_delete'] = TRUE;
+    return;
+  }
+
+  // Otherwise, follow the default behavior.
+  else {
+    taxonomy_form_term_submit($form, $form_state);
+  }
+    
+}
+
+/**
+ * Submit handler for vocabulary deletions.
+ * Overrides handling of vocab deletion to update relevant grants.
+ */
+function taxonomy_access_vocabulary_delete_submit(&$form,&$form_state) {
+  drupal_set_message("hi");
+  $vid = $form_state['values']['vid'];
+  // First, remove our data for the vocabulary.
+  $affected_nodes = _taxonomy_access_get_nodes_for_vocabulary($vid);
+  db_query("DELETE FROM {term_access_defaults} WHERE vid = '%d'", $vid);
+  
+  // Next, remove our data for all terms that were in the vocabulary.
+  $deleted_tids = array();
+  $r = db_query("SELECT tid FROM {term_data} WHERE vid = '%d'", $vid);
+  while ($tid = db_result($r)) {
+    $deleted_tids[] = $tid;
+  }
+  if (sizeof($deleted_tids) > 0) {
+    $placeholders = implode(',', array_fill(0, count($deleted_tids), "%d"));
+    db_query("DELETE FROM {term_access} WHERE tid IN ($placeholders)",$deleted_tids);
+  }
+  
+  // Now, update grants for the affected nodes.
+  _taxonomy_access_node_access_update($affected_nodes);
+  
+  // Finally, proceed with term deletion.
+  return taxonomy_vocabulary_confirm_delete_submit($form, $form_state);
+}
+
 /**
  * Implementation of hook_nodeapi().
  */
@@ -252,30 +341,13 @@ function taxonomy_access_nodeapi(&$node,
  * Hook_taxonomy is called when changes are made to the taxonomy structure
 **/
 function taxonomy_access_taxonomy($op, $type, $array = NULL) {
-  if ($type == 'term') {
-    switch ($op) {
-      case 'delete': // delete everything from term_access and node_access
-        // issue #167977 - klance
-        $affected_nodes = _taxonomy_access_get_nodes_for_term($array['tid']);
-        db_query('DELETE FROM {term_access} WHERE tid = %d', $array['tid']);
-        // issue #167977 - klance
-        _taxonomy_access_node_access_update($affected_nodes);
-        //node_access_rebuild();
-        break;
-    }
-  }
-  if ($type == 'vocabulary') {
-    switch ($op) {
-      case 'delete': // delete vocabulary from table 'term_access_defaults'
-
-        // issue #167977 - klance
-        $affected_nodes = _taxonomy_access_get_nodes_for_vocabulary($array['vid'], NULL);
-        db_query('DELETE FROM {term_access_defaults} WHERE vid = %d', $array['vid']);
-        // issue #167977 - klance
-        _taxonomy_access_node_access_update($affected_nodes);
-        // TODO: need rebuild here? can we avoid multiple rebuilds on large vocab delete?
-        break;
-    }
+  switch ($op) {
+    case 'delete':
+      /* Term and vocabulary deletion are handled by our form overrides;
+       * see taxonomy_access_form_taxonomy_form_term_alter()
+       * and taxonomy_access_form_taxonomy_form_vocabulary_alter.
+       */
+      break;
   }
   return;
 }
