WordPress 3.9-scripts
[autoinstalls/wordpress.git] / wp-includes / cache.php
1 <?php
2 /**
3  * Object Cache API
4  *
5  * @link http://codex.wordpress.org/Function_Reference/WP_Cache
6  *
7  * @package WordPress
8  * @subpackage Cache
9  */
10
11 /**
12  * Adds data to the cache, if the cache key doesn't already exist.
13  *
14  * @since 2.0.0
15  * @uses $wp_object_cache Object Cache Class
16  * @see WP_Object_Cache::add()
17  *
18  * @param int|string $key The cache key to use for retrieval later
19  * @param mixed $data The data to add to the cache store
20  * @param string $group The group to add the cache to
21  * @param int $expire When the cache data should be expired
22  * @return bool False if cache key and group already exist, true on success
23  */
24 function wp_cache_add( $key, $data, $group = '', $expire = 0 ) {
25         global $wp_object_cache;
26
27         return $wp_object_cache->add( $key, $data, $group, (int) $expire );
28 }
29
30 /**
31  * Closes the cache.
32  *
33  * This function has ceased to do anything since WordPress 2.5. The
34  * functionality was removed along with the rest of the persistent cache. This
35  * does not mean that plugins can't implement this function when they need to
36  * make sure that the cache is cleaned up after WordPress no longer needs it.
37  *
38  * @since 2.0.0
39  *
40  * @return bool Always returns True
41  */
42 function wp_cache_close() {
43         return true;
44 }
45
46 /**
47  * Decrement numeric cache item's value
48  *
49  * @since 3.3.0
50  * @uses $wp_object_cache Object Cache Class
51  * @see WP_Object_Cache::decr()
52  *
53  * @param int|string $key The cache key to increment
54  * @param int $offset The amount by which to decrement the item's value. Default is 1.
55  * @param string $group The group the key is in.
56  * @return false|int False on failure, the item's new value on success.
57  */
58 function wp_cache_decr( $key, $offset = 1, $group = '' ) {
59         global $wp_object_cache;
60
61         return $wp_object_cache->decr( $key, $offset, $group );
62 }
63
64 /**
65  * Removes the cache contents matching key and group.
66  *
67  * @since 2.0.0
68  * @uses $wp_object_cache Object Cache Class
69  * @see WP_Object_Cache::delete()
70  *
71  * @param int|string $key What the contents in the cache are called
72  * @param string $group Where the cache contents are grouped
73  * @return bool True on successful removal, false on failure
74  */
75 function wp_cache_delete($key, $group = '') {
76         global $wp_object_cache;
77
78         return $wp_object_cache->delete($key, $group);
79 }
80
81 /**
82  * Removes all cache items.
83  *
84  * @since 2.0.0
85  * @uses $wp_object_cache Object Cache Class
86  * @see WP_Object_Cache::flush()
87  *
88  * @return bool False on failure, true on success
89  */
90 function wp_cache_flush() {
91         global $wp_object_cache;
92
93         return $wp_object_cache->flush();
94 }
95
96 /**
97  * Retrieves the cache contents from the cache by key and group.
98  *
99  * @since 2.0.0
100  * @uses $wp_object_cache Object Cache Class
101  * @see WP_Object_Cache::get()
102  *
103  * @param int|string $key What the contents in the cache are called
104  * @param string $group Where the cache contents are grouped
105  * @param bool $force Whether to force an update of the local cache from the persistent cache (default is false)
106  * @param &bool $found Whether key was found in the cache. Disambiguates a return of false, a storable value.
107  * @return bool|mixed False on failure to retrieve contents or the cache
108  *              contents on success
109  */
110 function wp_cache_get( $key, $group = '', $force = false, &$found = null ) {
111         global $wp_object_cache;
112
113         return $wp_object_cache->get( $key, $group, $force, $found );
114 }
115
116 /**
117  * Increment numeric cache item's value
118  *
119  * @since 3.3.0
120  * @uses $wp_object_cache Object Cache Class
121  * @see WP_Object_Cache::incr()
122  *
123  * @param int|string $key The cache key to increment
124  * @param int $offset The amount by which to increment the item's value. Default is 1.
125  * @param string $group The group the key is in.
126  * @return false|int False on failure, the item's new value on success.
127  */
128 function wp_cache_incr( $key, $offset = 1, $group = '' ) {
129         global $wp_object_cache;
130
131         return $wp_object_cache->incr( $key, $offset, $group );
132 }
133
134 /**
135  * Sets up Object Cache Global and assigns it.
136  *
137  * @since 2.0.0
138  * @global WP_Object_Cache $wp_object_cache WordPress Object Cache
139  */
140 function wp_cache_init() {
141         $GLOBALS['wp_object_cache'] = new WP_Object_Cache();
142 }
143
144 /**
145  * Replaces the contents of the cache with new data.
146  *
147  * @since 2.0.0
148  * @uses $wp_object_cache Object Cache Class
149  * @see WP_Object_Cache::replace()
150  *
151  * @param int|string $key What to call the contents in the cache
152  * @param mixed $data The contents to store in the cache
153  * @param string $group Where to group the cache contents
154  * @param int $expire When to expire the cache contents
155  * @return bool False if not exists, true if contents were replaced
156  */
157 function wp_cache_replace( $key, $data, $group = '', $expire = 0 ) {
158         global $wp_object_cache;
159
160         return $wp_object_cache->replace( $key, $data, $group, (int) $expire );
161 }
162
163 /**
164  * Saves the data to the cache.
165  *
166  * @since 2.0.0
167  *
168  * @uses $wp_object_cache Object Cache Class
169  * @see WP_Object_Cache::set()
170  *
171  * @param int|string $key What to call the contents in the cache
172  * @param mixed $data The contents to store in the cache
173  * @param string $group Where to group the cache contents
174  * @param int $expire When to expire the cache contents
175  * @return bool False on failure, true on success
176  */
177 function wp_cache_set( $key, $data, $group = '', $expire = 0 ) {
178         global $wp_object_cache;
179
180         return $wp_object_cache->set( $key, $data, $group, (int) $expire );
181 }
182
183 /**
184  * Switch the interal blog id.
185  *
186  * This changes the blog id used to create keys in blog specific groups.
187  *
188  * @since 3.5.0
189  *
190  * @param int $blog_id Blog ID
191  */
192 function wp_cache_switch_to_blog( $blog_id ) {
193         global $wp_object_cache;
194
195         return $wp_object_cache->switch_to_blog( $blog_id );
196 }
197
198 /**
199  * Adds a group or set of groups to the list of global groups.
200  *
201  * @since 2.6.0
202  *
203  * @param string|array $groups A group or an array of groups to add
204  */
205 function wp_cache_add_global_groups( $groups ) {
206         global $wp_object_cache;
207
208         return $wp_object_cache->add_global_groups( $groups );
209 }
210
211 /**
212  * Adds a group or set of groups to the list of non-persistent groups.
213  *
214  * @since 2.6.0
215  *
216  * @param string|array $groups A group or an array of groups to add
217  */
218 function wp_cache_add_non_persistent_groups( $groups ) {
219         // Default cache doesn't persist so nothing to do here.
220         return;
221 }
222
223 /**
224  * Reset internal cache keys and structures. If the cache backend uses global
225  * blog or site IDs as part of its cache keys, this function instructs the
226  * backend to reset those keys and perform any cleanup since blog or site IDs
227  * have changed since cache init.
228  *
229  * This function is deprecated. Use wp_cache_switch_to_blog() instead of this
230  * function when preparing the cache for a blog switch. For clearing the cache
231  * during unit tests, consider using wp_cache_init(). wp_cache_init() is not
232  * recommended outside of unit tests as the performance penality for using it is
233  * high.
234  *
235  * @since 2.6.0
236  * @deprecated 3.5.0
237  */
238 function wp_cache_reset() {
239         _deprecated_function( __FUNCTION__, '3.5' );
240
241         global $wp_object_cache;
242
243         return $wp_object_cache->reset();
244 }
245
246 /**
247  * WordPress Object Cache
248  *
249  * The WordPress Object Cache is used to save on trips to the database. The
250  * Object Cache stores all of the cache data to memory and makes the cache
251  * contents available by using a key, which is used to name and later retrieve
252  * the cache contents.
253  *
254  * The Object Cache can be replaced by other caching mechanisms by placing files
255  * in the wp-content folder which is looked at in wp-settings. If that file
256  * exists, then this file will not be included.
257  *
258  * @package WordPress
259  * @subpackage Cache
260  * @since 2.0.0
261  */
262 class WP_Object_Cache {
263
264         /**
265          * Holds the cached objects
266          *
267          * @var array
268          * @access private
269          * @since 2.0.0
270          */
271         var $cache = array ();
272
273         /**
274          * The amount of times the cache data was already stored in the cache.
275          *
276          * @since 2.5.0
277          * @access private
278          * @var int
279          */
280         var $cache_hits = 0;
281
282         /**
283          * Amount of times the cache did not have the request in cache
284          *
285          * @var int
286          * @access public
287          * @since 2.0.0
288          */
289         var $cache_misses = 0;
290
291         /**
292          * List of global groups
293          *
294          * @var array
295          * @access protected
296          * @since 3.0.0
297          */
298         var $global_groups = array();
299
300         /**
301          * The blog prefix to prepend to keys in non-global groups.
302          *
303          * @var int
304          * @access private
305          * @since 3.5.0
306          */
307         var $blog_prefix;
308
309         /**
310          * Adds data to the cache if it doesn't already exist.
311          *
312          * @uses WP_Object_Cache::_exists Checks to see if the cache already has data.
313          * @uses WP_Object_Cache::set Sets the data after the checking the cache
314          *              contents existence.
315          *
316          * @since 2.0.0
317          *
318          * @param int|string $key What to call the contents in the cache
319          * @param mixed $data The contents to store in the cache
320          * @param string $group Where to group the cache contents
321          * @param int $expire When to expire the cache contents
322          * @return bool False if cache key and group already exist, true on success
323          */
324         function add( $key, $data, $group = 'default', $expire = 0 ) {
325                 if ( wp_suspend_cache_addition() )
326                         return false;
327
328                 if ( empty( $group ) )
329                         $group = 'default';
330
331                 $id = $key;
332                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
333                         $id = $this->blog_prefix . $key;
334
335                 if ( $this->_exists( $id, $group ) )
336                         return false;
337
338                 return $this->set( $key, $data, $group, (int) $expire );
339         }
340
341         /**
342          * Sets the list of global groups.
343          *
344          * @since 3.0.0
345          *
346          * @param array $groups List of groups that are global.
347          */
348         function add_global_groups( $groups ) {
349                 $groups = (array) $groups;
350
351                 $groups = array_fill_keys( $groups, true );
352                 $this->global_groups = array_merge( $this->global_groups, $groups );
353         }
354
355         /**
356          * Decrement numeric cache item's value
357          *
358          * @since 3.3.0
359          *
360          * @param int|string $key The cache key to increment
361          * @param int $offset The amount by which to decrement the item's value. Default is 1.
362          * @param string $group The group the key is in.
363          * @return false|int False on failure, the item's new value on success.
364          */
365         function decr( $key, $offset = 1, $group = 'default' ) {
366                 if ( empty( $group ) )
367                         $group = 'default';
368
369                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
370                         $key = $this->blog_prefix . $key;
371
372                 if ( ! $this->_exists( $key, $group ) )
373                         return false;
374
375                 if ( ! is_numeric( $this->cache[ $group ][ $key ] ) )
376                         $this->cache[ $group ][ $key ] = 0;
377
378                 $offset = (int) $offset;
379
380                 $this->cache[ $group ][ $key ] -= $offset;
381
382                 if ( $this->cache[ $group ][ $key ] < 0 )
383                         $this->cache[ $group ][ $key ] = 0;
384
385                 return $this->cache[ $group ][ $key ];
386         }
387
388         /**
389          * Remove the contents of the cache key in the group
390          *
391          * If the cache key does not exist in the group, then nothing will happen.
392          *
393          * @since 2.0.0
394          *
395          * @param int|string $key What the contents in the cache are called
396          * @param string $group Where the cache contents are grouped
397          * @param bool $deprecated Deprecated.
398          *
399          * @return bool False if the contents weren't deleted and true on success
400          */
401         function delete( $key, $group = 'default', $deprecated = false ) {
402                 if ( empty( $group ) )
403                         $group = 'default';
404
405                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
406                         $key = $this->blog_prefix . $key;
407
408                 if ( ! $this->_exists( $key, $group ) )
409                         return false;
410
411                 unset( $this->cache[$group][$key] );
412                 return true;
413         }
414
415         /**
416          * Clears the object cache of all data
417          *
418          * @since 2.0.0
419          *
420          * @return bool Always returns true
421          */
422         function flush() {
423                 $this->cache = array ();
424
425                 return true;
426         }
427
428         /**
429          * Retrieves the cache contents, if it exists
430          *
431          * The contents will be first attempted to be retrieved by searching by the
432          * key in the cache group. If the cache is hit (success) then the contents
433          * are returned.
434          *
435          * On failure, the number of cache misses will be incremented.
436          *
437          * @since 2.0.0
438          *
439          * @param int|string $key What the contents in the cache are called
440          * @param string $group Where the cache contents are grouped
441          * @param string $force Whether to force a refetch rather than relying on the local cache (default is false)
442          * @return bool|mixed False on failure to retrieve contents or the cache
443          *              contents on success
444          */
445         function get( $key, $group = 'default', $force = false, &$found = null ) {
446                 if ( empty( $group ) )
447                         $group = 'default';
448
449                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
450                         $key = $this->blog_prefix . $key;
451
452                 if ( $this->_exists( $key, $group ) ) {
453                         $found = true;
454                         $this->cache_hits += 1;
455                         if ( is_object($this->cache[$group][$key]) )
456                                 return clone $this->cache[$group][$key];
457                         else
458                                 return $this->cache[$group][$key];
459                 }
460
461                 $found = false;
462                 $this->cache_misses += 1;
463                 return false;
464         }
465
466         /**
467          * Increment numeric cache item's value
468          *
469          * @since 3.3.0
470          *
471          * @param int|string $key The cache key to increment
472          * @param int $offset The amount by which to increment the item's value. Default is 1.
473          * @param string $group The group the key is in.
474          * @return false|int False on failure, the item's new value on success.
475          */
476         function incr( $key, $offset = 1, $group = 'default' ) {
477                 if ( empty( $group ) )
478                         $group = 'default';
479
480                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
481                         $key = $this->blog_prefix . $key;
482
483                 if ( ! $this->_exists( $key, $group ) )
484                         return false;
485
486                 if ( ! is_numeric( $this->cache[ $group ][ $key ] ) )
487                         $this->cache[ $group ][ $key ] = 0;
488
489                 $offset = (int) $offset;
490
491                 $this->cache[ $group ][ $key ] += $offset;
492
493                 if ( $this->cache[ $group ][ $key ] < 0 )
494                         $this->cache[ $group ][ $key ] = 0;
495
496                 return $this->cache[ $group ][ $key ];
497         }
498
499         /**
500          * Replace the contents in the cache, if contents already exist
501          *
502          * @since 2.0.0
503          * @see WP_Object_Cache::set()
504          *
505          * @param int|string $key What to call the contents in the cache
506          * @param mixed $data The contents to store in the cache
507          * @param string $group Where to group the cache contents
508          * @param int $expire When to expire the cache contents
509          * @return bool False if not exists, true if contents were replaced
510          */
511         function replace( $key, $data, $group = 'default', $expire = 0 ) {
512                 if ( empty( $group ) )
513                         $group = 'default';
514
515                 $id = $key;
516                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
517                         $id = $this->blog_prefix . $key;
518
519                 if ( ! $this->_exists( $id, $group ) )
520                         return false;
521
522                 return $this->set( $key, $data, $group, (int) $expire );
523         }
524
525         /**
526          * Reset keys
527          *
528          * @since 3.0.0
529          * @deprecated 3.5.0
530          */
531         function reset() {
532                 _deprecated_function( __FUNCTION__, '3.5', 'switch_to_blog()' );
533
534                 // Clear out non-global caches since the blog ID has changed.
535                 foreach ( array_keys( $this->cache ) as $group ) {
536                         if ( ! isset( $this->global_groups[ $group ] ) )
537                                 unset( $this->cache[ $group ] );
538                 }
539         }
540
541         /**
542          * Sets the data contents into the cache
543          *
544          * The cache contents is grouped by the $group parameter followed by the
545          * $key. This allows for duplicate ids in unique groups. Therefore, naming of
546          * the group should be used with care and should follow normal function
547          * naming guidelines outside of core WordPress usage.
548          *
549          * The $expire parameter is not used, because the cache will automatically
550          * expire for each time a page is accessed and PHP finishes. The method is
551          * more for cache plugins which use files.
552          *
553          * @since 2.0.0
554          *
555          * @param int|string $key What to call the contents in the cache
556          * @param mixed $data The contents to store in the cache
557          * @param string $group Where to group the cache contents
558          * @param int $expire Not Used
559          * @return bool Always returns true
560          */
561         function set( $key, $data, $group = 'default', $expire = 0 ) {
562                 if ( empty( $group ) )
563                         $group = 'default';
564
565                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
566                         $key = $this->blog_prefix . $key;
567
568                 if ( is_object( $data ) )
569                         $data = clone $data;
570
571                 $this->cache[$group][$key] = $data;
572                 return true;
573         }
574
575         /**
576          * Echoes the stats of the caching.
577          *
578          * Gives the cache hits, and cache misses. Also prints every cached group,
579          * key and the data.
580          *
581          * @since 2.0.0
582          */
583         function stats() {
584                 echo "<p>";
585                 echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />";
586                 echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />";
587                 echo "</p>";
588                 echo '<ul>';
589                 foreach ($this->cache as $group => $cache) {
590                         echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / 1024, 2 ) . 'k )</li>';
591                 }
592                 echo '</ul>';
593         }
594
595         /**
596          * Switch the interal blog id.
597          *
598          * This changes the blog id used to create keys in blog specific groups.
599          *
600          * @since 3.5.0
601          *
602          * @param int $blog_id Blog ID
603          */
604         function switch_to_blog( $blog_id ) {
605                 $blog_id = (int) $blog_id;
606                 $this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
607         }
608
609         /**
610          * Utility function to determine whether a key exists in the cache.
611          *
612          * @since 3.4.0
613          *
614          * @access protected
615          */
616         protected function _exists( $key, $group ) {
617                 return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) );
618         }
619
620         /**
621          * Sets up object properties; PHP 5 style constructor
622          *
623          * @since 2.0.8
624          * @return null|WP_Object_Cache If cache is disabled, returns null.
625          */
626         function __construct() {
627                 global $blog_id;
628
629                 $this->multisite = is_multisite();
630                 $this->blog_prefix =  $this->multisite ? $blog_id . ':' : '';
631
632
633                 /**
634                  * @todo This should be moved to the PHP4 style constructor, PHP5
635                  * already calls __destruct()
636                  */
637                 register_shutdown_function( array( $this, '__destruct' ) );
638         }
639
640         /**
641          * Will save the object cache before object is completely destroyed.
642          *
643          * Called upon object destruction, which should be when PHP ends.
644          *
645          * @since  2.0.8
646          *
647          * @return bool True value. Won't be used by PHP
648          */
649         function __destruct() {
650                 return true;
651         }
652 }