WordPress.org

Make WordPress Core

Ticket #21760: 21760.8.patch

File 21760.8.patch, 11.5 KB (added by ocean90, 4 years ago)
  • src/wp-includes/taxonomy.php

     
    927927 *                      or `$term` was not found.
    928928 */
    929929function get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) {
    930         global $wpdb;
    931930
    932931        // 'term_taxonomy_id' lookups don't require taxonomy checks.
    933932        if ( 'term_taxonomy_id' !== $field && ! taxonomy_exists( $taxonomy ) ) {
    934933                return false;
    935934        }
    936935
    937         $tax_clause = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
    938 
    939         if ( 'slug' == $field ) {
    940                 $_field = 't.slug';
    941                 $value = sanitize_title($value);
    942                 if ( empty($value) )
    943                         return false;
    944         } elseif ( 'name' == $field ) {
    945                 // Assume already escaped
    946                 $value = wp_unslash($value);
    947                 $_field = 't.name';
    948         } elseif ( 'term_taxonomy_id' == $field ) {
    949                 $value = (int) $value;
    950                 $_field = 'tt.term_taxonomy_id';
    951 
    952                 // No `taxonomy` clause when searching by 'term_taxonomy_id'.
    953                 $tax_clause = '';
    954         } else {
     936        if ( 'id' === $field ) {
    955937                $term = get_term( (int) $value, $taxonomy, $output, $filter );
    956938                if ( is_wp_error( $term ) || is_null( $term ) ) {
    957939                        $term = false;
     
    959941                return $term;
    960942        }
    961943
    962         $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", $value ) . " $tax_clause LIMIT 1" );
    963         if ( ! $term )
     944        $args = array(
     945                'get'                    => 'all',
     946                'number'                 => 1,
     947                'taxonomy'               => $taxonomy,
     948                'update_term_meta_cache' => false,
     949                'orderby'                => 'none',
     950        );
     951
     952        if ( 'slug' == $field ) {
     953                $args['slug'] = $value;
     954        } elseif ( 'name' == $field ) {
     955                $args['name'] = $value;
     956        } elseif ( 'term_taxonomy_id' == $field ) {
     957                $args['term_taxonomy_id'] = $value;
     958                unset( $args[ 'taxonomy' ] );
     959        } else {
     960                $args['include'] = $value;
     961        }
     962
     963        $terms = get_terms( $args );
     964        if ( is_wp_error( $terms ) || empty( $terms ) ) {
    964965                return false;
     966        }
    965967
     968        $term = array_shift( $terms );
     969
    966970        // In the case of 'term_taxonomy_id', override the provided `$taxonomy` with whatever we find in the db.
    967971        if ( 'term_taxonomy_id' === $field ) {
    968972                $taxonomy = $term->taxonomy;
    969973        }
    970974
    971         wp_cache_add( $term->term_id, $term, 'terms' );
    972 
    973975        return get_term( $term, $taxonomy, $output, $filter );
    974976}
    975977
  • tests/phpunit/tests/term/cache.php

     
    219219                        $this->assertSame( $p, $term->object_id );
    220220                }
    221221        }
     222
     223        /**
     224         * @ticket 21760
     225         */
     226        function test_get_term_by_slug_cache() {
     227                global $wpdb;
     228
     229                $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'name' => 'Taco', 'taxonomy' => 'post_tag' ) );
     230
     231                clean_term_cache( $term_id, 'post_tag' );
     232                $num_queries = $wpdb->num_queries;
     233
     234                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
     235                $num_queries++;
     236                $this->assertEquals( 'Taco', $term->name );
     237                $this->assertEquals( $num_queries, $wpdb->num_queries );
     238
     239                // This should now hit cache.
     240                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
     241                $this->assertEquals( 'Taco', $term->name );
     242                $this->assertEquals( $num_queries, $wpdb->num_queries );
     243
     244                $this->assertEquals( get_term( $term_id, 'post_tag' ), $term );
     245                $this->assertEquals( $num_queries, $wpdb->num_queries );
     246        }
     247
     248        /**
     249         * @ticket 21760
     250         */
     251        function test_get_term_by_slug_cache_update() {
     252                global $wpdb;
     253
     254                $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'name' => 'Taco', 'taxonomy' => 'post_tag' ) );
     255
     256                clean_term_cache( $term_id, 'post_tag' );
     257                $num_queries = $wpdb->num_queries;
     258
     259                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
     260                $num_queries++;
     261                $this->assertEquals( 'Taco', $term->name );
     262                $this->assertEquals( $num_queries, $wpdb->num_queries );
     263
     264                // This should now hit cache.
     265                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
     266                $this->assertEquals( 'Taco', $term->name );
     267                $this->assertEquals( $num_queries, $wpdb->num_queries );
     268
     269                // Update the tag which invalidates the cache.
     270                wp_update_term( $term_id, 'post_tag', array( 'name' => 'No Taco' ) );
     271                $num_queries = $wpdb->num_queries;
     272
     273                // This should not hit cache.
     274                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
     275                $num_queries++;
     276                $this->assertEquals( 'No Taco', $term->name );
     277                $this->assertEquals( $num_queries, $wpdb->num_queries );
     278        }
     279
     280        /**
     281         * @ticket 21760
     282         */
     283        function test_get_term_by_name_cache() {
     284                global $wpdb;
     285
     286                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
     287
     288                clean_term_cache( $term_id, 'post_tag' );
     289                $num_queries = $wpdb->num_queries;
     290
     291                get_term_by( 'name', 'Burrito', 'post_tag' );
     292                $num_queries++;
     293                $this->assertEquals( $num_queries, $wpdb->num_queries );
     294
     295                // This should now hit cache.
     296                $term = get_term_by( 'name', 'Burrito', 'post_tag' );
     297                $this->assertEquals( $num_queries, $wpdb->num_queries );
     298
     299                $this->assertEquals( get_term( $term_id, 'post_tag' ), $term );
     300                $this->assertEquals( $num_queries, $wpdb->num_queries );
     301        }
     302
     303        /**
     304         * @ticket 21760
     305         */
     306        function test_get_term_by_name_cache_update() {
     307                global $wpdb;
     308
     309                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
     310
     311                clean_term_cache( $term_id, 'post_tag' );
     312                $num_queries = $wpdb->num_queries;
     313
     314                get_term_by( 'name', 'Burrito', 'post_tag' );
     315                $num_queries++;
     316                $this->assertEquals( $num_queries, $wpdb->num_queries );
     317
     318                // This should now hit cache.
     319                get_term_by( 'name', 'Burrito', 'post_tag' );
     320                $this->assertEquals( $num_queries, $wpdb->num_queries );
     321
     322                // Update the tag which invalidates the cache.
     323                wp_update_term( $term_id, 'post_tag', array( 'slug' => 'taco' ) );
     324                $num_queries = $wpdb->num_queries;
     325
     326                // This should not hit cache.
     327                get_term_by( 'name', 'burrito', 'post_tag' );
     328                $num_queries++;
     329                $this->assertEquals( $num_queries, $wpdb->num_queries );
     330        }
     331
     332        /**
     333         * @ticket 21760
     334         */
     335        function test_invalidating_term_caches_should_fail_when_invalidation_is_suspended() {
     336                global $wpdb;
     337
     338                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'taxonomy' => 'post_tag' ) );
     339
     340                clean_term_cache( $term_id, 'post_tag' );
     341                $num_queries = $wpdb->num_queries;
     342                $last_changed = wp_cache_get( 'last_changed', 'terms' );
     343
     344                $term1 = get_term_by( 'name', 'Burrito', 'post_tag' );
     345                $num_queries++;
     346
     347                // Verify the term is cached.
     348                $term2 = get_term_by( 'name', 'Burrito', 'post_tag' );
     349                $this->assertEquals( $num_queries, $wpdb->num_queries );
     350                $this->assertEquals( $term1, $term2 );
     351
     352                $suspend = wp_suspend_cache_invalidation();
     353
     354                // Update the tag.
     355                wp_update_term( $term_id, 'post_tag', array( 'name' => 'Taco' ) );
     356                $num_queries = $wpdb->num_queries;
     357
     358                // Verify that the cached term still matches the initial cached term.
     359                $term3 = get_term_by( 'name', 'Burrito', 'post_tag' );
     360                $this->assertEquals( $num_queries, $wpdb->num_queries );
     361                $this->assertEquals( $term1, $term3 );
     362
     363                // Verify that last changed has not been updated as part of an invalidation routine.
     364                $this->assertSame( $last_changed, wp_cache_get( 'last_changed', 'terms' ) );
     365
     366                // Clean up.
     367                wp_suspend_cache_invalidation( $suspend );
     368        }
     369
     370        /**
     371         * @ticket 21760
     372         */
     373        public function test_get_term_by_does_not_prime_term_meta_cache() {
     374                global $wpdb;
     375
     376                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'taxonomy' => 'post_tag' ) );
     377                add_term_meta( $term_id, 'foo', 'bar' );
     378
     379                clean_term_cache( $term_id, 'post_tag' );
     380                $num_queries = $wpdb->num_queries;
     381
     382                $term = get_term_by( 'name', 'Burrito', 'post_tag' );
     383                $num_queries++;
     384                $this->assertTrue( $term instanceof WP_Term );
     385                $this->assertSame( $term_id, $term->term_id );
     386                $this->assertEquals( $num_queries, $wpdb->num_queries );
     387
     388                $term_meta = get_term_meta( $term_id, 'foo', true );
     389                $num_queries++;
     390                $this->assertSame( $term_meta, 'bar' );
     391                $this->assertEquals( $num_queries, $wpdb->num_queries );
     392        }
    222393}
  • tests/phpunit/tests/term/getTermBy.php

     
    44 * @group taxonomy
    55 */
    66class Tests_Term_GetTermBy extends WP_UnitTestCase {
     7
     8        function test_get_term_by_slug() {
     9                $term1 = wp_insert_term( 'Foo', 'category', array( 'slug' => 'foo' ) );
     10                $term2 = get_term_by( 'slug', 'foo', 'category' );
     11                $this->assertEquals( get_term( $term1['term_id'], 'category' ), $term2 );
     12        }
     13
     14        function test_get_term_by_name() {
     15                $term1 = wp_insert_term( 'Foo', 'category', array( 'slug' => 'foo' ) );
     16                $term2 = get_term_by( 'name', 'Foo', 'category' );
     17                $this->assertEquals( get_term( $term1['term_id'], 'category' ), $term2 );
     18        }
     19
     20        function test_get_term_by_id() {
     21                $term1 = wp_insert_term( 'Foo', 'category', array( 'slug' => 'foo' ) );
     22                $term2 = get_term_by( 'id', $term1['term_id'], 'category' );
     23                $this->assertEquals( get_term( $term1['term_id'], 'category' ), $term2 );
     24        }
     25
    726        /**
    827         * @ticket 21651
    928         */
     
    87106                $this->assertSame( $t, $found->term_id );
    88107                $this->assertSame( $num_queries, $wpdb->num_queries );
    89108        }
     109
     110        /**
     111         * @ticket 21760
     112         */
     113        public function test_should_unslash_name() {
     114                register_taxonomy( 'wptests_tax', 'post' );
     115                $term_name = 'Foo " \o/';
     116                $term_name_slashed = wp_slash( $term_name );
     117                $t = self::factory()->term->create( array(
     118                        'taxonomy' => 'wptests_tax',
     119                        'name' => $term_name_slashed,
     120                ) );
     121
     122                $found = get_term_by( 'name', $term_name_slashed, 'wptests_tax' );
     123
     124                $this->assertTrue( $found instanceof WP_Term );
     125                $this->assertSame( $t, $found->term_id );
     126                $this->assertSame( $term_name, $found->name );
     127        }
     128
     129        /**
     130         * @ticket 21760
     131         */
     132        public function test_should_sanitize_slug() {
     133                register_taxonomy( 'wptests_tax', 'post' );
     134                $t1 = self::factory()->term->create( array(
     135                        'taxonomy' => 'wptests_tax',
     136                        'slug' => 'foo-foo',
     137                ) );
     138
     139                // Whitespace should get replaced by a '-'.
     140                $found1 = get_term_by( 'slug', 'foo foo', 'wptests_tax' );
     141
     142                $this->assertTrue( $found1 instanceof WP_Term );
     143                $this->assertSame( $t1, $found1->term_id );
     144
     145                $t2 = self::factory()->term->create( array(
     146                        'taxonomy' => 'wptests_tax',
     147                        'slug' => '%e4%bb%aa%e8%a1%a8%e7%9b%98',
     148                ) );
     149
     150                // Slug should get urlencoded.
     151                $found2 = get_term_by( 'slug', '仪表盘', 'wptests_tax' );
     152
     153                $this->assertTrue( $found2 instanceof WP_Term );
     154                $this->assertSame( $t2, $found2->term_id );
     155        }
     156
     157        /**
     158         * @ticket 21760
     159         */
     160        public function test_query_should_not_contain_order_by_clause() {
     161                global $wpdb;
     162
     163                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
     164                $found = get_term_by( 'name', 'burrito', 'post_tag' );
     165                $this->assertSame( $term_id, $found->term_id );
     166                $this->assertNotContains( 'ORDER BY', $wpdb->last_query );
     167        }
     168
     169        /**
     170         * @ticket 21760
     171         */
     172        public function test_query_should_contain_limit_clause() {
     173                global $wpdb;
     174
     175                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
     176                $found = get_term_by( 'name', 'burrito', 'post_tag' );
     177                $this->assertSame( $term_id, $found->term_id );
     178                $this->assertContains( 'LIMIT 1', $wpdb->last_query );
     179        }
    90180}