Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.464
diff -u -p -r1.464 forum.module
--- modules/forum/forum.module	19 Sep 2008 20:25:02 -0000	1.464
+++ modules/forum/forum.module	28 Sep 2008 14:26:02 -0000
@@ -224,7 +224,7 @@ function forum_nodeapi(&$node, $op, $tea
         foreach ($node->taxonomy as $term) {
           if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
             if (in_array($term, $containers)) {
-              $term = taxonomy_term_load($term);
+              $term = taxonomy_get_term_data($term);
               form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => $term->name)));
             }
           }
@@ -565,8 +565,6 @@ function forum_get_topics($tid, $sortby,
     }
   }
 
-  $term = taxonomy_term_load($tid);
-
   $sql = db_rewrite_sql("SELECT n.nid, r.tid, n.title, n.type, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid != 0, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments, f.tid AS forum_tid FROM {node_comment_statistics} l INNER JOIN {node} n ON n.nid = l.nid INNER JOIN {users} cu ON l.last_comment_uid = cu.uid INNER JOIN {term_node} r ON n.vid = r.vid INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {forum} f ON n.vid = f.vid WHERE n.status = 1 AND r.tid = %d");
   $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
   $sql .= ', n.created DESC';  // Always add a secondary sort order so that the news forum topics are on top.
