Ticket #21760: term-cache.diff

File term-cache.diff, 13.0 KB (added by wonderboymusic, 9 months ago)
Line 
1Index: wp-includes/category.php
2===================================================================
3--- wp-includes/category.php    (revision 21762)
4+++ wp-includes/category.php    (working copy)
5@@ -14,12 +14,8 @@
6  * @return object List of all of the category IDs.
7  */
8 function get_all_category_ids() {
9-       if ( ! $cat_ids = wp_cache_get( 'all_category_ids', 'category' ) ) {
10-               $cat_ids = get_terms( 'category', array('fields' => 'ids', 'get' => 'all') );
11-               wp_cache_add( 'all_category_ids', $cat_ids, 'category' );
12-       }
13-
14-       return $cat_ids;
15+       // this call returns from cache if present
16+       return get_terms( 'category', array( 'fields' => 'ids', 'get' => 'all' ) );
17 }
18 
19 /**
20@@ -36,7 +32,7 @@
21  * @param string|array $args Optional. Change the defaults retrieving categories.
22  * @return array List of categories.
23  */
24-function &get_categories( $args = '' ) {
25+function get_categories( $args = '' ) {
26        $defaults = array( 'taxonomy' => 'category' );
27        $args = wp_parse_args( $args, $defaults );
28 
29@@ -78,7 +74,7 @@
30  * @param string $filter Optional. Default is raw or no WordPress defined filter will applied.
31  * @return mixed Category data in type defined by $output parameter.
32  */
33-function &get_category( $category, $output = OBJECT, $filter = 'raw' ) {
34+function get_category( $category, $output = OBJECT, $filter = 'raw' ) {
35        $category = get_term( $category, 'category', $output, $filter );
36        if ( is_wp_error( $category ) )
37                return $category;
38@@ -249,7 +245,7 @@
39  * @param string|array $args Tag arguments to use when retrieving tags.
40  * @return array List of tags.
41  */
42-function &get_tags( $args = '' ) {
43+function get_tags( $args = '' ) {
44        $tags = get_terms( 'post_tag', $args );
45 
46        if ( empty( $tags ) ) {
47@@ -280,7 +276,7 @@
48  * @param string $filter Optional. Default is raw or no WordPress defined filter will applied.
49  * @return object|array Return type based on $output value.
50  */
51-function &get_tag( $tag, $output = OBJECT, $filter = 'raw' ) {
52+function get_tag( $tag, $output = OBJECT, $filter = 'raw' ) {
53        return get_term( $tag, 'post_tag', $output, $filter );
54 }
55 
56Index: wp-includes/taxonomy.php
57===================================================================
58--- wp-includes/taxonomy.php    (revision 21762)
59+++ wp-includes/taxonomy.php    (working copy)
60@@ -853,13 +853,13 @@
61  * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param.
62  *
63  * @param int|object $term If integer, will get from database. If object will apply filters and return $term.
64- * @param string $taxonomy Taxonomy name that $term is part of.
65+ * @param string $taxonomy Optional if object is passed for $term. Taxonomy name that $term is part of.
66  * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N
67  * @param string $filter Optional, default is raw or no WordPress defined filter will applied.
68  * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not
69  * exist then WP_Error will be returned.
70  */
71-function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') {
72+function get_term($term, $taxonomy = '', $output = OBJECT, $filter = 'raw') {
73        global $wpdb;
74        $null = null;
75 
76@@ -868,24 +868,28 @@
77                return $error;
78        }
79 
80-       if ( ! taxonomy_exists($taxonomy) ) {
81-               $error = new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
82-               return $error;
83-       }
84+       if ( is_object( $term ) )
85+               $taxonomy = $term->taxonomy;
86 
87+       if ( ! taxonomy_exists( $taxonomy ) )
88+               return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy' ) );   
89+
90        if ( is_object($term) && empty($term->filter) ) {
91-               wp_cache_add($term->term_id, $term, $taxonomy);
92+               update_term_cache( $term, $taxonomy );
93                $_term = $term;
94        } else {
95                if ( is_object($term) )
96                        $term = $term->term_id;
97+               
98                if ( !$term = (int) $term )
99                        return $null;
100-               if ( ! $_term = wp_cache_get($term, $taxonomy) ) {
101+               
102+               if ( ! $_term = wp_cache_get( $term, term_cache_group( $taxonomy ) ) ) {
103                        $_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) );
104                        if ( ! $_term )
105                                return $null;
106-                       wp_cache_add($term, $_term, $taxonomy);
107+                       
108+                       update_term_cache( $_term, $taxonomy );
109                }
110        }
111 
112@@ -940,18 +944,26 @@
113                return false;
114 
115        if ( 'slug' == $field ) {
116-               $field = 't.slug';
117-               $value = sanitize_title($value);
118-               if ( empty($value) )
119+               $value = sanitize_title( $value );
120+               if ( empty( $value ) )
121                        return false;
122+               
123+               $term_id = wp_cache_get( $value, term_cache_group( $taxonomy, $field ) );
124+               $field = 't.slug';             
125        } else if ( 'name' == $field ) {
126                // Assume already escaped
127-               $value = stripslashes($value);
128-               $field = 't.name';
129+               $value = stripslashes( $value );
130+               $term_id = wp_cache_get( $value, term_cache_group( $taxonomy, $field ) );
131+               $field = 't.name';             
132        } else {
133-               $term = get_term( (int) $value, $taxonomy, $output, $filter);
134+               $term_id = $value;
135+       }
136+       
137+       if ( ! empty( $term_id ) ) {
138+               $term = get_term( (int) $term_id, $taxonomy, $output, $filter );
139                if ( is_wp_error( $term ) )
140                        $term = false;
141+               
142                return $term;
143        }
144 
145@@ -959,7 +971,7 @@
146        if ( !$term )
147                return false;
148 
149-       wp_cache_add($term->term_id, $term, $taxonomy);
150+       update_term_cache( $term, $taxonomy );
151 
152        $term = apply_filters('get_term', $term, $taxonomy);
153        $term = apply_filters("get_$taxonomy", $term, $taxonomy);
154@@ -1176,7 +1188,7 @@
155  * @param string|array $args The values of what to search for when returning terms
156  * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist.
157  */
158-function &get_terms($taxonomies, $args = '') {
159+function get_terms($taxonomies, $args = '') {
160        global $wpdb;
161        $empty_array = array();
162 
163@@ -1232,8 +1244,11 @@
164        }
165 
166        // $args can be whatever, only use the args defined in defaults to compute the key
167-       $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
168-       $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key );
169+       // deprecate 'list_terms_exclusions' - use 'get_terms' filter instead
170+       if ( has_filter( 'list_terms_exclusions' ) )
171+               _doing_it_wrong( __FUNCTION__, __( '"list_terms_exclusions" is no longer supported. Use the "get_terms" filter instead.' ), '3.5' );
172+       
173+       $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) );
174        $last_changed = wp_cache_get('last_changed', 'terms');
175        if ( !$last_changed ) {
176                $last_changed = time();
177@@ -2556,7 +2571,7 @@
178 
179        foreach ( $object_ids as $id )
180                foreach ( get_object_taxonomies($object_type) as $taxonomy )
181-                       wp_cache_delete($id, "{$taxonomy}_relationships");
182+                       wp_cache_delete( $id, term_cache_group( $taxonomy, 'relationships' ) );
183 
184        do_action('clean_object_term_cache', $object_ids, $object_type);
185 }
186@@ -2579,28 +2594,31 @@
187 
188        if ( !is_array($ids) )
189                $ids = array($ids);
190-
191+       
192        $taxonomies = array();
193+       
194+       $select = "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
195+       
196+       $ids = array_map( 'intval', $ids );
197        // If no taxonomy, assume tt_ids.
198-       if ( empty($taxonomy) ) {
199-               $tt_ids = array_map('intval', $ids);
200-               $tt_ids = implode(', ', $tt_ids);
201-               $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)");
202+       if ( empty( $taxonomy ) ) {
203+               $terms = $wpdb->get_results( $wpdb->prepare( "$select WHERE tt.term_taxonomy_id IN (" . join( ',', $ids ) . ")" ) );
204                $ids = array();
205-               foreach ( (array) $terms as $term ) {
206+               foreach ( $terms as $term ) {
207                        $taxonomies[] = $term->taxonomy;
208                        $ids[] = $term->term_id;
209-                       wp_cache_delete($term->term_id, $term->taxonomy);
210                }
211                $taxonomies = array_unique($taxonomies);
212        } else {
213-               $taxonomies = array($taxonomy);
214-               foreach ( $taxonomies as $taxonomy ) {
215-                       foreach ( $ids as $id ) {
216-                               wp_cache_delete($id, $taxonomy);
217-                       }
218-               }
219+               $terms = $wpdb->get_results( $wpdb->prepare( "$select WHERE tt.taxonomy = %s AND tt.term_id IN (" . join( ',', $ids ) . ")", $taxonomy ) );
220+               $taxonomies = array( $taxonomy );               
221        }
222+       
223+       foreach ( $terms as $term ) {
224+               wp_cache_delete( $term->term_id, term_cache_group( $term->taxonomy ) );
225+               wp_cache_delete( $term->name, term_cache_group( $term->taxonomy, 'names' ) );
226+               wp_cache_delete( $term->slug, term_cache_group( $term->taxonomy, 'slugs' ) );   
227+       }
228 
229        foreach ( $taxonomies as $taxonomy ) {
230                if ( isset($cleaned[$taxonomy]) )
231@@ -2608,8 +2626,6 @@
232                $cleaned[$taxonomy] = true;
233 
234                if ( $clean_taxonomy ) {
235-                       wp_cache_delete('all_ids', $taxonomy);
236-                       wp_cache_delete('get', $taxonomy);
237                        delete_option("{$taxonomy}_children");
238                        // Regenerate {$taxonomy}_children
239                        _get_term_hierarchy($taxonomy);
240@@ -2634,8 +2650,8 @@
241  * @param string $taxonomy Taxonomy Name
242  * @return bool|array Empty array if $terms found, but not $taxonomy. False if nothing is in cache for $taxonomy and $id.
243  */
244-function &get_object_term_cache($id, $taxonomy) {
245-       $cache = wp_cache_get($id, "{$taxonomy}_relationships");
246+function get_object_term_cache($id, $taxonomy) {
247+       $cache = wp_cache_get( $id, term_cache_group( $taxonomy, 'relationships' ) );
248        return $cache;
249 }
250 
251@@ -2675,7 +2691,7 @@
252        $ids = array();
253        foreach ( (array) $object_ids as $id ) {
254                foreach ( $taxonomies as $taxonomy ) {
255-                       if ( false === wp_cache_get($id, "{$taxonomy}_relationships") ) {
256+                       if ( false === wp_cache_get( $id, term_cache_group( $taxonomy, 'relationships' ) ) ) {
257                                $ids[] = $id;
258                                break;
259                        }
260@@ -2703,7 +2719,7 @@
261 
262        foreach ( $object_terms as $id => $value ) {
263                foreach ( $value as $taxonomy => $terms ) {
264-                       wp_cache_add( $id, $terms, "{$taxonomy}_relationships" );
265+                       wp_cache_add( $id, $terms, term_cache_group( $taxonomy, 'relationships' ) );
266                }
267        }
268 }
269@@ -2718,16 +2734,73 @@
270  * @param array $terms List of Term objects to change
271  * @param string $taxonomy Optional. Update Term to this taxonomy in cache
272  */
273-function update_term_cache($terms, $taxonomy = '') {
274-       foreach ( (array) $terms as $term ) {
275-               $term_taxonomy = $taxonomy;
276-               if ( empty($term_taxonomy) )
277-                       $term_taxonomy = $term->taxonomy;
278+function update_term_cache( $terms, $taxonomy = '' ) {
279+       if ( ! is_array( $terms ) )
280+               $terms = array( $terms );
281+       
282+       foreach ( $terms as $term ) {
283+               $tax = $taxonomy;
284+               if ( empty( $tax ) )
285+                       $tax = $term->taxonomy;
286 
287-               wp_cache_add($term->term_id, $term, $term_taxonomy);
288+               wp_cache_add( $term->term_id, $term, term_cache_group( $tax ) );
289+               wp_cache_add( $term->name, $term->term_id, term_cache_group( $tax, 'names' ) );
290+               wp_cache_add( $term->slug, $term->term_id, term_cache_group( $tax, 'slugs' ) );
291        }
292 }
293 
294+/**
295+ *
296+ * @package WordPress
297+ * @subpackage Taxonomy
298+ * @since 3.5.0
299+ *
300+ * @param string $taxonomy Taxonomy
301+ * @param string $group Optional. ids, names, slugs, or relationships.
302+ */
303+function term_cache_group( $taxonomy, $group = 'ids' ) {
304+       $tax = get_taxonomy( $taxonomy );
305+       
306+       if ( ! $tax )
307+               return false;
308+
309+       if ( $tax->_builtin ) {
310+               $key = $taxonomy;
311+               switch ( $group ) {
312+                       case 'name':
313+                       case 'names':
314+                               $key = "$taxonomy:names";
315+                               break;
316+                       case 'slug':
317+                       case 'slugs':
318+                               $key = "$taxonomy:slugs";
319+                               break;
320+                       case 'relationship':
321+                       case 'relationships':
322+                               $key = "{$taxonomy}_relationships";
323+                               break;                 
324+               }
325+       } else {
326+               $key = "taxonomy:$taxonomy:ids";
327+               switch ( $group ) {
328+                       case 'name':
329+                       case 'names':
330+                               $key = "taxonomy:$taxonomy:names";
331+                               break;
332+                       case 'slug':
333+                       case 'slugs':
334+                               $key = "taxonomy:$taxonomy:slugs";
335+                               break;
336+                       case 'relationship':
337+                       case 'relationships':
338+                               $key = "taxonomy:$taxonomy:relationships";
339+                               break;                 
340+               }
341+       }
342+       
343+       return $key;   
344+}
345+
346 //
347 // Private
348 //
349@@ -2780,7 +2853,7 @@
350  * @param string $taxonomy The taxonomy which determines the hierarchy of the terms.
351  * @return array The subset of $terms that are descendants of $term_id.
352  */
353-function &_get_term_children($term_id, $terms, $taxonomy) {
354+function _get_term_children($term_id, $terms, $taxonomy) {
355        $empty_array = array();
356        if ( empty($terms) )
357                return $empty_array;
358Index: wp-includes/media.php
359===================================================================
360--- wp-includes/media.php       (revision 21762)
361+++ wp-includes/media.php       (working copy)
362@@ -1156,8 +1156,6 @@
363         * @uses WP_Embed::maybe_make_link()
364         * @uses get_option()
365         * @uses current_user_can()
366-        * @uses wp_cache_get()
367-        * @uses wp_cache_set()
368         * @uses get_post_meta()
369         * @uses update_post_meta()
370         *
371Index: wp-includes/category-template.php
372===================================================================
373--- wp-includes/category-template.php   (revision 21762)
374+++ wp-includes/category-template.php   (working copy)
375@@ -1065,7 +1065,7 @@
376        $terms = get_object_term_cache( $post->ID, $taxonomy );
377        if ( false === $terms ) {
378                $terms = wp_get_object_terms( $post->ID, $taxonomy );
379-               wp_cache_add($post->ID, $terms, $taxonomy . '_relationships');
380+               wp_cache_add( $post->ID, $terms, term_cache_group( $taxonomy, 'relationships' ) );
381        }
382 
383        $terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy );