WordPress.org

Make WordPress Core

Ticket #21760: 21760.7.patch

File 21760.7.patch, 10.1 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 );
     936        $args = array(
     937                'get'                    => 'all',
     938                'number'                 => 1,
     939                'taxonomy'               => $taxonomy,
     940                'update_term_meta_cache' => false,
     941                'orderby'                => 'none',
     942        );
    938943
    939944        if ( 'slug' == $field ) {
    940                 $_field = 't.slug';
    941                 $value = sanitize_title($value);
    942                 if ( empty($value) )
    943                         return false;
     945                $args['slug'] = $value;
    944946        } elseif ( 'name' == $field ) {
    945                 // Assume already escaped
    946                 $value = wp_unslash($value);
    947                 $_field = 't.name';
     947                $args['name'] = $value;
    948948        } 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 = '';
     949                $args['term_taxonomy_id'] = $value;
     950                unset( $args[ 'taxonomy' ] );
    954951        } else {
    955                 $term = get_term( (int) $value, $taxonomy, $output, $filter );
    956                 if ( is_wp_error( $term ) || is_null( $term ) ) {
    957                         $term = false;
    958                 }
    959                 return $term;
     952                $args['include'] = $value;
    960953        }
    961954
    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 )
     955        $terms = get_terms( $args );
     956        if ( is_wp_error( $terms ) || empty( $terms ) ) {
    964957                return false;
     958        }
    965959
     960        $term = array_shift( $terms );
     961
    966962        // In the case of 'term_taxonomy_id', override the provided `$taxonomy` with whatever we find in the db.
    967963        if ( 'term_taxonomy_id' === $field ) {
    968964                $taxonomy = $term->taxonomy;
    969965        }
    970966
    971         wp_cache_add( $term->term_id, $term, 'terms' );
    972 
    973967        return get_term( $term, $taxonomy, $output, $filter );
    974968}
    975969
  • 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', 'taxonomy' => 'post_tag' ) );
     230
     231                clean_term_cache( $term_id, 'post_tag' );
     232                $num_queries = $wpdb->num_queries;
     233
     234                get_term_by( 'slug', 'burrito', 'post_tag' );
     235                $num_queries++;
     236                $this->assertEquals( $num_queries, $wpdb->num_queries );
     237
     238                // This should now hit cache.
     239                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
     240                $this->assertEquals( $num_queries, $wpdb->num_queries );
     241
     242                $this->assertEquals( get_term( $term_id, 'post_tag' ), $term );
     243                $this->assertEquals( $num_queries, $wpdb->num_queries );
     244        }
     245
     246        /**
     247         * @ticket 21760
     248         */
     249        function test_get_term_by_slug_cache_update() {
     250                global $wpdb;
     251
     252                $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'taxonomy' => 'post_tag' ) );
     253
     254                clean_term_cache( $term_id, 'post_tag' );
     255                $num_queries = $wpdb->num_queries;
     256
     257                get_term_by( 'slug', 'burrito', 'post_tag' );
     258                $num_queries++;
     259                $this->assertEquals( $num_queries, $wpdb->num_queries );
     260
     261                // This should now hit cache.
     262                get_term_by( 'slug', 'burrito', 'post_tag' );
     263                $this->assertEquals( $num_queries, $wpdb->num_queries );
     264
     265                // Update the tag which invalidates the cache.
     266                wp_update_term( $term_id, 'post_tag', array( 'name' => 'Taco' ) );
     267                $num_queries = $wpdb->num_queries;
     268
     269                // This should not hit cache.
     270                get_term_by( 'slug', 'burrito', 'post_tag' );
     271                $num_queries++;
     272                $this->assertEquals( $num_queries, $wpdb->num_queries );
     273        }
     274
     275        /**
     276         * @ticket 21760
     277         */
     278        function test_get_term_by_name_cache() {
     279                global $wpdb;
     280
     281                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
     282
     283                clean_term_cache( $term_id, 'post_tag' );
     284                $num_queries = $wpdb->num_queries;
     285
     286                get_term_by( 'name', 'burrito', 'post_tag' );
     287                $num_queries++;
     288                $this->assertEquals( $num_queries, $wpdb->num_queries );
     289
     290                // This should now hit cache.
     291                $term = get_term_by( 'name', 'burrito', 'post_tag' );
     292                $this->assertEquals( $num_queries, $wpdb->num_queries );
     293
     294                $this->assertEquals( get_term( $term_id, 'post_tag' ), $term );
     295                $this->assertEquals( $num_queries, $wpdb->num_queries );
     296        }
     297
     298        /**
     299         * @ticket 21760
     300         */
     301        function test_get_term_by_name_cache_update() {
     302                global $wpdb;
     303
     304                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
     305
     306                clean_term_cache( $term_id, 'post_tag' );
     307                $num_queries = $wpdb->num_queries;
     308
     309                get_term_by( 'name', 'burrito', 'post_tag' );
     310                $num_queries++;
     311                $this->assertEquals( $num_queries, $wpdb->num_queries );
     312
     313                // This should now hit cache.
     314                get_term_by( 'name', 'burrito', 'post_tag' );
     315                $this->assertEquals( $num_queries, $wpdb->num_queries );
     316
     317                // Update the tag which invalidates the cache.
     318                wp_update_term( $term_id, 'post_tag', array( 'slug' => 'taco' ) );
     319                $num_queries = $wpdb->num_queries;
     320
     321                // This should not hit cache.
     322                get_term_by( 'name', 'burrito', 'post_tag' );
     323                $num_queries++;
     324                $this->assertEquals( $num_queries, $wpdb->num_queries );
     325        }
     326
     327        /**
     328         * @ticket 21760
     329         */
     330        function test_invalidating_term_caches_should_fail_when_invalidation_is_suspended() {
     331                global $wpdb;
     332
     333                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
     334
     335                clean_term_cache( $term_id, 'post_tag' );
     336                $num_queries = $wpdb->num_queries;
     337                $last_changed = wp_cache_get( 'last_changed', 'terms' );
     338
     339                $term1 = get_term_by( 'name', 'burrito', 'post_tag' );
     340                $num_queries++;
     341
     342                // Verify the term is cached.
     343                $term2 = get_term_by( 'name', 'burrito', 'post_tag' );
     344                $this->assertEquals( $num_queries, $wpdb->num_queries );
     345                $this->assertEquals( $term1, $term2 );
     346
     347                $suspend = wp_suspend_cache_invalidation();
     348                clean_term_cache( $term_id, 'post_tag' );
     349
     350                // Verify that the cached term still matches the initial term.
     351                $term3 = get_term_by( 'name', 'burrito', 'post_tag' );
     352                $this->assertEquals( $num_queries, $wpdb->num_queries );
     353                $this->assertEquals( $term1, $term3 );
     354
     355                // Verify that last changed has not been updated as part of an invalidation routine.
     356                $this->assertSame( $last_changed, wp_cache_get( 'last_changed', 'terms' ) );
     357
     358                // Clean up.
     359                wp_suspend_cache_invalidation( $suspend );
     360        }
     361
     362        /**
     363         * @ticket 21760
     364         */
     365        public function test_get_term_by_does_not_prime_term_meta_cache() {
     366                global $wpdb;
     367
     368                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
     369                add_term_meta( $term_id, 'foo', 'bar' );
     370
     371                clean_term_cache( $term_id, 'post_tag' );
     372                $num_queries = $wpdb->num_queries;
     373
     374                $term = get_term_by( 'name', 'burrito', 'post_tag' );
     375                $num_queries++;
     376                $this->assertTrue( $term instanceof WP_Term );
     377                $this->assertSame( $term_id, $term->term_id );
     378                $this->assertEquals( $num_queries, $wpdb->num_queries );
     379
     380                $term_meta = get_term_meta( $term_id, 'foo', true );
     381                $num_queries++;
     382                $this->assertSame( $term_meta, 'bar' );
     383                $this->assertEquals( $num_queries, $wpdb->num_queries );
     384        }
    222385}
  • 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        }
    90156}