Make WordPress Core

Ticket #37189: 37189.3.patch

File 37189.3.patch, 16.0 KB (added by boonebgorges, 8 years ago)
  • src/wp-includes/class-wp-term-query.php

    diff --git src/wp-includes/class-wp-term-query.php src/wp-includes/class-wp-term-query.php
    index 2f3da47301..c4545eda75 100644
    class WP_Term_Query { 
    585585
    586586                $selects = array();
    587587                switch ( $args['fields'] ) {
    588                         case 'all':
    589                         case 'all_with_object_id' :
    590                         case 'tt_ids' :
    591                         case 'slugs' :
    592                                 $selects = array( 't.*', 'tt.*' );
    593                                 if ( 'all_with_object_id' === $args['fields'] && ! empty( $args['object_ids'] ) ) {
    594                                         $selects[] = 'tr.object_id';
    595                                 }
    596                                 break;
    597                         case 'ids':
    598                         case 'id=>parent':
    599                                 $selects = array( 't.term_id', 'tt.parent', 'tt.count', 'tt.taxonomy' );
    600                                 break;
    601                         case 'names':
    602                                 $selects = array( 't.term_id', 'tt.parent', 'tt.count', 't.name', 'tt.taxonomy' );
    603                                 break;
    604588                        case 'count':
    605589                                $orderby = '';
    606590                                $order = '';
    607591                                $selects = array( 'COUNT(*)' );
    608592                                break;
    609                         case 'id=>name':
    610                                 $selects = array( 't.term_id', 't.name', 'tt.count', 'tt.taxonomy' );
     593                        case 'all_with_object_id' :
     594                                $selects = array( 't.term_id', 'tr.object_id' );
    611595                                break;
    612                         case 'id=>slug':
    613                                 $selects = array( 't.term_id', 't.slug', 'tt.count', 'tt.taxonomy' );
     596
     597                        default:
     598                                $selects = array( 't.term_id' );
    614599                                break;
    615600                }
    616601
    class WP_Term_Query { 
    672657
    673658                $this->request = "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['orderby']} {$this->sql_clauses['limits']}";
    674659
    675                 // $args can be anything. Only use the args defined in defaults to compute the key.
    676                 $key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) ) ) . serialize( $taxonomies ) . $this->request );
     660                $key = md5( $this->request );
    677661                $last_changed = wp_cache_get_last_changed( 'terms' );
    678662                $cache_key = "get_terms:$key:$last_changed";
     663
    679664                $cache = wp_cache_get( $cache_key, 'terms' );
    680                 if ( false !== $cache ) {
    681                         if ( 'all' === $_fields ) {
    682                                 $cache = array_map( 'get_term', $cache );
    683                         }
    684665
    685                         $this->terms = $cache;
    686                         return $this->terms;
    687                 }
     666                if ( 'count' === $_fields ) {
     667                        if ( false === $cache ) {
     668                                $cache = $wpdb->get_var( $this->request );
     669                                wp_cache_set( $cache_key, $cache, 'terms' );
     670                        }
    688671
    689                 if ( 'count' == $_fields ) {
    690                         $count = $wpdb->get_var( $this->request );
    691                         wp_cache_set( $cache_key, $count, 'terms' );
    692                         return $count;
     672                        return $cache;
    693673                }
    694674
    695                 $terms = $wpdb->get_results( $this->request );
    696                 if ( 'all' == $_fields || 'all_with_object_id' === $_fields ) {
    697                         update_term_cache( $terms );
     675                if ( false === $cache ) {
     676                        $results = $wpdb->get_results( $this->request );
     677                        $cache = wp_list_pluck( $results, 'term_id' );
     678                        wp_cache_set( $cache_key, $cache, 'terms' );
    698679                }
    699680
    700                 // Prime termmeta cache.
    701                 if ( $args['update_term_meta_cache'] ) {
    702                         $term_ids = wp_list_pluck( $terms, 'term_id' );
    703                         update_termmeta_cache( $term_ids );
    704                 }
     681                $term_ids = $cache;
    705682
    706                 if ( empty( $terms ) ) {
     683                if ( empty( $term_ids ) ) {
    707684                        wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS );
    708685                        return array();
    709686                }
    710687
     688                // 'ids' requests only need full term objects in certain cases.
     689                if ( 'ids' === $_fields && ! $child_of && ( ! $hierarchical || ! $args['hide_empty'] ) ) {
     690                        $terms = array();
     691                        foreach ( $term_ids as $term_id ) {
     692                                $_term = new stdClass;
     693                                $_term->term_id = $term_id;
     694                                $terms[] = $_term;
     695                        }
     696
     697                        if ( $args['update_term_meta_cache'] ) {
     698                                update_termmeta_cache( $term_ids );
     699                        }
     700                } else {
     701                        _prime_term_caches( $term_ids, $args['update_term_meta_cache'] );
     702                        $terms = array_map( 'get_term', $term_ids );
     703
     704                        if ( in_array( 'tr.object_id', $selects ) ) {
     705                                foreach ( $results as $index => $result ) {
     706                                        $terms[ $index ]->object_id = (int) $result->object_id;
     707                                }
     708                        }
     709                }
     710
    711711                if ( $child_of ) {
    712712                        foreach ( $taxonomies as $_tax ) {
    713713                                $children = _get_term_hierarchy( $_tax );
    class WP_Term_Query { 
    758758                                }
    759759
    760760                                $_tt_ids[ $term->term_id ] = 1;
    761                                 $_terms[] = $term;
     761                                $_terms[]                  = $term;
    762762                        }
    763763
    764764                        $terms = $_terms;
    class WP_Term_Query { 
    808808                        }
    809809                }
    810810
    811                 wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS );
    812 
    813                 if ( 'all' === $_fields || 'all_with_object_id' === $_fields ) {
    814                         $terms = array_map( 'get_term', $terms );
    815                 }
    816 
    817811                $this->terms = $terms;
     812
    818813                return $this->terms;
    819814        }
    820815
  • src/wp-includes/class-wp-term.php

    diff --git src/wp-includes/class-wp-term.php src/wp-includes/class-wp-term.php
    index 8eb87efbe0..63381b6db0 100644
    final class WP_Term { 
    140140                                return false;
    141141                        }
    142142
     143                        $_term = false;
     144
    143145                        // If a taxonomy was specified, find a match.
    144146                        if ( $taxonomy ) {
    145147                                foreach ( $terms as $match ) {
  • src/wp-includes/taxonomy.php

    diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
    index 0c4012242c..e8c3e149f4 100644
    function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) { 
    30033003
    30043004        foreach ( $taxonomies as $taxonomy ) {
    30053005                if ( $clean_taxonomy ) {
    3006                         wp_cache_delete('all_ids', $taxonomy);
    3007                         wp_cache_delete('get', $taxonomy);
    3008                         delete_option("{$taxonomy}_children");
    3009                         // Regenerate {$taxonomy}_children
    3010                         _get_term_hierarchy($taxonomy);
     3006                        clean_taxonomy_cache( $taxonomy );
    30113007                }
    30123008
    30133009                /**
    function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) { 
    30273023}
    30283024
    30293025/**
     3026 * Clean the caches for a taxonomy.
     3027 *
     3028 * @since 4.9.0
     3029 *
     3030 * @param string $taxonomy Taxonomy slug.
     3031 */
     3032function clean_taxonomy_cache( $taxonomy ) {
     3033        wp_cache_delete( 'all_ids', $taxonomy );
     3034        wp_cache_delete( 'get', $taxonomy );
     3035
     3036        // Regenerate cached hierarchy.
     3037        delete_option( "{$taxonomy}_children" );
     3038        _get_term_hierarchy( $taxonomy );
     3039
     3040        /**
     3041         * Fires after a taxonomy's caches have been cleaned.
     3042         *
     3043         * @since 4.9.0
     3044         *
     3045         * @param string $taxonomy Taxonomy slug.
     3046         */
     3047        do_action( 'clean_term_cache', $taxonomy );
     3048}
     3049
     3050/**
    30303051 * Retrieves the taxonomy relationship to the term object id.
    30313052 *
    30323053 * Upstream functions (like get_the_terms() and is_object_in_term()) are
    function _split_shared_term( $term_id, $term_taxonomy_id, $record = true ) { 
    35273548                                array( 'parent' => $new_term_id ),
    35283549                                array( 'term_taxonomy_id' => $child_tt_id )
    35293550                        );
    3530                         clean_term_cache( $term_id, $term_taxonomy->taxonomy );
     3551                        clean_term_cache( (int) $child_tt_id, '', false );
    35313552                }
    35323553        } else {
    35333554                // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
    3534                 clean_term_cache( $new_term_id, $term_taxonomy->taxonomy );
     3555                clean_term_cache( $new_term_id, $term_taxonomy->taxonomy, false );
    35353556        }
    35363557
     3558        clean_term_cache( $term_id, $term_taxonomy->taxonomy, false );
     3559
     3560        /*
     3561         * Taxonomy cache clearing is delayed to avoid race conditions that may occur when
     3562         * regenerating the taxonomy's hierarchy tree.
     3563         */
     3564        $taxonomies_to_clean = array( $term_taxonomy->taxonomy );
     3565
    35373566        // Clean the cache for term taxonomies formerly shared with the current term.
    3538         $shared_term_taxonomies = $wpdb->get_row( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) );
    3539         if ( $shared_term_taxonomies ) {
    3540                 foreach ( $shared_term_taxonomies as $shared_term_taxonomy ) {
    3541                         clean_term_cache( $term_id, $shared_term_taxonomy );
    3542                 }
     3567        $shared_term_taxonomies = $wpdb->get_col( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) );
     3568        $taxonomies_to_clean = array_merge( $taxonomies_to_clean, $shared_term_taxonomies );
     3569
     3570        foreach ( $taxonomies_to_clean as $taxonomy_to_clean ) {
     3571                clean_taxonomy_cache( $taxonomy_to_clean );
    35433572        }
    35443573
    35453574        // Keep a record of term_ids that have been split, keyed by old term_id. See wp_get_split_term().
  • tests/phpunit/tests/term/cache.php

    diff --git tests/phpunit/tests/term/cache.php tests/phpunit/tests/term/cache.php
    index fb7a5a84ab..b303bc840a 100644
    class Tests_Term_Cache extends WP_UnitTestCase { 
    229229                $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'name' => 'Taco', 'taxonomy' => 'post_tag' ) );
    230230
    231231                clean_term_cache( $term_id, 'post_tag' );
    232                 $num_queries = $wpdb->num_queries;
    233232
    234233                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
    235                 $num_queries++;
    236234                $this->assertEquals( 'Taco', $term->name );
    237                 $this->assertEquals( $num_queries, $wpdb->num_queries );
    238235
    239236                // This should now hit cache.
     237                $num_queries = $wpdb->num_queries;
    240238                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
    241239                $this->assertEquals( 'Taco', $term->name );
    242240                $this->assertEquals( $num_queries, $wpdb->num_queries );
    class Tests_Term_Cache extends WP_UnitTestCase { 
    254252                $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'name' => 'Taco', 'taxonomy' => 'post_tag' ) );
    255253
    256254                clean_term_cache( $term_id, 'post_tag' );
    257                 $num_queries = $wpdb->num_queries;
    258255
    259256                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
    260                 $num_queries++;
    261257                $this->assertEquals( 'Taco', $term->name );
    262                 $this->assertEquals( $num_queries, $wpdb->num_queries );
    263258
    264259                // This should now hit cache.
     260                $num_queries = $wpdb->num_queries;
    265261                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
    266262                $this->assertEquals( 'Taco', $term->name );
    267263                $this->assertEquals( $num_queries, $wpdb->num_queries );
    class Tests_Term_Cache extends WP_UnitTestCase { 
    272268
    273269                // This should not hit cache.
    274270                $term = get_term_by( 'slug', 'burrito', 'post_tag' );
    275                 $num_queries++;
    276271                $this->assertEquals( 'No Taco', $term->name );
    277                 $this->assertEquals( $num_queries, $wpdb->num_queries );
     272                $this->assertGreaterThan( $num_queries, $wpdb->num_queries );
    278273        }
    279274
    280275        /**
    class Tests_Term_Cache extends WP_UnitTestCase { 
    286281                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
    287282
    288283                clean_term_cache( $term_id, 'post_tag' );
    289                 $num_queries = $wpdb->num_queries;
    290284
    291                 get_term_by( 'name', 'Burrito', 'post_tag' );
    292                 $num_queries++;
    293                 $this->assertEquals( $num_queries, $wpdb->num_queries );
     285                $term = get_term_by( 'name', 'Burrito', 'post_tag' );
     286                $this->assertSame( 'Burrito', $term->name );
    294287
    295288                // This should now hit cache.
     289                $num_queries = $wpdb->num_queries;
    296290                $term = get_term_by( 'name', 'Burrito', 'post_tag' );
    297291                $this->assertEquals( $num_queries, $wpdb->num_queries );
    298292
    class Tests_Term_Cache extends WP_UnitTestCase { 
    309303                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
    310304
    311305                clean_term_cache( $term_id, 'post_tag' );
    312                 $num_queries = $wpdb->num_queries;
    313306
    314307                get_term_by( 'name', 'Burrito', 'post_tag' );
    315                 $num_queries++;
    316                 $this->assertEquals( $num_queries, $wpdb->num_queries );
    317308
    318309                // This should now hit cache.
     310                $num_queries = $wpdb->num_queries;
    319311                get_term_by( 'name', 'Burrito', 'post_tag' );
    320312                $this->assertEquals( $num_queries, $wpdb->num_queries );
    321313
    class Tests_Term_Cache extends WP_UnitTestCase { 
    325317
    326318                // This should not hit cache.
    327319                get_term_by( 'name', 'burrito', 'post_tag' );
    328                 $num_queries++;
    329                 $this->assertEquals( $num_queries, $wpdb->num_queries );
     320                $this->assertGreaterThan( $num_queries, $wpdb->num_queries );
    330321        }
    331322
    332323        /**
    class Tests_Term_Cache extends WP_UnitTestCase { 
    338329                $term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'taxonomy' => 'post_tag' ) );
    339330
    340331                clean_term_cache( $term_id, 'post_tag' );
    341                 $num_queries = $wpdb->num_queries;
    342332                $last_changed = wp_cache_get( 'last_changed', 'terms' );
    343333
    344334                $term1 = get_term_by( 'name', 'Burrito', 'post_tag' );
    345                 $num_queries++;
    346335
    347336                // Verify the term is cached.
     337                $num_queries = $wpdb->num_queries;
    348338                $term2 = get_term_by( 'name', 'Burrito', 'post_tag' );
    349339                $this->assertEquals( $num_queries, $wpdb->num_queries );
    350340                $this->assertEquals( $term1, $term2 );
    class Tests_Term_Cache extends WP_UnitTestCase { 
    377367                add_term_meta( $term_id, 'foo', 'bar' );
    378368
    379369                clean_term_cache( $term_id, 'post_tag' );
    380                 $num_queries = $wpdb->num_queries;
    381370
    382371                $term = get_term_by( 'name', 'Burrito', 'post_tag' );
    383                 $num_queries++;
    384372                $this->assertTrue( $term instanceof WP_Term );
    385373                $this->assertSame( $term_id, $term->term_id );
    386                 $this->assertEquals( $num_queries, $wpdb->num_queries );
    387374
     375                $num_queries = $wpdb->num_queries;
    388376                $term_meta = get_term_meta( $term_id, 'foo', true );
    389377                $num_queries++;
    390378                $this->assertSame( $term_meta, 'bar' );
  • tests/phpunit/tests/term/getTermBy.php

    diff --git tests/phpunit/tests/term/getTermBy.php tests/phpunit/tests/term/getTermBy.php
    index 4adda74f5a..ea8c386779 100644
    class Tests_Term_GetTermBy extends WP_UnitTestCase { 
    108108
    109109                clean_term_cache( $t, 'wptests_tax' );
    110110
    111                 $num_queries = $wpdb->num_queries;
    112111                $found = get_term_by( 'slug', 'foo', 'wptests_tax' );
    113                 $num_queries++;
    114112
    115113                $this->assertTrue( $found instanceof WP_Term );
    116114                $this->assertSame( $t, $found->term_id );
    117                 $this->assertSame( $num_queries, $wpdb->num_queries );
    118115
    119116                // Calls to `get_term()` should now hit cache.
     117                $num_queries = $wpdb->num_queries;
    120118                $found2 = get_term( $t );
    121119                $this->assertSame( $t, $found->term_id );
    122120                $this->assertSame( $num_queries, $wpdb->num_queries );
    class Tests_Term_GetTermBy extends WP_UnitTestCase { 
    172170        /**
    173171         * @ticket 21760
    174172         */
    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         }
    195 
    196         /**
    197          * @ticket 21760
    198          */
    199173        public function test_prevent_recursion_by_get_terms_filter() {
    200174                $action = new MockAction();
    201175
  • tests/phpunit/tests/term/getTerms.php

    diff --git tests/phpunit/tests/term/getTerms.php tests/phpunit/tests/term/getTerms.php
    index 575e5ca1c0..01a79faddd 100644
    class Tests_Term_getTerms extends WP_UnitTestCase { 
    112112                $this->assertEquals( 3, count( $terms ) );
    113113                $time1 = wp_cache_get( 'last_changed', 'terms' );
    114114                $this->assertNotEmpty( $time1 );
    115                 $this->assertEquals( $num_queries + 1, $wpdb->num_queries );
     115                $this->assertEquals( $num_queries + 2, $wpdb->num_queries );
    116116
    117117                $num_queries = $wpdb->num_queries;
    118118
  • tests/phpunit/tests/term/isObjectInTerm.php

    diff --git tests/phpunit/tests/term/isObjectInTerm.php tests/phpunit/tests/term/isObjectInTerm.php
    index ed054f8ea3..5aa55d88a0 100644
    class Tests_IsObjectInTerm extends WP_UnitTestCase { 
    113113                $o = 12345;
    114114                wp_set_object_terms( $o, $terms[0], 'wptests_tax' );
    115115
    116                 $num_queries = $wpdb->num_queries;
    117116                $this->assertTrue( is_object_in_term( $o, 'wptests_tax', $terms[0] ) );
    118                 $num_queries++;
    119                 $this->assertSame( $num_queries, $wpdb->num_queries );
    120117
     118                $num_queries = $wpdb->num_queries;
    121119                $this->assertFalse( is_object_in_term( $o, 'wptests_tax', $terms[1] ) );
    122120                $this->assertSame( $num_queries, $wpdb->num_queries );
    123121        }
    class Tests_IsObjectInTerm extends WP_UnitTestCase { 
    134132                $o = 12345;
    135133                wp_set_object_terms( $o, $terms[0], 'wptests_tax' );
    136134
    137                 $num_queries = $wpdb->num_queries;
    138135                $this->assertTrue( is_object_in_term( $o, 'wptests_tax', $terms[0] ) );
    139                 $num_queries++;
    140                 $this->assertSame( $num_queries, $wpdb->num_queries );
    141136
    142137                wp_set_object_terms( $o, $terms[1], 'wptests_tax' );
    143138
    144                 $num_queries = $wpdb->num_queries;
    145139                $this->assertTrue( is_object_in_term( $o, 'wptests_tax', $terms[1] ) );
    146                 $num_queries++;
    147                 $this->assertSame( $num_queries, $wpdb->num_queries );
    148140        }
    149141
    150142        /**