Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.341
diff -u -r1.341 taxonomy.module
--- modules/taxonomy/taxonomy.module	27 Feb 2007 12:48:33 -0000	1.341
+++ modules/taxonomy/taxonomy.module	19 Mar 2007 19:49:13 -0000
@@ -319,7 +319,7 @@
     module_invoke_all('taxonomy', 'insert', 'vocabulary', $edit);
     $status = SAVED_NEW;
   }
-
+  cache_clear_all('taxonomy:'. $edit['vid'] .':', 'cache', TRUE);
   cache_clear_all();
 
   return $status;
@@ -345,6 +345,7 @@
 
   module_invoke_all('taxonomy', 'delete', 'vocabulary', $vocabulary);
 
+  cache_clear_all('taxonomy:'. $vid .':', 'cache', TRUE);
   cache_clear_all();
 
   return SAVED_DELETED;
@@ -521,6 +522,8 @@
     module_invoke_all('taxonomy', $hook, 'term', $form_values);
   }
 
+  $term = taxonomy_get_term($form_values['tid']);
+  cache_clear_all('taxonomy:'. $term->vid .':', 'cache', TRUE);
   cache_clear_all();
 
   return $status;
@@ -536,6 +539,8 @@
  */
 function taxonomy_del_term($tid) {
   $tids = array($tid);
+  $vids = array();
+
   while ($tids) {
     $children_tids = $orphans = array();
     foreach ($tids as $tid) {
@@ -552,6 +557,9 @@
 
       $term = (array) taxonomy_get_term($tid);
 
+      // Record vocabulary IDs for clearing cache.
+      $vids[$term->vid] = $term->vid;
+
       db_query('DELETE FROM {term_data} WHERE tid = %d', $tid);
       db_query('DELETE FROM {term_hierarchy} WHERE tid = %d', $tid);
       db_query('DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d', $tid, $tid);
@@ -564,6 +572,12 @@
     $tids = $orphans;
   }
 
+  // Clear cache for all affected vocabularies just in case a term has a child
+  // in another vocabulary.
+  foreach($vids as $vid) {
+    cache_clear_all('taxonomy:'. $vid .':', 'cache', TRUE);
+  }
+
   cache_clear_all();
 
   return SAVED_DELETED;
@@ -958,13 +972,25 @@
  * @param $max_depth
  *   The number of levels of the tree to return. Leave NULL to return all levels.
  *
+ * @param $cache
+ *   Whether this tree should be cached in the database. This is used for
+ *   internal purposes and should almost always be left set to TRUE.
+ *
  * @return
  *   An array of all term objects in the tree. Each term object is extended
  *   to have "depth" and "parents" attributes in addition to its normal ones.
  *   Results are statically cached.
  */
-function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL) {
-  static $children, $parents, $terms;
+function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL, $cache = TRUE) {
+  // Check for a cached version of this vocabulary's tree with the given params.
+  $id = 'taxonomy:'. $vid .':'. (int)$parent .':'. (int)$depth .':'. (int)$max_depth;
+  if ($cache && $cached = cache_get($id, 'cache')) {
+    return unserialize($cached->data);
+  }
+
+  $children = array();
+  $parents = array();
+  $terms = array();
 
   $depth++;
 
@@ -994,12 +1020,17 @@
         $tree[] = $term;
 
         if (!empty($children[$vid][$child])) {
-          $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth));
+          // Recurse down the tree, but do not cache recursive calls.
+          $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth, FALSE));
         }
       }
     }
   }
 
+  if ($cache) {
+    cache_set($id, 'cache', serialize($tree));
+  }
+
   return $tree;
 }
 

