WordPress.org

Make WordPress Core

Changeset 39454


Ignore:
Timestamp:
12/03/2016 04:04:05 AM (18 months ago)
Author:
dd32
Message:

Revert [38677] from the 4.7 branch.
This avoids fatal errors caused with recursive calling of term functions within the get_terms filter.

See #21760.

Location:
branches/4.7
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/4.7/src/wp-includes/taxonomy.php

    r39326 r39454  
    825825 */
    826826function get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) {
     827    global $wpdb;
    827828
    828829    // 'term_taxonomy_id' lookups don't require taxonomy checks.
     
    831832    }
    832833
    833     if ( 'id' === $field || 'term_id' === $field ) {
     834    $tax_clause = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
     835
     836    if ( 'slug' == $field ) {
     837        $_field = 't.slug';
     838        $value = sanitize_title($value);
     839        if ( empty($value) )
     840            return false;
     841    } elseif ( 'name' == $field ) {
     842        // Assume already escaped
     843        $value = wp_unslash($value);
     844        $_field = 't.name';
     845    } elseif ( 'term_taxonomy_id' == $field ) {
     846        $value = (int) $value;
     847        $_field = 'tt.term_taxonomy_id';
     848
     849        // No `taxonomy` clause when searching by 'term_taxonomy_id'.
     850        $tax_clause = '';
     851    } else {
    834852        $term = get_term( (int) $value, $taxonomy, $output, $filter );
    835         if ( is_wp_error( $term ) || null === $term ) {
     853        if ( is_wp_error( $term ) || is_null( $term ) ) {
    836854            $term = false;
    837855        }
     
    839857    }
    840858
    841     $args = array(
    842         'get'                    => 'all',
    843         'number'                 => 1,
    844         'taxonomy'               => $taxonomy,
    845         'update_term_meta_cache' => false,
    846         'orderby'                => 'none',
    847     );
    848 
    849     switch ( $field ) {
    850         case 'slug' :
    851             $args['slug'] = $value;
    852             break;
    853         case 'name' :
    854             $args['name'] = $value;
    855             break;
    856         case 'term_taxonomy_id' :
    857             $args['term_taxonomy_id'] = $value;
    858             unset( $args[ 'taxonomy' ] );
    859             break;
    860         default :
    861             return false;
    862     }
    863 
    864     $terms = get_terms( $args );
    865     if ( is_wp_error( $terms ) || empty( $terms ) ) {
     859    $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" );
     860    if ( ! $term )
    866861        return false;
    867     }
    868 
    869     $term = array_shift( $terms );
    870862
    871863    // In the case of 'term_taxonomy_id', override the provided `$taxonomy` with whatever we find in the db.
     
    873865        $taxonomy = $term->taxonomy;
    874866    }
     867
     868    wp_cache_add( $term->term_id, $term, 'terms' );
    875869
    876870    return get_term( $term, $taxonomy, $output, $filter );
  • branches/4.7/tests/phpunit/tests/term/cache.php

    r38776 r39454  
    222222
    223223    /**
    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     }
    393 
    394     /**
    395224     * @ticket 37291
    396225     */
Note: See TracChangeset for help on using the changeset viewer.