Index: taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.335
diff -u -r1.335 taxonomy.module
--- taxonomy.module	25 Jan 2007 22:14:06 -0000	1.335
+++ taxonomy.module	27 Jan 2007 18:00:38 -0000
@@ -1190,10 +1190,9 @@
 /**
  * Finds all nodes that match selected taxonomy conditions.
  *
- * @param $tids
- *   An array of term IDs to match.
- * @param $operator
- *   How to interpret multiple IDs in the array. Can be "or" or "and".
+ * @param $parts
+ *   An array of parts containing the term IDs to be ANDed.
+ *   The term IDs in each part will be Ored.
  * @param $depth
  *   How many levels deep to traverse the taxonomy tree. Can be a nonnegative
  *   integer or "all".
@@ -1205,46 +1204,49 @@
  * @return
  *   A resource identifier pointing to the query results.
  */
-function taxonomy_select_nodes($tids = array(), $operator = 'or', $depth = 0, $pager = TRUE, $order = 'n.sticky DESC, n.created DESC') {
-  if (count($tids) > 0) {
-    // For each term ID, generate an array of descendant term IDs to the right depth.
-    $descendant_tids = array();
-    if ($depth === 'all') {
-      $depth = NULL;
-    }
-    foreach ($tids as $index => $tid) {
+function taxonomy_select_nodes($parts = array(), $depth = 0, $pager = TRUE, $order = 'n.sticky DESC, n.created DESC') {
+  if (empty($parts)) return FALSE;
+
+  // For each term ID, generate an array of descendant term IDs to the right depth.
+  $descendant_tids = array();
+  if ($depth === 'all') {
+    $depth = NULL;
+  }
+
+  $joins = '';
+  $wheres = '';
+
+  foreach ($parts as $index => $tids) {
+    $list = array();
+    $tids = preg_split('/[ ]/', $tids);
+    foreach ($tids as $tid) {
+      // For each term ID, generate an array of descendant term IDs to the right depth.
+      $descendant_tids = array();
       $term = taxonomy_get_term($tid);
       $tree = taxonomy_get_tree($term->vid, $tid, -1, $depth);
       $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree));
-    }
 
-    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';
-    }
-    else {
-      $joins = '';
-      $wheres = '';
-      foreach ($descendant_tids as $index => $tids) {
-        $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid';
-        $wheres .= ' AND tn'. $index .'.tid IN ('. implode(',', $tids) .')';
+      foreach ($descendant_tids as $i => $tid1) {
+	$list[] = implode(',', $tid1);
       }
-      $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY '. $order;
-      $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres;
-    }
-    $sql = db_rewrite_sql($sql);
-    $sql_count = db_rewrite_sql($sql_count);
-    if ($pager) {
-      $result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count);
-    }
-    else {
-      $result = db_query_range($sql, 0, variable_get('feed_default_items', 10));
     }
+    if (empty($list)) continue;
+
+    $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid';
+    $wheres .= ' AND tn'. $index .'.tid IN ('. implode(',', $list) .')';
   }
 
+  $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY '. $order;
+  $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n '. $joins .' WHERE n.status = 1 ' . $wheres;
+  if ($pager) {
+    $result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count);
+  }
+  else {
+    $result = db_query_range($sql, 0, variable_get('feed_default_items', 10));
+  }
   return $result;
 }
+  
 
 /**
  * Accepts the result of a pager_query() call, such as that performed by
@@ -1304,27 +1306,21 @@
 }
 
 /**
- * Parses a comma or plus separated string of term IDs.
+ * Parses a comma and/or plus separated string of term IDs.
  *
  * @param $str_tids
- *   A string of term IDs, separated by plus or comma.
+ *   A string of term IDs, separated by plus and/or comma.
  *   comma (,) means AND
  *   plus (+) means OR
  *
- * @return an associative array with an operator key (either 'and'
- *   or 'or') and a tid key containing an array of the term ids.
+ * @return an associative array with a 'parts' key containing term IDs
+ * splitted into parts to be ANDed, and a 'tids' key containing an
+ * array of all the term ids.
  */
 function taxonomy_terms_parse_string($str_tids) {
   $terms = array();
-  if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str_tids)) {
-    $terms['operator'] = 'or';
-    // The '+' character in a query string may be parsed as ' '.
-    $terms['tids'] = preg_split('/[+ ]/', $str_tids);
-  }
-  else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str_tids)) {
-    $terms['operator'] = 'and';
-    $terms['tids'] = explode(',', $str_tids);
-  }
+  $terms['parts'] = preg_split('/[,]/', $str_tids);
+  $terms['tids'] = preg_split('/[,|+ ]/', $str_tids);
   return $terms;
 }
 
@@ -1334,7 +1330,7 @@
  */
 function taxonomy_term_page($str_tids = '', $depth = 0, $op = 'page') {
   $terms = taxonomy_terms_parse_string($str_tids);
-  if ($terms['operator'] != 'and' && $terms['operator'] != 'or') {
+  if (!$terms['parts']) {
     drupal_not_found();
   }
 
@@ -1363,7 +1359,7 @@
           $breadcrumbs = array_reverse($breadcrumbs);
           menu_set_location($breadcrumbs);
 
-          $output = taxonomy_render_nodes(taxonomy_select_nodes($tids, $terms['operator'], $depth, TRUE));
+          $output = taxonomy_render_nodes(taxonomy_select_nodes($terms['parts'], $depth, TRUE));
           drupal_add_feed(url('taxonomy/term/'. $str_tids .'/'. $depth .'/feed'), 'RSS - '. $title);
           return $output;
           break;
@@ -1374,7 +1370,7 @@
           $channel['title'] = variable_get('site_name', 'Drupal') .' - '. $title;
           $channel['description'] = $term->description;
 
-          $result = taxonomy_select_nodes($tids, $terms['operator'], $depth, FALSE);
+          $result = taxonomy_select_nodes($terms['parts'], $depth, FALSE);
           node_feed($result, $channel);
           break;
         default:
