Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.385
diff -u -F^f -r1.385 taxonomy.module
--- modules/taxonomy/taxonomy.module	27 Oct 2007 13:39:07 -0000	1.385
+++ modules/taxonomy/taxonomy.module	28 Oct 2007 12:18:08 -0000
@@ -190,6 +190,7 @@ function taxonomy_save_vocabulary(&$edit
     $status = SAVED_NEW;
   }
 
+  cache_clear_all('taxonomy:'. $edit['vid'] .':', 'cache', TRUE);
   cache_clear_all();
 
   return $status;
@@ -215,6 +216,7 @@ function taxonomy_del_vocabulary($vid) {
 
   module_invoke_all('taxonomy', 'delete', 'vocabulary', $vocabulary);
 
+  cache_clear_all('taxonomy:'. $vid .':', 'cache', TRUE);
   cache_clear_all();
 
   return SAVED_DELETED;
@@ -289,6 +291,8 @@ function taxonomy_save_term(&$form_value
     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;
@@ -304,6 +308,8 @@ function taxonomy_save_term(&$form_value
  */
 function taxonomy_del_term($tid) {
   $tids = array($tid);
+  $vids = array();
+
   while ($tids) {
     $children_tids = $orphans = array();
     foreach ($tids as $tid) {
@@ -318,7 +324,10 @@ function taxonomy_del_term($tid) {
         }
       }
 
-      $term = (array) taxonomy_get_term($tid);
+      $term = 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);
@@ -332,6 +341,12 @@ function taxonomy_del_term($tid) {
     $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;
@@ -688,13 +703,31 @@ function taxonomy_get_children($tid, $vi
  * @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.
+ *   Results are cached in the database.
  */
-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.
+  // Some functions pass in NULL for $parent and $max_depth so we need placeholders
+  // for those.
+  $id = 'taxonomy:'. $vid .':';
+  $id .= isset($parent) ? $parent : 'NULL';
+  $id .= ':'. $depth .':';
+  $id .= isset($max_depth) ? $max_depth : 'NULL';
+
+  if ($cache && ($cached = cache_get($id))) {
+    return $cached->data;
+  }
+
+  $children = array();
+  $parents = array();
+  $terms = array();
 
   $depth++;
 
@@ -724,12 +757,18 @@ function taxonomy_get_tree($vid, $parent
         $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));
         }
       }
     }
   }
 
+  // Don't cache tree if empty, may be able to remove this after more testing.
+  if ($tree && $cache) {
+    cache_set($id, $tree);
+  }
+
   return $tree;
 }
 
