Index: query.php
===================================================================
--- query.php	(revision 12584)
+++ query.php	(working copy)
@@ -1794,18 +1794,6 @@
 			$q['cat'] = implode(',', $req_cats);
 		}
 
-		if ( !empty($q['category__in']) ) {
-			$join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
-			$whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'category' ";
-			$include_cats = "'" . implode("', '", $q['category__in']) . "'";
-			$whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_cats) ";
-		}
-
-		if ( !empty($q['category__not_in']) ) {
-			$cat_string = "'" . implode("', '", $q['category__not_in']) . "'";
-			$whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'category' AND tt.term_id IN ($cat_string) )";
-		}
-
 		// Category stuff for nice URLs
 		if ( '' != $q['category_name'] && !$this->is_singular ) {
 			$q['category_name'] = implode('/', array_map('sanitize_title', explode('/', $q['category_name'])));
@@ -1860,54 +1848,79 @@
 				$q['tag_slug__in'][] = $q['tag'];
 			}
 		}
+		
+		// Set up the arrays for querying by taxonomy (tag and category included)
+		$this->taxonomies__in = array();
+		$this->taxonomies__not_in = array();
+		$this->taxonomies__and = array();
+		$this->taxonomies_slug__in = array();
+		$this->taxonomies_slug__and = array();
+			
+		// loop through registered taxonomies to check for respective query vars (must be done after 'tag' and 'cat')
+		foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
+		    
+		    // check if query vars have been passed for the taxonomy (annoying explicit check for tag as the taxonomy is called post_tag)
+		    if( array_key_exists( $taxonomy . '__in', $q ) && !empty($qv[$taxonomy . '__in']) ) {
+		    	$is = 'is_' . $taxonomy;
+		    	$this->$is = true;
+		    	$this->taxonomies__in[$taxonomy . '__in'] = $taxonomy;
+		    	
+		    	// cast the array to integers, again annoying check for tag passed instead of post_tag
+		    	$q[$taxonomy . '__in'] = array_map('absint', $q[$taxonomy . '__in']);
+		    }
+		    elseif( array_key_exists( $taxonomy . '__not_in', $q ) && !empty($q[$taxonomy . '__not_in']) ) {
+		    	$is = 'is_' . $taxonomy;
+		    	$this->taxonomies__not_in[$taxonomy . '__not_in'] = $taxonomy;
+		    	$q[$taxonomy . '__not_in'] = array_map('absint', $q[$taxonomy . '__not_in']);
 
-		if ( !empty($q['category__in']) || !empty($q['meta_key']) || !empty($q['tag__in']) || !empty($q['tag_slug__in']) ) {
-			$groupby = "{$wpdb->posts}.ID";
-		}
+		    }
+		    elseif( array_key_exists( $taxonomy . '__and', $q ) && !empty($q[$taxonomy . '__and']) ) {
+		    	$is = 'is_' . $taxonomy;
+		    	$this->$is = true;
+		    	$this->taxonomies__and[$taxonomy . '__and'] = $taxonomy;
+		    	$q[$taxonomy . '__and'] = array_map('absint', $q[$taxonomy . '__and']);
+		    }
+		    elseif( array_key_exists( $taxonomy . '_slug__in', $q ) && !empty($q[$taxonomy . '_slug__in']) ) {
+		    	$is = 'is_' . $taxonomy;
+		    	$this->$is = true;
+		    	$this->taxonomies_slug__in[$taxonomy . '_slug__in'] = $taxonomy;
+		    	$q[$taxonomy . '_slug__in'] = array_map('sanitize_title', $q[$taxonomy . '_slug__in']);
 
-		if ( !empty($q['tag__in']) && empty($q['cat']) ) {
-			$join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
-			$whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' ";
-			$include_tags = "'" . implode("', '", $q['tag__in']) . "'";
-			$whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_tags) ";
-			$reqtag = is_term( $q['tag__in'][0], 'post_tag' );
-			if ( !empty($reqtag) )
-				$q['tag_id'] = $reqtag['term_id'];
+		    }
+		    elseif( array_key_exists( $taxonomy . '_slug__and', $q ) && !empty($q[$taxonomy . '_slug__and']) ) {
+		    	$is = 'is_' . $taxonomy;
+		    	$this->$is = true;
+		    	$this->taxonomies_slug__and[$taxonomy . '_slug__and'] = $taxonomy;
+		    	$qv[$taxonomy . '_slug__and'] = array_map('sanitize_title', $q[$taxonomy . '_slug__and']);
+		    }
 		}
 
