Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.316 diff -u -r1.316 taxonomy.module --- modules/taxonomy/taxonomy.module 11 Sep 2006 08:18:24 -0000 1.316 +++ modules/taxonomy/taxonomy.module 14 Sep 2006 10:01:19 -0000 @@ -611,18 +611,7 @@ function taxonomy_form_alter($form_id, &$form) { if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) { $node = $form['#node']; - - if (!isset($node->taxonomy)) { - if ($node->nid) { - $terms = taxonomy_node_get_terms($node->nid); - } - else { - $terms = array(); - } - } - else { - $terms = $node->taxonomy; - } + $terms = isset($node->taxonomy) ? $node->taxonomy : array(); $c = db_query(db_rewrite_sql("SELECT v.* 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'), $node->type); @@ -706,17 +695,26 @@ /** * Find all terms associated to the given node, ordered by vocabulary and term weight. */ -function taxonomy_node_get_terms($nid, $key = 'tid') { +function taxonomy_node_get_terms(&$node, $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(); - while ($term = db_fetch_object($result)) { - $terms[$nid][$term->$key] = $term; + if (!isset($terms[$node->nid])) { + $vocabularies = taxonomy_get_vocabularies($node->type); + if (count($vocabularies)) { + $placeholder = array_fill(0, count($vocabularies), '%d'); + $args = array_keys($vocabularies); + $args[] = $node->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 AND v.vid IN ('. implode(',', $placeholder) .') WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $args); + $terms[$node->nid] = array(); + while ($term = db_fetch_object($result)) { + $terms[$node->nid][$term->$key] = $term; + } + } + else { + $terms[$node->nid] = array(); } } - return $terms[$nid]; + return $terms[$node->nid]; } /** @@ -741,8 +739,11 @@ /** * Save term associations for a given node. */ -function taxonomy_node_save($nid, $terms) { - taxonomy_node_delete($nid); +function taxonomy_node_save($nid, $terms, $old_terms = FALSE) { + if ($old_terms === FALSE) { + $node = node_load($nid); + $old_terms = $node->taxonomy; + } // Free tagging vocabularies do not send their tids in the form, // so we'll detect them here and process them independently. @@ -784,7 +785,7 @@ // Defend against duplicate, different cased tags if (!isset($inserted[$typed_term_tid])) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $typed_term_tid); + _taxonomy_node_insert_tid($nid, $typed_term_tid, $old_terms); $inserted[$typed_term_tid] = TRUE; } } @@ -796,18 +797,37 @@ if (is_array($term)) { foreach ($term as $tid) { if ($tid) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $tid); + _taxonomy_node_insert_tid($nid, $tid, $old_terms); } } } else if (is_object($term)) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term->tid); + _taxonomy_node_insert_tid($nid, $term->tid, $old_terms); } else if ($term) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term); + _taxonomy_node_insert_tid($nid, $term, $old_terms); } } } + //delete removed terms + if (!empty($old_terms)) { + $placeholder = array_fill(0, count($old_terms), '%d'); + $args = array($nid); + $args = array_merge($args, array_keys($old_terms)); + db_query('DELETE FROM {term_node} WHERE nid = %d AND tid IN ('. implode(',', $placeholder) .')', $args); + } +} + +/* + * Helper function for taxonomy_node_save() + */ +function _taxonomy_node_insert_tid($nid, $tid, &$old_terms) { + if (!array_key_exists($tid, $old_terms)) { + db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $tid); + } + else { + unset($old_terms[$tid]); + } } /** @@ -1173,13 +1193,15 @@ 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->nid, $node->taxonomy, array()); break; - case 'update': - taxonomy_node_save($node->nid, $node->taxonomy); + case 'submit': + if ($node->nid) { + taxonomy_node_save($node->nid, $node->taxonomy); + } break; case 'delete': taxonomy_node_delete($node->nid);