diff --git a/wp-includes/functions.php b/wp-includes/functions.php index abcb63d639..39b7bb1cb8 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -3049,21 +3049,26 @@ function wp_filter_object_list( $list, $args = array(), $operator = 'and', $fiel * * @param array $list An array of objects to filter * @param array $args An array of key => value arguments to match against each object - * @param string $operator The logical operation to perform. 'or' means only one element - * from the array needs to match; 'and' means all elements must match. The default is 'and'. + * @param string $operator The logical operation to perform: + * 'AND' means all elements from the array must match; + * 'OR' means only one element needs to match; + * 'NOT' means no elements may match. + * The default is 'AND'. * @return array */ -function wp_list_filter( $list, $args = array(), $operator = 'and' ) { +function wp_list_filter( $list, $args = array(), $operator = 'AND' ) { if ( empty( $args ) ) return $list; + $operator = strtoupper( $operator ); $count = count( $args ); - $filtered = array(); foreach ( $list as $key => $obj ) { $matched = count( array_intersect_assoc( (array) $obj, $args ) ); - if ( ('and' == $operator && $matched == $count) || ('or' == $operator && $matched <= $count) ) { + if ( ( 'AND' == $operator && $matched == $count ) + || ( 'OR' == $operator && $matched <= $count ) + || ( 'NOT' == $operator && 0 == $matched ) ) { $filtered[$key] = $obj; } } diff --git a/wp-includes/query.php b/wp-includes/query.php index 5a2d6fe28c..d954e8a889 100644 --- a/wp-includes/query.php +++ b/wp-includes/query.php @@ -2143,10 +2143,10 @@ class WP_Query { // Back-compat if ( !empty($this->tax_query->queries) ) { - $tax_query_in = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'IN' ) ); - if ( !empty( $tax_query_in ) ) { + $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' ); + if ( !empty( $tax_query_in_and ) ) { if ( !isset( $q['taxonomy'] ) ) { - foreach ( $tax_query_in as $a_tax_query ) { + foreach ( $tax_query_in_and as $a_tax_query ) { if ( !in_array( $a_tax_query['taxonomy'], array( 'category', 'post_tag' ) ) ) { $q['taxonomy'] = $a_tax_query['taxonomy']; if ( 'slug' == $a_tax_query['field'] ) @@ -2159,15 +2159,28 @@ class WP_Query { } } - $cat_query = wp_list_filter( $tax_query_in, array( 'taxonomy' => 'category' ) ); + $cat_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'category' ) ); if ( !empty( $cat_query ) ) { $cat_query = reset( $cat_query ); - $cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' ); - if ( $cat ) { - $this->set( 'cat', $cat->term_id ); - $this->set( 'category_name', $cat->slug ); + $the_cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' ); + if ( $the_cat ) { + $this->set( 'cat', $the_cat->term_id ); + $this->set( 'category_name', $the_cat->slug ); } + unset( $the_cat ); } + unset( $cat_query ); + + $tag_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'post_tag' ) ); + if ( !empty( $tag_query ) ) { + $tag_query = reset( $tag_query ); + $the_tag = get_term_by( $tag_query['field'], $tag_query['terms'][0], 'post_tag' ); + if ( $the_tag ) { + $this->set( 'tag_id', $the_tag->term_id ); + } + unset( $the_tag ); + } + unset( $tag_query ); } } @@ -2844,9 +2857,9 @@ class WP_Query { $this->queried_object_id = 0; if ( $this->is_category || $this->is_tag || $this->is_tax ) { - $tax_query_in = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'IN' ) ); + $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' ); - $query = reset( $tax_query_in ); + $query = reset( $tax_query_in_and ); if ( 'term_id' == $query['field'] ) $term = get_term( reset( $query['terms'] ), $query['taxonomy'] );