WordPress.org

Make WordPress Core

Ticket #21760: 21760.9.patch

File 21760.9.patch, 12.2 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 || 'term_id' === $field ) {
    955937                $term = get_term( (int) $value, $taxonomy, $output, $filter );
    956                 if ( is_wp_error( $term ) || is_null( $term ) ) {
     938                if ( is_wp_error( $term ) || null === $term ) {
    957939                        $term = false;
    958940                }
    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        switch ( $field ) {
     953                case 'slug' :
     954                        $args['slug'] = $value;
     955                        break;
     956                case 'name' :
     957                        $args['name'] = $value;
     958                        break;
     959                case 'term_taxonomy_id' :
     960                        $args['term_taxonomy_id'] = $value;
     961                        unset( $args[ 'taxonomy' ] );
     962                        break;
     963                default :
     964                        return false;
     965        }
     966
     967        $terms = get_terms( $args );
     968        if ( is_wp_error( $terms ) || empty( $terms ) ) {
    964969                return false;
     970        }
    965971
     972        $term = array_shift( $terms );
     973
    966974        // In the case of 'term_taxonomy_id', override the provided `$taxonomy` with whatever we find in the db.
    967975        if ( 'term_taxonomy_id' === $field ) {
    968976                $taxonomy = $term->taxonomy;
    969977        }
    970978
    971         wp_cache_add( $term->term_id, $term, 'terms' );
    972 
    973979        return get_term( $term, $taxonomy, $output, $filter );
    974980}
    975981
  • 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        /**
     27         * 'term_id' is an alias of 'id'.
     28         */
     29        function test_get_term_by_term_id() {
     30                $term1 = wp_insert_term( 'Foo', 'category', array( 'slug' => 'foo' ) );
     31                $term2 = get_term_by( 'term_id', $term1['term_id'], 'category' );
     32                $this->assertEquals( get_term( $term1['term_id'], 'category' ), $term2 );
     33        }
     34
     35        /**
    836         * @ticket 21651
    937         */
    1038        function test_get_term_by_tt_id() {
     
    1341                $this->assertEquals( get_term( $term1['term_id'], 'category' ), $term2 );
    1442        }
    1543
     44        function test_get_term_by_unknown() {
     45                wp_insert_term( 'Foo', 'category', array( 'slug' => 'foo' ) );
     46                $term2 = get_term_by( 'unknown', 'foo', 'category' );
     47                $this->assertFalse( $term2 );
     48        }
     49
    1650        /**
    1751         * @ticket 33281
    1852         */
     
    87121                $this->assertSame( $t, $found->term_id );
    88122                $this->assertSame( $num_queries, $wpdb->num_queries );
    89123        }
     124
     125        /**
     126         * @ticket 21760
     127         */
     128        public function test_should_unslash_name() {
     129                register_taxonomy( 'wptests_tax', 'post' );
     130                $term_name = 'Foo " \o/';
     131                $term_name_slashed = wp_slash( $term_name );
     132                $t = self::factory()->term->create( array(
     133                        'taxonomy' => 'wptests_tax',
     134                        'name' => $term_name_slashed,
     135                ) );
     136
     137                $found = get_term_by( 'name', $term_name_slashed, 'wptests_tax' );
     138
     139                $this->assertTrue( $found instanceof WP_Term );
     140                $this->assertSame( $t, $found->term_id );
     141                $this->assertSame( $term_name, $found->name );
     142        }
     143
     144        /**
     145         * @ticket 21760
     146         */
     147        public function test_should_sanitize_slug() {
     148                register_taxonomy( 'wptests_tax', 'post' );
     149                $t1 = self::factory()->term->create( array(
     150                        'taxonomy' => 'wptests_tax',
     151                        'slug' => 'foo-foo',
     152                ) );
     153
     154                // Whitespace should get replaced by a '-'.
     155                $found1 = get_term_by( 'slug', 'foo foo', 'wptests_tax' );
     156
     157                $this->assertTrue( $found1 instanceof WP_Term );
     158                $this->assertSame( $t1, $found1->term_id );
     159
     160                $t2 = self::factory()->term->create( array(
     161                        'taxonomy' => 'wptests_tax',
     162                        'slug' => '%e4%bb%aa%e8%a1%a8%e7%9b%98',
     163                ) );
     164
     165                // Slug should get urlencoded.
     166                $found2 = get_term_by( 'slug', '仪表盘', 'wptests_tax' );
     167
     168                $this->assertTrue( $found2 instanceof WP_Term );
     169                $this->assertSame( $t2, $found2->term_id );
     170        }
     171
     172        /**
     173         * @ticket 21760
     174         */
     175        public function test_query_should_not_contain_order_by_clause() {
     176                global $wpdb;
     177
     178                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
     179                $found = get_term_by( 'name', 'burrito', 'post_tag' );
     180                $this->assertSame( $term_id, $found->term_id );
     181                $this->assertNotContains( 'ORDER BY', $wpdb->last_query );
     182        }
     183
     184        /**
     185         * @ticket 21760
     186         */
     187        public function test_query_should_contain_limit_clause() {
     188                global $wpdb;
     189
     190                $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
     191                $found = get_term_by( 'name', 'burrito', 'post_tag' );
     192                $this->assertSame( $term_id, $found->term_id );
     193                $this->assertContains( 'LIMIT 1', $wpdb->last_query );
     194        }
    90195}