-		if ( !empty($q['tag_slug__in']) && empty($q['cat']) ) {
-			$join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) INNER JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id) ";
-			$whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' ";
-			$include_tags = "'" . implode("', '", $q['tag_slug__in']) . "'";
-			$whichcat .= " AND $wpdb->terms.slug IN ($include_tags) ";
-			$reqtag = get_term_by( 'slug', $q['tag_slug__in'][0], 'post_tag' );
-			if ( !empty($reqtag) )
-				$q['tag_id'] = $reqtag->term_id;
+		//Taxonomies not in
+		foreach( (array) $this->taxonomies__not_in as $taxonomy ) {
+			$term_string = "'" . implode("', '", $q[$taxonomy . '__not_in']) . "'";
+			$whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = '$taxonomy' AND tt.term_id IN ($term_string) )";
 		}
 
-		if ( !empty($q['tag__not_in']) ) {
-			$tag_string = "'" . implode("', '", $q['tag__not_in']) . "'";
-			$whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'post_tag' AND tt.term_id IN ($tag_string) )";
-		}
-
-		// Tag and slug intersections.
-		$intersections = array('category__and' => 'category', 'tag__and' => 'post_tag', 'tag_slug__and' => 'post_tag', 'tag__in' => 'post_tag', 'tag_slug__in' => 'post_tag');
-		$tagin = array('tag__in', 'tag_slug__in'); // These are used to make some exceptions below
+		// Term and slug intersections.
+		$intersections = array();
+		$intersections = array_merge( $intersections, $this->taxonomies__in, $this->taxonomies__and, $this->taxonomies_slug__in, $this->taxonomies_slug__and );
+		$intersections = array_merge( $intersections, array('tag__and' => 'post_tag', 'tag_slug__and' => 'post_tag', 'tag__in' => 'post_tag', 'tag_slug__in' => 'post_tag') );
+		
+		$tagin = array_merge( array_keys( $this->taxonomies__in ), array('tag__in', 'tag_slug__in') ); // These are used to make some exceptions below
 		foreach ($intersections as $item => $taxonomy) {
+			
 			if ( empty($q[$item]) ) continue;
-			if ( in_array($item, $tagin) && empty($q['cat']) ) continue; // We should already have what we need if categories aren't being used
-
+			
 			if ( $item != 'category__and' ) {
 				$reqtag = is_term( $q[$item][0], 'post_tag' );
 				if ( !empty($reqtag) )
 					$q['tag_id'] = $reqtag['term_id'];
 			}
 
-			if ( in_array( $item, array('tag_slug__and', 'tag_slug__in' ) ) )
+			if ( in_array( $item, array_merge( array_keys( $this->taxonomies_slug__in ), array_keys( $this->taxonomies_slug__and ), array('tag_slug__and', 'tag_slug__in' ) ) ) )
 				$taxonomy_field = 'slug';
 			else
 				$taxonomy_field = 'term_id';
-
 			$q[$item] = array_unique($q[$item]);
 			$tsql = "SELECT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->term_relationships tr ON (p.ID = tr.object_id) INNER JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) INNER JOIN $wpdb->terms t ON (tt.term_id = t.term_id)";
 			$tsql .= " WHERE tt.taxonomy = '$taxonomy' AND t.$taxonomy_field IN ('" . implode("', '", $q[$item]) . "')";
@@ -2154,7 +2167,7 @@
 		if ( ! empty($q['meta_key']) )
 			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s ", $q['meta_key']);
 		if ( ! empty($q['meta_value']) ) {
-			if ( ! isset($q['meta_compare']) || empty($q['meta_compare']) || ! in_array($q['meta_compare'], array('=', '!=', '>', '>=', '<', '<=')) )
+			if ( ! isset($q['meta_compare']) || empty($q['meta_compare']) || ! in_array($q['meta_compare'], array('=', '!=', '>', '>=', '<', '<=', 'LIKE')) )
 				$q['meta_compare'] = '=';
 
 			$where .= $wpdb->prepare("AND $wpdb->postmeta.meta_value {$q['meta_compare']} %s ", $q['meta_value']);
@@ -2725,4 +2738,4 @@
 	return true;
 }
 
-?>
+?>
\ No newline at end of file

