From deae2f7cbf543094e838b75d674a4ebe3c97965e Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 21 Jun 2017 03:56:25 +0000 Subject: [PATCH] Use `WP_Term_Query` when transforming tax queries. This change allows tax query transformations to be cached. Props spacedmonkey. Fixes #37038. git-svn-id: https://develop.svn.wordpress.org/trunk@40918 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-tax-query.php | 90 ++++++++++++-------------- tests/phpunit/tests/term/taxQuery.php | 4 +- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/wp-includes/class-wp-tax-query.php b/src/wp-includes/class-wp-tax-query.php index b46aede70a..b5f24a263d 100644 --- a/src/wp-includes/class-wp-tax-query.php +++ b/src/wp-includes/class-wp-tax-query.php @@ -595,6 +595,9 @@ class WP_Tax_Query { /** * Transforms a single query, from one field to another. * + * Operates on the `$query` object by reference. In the case of error, + * `$query` is converted to a WP_Error object. + * * @since 3.2.0 * * @global wpdb $wpdb The WordPress database abstraction object. @@ -604,8 +607,6 @@ class WP_Tax_Query { * or 'term_id'. Default 'term_id'. */ public function transform_query( &$query, $resulting_field ) { - global $wpdb; - if ( empty( $query['terms'] ) ) return; @@ -614,57 +615,52 @@ class WP_Tax_Query { $resulting_field = sanitize_key( $resulting_field ); - switch ( $query['field'] ) { - case 'slug': - case 'name': - foreach ( $query['terms'] as &$term ) { - /* - * 0 is the $term_id parameter. We don't have a term ID yet, but it doesn't - * matter because `sanitize_term_field()` ignores the $term_id param when the - * context is 'db'. - */ - $clean_term = sanitize_term_field( $query['field'], $term, 0, $query['taxonomy'], 'db' ); - - // Match sanitization in wp_insert_term(). - $clean_term = wp_unslash( $clean_term ); - - $term = "'" . esc_sql( $clean_term ) . "'"; - } - - $terms = implode( ",", $query['terms'] ); - - $terms = $wpdb->get_col( " - SELECT $wpdb->term_taxonomy.$resulting_field - FROM $wpdb->term_taxonomy - INNER JOIN $wpdb->terms USING (term_id) - WHERE taxonomy = '{$query['taxonomy']}' - AND $wpdb->terms.{$query['field']} IN ($terms) - " ); - break; - case 'term_taxonomy_id': - $terms = implode( ',', array_map( 'intval', $query['terms'] ) ); - $terms = $wpdb->get_col( " - SELECT $resulting_field - FROM $wpdb->term_taxonomy - WHERE term_taxonomy_id IN ($terms) - " ); - break; - default: - $terms = implode( ',', array_map( 'intval', $query['terms'] ) ); - $terms = $wpdb->get_col( " - SELECT $resulting_field - FROM $wpdb->term_taxonomy - WHERE taxonomy = '{$query['taxonomy']}' - AND term_id IN ($terms) - " ); + // Empty 'terms' always results in a null transformation. + $terms = array_filter( $query['terms'] ); + if ( empty( $terms ) ) { + $query['terms'] = array(); + $query['field'] = $resulting_field; + return; } - if ( 'AND' == $query['operator'] && count( $terms ) < count( $query['terms'] ) ) { + $args = array( + 'get' => 'all', + 'number' => 0, + 'taxonomy' => $query['taxonomy'], + 'update_term_meta_cache' => false, + 'orderby' => 'none', + ); + + // Term query parameter name depends on the 'field' being searched on. + switch ( $query['field'] ) { + case 'slug': + $args['slug'] = $terms; + break; + case 'name': + $args['name'] = $terms; + break; + case 'term_taxonomy_id': + $args['term_taxonomy_id'] = $terms; + break; + default: + $args['include'] = wp_parse_id_list( $terms ); + break; + } + + $term_query = new WP_Term_Query(); + $term_list = $term_query->query( $args ); + + if ( is_wp_error( $term_list ) ) { + $query = $term_list; + return; + } + + if ( 'AND' == $query['operator'] && count( $term_list ) < count( $query['terms'] ) ) { $query = new WP_Error( 'inexistent_terms', __( 'Inexistent terms.' ) ); return; } - $query['terms'] = $terms; + $query['terms'] = wp_list_pluck( $term_list, $resulting_field ); $query['field'] = $resulting_field; } } diff --git a/tests/phpunit/tests/term/taxQuery.php b/tests/phpunit/tests/term/taxQuery.php index 179d25123d..1aacaca67b 100644 --- a/tests/phpunit/tests/term/taxQuery.php +++ b/tests/phpunit/tests/term/taxQuery.php @@ -163,7 +163,7 @@ class Tests_Term_Tax_Query extends WP_UnitTestCase { ) ); $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); - $this->assertSame( $tt_ids, $tq->queries[0]['terms'] ); + $this->assertEqualSets( $tt_ids, $tq->queries[0]['terms'] ); $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); } @@ -181,7 +181,7 @@ class Tests_Term_Tax_Query extends WP_UnitTestCase { ) ); $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); - $this->assertSame( $tt_ids, $tq->queries[0]['terms'] ); + $this->assertEqualSets( $tt_ids, $tq->queries[0]['terms'] ); $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); }