Ticket #21760: 21760.2.patch
File 21760.2.patch, 10.5 KB (added by , 6 years ago) |
---|
-
src/wp-includes/functions.php
diff --git src/wp-includes/functions.php src/wp-includes/functions.php index c19e0dd..ae15ca2 100644
function wp_validate_boolean( $var ) { 4629 4629 4630 4630 return (bool) $var; 4631 4631 } 4632 4633 /** 4634 * Helper function to retrieve an incrementer identified by $group 4635 * 4636 * @since 4.0.0 4637 * 4638 * @param string $group The cache group for the incrementer. 4639 * @param bool $force Whether or not to generate a new incrementor. 4640 * @return int The timestamp representing 'last_changed'. 4641 */ 4642 function wp_get_last_changed( $group, $force = false ) { 4643 $last_changed = wp_cache_get( 'last_changed', $group ); 4644 if ( ! $last_changed || true === $force ) { 4645 $last_changed = microtime(); 4646 wp_cache_set( 'last_changed', $last_changed, $group ); 4647 } 4648 return $last_changed; 4649 } 4650 No newline at end of file -
src/wp-includes/taxonomy.php
diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php index 013c3d3..f0a112a 100644
function get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { 963 963 return $error; 964 964 } 965 965 966 $group = $taxonomy . ':' . wp_get_last_changed( 'terms' ); 966 967 if ( is_object($term) && empty($term->filter) ) { 967 wp_cache_add($term->term_id, $term, $taxonomy); 968 wp_cache_add( $term->term_id, $term, $taxonomy ); 969 wp_cache_add( "slug:{$term->slug}", $term->term_id, $group ); 970 wp_cache_add( "name:" . md5( $term->name ), $term->term_id, $group ); 968 971 $_term = $term; 969 972 } else { 970 973 if ( is_object($term) ) … … function get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { 975 978 $_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 tt.taxonomy = %s AND t.term_id = %d LIMIT 1", $taxonomy, $term) ); 976 979 if ( ! $_term ) 977 980 return null; 978 wp_cache_add($term, $_term, $taxonomy); 981 wp_cache_add( $term, $_term, $taxonomy ); 982 wp_cache_add( "slug:{$_term->slug}", $term, $group ); 983 wp_cache_add( "name:" . md5( $_term->name ), $term, $group ); 979 984 } 980 985 } 981 986 … … function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw 1047 1052 if ( ! taxonomy_exists($taxonomy) ) 1048 1053 return false; 1049 1054 1055 $cache = false; 1056 $group = $taxonomy . ':' . wp_get_last_changed( 'terms' ); 1050 1057 if ( 'slug' == $field ) { 1051 1058 $field = 't.slug'; 1052 1059 $value = sanitize_title($value); 1053 1060 if ( empty($value) ) 1054 1061 return false; 1062 1063 $term_id = wp_cache_get( "slug:{$value}", $group ); 1064 if ( $term_id ) { 1065 $value = $term_id; 1066 $cache = true; 1067 } 1055 1068 } else if ( 'name' == $field ) { 1056 1069 // Assume already escaped 1057 1070 $value = wp_unslash($value); 1058 1071 $field = 't.name'; 1072 $term_id = wp_cache_get( "name:" . md5( $value ), $group ); 1073 if ( $term_id ) { 1074 $value = $term_id; 1075 $cache = true; 1076 } 1059 1077 } else if ( 'term_taxonomy_id' == $field ) { 1060 1078 $value = (int) $value; 1061 1079 $field = 'tt.term_taxonomy_id'; 1062 1080 } else { 1081 $cache = true; 1082 } 1083 1084 if ( $cache ) { 1063 1085 $term = get_term( (int) $value, $taxonomy, $output, $filter); 1064 if ( is_wp_error( $term ) ) 1086 if ( is_wp_error( $term ) ) { 1065 1087 $term = false; 1066 return $term; 1088 } 1089 } else { 1090 $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 tt.taxonomy = %s AND $field = %s LIMIT 1", $taxonomy, $value) ); 1067 1091 } 1068 1092 1069 $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 tt.taxonomy = %s AND $field = %s LIMIT 1", $taxonomy, $value) );1070 1093 if ( !$term ) 1071 1094 return false; 1072 1095 1073 wp_cache_add($term->term_id, $term, $taxonomy);1074 1075 1096 /** This filter is documented in wp-includes/taxonomy.php */ 1076 1097 $term = apply_filters( 'get_term', $term, $taxonomy ); 1077 1098 … … function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw 1080 1101 1081 1102 $term = sanitize_term($term, $taxonomy, $filter); 1082 1103 1104 wp_cache_add( $term->term_id, $term, $taxonomy ); 1105 wp_cache_add( "slug:{$term->slug}", $term->term_id, $group ); 1106 wp_cache_add( "name:" . md5( $term->name ), $term->term_id, $group ); 1107 1083 1108 if ( $output == OBJECT ) { 1084 1109 return $term; 1085 1110 } elseif ( $output == ARRAY_A ) { … … function get_terms( $taxonomies, $args = '' ) { 1562 1587 } 1563 1588 1564 1589 $terms = $wpdb->get_results($query); 1565 if ( 'all' == $_fields ) {1566 update_term_cache($terms);1567 }1568 1590 1569 1591 if ( empty($terms) ) { 1570 1592 wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS ); … … function clean_object_term_cache($object_ids, $object_type) { 3256 3278 * @param bool $clean_taxonomy Whether to clean taxonomy wide caches (true), or just individual term object caches (false). Default is true. 3257 3279 */ 3258 3280 function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) { 3259 global $wpdb; 3281 global $_wp_suspend_cache_invalidation, $wpdb; 3282 3283 if ( ! empty( $_wp_suspend_cache_invalidation ) ) { 3284 return; 3285 } 3260 3286 3261 3287 if ( !is_array($ids) ) 3262 3288 $ids = array($ids); … … function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) { 3303 3329 do_action( 'clean_term_cache', $ids, $taxonomy ); 3304 3330 } 3305 3331 3306 wp_ cache_set( 'last_changed', microtime(), 'terms');3332 wp_get_last_changed( 'terms', true ); 3307 3333 } 3308 3334 3309 3335 /** … … function update_object_term_cache($object_ids, $object_type) { 3398 3424 * @param string $taxonomy Optional. Update Term to this taxonomy in cache 3399 3425 */ 3400 3426 function update_term_cache($terms, $taxonomy = '') { 3427 global $_wp_suspend_cache_invalidation; 3428 3429 if ( ! empty( $_wp_suspend_cache_invalidation ) ) { 3430 return; 3431 } 3432 3401 3433 foreach ( (array) $terms as $term ) { 3402 3434 $term_taxonomy = $taxonomy; 3403 3435 if ( empty($term_taxonomy) ) 3404 3436 $term_taxonomy = $term->taxonomy; 3405 3437 3406 wp_cache_add($term->term_id, $term, $term_taxonomy); 3438 wp_cache_add( $term->term_id, $term, $term_taxonomy ); 3439 $group = $term_taxonomy . ':' . wp_get_last_changed( 'terms', true ); 3440 wp_cache_add( "slug:{$term->slug}", $term->term_id, $group ); 3441 wp_cache_add( "name:" . md5( $term->name ), $term->term_id, $group ); 3407 3442 } 3408 3443 } 3409 3444 -
tests/phpunit/tests/term/cache.php
diff --git tests/phpunit/tests/term/cache.php tests/phpunit/tests/term/cache.php index a63f30f..0c7f1b5 100644
class Tests_Term_Cache extends WP_UnitTestCase { 93 93 94 94 _unregister_taxonomy( $tax ); 95 95 } 96 97 /** 98 * @ticket 21760 99 */ 100 function test_get_term_by_slug_cache() { 101 global $wpdb; 102 $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'taxonomy' => 'post_tag' ) ); 103 104 $queries = $wpdb->num_queries; 105 get_term_by( 'slug', 'burrito', 'post_tag' ); 106 $initial = $queries + 1; 107 $this->assertEquals( $initial, $wpdb->num_queries ); 108 $term = get_term_by( 'slug', 'burrito', 'post_tag' ); 109 $this->assertEquals( $initial, $wpdb->num_queries ); 110 111 $this->assertEquals( $term, wp_cache_get( $term_id, 'post_tag' ) ); 112 113 $this->assertEquals( get_term( $term_id, 'post_tag' ), $term ); 114 $this->assertEquals( $initial, $wpdb->num_queries ); 115 } 116 117 /** 118 * @ticket 21760 119 */ 120 function test_get_term_by_slug_cache_update() { 121 global $wpdb; 122 $term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'taxonomy' => 'post_tag' ) ); 123 124 $queries = $wpdb->num_queries; 125 get_term_by( 'slug', 'burrito', 'post_tag' ); 126 $initial = $queries + 1; 127 $this->assertEquals( $initial, $wpdb->num_queries ); 128 $term = get_term_by( 'slug', 'burrito', 'post_tag' ); 129 $this->assertEquals( $initial, $wpdb->num_queries ); 130 131 $this->assertEquals( $term, wp_cache_get( $term_id, 'post_tag' ) ); 132 133 wp_update_term( $term_id, 'post_tag', array( 'name' => 'Taco' ) ); 134 $this->assertNotEquals( $term, get_term( $term_id, 'post_tag' ) ); 135 $after_queries = $wpdb->num_queries; 136 get_term_by( 'slug', 'burrito', 'post_tag' ); 137 $this->assertEquals( $after_queries, $wpdb->num_queries ); 138 } 139 140 /** 141 * @ticket 21760 142 */ 143 function test_get_term_by_name_cache() { 144 global $wpdb; 145 $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) ); 146 147 $queries = $wpdb->num_queries; 148 get_term_by( 'name', 'burrito', 'post_tag' ); 149 $initial = $queries + 1; 150 $this->assertEquals( $initial, $wpdb->num_queries ); 151 $term = get_term_by( 'name', 'burrito', 'post_tag' ); 152 $this->assertEquals( $initial, $wpdb->num_queries ); 153 154 $this->assertEquals( get_term( $term_id, 'post_tag' ), $term ); 155 $this->assertEquals( $initial, $wpdb->num_queries ); 156 } 157 158 /** 159 * @ticket 21760 160 */ 161 function test_get_term_by_name_cache_update() { 162 global $wpdb; 163 $term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) ); 164 165 $queries = $wpdb->num_queries; 166 get_term_by( 'name', 'burrito', 'post_tag' ); 167 $initial = $queries + 1; 168 $this->assertEquals( $initial, $wpdb->num_queries ); 169 $term = get_term_by( 'name', 'burrito', 'post_tag' ); 170 $this->assertEquals( $initial, $wpdb->num_queries ); 171 172 wp_update_term( $term_id, 'post_tag', array( 'slug' => 'Taco' ) ); 173 $this->assertNotEquals( $term, get_term( $term_id, 'post_tag' ) ); 174 $after_queries = $wpdb->num_queries; 175 get_term_by( 'name', 'burrito', 'post_tag' ); 176 $this->assertEquals( $after_queries, $wpdb->num_queries ); 177 } 178 179 /** 180 * @ticket 21760 181 */ 182 function test_invalidating_term_caches_should_fail_when_invalidation_is_suspended() { 183 $slug = 'taco'; 184 $name = 'Taco'; 185 $taxonomy = 'post_tag'; 186 $cache_key_slug = 'slug:' . $slug; 187 $cache_key_name = 'name:' . md5( $name ); 188 189 $term_id = $this->factory->term->create( array( 'slug' => $slug, 'name' => $name, 'taxonomy' => $taxonomy ) ); 190 191 $last_changed = wp_get_last_changed( 'terms' ); 192 $group = $taxonomy . ':' . $last_changed; 193 194 $term = get_term_by( 'slug', $slug, $taxonomy ); 195 196 // Verify the term is cached by ID, slug and name 197 $this->assertEquals( $term, wp_cache_get( $term_id, $taxonomy ) ); 198 $this->assertEquals( $term_id, wp_cache_get( $cache_key_slug, $group ) ); 199 $this->assertEquals( $term_id, wp_cache_get( $cache_key_name, $group ) ); 200 201 wp_suspend_cache_invalidation(); 202 clean_term_cache( $term_id, $taxonomy ); 203 204 // Verify that the cached value still matches the correct value 205 $this->assertEquals( $term, wp_cache_get( $term_id, $taxonomy ) ); 206 $this->assertEquals( $term_id, wp_cache_get( $cache_key_slug, $group ) ); 207 $this->assertEquals( $term_id, wp_cache_get( $cache_key_name, $group ) ); 208 209 // Verify that last changed has not been updated as part of an invalidation routine 210 $this->assertEquals( $last_changed, wp_get_last_changed( 'terms' ) ); 211 } 96 212 } 213 No newline at end of file