return isset($this->$name);
* Makes private properties un-settable for backward compatibility.
* @param string $name Property to unset.
public function __unset($name)
* Serves as a utility function to determine whether a key is valid.
* @param int|string $key Cache key to check for validity.
* @return bool Whether the key is valid.
protected function is_valid_key($key)
if (is_string($key) && trim($key) !== '') {
if (!function_exists('__')) {
wp_load_translations_early();
$message = is_string($key)
? __('Cache key must not be an empty string.')
: /* translators: %s: The type of the given cache key. */
sprintf(__('Cache key must be integer or non-empty string, %s given.'), $type);
_doing_it_wrong(sprintf('%s::%s', __CLASS__, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function']), $message, '6.1.0');
private function _key($key, $group = 'default')
$prefix = $this->_object_cache->is_global($group) ? '' : $this->blog_prefix;
return LSOC_PREFIX . $prefix . $group . '.' . $key;
$this->count_hit_incall .
$this->count_miss_incall .
* Adds data to the cache if it doesn't already exist.
* @uses WP_Object_Cache::_exists() Checks to see if the cache already has data.
* @uses WP_Object_Cache::set() Sets the data after the checking the cache
* @param int|string $key What to call the contents in the cache.
* @param mixed $data The contents to store in the cache.
* @param string $group Optional. Where to group the cache contents. Default 'default'.
* @param int $expire Optional. When to expire the cache contents, in seconds.
* Default 0 (no expiration).
* @return bool True on success, false if cache key and group already exist.
public function add($key, $data, $group = 'default', $expire = 0)
if (wp_suspend_cache_addition()) {
if (!$this->is_valid_key($key)) {
$id = $this->_key($key, $group);
if (array_key_exists($id, $this->_cache)) {
return $this->set($key, $data, $group, (int) $expire);
* Adds multiple values to the cache in one call.
* @param array $data Array of keys and values to be added.
* @param string $group Optional. Where the cache contents are grouped. Default empty.
* @param int $expire Optional. When to expire the cache contents, in seconds.
* Default 0 (no expiration).
* @return bool[] Array of return values, grouped by key. Each value is either
* true on success, or false if cache key and group already exist.
public function add_multiple(array $data, $group = '', $expire = 0)
foreach ($data as $key => $value) {
$values[$key] = $this->add($key, $value, $group, $expire);
* Replaces the contents in the cache, if contents already exist.
* @see WP_Object_Cache::set()
* @param int|string $key What to call the contents in the cache.
* @param mixed $data The contents to store in the cache.
* @param string $group Optional. Where to group the cache contents. Default 'default'.
* @param int $expire Optional. When to expire the cache contents, in seconds.
* Default 0 (no expiration).
* @return bool True if contents were replaced, false if original value does not exist.
public function replace($key, $data, $group = 'default', $expire = 0)
if (!$this->is_valid_key($key)) {
$id = $this->_key($key, $group);
if (!array_key_exists($id, $this->_cache)) {
return $this->set($key, $data, $group, (int) $expire);
* Sets the data contents into the cache.
* The cache contents are grouped by the $group parameter followed by the
* $key. This allows for duplicate IDs in unique groups. Therefore, naming of
* the group should be used with care and should follow normal function
* naming guidelines outside of core WordPress usage.
* The $expire parameter is not used, because the cache will automatically
* expire for each time a page is accessed and PHP finishes. The method is
* more for cache plugins which use files.
* @since 5.4 Returns false if cache key is invalid.
* @param int|string $key What to call the contents in the cache.
* @param mixed $data The contents to store in the cache.
* @param string $group Optional. Where to group the cache contents. Default 'default'.
* @param int $expire Optional. When to expire the cache contents, in seconds.
* Default 0 (no expiration).
* @return bool True if contents were set, false if key is invalid.
public function set($key, $data, $group = 'default', $expire = 0)
if (!$this->is_valid_key($key)) {
$id = $this->_key($key, $group);
// error_log("oc: set \t\t\t[key] " . $id );
$this->_cache[$id] = $data;
if (array_key_exists($id, $this->_cache_404)) {
// error_log("oc: unset404\t\t\t[key] " . $id );
unset($this->_cache_404[$id]);
if (!$this->_object_cache->is_non_persistent($group)) {
$this->_object_cache->set($id, serialize(array('data' => $data)), (int) $expire);
if ($this->_object_cache->store_transients($group)) {
$this->_transient_set($key, $data, $group, (int) $expire);
* Sets multiple values to the cache in one call.
* @param array $data Array of key and value to be set.
* @param string $group Optional. Where the cache contents are grouped. Default empty.
* @param int $expire Optional. When to expire the cache contents, in seconds.
* Default 0 (no expiration).
* @return bool[] Array of return values, grouped by key. Each value is always true.
public function set_multiple(array $data, $group = '', $expire = 0)
foreach ($data as $key => $value) {
$values[$key] = $this->set($key, $value, $group, $expire);
* Retrieves the cache contents, if it exists.
* The contents will be first attempted to be retrieved by searching by the
* key in the cache group. If the cache is hit (success) then the contents
* On failure, the number of cache misses will be incremented.
* @param int|string $key The key under which the cache contents are stored.
* @param string $group Optional. Where the cache contents are grouped. Default 'default'.
* @param bool $force Optional. Unused. Whether to force an update of the local cache
* from the persistent cache. Default false.
* @param bool $found Optional. Whether the key was found in the cache (passed by reference).
* Disambiguates a return of false, a storable value. Default null.
* @return mixed|false The cache contents on success, false on failure to retrieve contents.
public function get($key, $group = 'default', $force = false, &$found = null)
if (!$this->is_valid_key($key)) {
$id = $this->_key($key, $group);
// error_log("oc: get \t\t\t[key] " . $id . ( $force ? "\t\t\t [forced] " : '' ) );
if (array_key_exists($id, $this->_cache) && !$force) {
$cache_val = $this->_cache[$id];
$this->count_hit_incall++;
} elseif (!array_key_exists($id, $this->_cache_404) && !$this->_object_cache->is_non_persistent($group)) {
$v = $this->_object_cache->get($id);
$v = @maybe_unserialize($v);
// To be compatible with false val
if (is_array($v) && array_key_exists('data', $v)) {
// Can't find key, cache it to 404
// error_log("oc: add404\t\t\t[key] " . $id );
$this->_cache_404[$id] = 1;
$this->count_miss_incall++;
if (is_object($cache_val)) {
$cache_val = clone $cache_val;
// If not found but has `Store Transients` cfg on, still need to follow WP's get_transient() logic
if (!$found && $this->_object_cache->store_transients($group)) {
$cache_val = $this->_transient_get($key, $group);
$found = true; // $found not used for now (v1.8.3)
$this->_cache[$id] = $cache_val;
* Retrieves multiple values from the cache in one call.
* @param array $keys Array of keys under which the cache contents are stored.
* @param string $group Optional. Where the cache contents are grouped. Default 'default'.
* @param bool $force Optional. Whether to force an update of the local cache
* from the persistent cache. Default false.
* @return array Array of return values, grouped by key. Each value is either
* the cache contents on success, or false on failure.
public function get_multiple($keys, $group = 'default', $force = false)
foreach ($keys as $key) {
$values[$key] = $this->get($key, $group, $force);
* Removes the contents of the cache key in the group.
* If the cache key does not exist in the group, then nothing will happen.
* @param int|string $key What the contents in the cache are called.
* @param string $group Optional. Where the cache contents are grouped. Default 'default'.
* @param bool $deprecated Optional. Unused. Default false.
* @return bool True on success, false if the contents were not deleted.
public function delete($key, $group = 'default', $deprecated = false)
if (!$this->is_valid_key($key)) {
$id = $this->_key($key, $group);
if ($this->_object_cache->store_transients($group)) {
$this->_transient_del($key, $group);
if (array_key_exists($id, $this->_cache)) {
unset($this->_cache[$id]);
// error_log("oc: delete \t\t\t[key] " . $id );
if ($this->_object_cache->is_non_persistent($group)) {
return $this->_object_cache->delete($id);
* Deletes multiple values from the cache in one call.
* @param array $keys Array of keys to be deleted.
* @param string $group Optional. Where the cache contents are grouped. Default empty.
* @return bool[] Array of return values, grouped by key. Each value is either
* true on success, or false if the contents were not deleted.
public function delete_multiple(array $keys, $group = '')
foreach ($keys as $key) {
$values[$key] = $this->delete($key, $group);
* Increments numeric cache item's value.
* @param int|string $key The cache key to increment.
* @param int $offset Optional. The amount by which to increment the item's value.
* @param string $group Optional. The group the key is in. Default 'default'.
* @return int|false The item's new value on success, false on failure.
public function incr($key, $offset = 1, $group = 'default')
return $this->incr_desr($key, $offset, $group, true);
* Decrements numeric cache item's value.
* @param int|string $key The cache key to decrement.
* @param int $offset Optional. The amount by which to decrement the item's value.
* @param string $group Optional. The group the key is in. Default 'default'.
* @return int|false The item's new value on success, false on failure.
public function decr($key, $offset = 1, $group = 'default')
return $this->incr_desr($key, $offset, $group, false);
* Increments or decrements numeric cache item's value.
public function incr_desr($key, $offset = 1, $group = 'default', $incr = true)
if (!$this->is_valid_key($key)) {
$cache_val = $this->get($key, $group);
if (false === $cache_val) {
if (!is_numeric($cache_val)) {