Index: modules/forum/forum.module =================================================================== RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v retrieving revision 1.375.2.2 diff -u -p -r1.375.2.2 forum.module --- modules/forum/forum.module 2 Feb 2007 04:34:07 -0000 1.375.2.2 +++ modules/forum/forum.module 4 Feb 2007 21:57:09 -0000 @@ -392,7 +392,7 @@ function forum_form(&$node) { $form['title'] = array('#type' => 'textfield', '#title' => check_plain($type->title_label), '#default_value' => $node->title, '#required' => TRUE, '#weight' => -5); if ($node->nid) { - $forum_terms = taxonomy_node_get_terms_by_vocabulary(_forum_get_vid(), $node->nid); + $forum_terms = taxonomy_node_get_terms_by_vocabulary(_forum_get_vid(), $node); // if editing, give option to leave shadows $shadow = (count($forum_terms) > 1); $form['shadow'] = array('#type' => 'checkbox', '#title' => t('Leave shadow copy'), '#default_value' => $shadow, '#description' => t('If you move this topic, you can leave a link in the old forum to the new forum.')); Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.69 diff -u -p -r1.69 system.install --- modules/system/system.install 10 Jan 2007 23:22:34 -0000 1.69 +++ modules/system/system.install 4 Feb 2007 21:57:13 -0000 @@ -511,9 +511,11 @@ function system_install() { db_query("CREATE TABLE {term_node} ( nid int unsigned NOT NULL default '0', tid int unsigned NOT NULL default '0', + vid int unsigned NOT NULL default '0', KEY nid (nid), KEY tid (tid), - PRIMARY KEY (tid,nid) + KEY tid (vid), + PRIMARY KEY (tid,nid,vid) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); db_query("CREATE TABLE {term_relation} ( @@ -977,9 +979,11 @@ function system_install() { db_query("CREATE TABLE {term_node} ( nid int_unsigned NOT NULL default '0', tid int_unsigned NOT NULL default '0', - PRIMARY KEY (tid,nid) + vid int_unsigned NOT NULL default '0', + PRIMARY KEY (tid,nid,vid) )"); db_query("CREATE INDEX {term_node}_nid_idx ON {term_node} (nid)"); + db_query("CREATE INDEX {term_node}_vid_idx ON {term_node} (vid)"); db_query("CREATE INDEX {term_node}_tid_idx ON {term_node} (tid)"); db_query("CREATE TABLE {term_relation} ( @@ -3515,6 +3519,21 @@ function system_update_1021() { * @todo Start this series of updates at 2000. */ +function system_update_2000() { + $ret = array(); + // Add revision id to term-node relation. + db_add_column($ret, 'term_node', 'vid', 'int', array('default' => 0)); + $ret[] = update_sql('ALTER TABLE {term_node} DROP PRIMARY KEY'); + $ret[] = update_sql('ALTER TABLE {term_node} ADD PRIMARY KEY (tid,nid,vid)'); + $ret[] = update_sql('ALTER TABLE {term_node} ADD KEY (vid)'); + // Update all entries with the current revision number. + $nodes = db_query('SELECT nid,vid FROM {node}'); + while ($node = db_fetch_object($nodes)) { + db_query('UPDATE {term_node} SET vid = %d WHERE nid = %d', $node->vid, $node->nid); + } + return $ret; +} + /** * @} End of "defgroup updates-5.0-to-x.x" * The next series of updates should start at 3000. Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.330.2.2 diff -u -p -r1.330.2.2 taxonomy.module --- modules/taxonomy/taxonomy.module 25 Jan 2007 21:51:36 -0000 1.330.2.2 +++ modules/taxonomy/taxonomy.module 4 Feb 2007 21:57:13 -0000 @@ -665,7 +665,7 @@ function taxonomy_form_alter($form_id, & if (!isset($node->taxonomy)) { if ($node->nid) { - $terms = taxonomy_node_get_terms($node->nid); + $terms = taxonomy_node_get_terms($node); } else { $terms = array(); @@ -740,9 +740,19 @@ function taxonomy_form_alter($form_id, & /** * Find all terms associated with the given node, within one vocabulary. + * @param $param + * The node object or the node id. If the node id is given the terms are taken from the current revision. */ -function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = 'tid') { - $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.nid = %d ORDER BY weight', 't', 'tid'), $vid, $nid); +function taxonomy_node_get_terms_by_vocabulary($param, $vid, $key = 'tid') { + + if (is_object($param)) { + $node = $param; + } + else { + $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $param)); + } + + $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.nid = %d AND r.vid = %d ORDER BY weight', 't', 'tid'), $vid, $node->nid, $node->vid); $terms = array(); while ($term = db_fetch_object($result)) { $terms[$term->$key] = $term; @@ -752,18 +762,27 @@ function taxonomy_node_get_terms_by_voca /** * Find all terms associated with the given node, ordered by vocabulary and term weight. + * @param $param + * The node object or the node id. If the node id is given the terms are taken from the current revision. */ -function taxonomy_node_get_terms($nid, $key = 'tid') { +function taxonomy_node_get_terms($param, $key = 'tid') { static $terms; - if (!isset($terms[$nid])) { - $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $nid); - $terms[$nid] = array(); + if (is_object($param)) { + $node = $param; + } + else { + $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $param)); + } + + if (!isset($terms[$node->vid])) { + $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d AND r.vid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $node->nid, $node->vid); + $terms[$node->vid] = array(); while ($term = db_fetch_object($result)) { - $terms[$nid][$term->$key] = $term; + $terms[$node->vid][$term->$key] = $term; } } - return $terms[$nid]; + return $terms[$node->vid]; } /** @@ -787,9 +806,20 @@ function taxonomy_node_validate(&$node) /** * Save term associations for a given node. + * @param $param + * The node object or the node id. If the node id is given, the terms are associated with the current revision of the node. */ -function taxonomy_node_save($nid, $terms) { - taxonomy_node_delete($nid); +function taxonomy_node_save($param, $terms) { + + if (is_object($param)) { + $node = $param; + } + else { + $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $param)); + } + + // Delete terms associated with node revision. + taxonomy_node_delete_revision($node); // Free tagging vocabularies do not send their tids in the form, // so we'll detect them here and process them independently. @@ -831,7 +861,7 @@ function taxonomy_node_save($nid, $terms // Defend against duplicate, differently cased tags if (!isset($inserted[$typed_term_tid])) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $typed_term_tid); + db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $typed_term_tid); $inserted[$typed_term_tid] = TRUE; } } @@ -843,15 +873,15 @@ function taxonomy_node_save($nid, $terms if (is_array($term)) { foreach ($term as $tid) { if ($tid) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $tid); + db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $tid); } } } else if (is_object($term)) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term->tid); + db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $term->tid); } else if ($term) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term); + db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $term); } } } @@ -859,9 +889,31 @@ function taxonomy_node_save($nid, $terms /** * Remove associations of a node to its terms. + * @param $param + * The node object or the node id. */ -function taxonomy_node_delete($nid) { - db_query('DELETE FROM {term_node} WHERE nid = %d', $nid); +function taxonomy_node_delete($param) { + if (is_numeric($param)) { + db_query('DELETE FROM {term_node} WHERE nid = %d', $param); + } + else { + db_query('DELETE FROM {term_node} WHERE nid = %d', $param->nid); + } +} + +/** + * Remove associations of a node to its terms. + * @param $param + * The node object or the node id. If the node id is given the current revision is deleted. + */ +function taxonomy_node_delete_revision($param) { + if (is_numeric($param)) { + $node = node_load($param); + } + else { + $node = $param; + } + db_query('DELETE FROM {term_node} WHERE vid = %d', $node->vid); } /** @@ -1046,10 +1098,10 @@ function taxonomy_term_count_nodes($tid, if (!isset($count[$type])) { // $type == 0 always evaluates TRUE if $type is a string if (is_numeric($type)) { - $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid')); + $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid AND t.vid = n.vid WHERE n.status = 1 GROUP BY t.tid')); } else { - $result = db_query(db_rewrite_sql("SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type); + $result = db_query(db_rewrite_sql("SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid AND t.vid = n.vid WHERE n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type); } while ($term = db_fetch_object($result)) { $count[$type][$term->tid] = $term->c; @@ -1227,14 +1279,14 @@ function taxonomy_select_nodes($tids = a if ($operator == 'or') { $str_tids = implode(',', call_user_func_array('array_merge', $descendant_tids)); - $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1 ORDER BY '. $order; - $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1'; + $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid AND n.vid = t.vid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1 ORDER BY '. $order; + $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid AND n.vid = tn.vid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1'; } else { $joins = ''; $wheres = ''; foreach ($descendant_tids as $index => $tids) { - $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid'; + $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid AND n.vid = tn'. $index .'.vid'; $wheres .= ' AND tn'. $index .'.tid IN ('. implode(',', $tids) .')'; } $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY '. $order; @@ -1276,22 +1328,32 @@ function taxonomy_render_nodes($result) function taxonomy_nodeapi($node, $op, $arg = 0) { switch ($op) { case 'load': - $output['taxonomy'] = taxonomy_node_get_terms($node->nid); + $output['taxonomy'] = taxonomy_node_get_terms($node); return $output; + case 'insert': - taxonomy_node_save($node->nid, $node->taxonomy); + taxonomy_node_save($node, $node->taxonomy); break; + case 'update': - taxonomy_node_save($node->nid, $node->taxonomy); + taxonomy_node_save($node, $node->taxonomy); break; + case 'delete': - taxonomy_node_delete($node->nid); + taxonomy_node_delete($node); + break; + + case 'delete revision': + taxonomy_node_delete_revision($node); break; + case 'validate': taxonomy_node_validate($node); break; + case 'rss item': return taxonomy_rss_item($node); + case 'update index': return taxonomy_node_update_index($node); }