From 36af857315f135ac7110bd339ac3403cf8655d8f Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Tue, 29 Sep 2015 03:51:11 +0000 Subject: [PATCH] Don't require explicit taxonomy when getting terms by term_taxonomy_id. Props wonderboymusic. Fixes #30620. git-svn-id: https://develop.svn.wordpress.org/trunk@34679 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy-functions.php | 21 +++++++++++++++++---- tests/phpunit/tests/term/getTermBy.php | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/taxonomy-functions.php b/src/wp-includes/taxonomy-functions.php index 3d091e9165..e35b453556 100644 --- a/src/wp-includes/taxonomy-functions.php +++ b/src/wp-includes/taxonomy-functions.php @@ -781,23 +781,28 @@ function get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { * @todo Better formatting for DocBlock. * * @since 2.3.0 + * @since 4.4.0 `$taxonomy` is optional if `$field` is 'term_taxonomy_id'. * * @global wpdb $wpdb WordPress database abstraction object. * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. * * @param string $field Either 'slug', 'name', 'id' (term_id), or 'term_taxonomy_id' * @param string|int $value Search for this term value - * @param string $taxonomy Taxonomy Name + * @param string $taxonomy Taxonomy name. Optional, if `$field` is 'term_taxonomy_id'. * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N * @param string $filter Optional, default is raw or no WordPress defined filter will applied. * @return object|array|null|WP_Error|false Term Row from database. * Will return false if $taxonomy does not exist or $term was not found. */ -function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') { +function get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) { global $wpdb; - if ( ! taxonomy_exists($taxonomy) ) + // 'term_taxonomy_id' lookups don't require taxonomy checks. + if ( 'term_taxonomy_id' !== $field && ! taxonomy_exists( $taxonomy ) ) { return false; + } + + $tax_clause = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy ); if ( 'slug' == $field ) { $field = 't.slug'; @@ -811,6 +816,9 @@ function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw } elseif ( 'term_taxonomy_id' == $field ) { $value = (int) $value; $field = 'tt.term_taxonomy_id'; + + // No `taxonomy` clause when searching by 'term_taxonomy_id'. + $tax_clause = ''; } else { $term = get_term( (int) $value, $taxonomy, $output, $filter ); if ( is_wp_error( $term ) || is_null( $term ) ) { @@ -819,10 +827,15 @@ function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw return $term; } - $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND $field = %s LIMIT 1", $taxonomy, $value ) ); + $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE $field = %s $tax_clause LIMIT 1", $value ) ); if ( ! $term ) return false; + // In the case of 'term_taxonomy_id', override the provided `$taxonomy` with whatever we find in the db. + if ( 'term_taxonomy_id' === $field ) { + $taxonomy = $term->taxonomy; + } + wp_cache_add( $term->term_id, $term, $taxonomy ); /** This filter is documented in wp-includes/taxonomy-functions.php */ diff --git a/tests/phpunit/tests/term/getTermBy.php b/tests/phpunit/tests/term/getTermBy.php index 29a6bdc1aa..ffe818f7c0 100644 --- a/tests/phpunit/tests/term/getTermBy.php +++ b/tests/phpunit/tests/term/getTermBy.php @@ -36,4 +36,27 @@ class Tests_Term_GetTermBy extends WP_UnitTestCase { $found = get_term_by( 'slug', 'nas', 'wptests_tax' ); $this->assertSame( $t, $found->term_id ); } + + /** + * @ticket 30620 + */ + public function test_taxonomy_should_be_ignored_if_matching_by_term_taxonomy_id() { + global $wpdb; + + register_taxonomy( 'wptests_tax', 'post' ); + $t = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax' ) ); + $term = get_term( $t, 'wptests_tax' ); + + $new_ttid = $term->term_taxonomy_id + 1; + + // Offset just to be sure. + $wpdb->update( + $wpdb->term_taxonomy, + array( 'term_taxonomy_id' => $new_ttid ), + array( 'term_id' => $t ) + ); + + $found = get_term_by( 'term_taxonomy_id', $new_ttid, 'foo' ); + $this->assertSame( $t, $found->term_id ); + } }