Make WordPress Core

Ticket #49373: 49373.diff

File 49373.diff, 26.5 KB (added by xkon, 5 years ago)
  • src/wp-includes/cache.php

    diff --git a/src/wp-includes/cache.php b/src/wp-includes/cache.php
    index ea14e78b4d..95dabb27f0 100644
    a b  
    88 * @subpackage Cache
    99 */
    1010
     11/**
     12 * Require WP_Object_Cache that has been moved to it's own file on 5.4.0 for backward compatibility.
     13 */
     14require_once( ABSPATH . WPINC . '/class-wp-object-cache.php' );
     15
    1116/**
    1217 * Adds data to the cache, if the cache key doesn't already exist.
    1318 *
    function wp_cache_reset() { 
    270275
    271276        $wp_object_cache->reset();
    272277}
    273 
    274 /**
    275  * Core class that implements an object cache.
    276  *
    277  * The WordPress Object Cache is used to save on trips to the database. The
    278  * Object Cache stores all of the cache data to memory and makes the cache
    279  * contents available by using a key, which is used to name and later retrieve
    280  * the cache contents.
    281  *
    282  * The Object Cache can be replaced by other caching mechanisms by placing files
    283  * in the wp-content folder which is looked at in wp-settings. If that file
    284  * exists, then this file will not be included.
    285  *
    286  * @since 2.0.0
    287  */
    288 class WP_Object_Cache {
    289 
    290         /**
    291          * Holds the cached objects.
    292          *
    293          * @since 2.0.0
    294          * @var array
    295          */
    296         private $cache = array();
    297 
    298         /**
    299          * The amount of times the cache data was already stored in the cache.
    300          *
    301          * @since 2.5.0
    302          * @var int
    303          */
    304         public $cache_hits = 0;
    305 
    306         /**
    307          * Amount of times the cache did not have the request in cache.
    308          *
    309          * @since 2.0.0
    310          * @var int
    311          */
    312         public $cache_misses = 0;
    313 
    314         /**
    315          * List of global cache groups.
    316          *
    317          * @since 3.0.0
    318          * @var array
    319          */
    320         protected $global_groups = array();
    321 
    322         /**
    323          * The blog prefix to prepend to keys in non-global groups.
    324          *
    325          * @since 3.5.0
    326          * @var string
    327          */
    328         private $blog_prefix;
    329 
    330         /**
    331          * Holds the value of is_multisite().
    332          *
    333          * @since 3.5.0
    334          * @var bool
    335          */
    336         private $multisite;
    337 
    338         /**
    339          * Sets up object properties; PHP 5 style constructor.
    340          *
    341          * @since 2.0.8
    342          */
    343         public function __construct() {
    344                 $this->multisite   = is_multisite();
    345                 $this->blog_prefix = $this->multisite ? get_current_blog_id() . ':' : '';
    346         }
    347 
    348         /**
    349          * Makes private properties readable for backward compatibility.
    350          *
    351          * @since 4.0.0
    352          *
    353          * @param string $name Property to get.
    354          * @return mixed Property.
    355          */
    356         public function __get( $name ) {
    357                 return $this->$name;
    358         }
    359 
    360         /**
    361          * Makes private properties settable for backward compatibility.
    362          *
    363          * @since 4.0.0
    364          *
    365          * @param string $name  Property to set.
    366          * @param mixed  $value Property value.
    367          * @return mixed Newly-set property.
    368          */
    369         public function __set( $name, $value ) {
    370                 return $this->$name = $value;
    371         }
    372 
    373         /**
    374          * Makes private properties checkable for backward compatibility.
    375          *
    376          * @since 4.0.0
    377          *
    378          * @param string $name Property to check if set.
    379          * @return bool Whether the property is set.
    380          */
    381         public function __isset( $name ) {
    382                 return isset( $this->$name );
    383         }
    384 
    385         /**
    386          * Makes private properties un-settable for backward compatibility.
    387          *
    388          * @since 4.0.0
    389          *
    390          * @param string $name Property to unset.
    391          */
    392         public function __unset( $name ) {
    393                 unset( $this->$name );
    394         }
    395 
    396         /**
    397          * Adds data to the cache if it doesn't already exist.
    398          *
    399          * @since 2.0.0
    400          *
    401          * @uses WP_Object_Cache::_exists() Checks to see if the cache already has data.
    402          * @uses WP_Object_Cache::set()     Sets the data after the checking the cache
    403          *                                  contents existence.
    404          *
    405          * @param int|string $key    What to call the contents in the cache.
    406          * @param mixed      $data   The contents to store in the cache.
    407          * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
    408          * @param int        $expire Optional. When to expire the cache contents. Default 0 (no expiration).
    409          * @return bool True on success, false if cache key and group already exist.
    410          */
    411         public function add( $key, $data, $group = 'default', $expire = 0 ) {
    412                 if ( wp_suspend_cache_addition() ) {
    413                         return false;
    414                 }
    415 
    416                 if ( empty( $group ) ) {
    417                         $group = 'default';
    418                 }
    419 
    420                 $id = $key;
    421                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    422                         $id = $this->blog_prefix . $key;
    423                 }
    424 
    425                 if ( $this->_exists( $id, $group ) ) {
    426                         return false;
    427                 }
    428 
    429                 return $this->set( $key, $data, $group, (int) $expire );
    430         }
    431 
    432         /**
    433          * Sets the list of global cache groups.
    434          *
    435          * @since 3.0.0
    436          *
    437          * @param array $groups List of groups that are global.
    438          */
    439         public function add_global_groups( $groups ) {
    440                 $groups = (array) $groups;
    441 
    442                 $groups              = array_fill_keys( $groups, true );
    443                 $this->global_groups = array_merge( $this->global_groups, $groups );
    444         }
    445 
    446         /**
    447          * Decrements numeric cache item's value.
    448          *
    449          * @since 3.3.0
    450          *
    451          * @param int|string $key    The cache key to decrement.
    452          * @param int        $offset Optional. The amount by which to decrement the item's value. Default 1.
    453          * @param string     $group  Optional. The group the key is in. Default 'default'.
    454          * @return int|false The item's new value on success, false on failure.
    455          */
    456         public function decr( $key, $offset = 1, $group = 'default' ) {
    457                 if ( empty( $group ) ) {
    458                         $group = 'default';
    459                 }
    460 
    461                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    462                         $key = $this->blog_prefix . $key;
    463                 }
    464 
    465                 if ( ! $this->_exists( $key, $group ) ) {
    466                         return false;
    467                 }
    468 
    469                 if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
    470                         $this->cache[ $group ][ $key ] = 0;
    471                 }
    472 
    473                 $offset = (int) $offset;
    474 
    475                 $this->cache[ $group ][ $key ] -= $offset;
    476 
    477                 if ( $this->cache[ $group ][ $key ] < 0 ) {
    478                         $this->cache[ $group ][ $key ] = 0;
    479                 }
    480 
    481                 return $this->cache[ $group ][ $key ];
    482         }
    483 
    484         /**
    485          * Removes the contents of the cache key in the group.
    486          *
    487          * If the cache key does not exist in the group, then nothing will happen.
    488          *
    489          * @since 2.0.0
    490          *
    491          * @param int|string $key        What the contents in the cache are called.
    492          * @param string     $group      Optional. Where the cache contents are grouped. Default 'default'.
    493          * @param bool       $deprecated Optional. Unused. Default false.
    494          * @return bool False if the contents weren't deleted and true on success.
    495          */
    496         public function delete( $key, $group = 'default', $deprecated = false ) {
    497                 if ( empty( $group ) ) {
    498                         $group = 'default';
    499                 }
    500 
    501                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    502                         $key = $this->blog_prefix . $key;
    503                 }
    504 
    505                 if ( ! $this->_exists( $key, $group ) ) {
    506                         return false;
    507                 }
    508 
    509                 unset( $this->cache[ $group ][ $key ] );
    510                 return true;
    511         }
    512 
    513         /**
    514          * Clears the object cache of all data.
    515          *
    516          * @since 2.0.0
    517          *
    518          * @return true Always returns true.
    519          */
    520         public function flush() {
    521                 $this->cache = array();
    522 
    523                 return true;
    524         }
    525 
    526         /**
    527          * Retrieves the cache contents, if it exists.
    528          *
    529          * The contents will be first attempted to be retrieved by searching by the
    530          * key in the cache group. If the cache is hit (success) then the contents
    531          * are returned.
    532          *
    533          * On failure, the number of cache misses will be incremented.
    534          *
    535          * @since 2.0.0
    536          *
    537          * @param int|string $key    What the contents in the cache are called.
    538          * @param string     $group  Optional. Where the cache contents are grouped. Default 'default'.
    539          * @param bool       $force  Optional. Unused. Whether to force a refetch rather than relying on the local
    540          *                           cache. Default false.
    541          * @param bool       $found  Optional. Whether the key was found in the cache (passed by reference).
    542          *                           Disambiguates a return of false, a storable value. Default null.
    543          * @return mixed|false The cache contents on success, false on failure to retrieve contents.
    544          */
    545         public function get( $key, $group = 'default', $force = false, &$found = null ) {
    546                 if ( empty( $group ) ) {
    547                         $group = 'default';
    548                 }
    549 
    550                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    551                         $key = $this->blog_prefix . $key;
    552                 }
    553 
    554                 if ( $this->_exists( $key, $group ) ) {
    555                         $found             = true;
    556                         $this->cache_hits += 1;
    557                         if ( is_object( $this->cache[ $group ][ $key ] ) ) {
    558                                 return clone $this->cache[ $group ][ $key ];
    559                         } else {
    560                                 return $this->cache[ $group ][ $key ];
    561                         }
    562                 }
    563 
    564                 $found               = false;
    565                 $this->cache_misses += 1;
    566                 return false;
    567         }
    568 
    569         /**
    570          * Increments numeric cache item's value.
    571          *
    572          * @since 3.3.0
    573          *
    574          * @param int|string $key    The cache key to increment
    575          * @param int        $offset Optional. The amount by which to increment the item's value. Default 1.
    576          * @param string     $group  Optional. The group the key is in. Default 'default'.
    577          * @return int|false The item's new value on success, false on failure.
    578          */
    579         public function incr( $key, $offset = 1, $group = 'default' ) {
    580                 if ( empty( $group ) ) {
    581                         $group = 'default';
    582                 }
    583 
    584                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    585                         $key = $this->blog_prefix . $key;
    586                 }
    587 
    588                 if ( ! $this->_exists( $key, $group ) ) {
    589                         return false;
    590                 }
    591 
    592                 if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
    593                         $this->cache[ $group ][ $key ] = 0;
    594                 }
    595 
    596                 $offset = (int) $offset;
    597 
    598                 $this->cache[ $group ][ $key ] += $offset;
    599 
    600                 if ( $this->cache[ $group ][ $key ] < 0 ) {
    601                         $this->cache[ $group ][ $key ] = 0;
    602                 }
    603 
    604                 return $this->cache[ $group ][ $key ];
    605         }
    606 
    607         /**
    608          * Replaces the contents in the cache, if contents already exist.
    609          *
    610          * @since 2.0.0
    611          *
    612          * @see WP_Object_Cache::set()
    613          *
    614          * @param int|string $key    What to call the contents in the cache.
    615          * @param mixed      $data   The contents to store in the cache.
    616          * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
    617          * @param int        $expire Optional. When to expire the cache contents. Default 0 (no expiration).
    618          * @return bool False if not exists, true if contents were replaced.
    619          */
    620         public function replace( $key, $data, $group = 'default', $expire = 0 ) {
    621                 if ( empty( $group ) ) {
    622                         $group = 'default';
    623                 }
    624 
    625                 $id = $key;
    626                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    627                         $id = $this->blog_prefix . $key;
    628                 }
    629 
    630                 if ( ! $this->_exists( $id, $group ) ) {
    631                         return false;
    632                 }
    633 
    634                 return $this->set( $key, $data, $group, (int) $expire );
    635         }
    636 
    637         /**
    638          * Resets cache keys.
    639          *
    640          * @since 3.0.0
    641          *
    642          * @deprecated 3.5.0 Use switch_to_blog()
    643          * @see switch_to_blog()
    644          */
    645         public function reset() {
    646                 _deprecated_function( __FUNCTION__, '3.5.0', 'switch_to_blog()' );
    647 
    648                 // Clear out non-global caches since the blog ID has changed.
    649                 foreach ( array_keys( $this->cache ) as $group ) {
    650                         if ( ! isset( $this->global_groups[ $group ] ) ) {
    651                                 unset( $this->cache[ $group ] );
    652                         }
    653                 }
    654         }
    655 
    656         /**
    657          * Sets the data contents into the cache.
    658          *
    659          * The cache contents are grouped by the $group parameter followed by the
    660          * $key. This allows for duplicate ids in unique groups. Therefore, naming of
    661          * the group should be used with care and should follow normal function
    662          * naming guidelines outside of core WordPress usage.
    663          *
    664          * The $expire parameter is not used, because the cache will automatically
    665          * expire for each time a page is accessed and PHP finishes. The method is
    666          * more for cache plugins which use files.
    667          *
    668          * @since 2.0.0
    669          *
    670          * @param int|string $key    What to call the contents in the cache.
    671          * @param mixed      $data   The contents to store in the cache.
    672          * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
    673          * @param int        $expire Not Used.
    674          * @return true Always returns true.
    675          */
    676         public function set( $key, $data, $group = 'default', $expire = 0 ) {
    677                 if ( empty( $group ) ) {
    678                         $group = 'default';
    679                 }
    680 
    681                 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
    682                         $key = $this->blog_prefix . $key;
    683                 }
    684 
    685                 if ( is_object( $data ) ) {
    686                         $data = clone $data;
    687                 }
    688 
    689                 $this->cache[ $group ][ $key ] = $data;
    690                 return true;
    691         }
    692 
    693         /**
    694          * Echoes the stats of the caching.
    695          *
    696          * Gives the cache hits, and cache misses. Also prints every cached group,
    697          * key and the data.
    698          *
    699          * @since 2.0.0
    700          */
    701         public function stats() {
    702                 echo '<p>';
    703                 echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />";
    704                 echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />";
    705                 echo '</p>';
    706                 echo '<ul>';
    707                 foreach ( $this->cache as $group => $cache ) {
    708                         echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>';
    709                 }
    710                 echo '</ul>';
    711         }
    712 
    713         /**
    714          * Switches the internal blog ID.
    715          *
    716          * This changes the blog ID used to create keys in blog specific groups.
    717          *
    718          * @since 3.5.0
    719          *
    720          * @param int $blog_id Blog ID.
    721          */
    722         public function switch_to_blog( $blog_id ) {
    723                 $blog_id           = (int) $blog_id;
    724                 $this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
    725         }
    726 
    727         /**
    728          * Serves as a utility function to determine whether a key exists in the cache.
    729          *
    730          * @since 3.4.0
    731          *
    732          * @param int|string $key   Cache key to check for existence.
    733          * @param string     $group Cache group for the key existence check.
    734          * @return bool Whether the key exists in the cache for the given group.
    735          */
    736         protected function _exists( $key, $group ) {
    737                 return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) );
    738         }
    739 }
  • new file src/wp-includes/class-wp-object-cache.php

    diff --git a/src/wp-includes/class-wp-object-cache.php b/src/wp-includes/class-wp-object-cache.php
    new file mode 100644
    index 0000000000..99d05039a3
    - +  
     1<?php
     2
     3/**
     4 * Core class that implements an object cache.
     5 *
     6 * The WordPress Object Cache is used to save on trips to the database. The
     7 * Object Cache stores all of the cache data to memory and makes the cache
     8 * contents available by using a key, which is used to name and later retrieve
     9 * the cache contents.
     10 *
     11 * The Object Cache can be replaced by other caching mechanisms by placing files
     12 * in the wp-content folder which is looked at in wp-settings. If that file
     13 * exists, then this file will not be included.
     14 *
     15 * @since 2.0.0
     16 */
     17class WP_Object_Cache {
     18
     19        /**
     20         * Holds the cached objects.
     21         *
     22         * @since 2.0.0
     23         * @var array
     24         */
     25        private $cache = array();
     26
     27        /**
     28         * The amount of times the cache data was already stored in the cache.
     29         *
     30         * @since 2.5.0
     31         * @var int
     32         */
     33        public $cache_hits = 0;
     34
     35        /**
     36         * Amount of times the cache did not have the request in cache.
     37         *
     38         * @since 2.0.0
     39         * @var int
     40         */
     41        public $cache_misses = 0;
     42
     43        /**
     44         * List of global cache groups.
     45         *
     46         * @since 3.0.0
     47         * @var array
     48         */
     49        protected $global_groups = array();
     50
     51        /**
     52         * The blog prefix to prepend to keys in non-global groups.
     53         *
     54         * @since 3.5.0
     55         * @var string
     56         */
     57        private $blog_prefix;
     58
     59        /**
     60         * Holds the value of is_multisite().
     61         *
     62         * @since 3.5.0
     63         * @var bool
     64         */
     65        private $multisite;
     66
     67        /**
     68         * Sets up object properties; PHP 5 style constructor.
     69         *
     70         * @since 2.0.8
     71         */
     72        public function __construct() {
     73                $this->multisite   = is_multisite();
     74                $this->blog_prefix = $this->multisite ? get_current_blog_id() . ':' : '';
     75        }
     76
     77        /**
     78         * Makes private properties readable for backward compatibility.
     79         *
     80         * @since 4.0.0
     81         *
     82         * @param string $name Property to get.
     83         * @return mixed Property.
     84         */
     85        public function __get( $name ) {
     86                return $this->$name;
     87        }
     88
     89        /**
     90         * Makes private properties settable for backward compatibility.
     91         *
     92         * @since 4.0.0
     93         *
     94         * @param string $name  Property to set.
     95         * @param mixed  $value Property value.
     96         * @return mixed Newly-set property.
     97         */
     98        public function __set( $name, $value ) {
     99                return $this->$name = $value;
     100        }
     101
     102        /**
     103         * Makes private properties checkable for backward compatibility.
     104         *
     105         * @since 4.0.0
     106         *
     107         * @param string $name Property to check if set.
     108         * @return bool Whether the property is set.
     109         */
     110        public function __isset( $name ) {
     111                return isset( $this->$name );
     112        }
     113
     114        /**
     115         * Makes private properties un-settable for backward compatibility.
     116         *
     117         * @since 4.0.0
     118         *
     119         * @param string $name Property to unset.
     120         */
     121        public function __unset( $name ) {
     122                unset( $this->$name );
     123        }
     124
     125        /**
     126         * Adds data to the cache if it doesn't already exist.
     127         *
     128         * @since 2.0.0
     129         *
     130         * @uses WP_Object_Cache::_exists() Checks to see if the cache already has data.
     131         * @uses WP_Object_Cache::set()     Sets the data after the checking the cache
     132         *                                  contents existence.
     133         *
     134         * @param int|string $key    What to call the contents in the cache.
     135         * @param mixed      $data   The contents to store in the cache.
     136         * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
     137         * @param int        $expire Optional. When to expire the cache contents. Default 0 (no expiration).
     138         * @return bool True on success, false if cache key and group already exist.
     139         */
     140        public function add( $key, $data, $group = 'default', $expire = 0 ) {
     141                if ( wp_suspend_cache_addition() ) {
     142                        return false;
     143                }
     144
     145                if ( empty( $group ) ) {
     146                        $group = 'default';
     147                }
     148
     149                $id = $key;
     150                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     151                        $id = $this->blog_prefix . $key;
     152                }
     153
     154                if ( $this->_exists( $id, $group ) ) {
     155                        return false;
     156                }
     157
     158                return $this->set( $key, $data, $group, (int) $expire );
     159        }
     160
     161        /**
     162         * Sets the list of global cache groups.
     163         *
     164         * @since 3.0.0
     165         *
     166         * @param array $groups List of groups that are global.
     167         */
     168        public function add_global_groups( $groups ) {
     169                $groups = (array) $groups;
     170
     171                $groups              = array_fill_keys( $groups, true );
     172                $this->global_groups = array_merge( $this->global_groups, $groups );
     173        }
     174
     175        /**
     176         * Decrements numeric cache item's value.
     177         *
     178         * @since 3.3.0
     179         *
     180         * @param int|string $key    The cache key to decrement.
     181         * @param int        $offset Optional. The amount by which to decrement the item's value. Default 1.
     182         * @param string     $group  Optional. The group the key is in. Default 'default'.
     183         * @return int|false The item's new value on success, false on failure.
     184         */
     185        public function decr( $key, $offset = 1, $group = 'default' ) {
     186                if ( empty( $group ) ) {
     187                        $group = 'default';
     188                }
     189
     190                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     191                        $key = $this->blog_prefix . $key;
     192                }
     193
     194                if ( ! $this->_exists( $key, $group ) ) {
     195                        return false;
     196                }
     197
     198                if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
     199                        $this->cache[ $group ][ $key ] = 0;
     200                }
     201
     202                $offset = (int) $offset;
     203
     204                $this->cache[ $group ][ $key ] -= $offset;
     205
     206                if ( $this->cache[ $group ][ $key ] < 0 ) {
     207                        $this->cache[ $group ][ $key ] = 0;
     208                }
     209
     210                return $this->cache[ $group ][ $key ];
     211        }
     212
     213        /**
     214         * Removes the contents of the cache key in the group.
     215         *
     216         * If the cache key does not exist in the group, then nothing will happen.
     217         *
     218         * @since 2.0.0
     219         *
     220         * @param int|string $key        What the contents in the cache are called.
     221         * @param string     $group      Optional. Where the cache contents are grouped. Default 'default'.
     222         * @param bool       $deprecated Optional. Unused. Default false.
     223         * @return bool False if the contents weren't deleted and true on success.
     224         */
     225        public function delete( $key, $group = 'default', $deprecated = false ) {
     226                if ( empty( $group ) ) {
     227                        $group = 'default';
     228                }
     229
     230                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     231                        $key = $this->blog_prefix . $key;
     232                }
     233
     234                if ( ! $this->_exists( $key, $group ) ) {
     235                        return false;
     236                }
     237
     238                unset( $this->cache[ $group ][ $key ] );
     239                return true;
     240        }
     241
     242        /**
     243         * Clears the object cache of all data.
     244         *
     245         * @since 2.0.0
     246         *
     247         * @return true Always returns true.
     248         */
     249        public function flush() {
     250                $this->cache = array();
     251
     252                return true;
     253        }
     254
     255        /**
     256         * Retrieves the cache contents, if it exists.
     257         *
     258         * The contents will be first attempted to be retrieved by searching by the
     259         * key in the cache group. If the cache is hit (success) then the contents
     260         * are returned.
     261         *
     262         * On failure, the number of cache misses will be incremented.
     263         *
     264         * @since 2.0.0
     265         *
     266         * @param int|string $key    What the contents in the cache are called.
     267         * @param string     $group  Optional. Where the cache contents are grouped. Default 'default'.
     268         * @param bool       $force  Optional. Unused. Whether to force a refetch rather than relying on the local
     269         *                           cache. Default false.
     270         * @param bool       $found  Optional. Whether the key was found in the cache (passed by reference).
     271         *                           Disambiguates a return of false, a storable value. Default null.
     272         * @return mixed|false The cache contents on success, false on failure to retrieve contents.
     273         */
     274        public function get( $key, $group = 'default', $force = false, &$found = null ) {
     275                if ( empty( $group ) ) {
     276                        $group = 'default';
     277                }
     278
     279                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     280                        $key = $this->blog_prefix . $key;
     281                }
     282
     283                if ( $this->_exists( $key, $group ) ) {
     284                        $found             = true;
     285                        $this->cache_hits += 1;
     286                        if ( is_object( $this->cache[ $group ][ $key ] ) ) {
     287                                return clone $this->cache[ $group ][ $key ];
     288                        } else {
     289                                return $this->cache[ $group ][ $key ];
     290                        }
     291                }
     292
     293                $found               = false;
     294                $this->cache_misses += 1;
     295                return false;
     296        }
     297
     298        /**
     299         * Increments numeric cache item's value.
     300         *
     301         * @since 3.3.0
     302         *
     303         * @param int|string $key    The cache key to increment
     304         * @param int        $offset Optional. The amount by which to increment the item's value. Default 1.
     305         * @param string     $group  Optional. The group the key is in. Default 'default'.
     306         * @return int|false The item's new value on success, false on failure.
     307         */
     308        public function incr( $key, $offset = 1, $group = 'default' ) {
     309                if ( empty( $group ) ) {
     310                        $group = 'default';
     311                }
     312
     313                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     314                        $key = $this->blog_prefix . $key;
     315                }
     316
     317                if ( ! $this->_exists( $key, $group ) ) {
     318                        return false;
     319                }
     320
     321                if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
     322                        $this->cache[ $group ][ $key ] = 0;
     323                }
     324
     325                $offset = (int) $offset;
     326
     327                $this->cache[ $group ][ $key ] += $offset;
     328
     329                if ( $this->cache[ $group ][ $key ] < 0 ) {
     330                        $this->cache[ $group ][ $key ] = 0;
     331                }
     332
     333                return $this->cache[ $group ][ $key ];
     334        }
     335
     336        /**
     337         * Replaces the contents in the cache, if contents already exist.
     338         *
     339         * @since 2.0.0
     340         *
     341         * @see WP_Object_Cache::set()
     342         *
     343         * @param int|string $key    What to call the contents in the cache.
     344         * @param mixed      $data   The contents to store in the cache.
     345         * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
     346         * @param int        $expire Optional. When to expire the cache contents. Default 0 (no expiration).
     347         * @return bool False if not exists, true if contents were replaced.
     348         */
     349        public function replace( $key, $data, $group = 'default', $expire = 0 ) {
     350                if ( empty( $group ) ) {
     351                        $group = 'default';
     352                }
     353
     354                $id = $key;
     355                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     356                        $id = $this->blog_prefix . $key;
     357                }
     358
     359                if ( ! $this->_exists( $id, $group ) ) {
     360                        return false;
     361                }
     362
     363                return $this->set( $key, $data, $group, (int) $expire );
     364        }
     365
     366        /**
     367         * Resets cache keys.
     368         *
     369         * @since 3.0.0
     370         *
     371         * @deprecated 3.5.0 Use switch_to_blog()
     372         * @see switch_to_blog()
     373         */
     374        public function reset() {
     375                _deprecated_function( __FUNCTION__, '3.5.0', 'switch_to_blog()' );
     376
     377                // Clear out non-global caches since the blog ID has changed.
     378                foreach ( array_keys( $this->cache ) as $group ) {
     379                        if ( ! isset( $this->global_groups[ $group ] ) ) {
     380                                unset( $this->cache[ $group ] );
     381                        }
     382                }
     383        }
     384
     385        /**
     386         * Sets the data contents into the cache.
     387         *
     388         * The cache contents are grouped by the $group parameter followed by the
     389         * $key. This allows for duplicate ids in unique groups. Therefore, naming of
     390         * the group should be used with care and should follow normal function
     391         * naming guidelines outside of core WordPress usage.
     392         *
     393         * The $expire parameter is not used, because the cache will automatically
     394         * expire for each time a page is accessed and PHP finishes. The method is
     395         * more for cache plugins which use files.
     396         *
     397         * @since 2.0.0
     398         *
     399         * @param int|string $key    What to call the contents in the cache.
     400         * @param mixed      $data   The contents to store in the cache.
     401         * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
     402         * @param int        $expire Not Used.
     403         * @return true Always returns true.
     404         */
     405        public function set( $key, $data, $group = 'default', $expire = 0 ) {
     406                if ( empty( $group ) ) {
     407                        $group = 'default';
     408                }
     409
     410                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
     411                        $key = $this->blog_prefix . $key;
     412                }
     413
     414                if ( is_object( $data ) ) {
     415                        $data = clone $data;
     416                }
     417
     418                $this->cache[ $group ][ $key ] = $data;
     419                return true;
     420        }
     421
     422        /**
     423         * Echoes the stats of the caching.
     424         *
     425         * Gives the cache hits, and cache misses. Also prints every cached group,
     426         * key and the data.
     427         *
     428         * @since 2.0.0
     429         */
     430        public function stats() {
     431                echo '<p>';
     432                echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />";
     433                echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />";
     434                echo '</p>';
     435                echo '<ul>';
     436                foreach ( $this->cache as $group => $cache ) {
     437                        echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>';
     438                }
     439                echo '</ul>';
     440        }
     441
     442        /**
     443         * Switches the internal blog ID.
     444         *
     445         * This changes the blog ID used to create keys in blog specific groups.
     446         *
     447         * @since 3.5.0
     448         *
     449         * @param int $blog_id Blog ID.
     450         */
     451        public function switch_to_blog( $blog_id ) {
     452                $blog_id           = (int) $blog_id;
     453                $this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
     454        }
     455
     456        /**
     457         * Serves as a utility function to determine whether a key exists in the cache.
     458         *
     459         * @since 3.4.0
     460         *
     461         * @param int|string $key   Cache key to check for existence.
     462         * @param string     $group Cache group for the key existence check.
     463         * @return bool Whether the key exists in the cache for the given group.
     464         */
     465        protected function _exists( $key, $group ) {
     466                return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) );
     467        }
     468}