Index: modules/simpletest/tests/taxonomytest.info
===================================================================
RCS file: modules/simpletest/tests/taxonomytest.info
diff -N modules/simpletest/tests/taxonomytest.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/taxonomytest.info	28 Sep 2008 14:26:03 -0000
@@ -0,0 +1,9 @@
+; $Id$
+name = "Taxonomy test module"
+description = "Tests functions and hooks not used in core".
+package = Testing
+version = VERSION
+core = 7.x
+files[] = taxonomytest.module
+hidden[] = TRUE
+dependencies[] = Taxonomy
Index: modules/simpletest/tests/taxonomytest.install
===================================================================
RCS file: modules/simpletest/tests/taxonomytest.install
diff -N modules/simpletest/tests/taxonomytest.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/taxonomytest.install	28 Sep 2008 14:26:03 -0000
@@ -0,0 +1,54 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_schema().
+ */
+function taxonomytest_schema() {
+  $schema['term_antonym'] = array(
+    'description' => t('Stores term antonyms.'),
+    'fields' => array(
+      'taid' => array(
+        'type' => 'serial',
+        'not null' => TRUE,
+        'description' => t('Primary Key: Unique term antonym ID.'),
+      ),
+      'tid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => t('The {term_data}.tid of the term.'),
+      ),
+      'name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => t('The name of the antonym.'),
+      ),
+    ),
+    'indexes' => array(
+      'tid' => array('tid'),
+      'name_tid' => array('name', 'tid'),
+    ),
+    'primary key' => array('taid'),
+  );
+
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function taxonomytest_install() {
+  drupal_install_schema('taxonomytest');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function taxonomytest_uninstall() {
+  drupal_uninstall_schema('taxonomytest');
+}
+
Index: modules/simpletest/tests/taxonomytest.module
===================================================================
RCS file: modules/simpletest/tests/taxonomytest.module
diff -N modules/simpletest/tests/taxonomytest.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/taxonomytest.module	28 Sep 2008 14:26:03 -0000
@@ -0,0 +1,73 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Test module for Taxonomy hooks and functions not used in core.
+ */
+
+/**
+ * Implementation of hook_taxonomy_term_load().
+ */
+function taxonomytest_taxonomy_term_load($term) {
+  $term->antonyms = taxonomytest_get_antonyms($term->tid);
+}
+
+/**
+ * Implementation of hook_taxonomy_term_save().
+ */
+function taxonomytest_taxonomy_term_save($term) {
+  drupal_set_message('Hello World');
+  taxonomytest_taxonomy_term_delete($term);
+  if (!empty($term->antonyms)) {
+    foreach (explode ("\n", str_replace("\r", '', $term->antonyms)) as $antonym) {
+      if ($antonym) {
+        db_insert('term_antonym')
+        ->fields(array(
+          'tid' => $term->tid,
+          'name' => rtrim($antonym),
+        ))
+        ->execute();
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_taxonomy_term_delete().
+ */
+function taxonomytest_taxonomy_term_delete($term) {
+  db_delete('term_antonym')->condition('tid', $term->tid)->execute();
+}
+
+/**
+ * Implementation of hook_form_alter().
+ */
+function taxonomytest_form_alter(&$form, $form_state, $form_id) {
+  if ($form_id == 'taxonomy_form_term') {
+    $antonyms = taxonomytest_get_antonyms($form['#term']['tid']);
+    $form['advanced']['antonyms'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Antonyms'),
+      '#default_value' => !empty($antonyms) ? implode("\n", $antonyms) : NULL,
+      '#description' => t('Antonyms of this term, one antonym per line.')
+    );
+  }
+}
+
+/**
+ * Return an array of antonyms of the given term ID.
+ */
+function taxonomytest_get_antonyms($tid) {
+  if ($tid) {
+    $antonyms = array();
+    $result = db_query('SELECT name FROM {term_antonym} WHERE tid = :tid', array(':tid' => $tid));
+    foreach($result AS $antonym) {
+      $antonyms[] = $antonym->name;
+    }
+    return $antonyms;
+  }
+  else {
+    return FALSE;
+  }
+}
Index: modules/simpletest/tests/taxonomytest.test
===================================================================
RCS file: modules/simpletest/tests/taxonomytest.test
diff -N modules/simpletest/tests/taxonomytest.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/taxonomytest.test	28 Sep 2008 14:26:03 -0000
@@ -0,0 +1,53 @@
+<?php
+// $Id$
+
+class TaxonomyHooksTestCase extends DrupalWebTestCase {
+  /**
+   * Implementation of getInfo().
+   */
+  function getInfo() {
+    return array(
+      'name' => t('Taxonomy term hooks'),
+      'description' => t('Hooks for taxonomy term load/save/delete.'),
+      'group' => t('Taxonomy')
+    );
+  }
+
+  /**
+   * Implementation of setUp().
+   */
+  function setUp() {
+    parent::setUp('taxonomy', 'taxonomytest');
+    $taxonomy_admin = $this->drupalCreateUser(array('administer taxonomy'));
+    $this->drupalLogin($taxonomy_admin);
+  }
+
+  /**
+   * Test that hooks are run correctly on creating, editing and deleting a term.
+   */
+  function testTaxonomyTermHooks() {
+    // Create a term with one antonym.
+    $edit = array(
+      'name' => $this->randomName(),
+      'antonyms' => 'Long',
+    );
+    $this->drupalPost('admin/content/taxonomy/1/add', $edit, t('Save'));
+    $terms = taxonomy_get_term_by_name($edit['name']);
+    $term = taxonomy_term_load($terms[0]->tid);
+    $this->assertEqual($term->antonyms[0], $edit['antonyms'], t('Antonyms were loaded into the term object'));
+
+    // Update the term with a different antonym.
+    $edit = array(
+      'name' => $this->randomName(),
+      'antonyms' => 'Short',
+    );
+    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
+    $term = taxonomy_term_load($term->tid, TRUE);
+    $this->assertTrue(in_array($edit['antonyms'], $term->antonyms), t('Antonym was successfully edited'));
+
+    // Delete the term.
+    taxonomy_del_term($term->tid);
+    $antonyms = db_query('SELECT taid FROM {term_antonym} WHERE tid = :tid', array(':tid' => $term->tid))->fetchField();
+    $this->assertFalse($antonyms, t('The antonyms were deleted from the database.'));
+  }
+}
Index: modules/taxonomy/taxonomy.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v
retrieving revision 1.29
diff -u -p -r1.29 taxonomy.admin.inc
--- modules/taxonomy/taxonomy.admin.inc	19 Sep 2008 20:25:03 -0000	1.29
+++ modules/taxonomy/taxonomy.admin.inc	28 Sep 2008 14:26:03 -0000
@@ -747,7 +747,8 @@ function taxonomy_form_term_submit($form
     return;
   }
 
-  switch (taxonomy_save_term($form_state['values'])) {
+  $status = taxonomy_save_term($form_state['values']);
+  switch ($status) {
     case SAVED_NEW:
       drupal_set_message(t('Created new term %term.', array('%term' => $form_state['values']['name'])));
       watchdog('taxonomy', 'Created new term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'taxonomy/term/' . $form_state['values']['tid'] . '/edit'));
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.430
diff -u -p -r1.430 taxonomy.module
--- modules/taxonomy/taxonomy.module	27 Sep 2008 20:37:01 -0000	1.430
+++ modules/taxonomy/taxonomy.module	28 Sep 2008 14:26:04 -0000
@@ -320,18 +320,19 @@ function taxonomy_save_term(&$form_value
     'weight' => 0
   );
 
+  $term = (object) $form_values;
+
   if (!empty($form_values['tid']) && $form_values['name']) {
-    drupal_write_record('term_data', $form_values, 'tid');
-    $hook = 'update';
-    $status = SAVED_UPDATED;
+    $status = drupal_write_record('term_data', $form_values, 'tid');
+    module_invoke_all('taxonomy_term_save', $term);
   }
   else if (!empty($form_values['tid'])) {
     return taxonomy_del_term($form_values['tid']);
   }
   else {
-    drupal_write_record('term_data', $form_values);
-    $hook = 'insert';
-    $status = SAVED_NEW;
+    $status = drupal_write_record('term_data', $form_values);
+    $term->tid = $form_values['tid'];
+    module_invoke_all('taxonomy_term_save', $term);
   }
 
   db_query('DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d', $form_values['tid'], $form_values['tid']);
@@ -372,10 +373,6 @@ function taxonomy_save_term(&$form_value
     }
   }
 
-  if (isset($hook)) {
-    module_invoke_all('taxonomy', $hook, 'term', $form_values);
-  }
-
   cache_clear_all();
 
   return $status;
@@ -405,7 +402,7 @@ function taxonomy_del_term($tid) {
         }
       }
 
-      $term = (array) taxonomy_term_load($tid);
+      $term = taxonomy_term_load($tid);
 
       db_query('DELETE FROM {term_data} WHERE tid = %d', $tid);
       db_query('DELETE FROM {term_hierarchy} WHERE tid = %d', $tid);
@@ -413,7 +410,7 @@ function taxonomy_del_term($tid) {
       db_query('DELETE FROM {term_synonym} WHERE tid = %d', $tid);
       db_query('DELETE FROM {term_node} WHERE tid = %d', $tid);
 
-      module_invoke_all('taxonomy', 'delete', 'term', $term);
+      module_invoke_all('taxonomy_term_delete', $term);
     }
 
     $tids = $orphans;
@@ -1048,7 +1045,24 @@ function taxonomy_term_load($tid, $reset
   }
   static $terms = array();
   if (!isset($terms[$tid]) || $reset) {
-    $terms[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
+    $terms[$tid] = taxonomy_get_term_data($tid, $reset);
+    module_invoke_all('taxonomy_term_load', $terms[$tid]);
+  }
+  return $terms[$tid];
+}
+
+/**
+ * Return a term object from the term_data table.
+ * @param $tid
+ *   A term's ID
+ * @return Object
+ *  A term object. Results are statically cached.
+ */
+function taxonomy_get_term_data($tid, $reset = FALSE) {
+   static $terms = array();
+
+  if (!isset($terms[$tid]) || $reset) {
+    $terms[$tid] = db_query('SELECT * FROM {term_data} WHERE tid = :tid', array(':tid' => $tid))->fetchObject();
   }
   return $terms[$tid];
 }
@@ -1118,7 +1132,7 @@ function taxonomy_select_nodes($tids = a
       $depth = NULL;
     }
     foreach ($tids as $index => $tid) {
-      $term = taxonomy_term_load($tid);
+      $term = taxonomy_get_term_data($tid);
       $tree = taxonomy_get_tree($term->vid, $tid, -1, $depth);
       $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree));
     }
