Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.436 diff -u -p -r1.436 taxonomy.module --- modules/taxonomy/taxonomy.module 2 Nov 2008 17:46:47 -0000 1.436 +++ modules/taxonomy/taxonomy.module 3 Nov 2008 21:35:21 -0000 @@ -624,6 +624,41 @@ function taxonomy_node_get_terms_by_voca } /** + * Find all term IDs associated with a set of nodes. + * + * @param $nodes + * An array of node objects. + * + * @return + * An array of term and node IDs ordered by vocabulary and term weight. + */ +function taxonomy_get_tids_from_nodes($nodes) { + $vids = array(); + foreach ($nodes as $node) { + $vids = $node->vid; + } + + $query = db_select('term_node', 'r'); + $query->addField('r', 'tid'); + $query->addField('r', 'nid'); + $query->addField('r', 'vid'); + $query->join('term_data', 't', 'r.tid = t.tid'); + $query->join('vocabulary', 'v', 't.vid = v.vid'); + $query->condition('r.vid', $vids, 'IN'); + $query->orderBy('v.weight'); + $query->orderBy('t.weight'); + $query->orderBy('t.name'); + $query->addTag('term_access'); + $result = $query->execute(); + $tids = array(); + foreach ($result as $record) { + $tids[$record->tid] = $record; + } + + return $tids; +} + +/** * Find all terms associated with the given node, ordered by vocabulary and term weight. */ function taxonomy_node_get_terms($node, $key = 'tid') { @@ -1050,6 +1085,92 @@ function taxonomy_terms_load($str_tids) } /** + * Load multiple taxonomy terms based on certain conditions. + * + * @param $tids + * An array of taxonomy term IDs. + * @param $conditions + * An array of conditions to add to the query. + * @param $reset + * Whether to reset the internal cache. + * + * @return + * An array of term objects, indexed by tid. + */ +function taxonomy_term_multiple_load($tids = array(), $conditions = array(), $reset = FALSE) { + static $term_cache = array(); + + if ($reset) { + $term_cache = array(); + } + + $terms = array(); + + // Load any available terms from the cache. + if (!empty($tids)) { + foreach ($tids as $key => $tid) { + if (isset($term_cache[$tid])) { + $terms[$tid] = $term_cache[$tid]; + unset($tids[$key]); + } + } + } + + // If any terms loaded from the cache don't match a condition, remove them. + if (!empty($conditions)) { + foreach ($terms as $tid => $term) { + foreach ($conditions as $key => $value) { + if ($term->$key != $value) { + unset($terms[$tid]); + } + } + } + } + + // Fetch any remaining terms from the database. + if (!empty($tids) || !empty($conditions)) { + $query = db_select('term_data', 't'); + $term_data_fields = drupal_schema_fields_sql('term_data'); + foreach ($term_data_fields as $field) { + $query->addField('t', $field, $field); + } + + // If the $tids array is populated, add those to the query. + if (!empty($tids)) { + $query->condition('t.tid', $tids, 'IN'); + } + + // If the conditions array is populated, add those to the query. + if (!empty($conditions)) { + foreach ($conditions as $field => $value) { + $query->conditions('t.' . $field, $value); + } + } + $result = $query->execute(); + + foreach ($result as $record) { + $terms[$record->tid] = $record; + } + } + + // Invoke hook_taxonomy_multiple_load() on the terms array. + foreach (module_implements('taxonomy_term_multiple_load') as $module) { + $function = $module . '_taxonomy_term_multiple_load'; + call_user_func($function, &$terms); + } + + // Invoke hook_taxonomy_term_load() on each individual term. + foreach (module_implements('taxonomy_term_load') as $module) { + $function = $module . '_taxonomy_term_load'; + array_walk(&$terms, $function); + } + + $term_cache += $terms; + + return $terms; +} + +/** * Return the term object matching a term ID. * * @param $tid @@ -1062,12 +1183,7 @@ function taxonomy_term_load($tid, $reset if (!is_numeric($tid)) { return FALSE; } - static $terms = array(); - if (!isset($terms[$tid]) || $reset) { - $terms[$tid] = taxonomy_get_term_data($tid, $reset); - module_invoke_all('taxonomy_term_load', $terms[$tid]); - } - return $terms[$tid]; + return array_shift(taxonomy_term_multiple_load(array($tid), NULL, $reset)); } /** @@ -1210,9 +1326,17 @@ function taxonomy_render_nodes($result) /** * Implementation of hook_nodeapi_load(). */ -function taxonomy_nodeapi_load($node, $arg = 0) { - $output['taxonomy'] = taxonomy_node_get_terms($node); - return $output; +function taxonomy_nodeapi_load(&$nodes) { + $tids = taxonomy_get_tids_from_nodes($nodes); + $terms = taxonomy_term_multiple_load(array_keys($tids)); + foreach ($nodes as $node) { + $nodes[$node->nid]['taxonomy'] = array(); + foreach ($tids as $tid) { + if ($node->vid == $tid->vid) { + $nodes[$node->nid]['taxonomy'][] = $terms[$tid]; + } + } + } } /**