Nodes and Terms in Drupal 6
I often find myself writing custom chunks of code in Drupal to build taxonomy term arguments consisting of terms shared by the current node. This is useful in generating blocks of content based on shared tags. I finally decided to expand that code into a pretty useful function. The function accepts node(s), term id(s), and some configuration options and returns either an array of term objects or a concatenated string of term ids. I think it's pretty flexible for such a short amount of code, comments aside. Maybe someone else will find it useful!
/**
* Gets terms for a node filtered by certain vocabularies.
*
* Example(s):
*
* Get an array of terms from node 1 from vocabularies 2 and 3:
* mymodule_terms(1,array(2,3));
*
* Get terms common to nodes 1, 2, and 3 from vocabulary 7
* in a string separated by a '+':
* mymodule_terms(array(1,2,3), 7, array('intersection'=>true, 'implode'=>'+'));
*
* @param mixed $node An array of nids or node objects or a single nid or node objects
* @param mixed $vid An array of vids or single vid by which to filter, false to ignore
* @param mixed $config Additional configuration parameters including implode and intersection
* @return mixed A hash of $tid => $term pairs or a string of tids separated by the contents of $config[implode]
*/
function mymodule_terms($node, $vid = false, $config = array()) {
$defaults = array('implode' => false, 'intersection' => false);
$config += $defaults;
$tids = array();
$count = array();
/**
* Convert single nodes or vids into arrays
*/
if(!is_array($node)) $node = array($node);
if(!is_array($vid) && $vid != false) $vid = array($vid);
foreach($node as $n) {
/**
* Load the node if only a nid is provided
*/
if(!is_object($n)) $n = node_load($n);
/**
* Iterate over all terms, adding any that match the specified vids
* to the result set
*/
foreach($n->taxonomy as $tid => $term) {
if(!$vid || in_array($term->vid, $vid)) {
$tids[$tid] = $term;
$count[$tid] = (isset($count[$tid])) ? $count[$tid] + 1 : 1;
}
}
}
/**
* If we only want tids that all passed nodes share, strip out
* any that aren't present for each node
*/
if(count($node) > 1 && $config['intersection']) {
foreach($tids as $tid=>$term) {
if($count[$tid] != count($node)) unset($tids[$tid]);
}
}
/**
* Return either the array or a string of tids.
*/
return ($config['implode'] !== false) ? implode($config['implode'], array_keys($tids)) : $tids;
}