--- taxonomy.module_ori    2005-05-13 19:25:47.000000000 +0000
+++ taxonomy.module    2005-05-13 19:25:30.000000000 +0000
@@ -99,6 +99,8 @@
   }

   $form .= form_textfield(t('Vocabulary name'), 'name', $edit['name'], 50, 64, t('The name for this vocabulary.  Example: "Topic".'), NULL, TRUE);
+  // Prepend extra vocabulary form elements.
+  $form .= implode('', module_invoke_all('taxonomy','form pre', 'vocabulary',$edit));
   $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('Description of the vocabulary; can be used by modules.'));
   $form .= form_textfield(t('Help text'), 'help', $edit['help'], 50, 255, t('Instructions to present to the user when choosing a term.'));
   $form .= form_checkboxes(t('Types'), 'nodes', $edit['nodes'], $nodes, t('A list of node types you want to associate with this vocabulary.'), NULL, TRUE);
@@ -121,7 +123,7 @@
   $edit['nodes'] = ($edit['nodes']) ? $edit['nodes'] : array();
   $edit['weight'] = ($edit['weight']) ? $edit['weight'] : 0;

-  $data = array('name' => $edit['name'], 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight'],  'module' => isset($edit['module']) ? $edit['module'] : 'taxonomy');
+  $data = array('name' => $edit['name'], 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight'],  'module' => isset($edit['module']) ? $edit['module'] : 'taxonomy', 'language' => $edit['language']);
   if ($edit['vid'] && $edit['name']) {
     db_query('UPDATE {vocabulary} SET '. _taxonomy_prepare_update($data) .' WHERE vid = %d', $edit['vid']);
     db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d", $edit['vid']);
@@ -189,6 +191,8 @@
   $vocabulary = taxonomy_get_vocabulary($vocabulary_id);

   $form = form_textfield(t('Term name'), 'name', $edit['name'], 50, 64, t('The name for this term.  Example: "Linux".'), NULL, TRUE);
+  // Prepend extra term form elements.
+  $form .= implode('', module_invoke_all('taxonomy','form pre', 'term',$edit));
   $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('A description of the term.'));

   if ($vocabulary->hierarchy) {
@@ -231,7 +235,7 @@

 function taxonomy_save_term($edit) {
   if ($edit['tid'] && $edit['name']) {
-    $data = array('name' => $edit['name'], 'description' => $edit['description'], 'weight' => $edit['weight']);
+    $data = array('name' => $edit['name'], 'description' => $edit['description'], 'weight' => $edit['weight'], 'language' => $edit['language']);

     db_query('UPDATE {term_data} SET '. _taxonomy_prepare_update($data) .' WHERE tid = %d', $edit['tid']);
     module_invoke_all('taxonomy', 'update', 'term', $edit);
@@ -242,7 +246,7 @@
   }
   else {
     $edit['tid'] = db_next_id('{term_data}_tid');
-    $data = array('tid' => $edit['tid'], 'name' => $edit['name'], 'description' => $edit['description'], 'vid' => $edit['vid'], 'weight' => $edit['weight']);
+    $data = array('tid' => $edit['tid'], 'name' => $edit['name'], 'description' => $edit['description'], 'vid' => $edit['vid'], 'weight' => $edit['weight'], 'language' => $edit['language']);
     db_query('INSERT INTO {term_data} '. _taxonomy_prepare_insert($data, 1) .' VALUES '. _taxonomy_prepare_insert($data, 2));
     module_invoke_all('taxonomy', 'insert', 'term', $edit);
     $message = t('Created new term %term.', array('%term' => theme('placeholder', $edit['name'])));
@@ -387,7 +391,7 @@
     $blank = '<'. t('none') .'>';
   }

-  return _taxonomy_term_select(check_plain($vocabulary->name), $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
+  return _taxonomy_term_select(check_plain($vocabulary->name), $name, $value, $vid, $help, intval($vocabulary->multiple), $blank, array(), 'create');
 }

 /**
@@ -417,10 +421,10 @@
  */
 function taxonomy_get_vocabularies($type = NULL) {
   if ($type) {
-    $result = db_query("SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type);
+    $result = db_query(db_rewrite_sql("SELECT v.vid, v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $type);
   }
   else {
-    $result = db_query('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid ORDER BY v.weight, v.name');
+    $result = db_query(db_rewrite_sql('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid ORDER BY v.weight, v.name', 'v', 'vid'));
   }

   $vocabularies = array();
@@ -441,7 +445,12 @@
 function taxonomy_node_form($type, $node = '', $help = NULL, $name = 'taxonomy') {
   if (!$node->taxonomy) {
     if ($node->nid) {
-      $terms = array_keys(taxonomy_node_get_terms($node->nid));
+      if (function_exists('taxonomy_access')) {
+        $terms = array_keys(taxonomy_node_get_terms($node->nid, 'tid', 'create'));
+      }
+      else {
+        $terms = array_keys(taxonomy_node_get_terms($node->nid));
+      }
     }
     else {
       $terms = 0;
@@ -451,7 +460,7 @@
     $terms = $node->taxonomy;
   }

-  $c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type);
+  $c = db_query(db_rewrite_sql("SELECT v.vid, v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $type);
   while ($vocabulary = db_fetch_object($c)) {
     $result[] = taxonomy_form($vocabulary->vid, $terms, $help, $name);
   }
@@ -461,11 +470,19 @@
 /**
  * Find all terms associated to the given node, within one vocabulary.
  */
-function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = 'tid') {
-  $result = db_query('SELECT t.* FROM {term_data} t, {term_node} r WHERE t.tid = r.tid AND t.vid = %d AND r.nid = %d ORDER BY weight', $vid, $nid);
+function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = 'tid', $access = 'view') {
+  $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t, {term_node} r WHERE t.tid = r.tid AND t.vid = %d AND r.nid = %d ORDER BY weight', 't', 'tid'), $vid, $nid);
+
   $terms = array();
   while ($term = db_fetch_object($result)) {
-    $terms[$term->$key] = $term;
+    if (function_exists('taxonomy_access')) {
+      if (taxonomy_access($access, $term->tid)) {
+        $terms[$term->$key] = $term;
+      }
+    }
+    else {
+      $terms[$term->$key] = $term;
+    }
   }
   return $terms;
 }
@@ -473,14 +490,21 @@
 /**
  * Find all terms associated to the given node.
  */
-function taxonomy_node_get_terms($nid, $key = 'tid') {
+function taxonomy_node_get_terms($nid, $key = 'tid', $access = 'view') {
   static $terms;

   if (!isset($terms[$nid])) {
-    $result = db_query('SELECT t.* FROM {term_data} t, {term_node} r WHERE r.tid = t.tid AND r.nid = %d ORDER BY weight, name', $nid);
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t, {term_node} r WHERE r.tid = t.tid AND r.nid = %d ORDER BY weight, name', 't', 'tid'), $nid);
     $terms[$nid] = array();
     while ($term = db_fetch_object($result)) {
-      $terms[$nid][$term->$key] = $term;
+      if (function_exists('taxonomy_access')) {
+        if (taxonomy_access($access, $term->tid)) {
+          $terms[$nid][$term->$key] = $term;
+    }
+      }
+      else {
+        $terms[$nid][$term->$key] = $term;
+      }
     }
   }
   return $terms[$nid];
@@ -502,7 +526,14 @@
         }
       }
       else if ($term) {
-        db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
+        if (function_exists('taxonomy_access')) {
+      if (taxonomy_access('create', $term)) {
+            db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
+      }
+    }
+    else {
+          db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
+    }
       }
     }
   }
@@ -523,7 +554,14 @@
     $result = db_query('SELECT t.*, tid1, tid2 FROM {term_relation}, {term_data} t WHERE (t.tid = tid1 OR t.tid = tid2) AND (tid1 = %d OR tid2 = %d) AND t.tid != %d ORDER BY weight, name', $tid, $tid, $tid);
     $related = array();
     while ($term = db_fetch_object($result)) {
-      $related[$term->$key] = $term;
+        if (function_exists('taxonomy_access')) {
+           if (taxonomy_access('view', $term->tid)) {
+             $related[$term->$key] = $term;
+       }
+        }
+    else {
+      $related[$term->$key] = $term;
+    }
     }
     return $related;
   }
@@ -537,10 +575,17 @@
  */
 function taxonomy_get_parents($tid, $key = 'tid') {
   if ($tid) {
-    $result = db_query('SELECT t.* FROM {term_hierarchy} h, {term_data} t WHERE h.parent = t.tid AND h.tid = %d ORDER BY weight, name', $tid);
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_hierarchy} h, {term_data} t WHERE h.parent = t.tid AND h.tid = %d ORDER BY weight, name', 't', 'tid'), $tid);
     $parents = array();
     while ($parent = db_fetch_object($result)) {
-      $parents[$parent->$key] = $parent;
+        if (function_exists('taxonomy_access')) {
+          if (taxonomy_access('view', $parent->tid)) {
+            $parents[$parent->$key] = $parent;
+      }
+        }
+    else {
+      $parents[$parent->$key] = $parent;
+    }
     }
     return $parents;
   }
@@ -570,14 +615,21 @@
  */
 function taxonomy_get_children($tid, $vid = 0, $key = 'tid') {
   if ($vid) {
-    $result = db_query('SELECT t.* FROM {term_hierarchy} h, {term_data} t WHERE t.vid = %d AND h.tid = t.tid AND h.parent = %d ORDER BY weight, name', $vid, $tid);
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_hierarchy} h, {term_data} t WHERE t.vid = %d AND h.tid = t.tid AND h.parent = %d ORDER BY weight, name','t','tid'), $vid, $tid);
   }
   else {
-    $result = db_query('SELECT t.* FROM {term_hierarchy} h, {term_data} t WHERE h.tid = t.tid AND parent = %d ORDER BY weight', $tid);
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_hierarchy} h, {term_data} t WHERE h.tid = t.tid AND parent = %d ORDER BY weight','t','tid'), $tid);
   }
   $children = array();
   while ($term = db_fetch_object($result)) {
-    $children[$term->$key] = $term;
+    if (function_exists('taxonomy_access')) {
+      if (taxonomy_access('view', $term->tid)) {
+        $children[$term->$key] = $term;
+      }
+    }
+    else {
+      $children[$term->$key] = $term;
+    }
   }
   return $children;
 }
@@ -602,24 +654,45 @@
  *   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.
  */
-function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL) {
+function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL, $access = 'view') {
   static $children, $parents, $terms;

   $depth++;

   // We cache trees, so it's not CPU-intensive to call get_tree() on a term
   // and its children, too.
+  // pyromanfo: Cache based on user role and access
+  if (function_exists('taxonomy_access')) {
+    global $user;
+    if (isset($uid)) {
+      $user_object = user_load(array('uid' => $uid));
+    }
+    else {
+      $user_object = $user;
+    }
+    $real_vid = $vid;
+    if (isset($user) && is_array($user->roles)) {
+      $vid = $vid.implode("','", array_keys($user_object->roles)).$access;
+    }
+    else {
+      $vid = $vid.'1'.$access;
+    }
+  }
+  else {
+    $real_vid = $vid;
+  }
+
   if (!isset($children[$vid])) {
     $children[$vid] = array();

-    $result = db_query('SELECT t.*, parent FROM {term_data} t, {term_hierarchy} h WHERE t.tid = h.tid AND t.vid = %d ORDER BY weight, name', $vid);
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.*, parent FROM {term_data} t, {term_hierarchy} h WHERE t.tid = h.tid AND t.vid = %d ORDER BY weight, name', 't', 'tid'), $real_vid);
+
     while ($term = db_fetch_object($result)) {
       $children[$vid][$term->parent][] = $term->tid;
       $parents[$vid][$term->tid][] = $term->parent;
       $terms[$vid][$term->tid] = $term;
     }
   }
-
   $max_depth = (is_null($max_depth)) ? count($children[$vid]) : $max_depth;
   if ($children[$vid][$parent]) {
     foreach ($children[$vid][$parent] as $child) {
@@ -631,12 +704,23 @@
         $tree[] = $terms[$vid][$child];

         if ($children[$vid][$child]) {
-          $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth));
+          $tree = array_merge($tree, taxonomy_get_tree($real_vid, $child, $depth, $max_depth, $access));
         }
       }
     }
   }

+   // strip out entries where the user doesn't have proper access
+   if (function_exists('taxonomy_access') && is_array($tree)) {
+     $newtree = array();
+     foreach ($tree as $term) {
+       if (taxonomy_access($access, $term->tid)) {
+         $newtree[] = $term;
+       }
+     }
+     $tree = $newtree;
+   }
+
   return $tree ? $tree : array();
 }

@@ -697,7 +781,14 @@
   if (!isset($children)) {
     $result = db_query('SELECT tid, parent FROM {term_hierarchy}');
     while ($term = db_fetch_object($result)) {
-      $children[$term->parent][] = $term->tid;
+      if (function_exists('taxonomy_access')) {
+         if (taxonomy_access('view', $term->tid)) {
+           $children[$term->parent][] = $term->tid;
+     }
+      }
+      else {
+        $children[$term->parent][] = $term->tid;
+      }
     }
   }
   return $children[$tid] ? $children[$tid] : array();
@@ -716,10 +807,17 @@
  *   An array of matching term objects.
  */
 function taxonomy_get_term_by_name($name) {
-  $db_result = db_query("SELECT * FROM {term_data} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
+  $db_result = db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t WHERE LOWER('%s') LIKE LOWER(name)", 't', 'tid'), trim($name));
   $result = array();
   while ($term = db_fetch_object($db_result)) {
-    $result[] = $term;
+    if (function_exists('taxonomy_access')) {
+      if (taxonomy_access('view', $term->tid)) {
+         $result[] = $term;
+      }
+    }
+    else {
+      $result[] = $term;
+    }
   }

   return $result;
@@ -745,12 +843,17 @@
  * Return the term object matching a term ID.
  */
 function taxonomy_get_term($tid) {
+  if (function_exists('taxonomy_access')) {
+    if (!taxonomy_access('view', $tid)) {
+      return FALSE;
+    }
+  }
   // simple cache using a static var?
   return db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
 }

-function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
-  $tree = taxonomy_get_tree($vocabulary_id);
+function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array(), $access = 'view') {
+  $tree = taxonomy_get_tree($vocabulary_id,0,-1,NULL,$access);
   $options = array();

   if ($blank) {
@@ -919,9 +1022,25 @@
   // Needed for '+' to show up in RSS discovery URLs
   $rss_tids = urlencode($str_tids);

+  if (function_exists('taxonomy_access')) {
+    $access_tids = array();
+    foreach($tids as $tid) {
+      if (taxonomy_access('view', $tid)) {
+        $access_tids[] = $tid;
+      }
+    }
+    if ($access_tids) {
+      $tids = $access_tids;
+    }
+    else {
+      drupal_access_denied();
+      return;
+    }
+  }
+
   if ($tids) {
     // Build title:
-    $result = db_query('SELECT name FROM {term_data} WHERE tid IN (%s)', implode(',', $tids));
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.name FROM {term_data} t WHERE t.tid IN (%s)', 't', 'tid'), implode(',', $tids));
     $names = array();
     while ($term = db_fetch_object($result)) {
       $names[] = $term->name;
