%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/opti/public_html/stlc/wp-content/
Upload File :
Create Path :
Current File : /home/opti/public_html/stlc/wp-content/object-cache.php

<?php
/*
Plugin Name: Redis Object Cache Drop-In
Plugin URI: http://wordpress.org/plugins/redis-cache/
Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, HHVM, replication, clustering and WP-CLI.
Version: 2.0.1
Author: Till Krüss
Author URI: https://till.im/
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html

Based on Eric Mann's and Erick Hitter's Redis Object Cache:
https://github.com/ericmann/Redis-Object-Cache
*/

/**
 * We are using v2.0.0+
 * To be sure that everything will work fine, we're going to check the EasyWP Plugin.
 */
function easywp_plugin_exists()
{
    $plugin_dir = defined('WPMU_PLUGIN_DIR') ? WPMU_PLUGIN_DIR : WP_CONTENT_DIR . '/mu-plugins';

    return file_exists($plugin_dir . '/wp-nc-easywp/plugin/Http/Redis/includes/predis.php');
}


if ((!defined('WP_REDIS_DISABLED') || !WP_REDIS_DISABLED) && easywp_plugin_exists()) :

    /**
     * Adds a value to cache.
     *
     * If the specified key already exists, the value is not stored and the function
     * returns false.
     *
     * @param string           $key        The key under which to store the value.
     * @param mixed            $value      The value to store.
     * @param string           $group      The group value appended to the $key.
     * @param int              $expiration The expiration time, defaults to 0.
     *
     * @return bool              Returns TRUE on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_add($key, $value, $group = '', $expiration = 0)
    {
        global $wp_object_cache;

        return $wp_object_cache->add($key, $value, $group, $expiration);
    }

    /**
     * Closes the cache.
     *
     * This function has ceased to do anything since WordPress 2.5. The
     * functionality was removed along with the rest of the persistent cache. This
     * does not mean that plugins can't implement this function when they need to
     * make sure that the cache is cleaned up after WordPress no longer needs it.
     *
     * @return  bool    Always returns True
     */
    function wp_cache_close()
    {
        return true;
    }

    /**
     * Decrement a numeric item's value.
     *
     * @param string           $key    The key under which to store the value.
     * @param int              $offset The amount by which to decrement the item's value.
     * @param string           $group  The group value appended to the $key.
     *
     * @return int|bool      Returns item's new value on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_decr($key, $offset = 1, $group = '')
    {
        global $wp_object_cache;

        return $wp_object_cache->decrement($key, $offset, $group);
    }

    /**
     * Remove the item from the cache.
     *
     * @param string           $key   The key under which to store the value.
     * @param string           $group The group value appended to the $key.
     * @param int              $time  The amount of time the server will wait to delete the item in seconds.
     *
     * @return bool           Returns TRUE on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_delete($key, $group = '', $time = 0)
    {
        global $wp_object_cache;

        return $wp_object_cache->delete($key, $group, $time);
    }

    /**
     * Invalidate all items in the cache.
     *
     * @param int              $delay Number of seconds to wait before invalidating the items.
     *
     * @return bool             Returns TRUE on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_flush($delay = 0)
    {
        global $wp_object_cache;

        return $wp_object_cache->flush($delay);
    }

    /**
     * Retrieve object from cache.
     *
     * Gets an object from cache based on $key and $group.
     *
     * @param string            $key   The key under which to store the value.
     * @param string            $group The group value appended to the $key.
     * @param bool              $force Optional. 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. Disambiguates a return of false,
     *                                 a storable value. Passed by reference. Default null.
     *
     * @return bool|mixed             Cached object value.
     * @global WP_Object_Cache  $wp_object_cache
     *
     */
    function wp_cache_get($key, $group = '', $force = false, &$found = null)
    {
        global $wp_object_cache;

        return $wp_object_cache->get($key, $group, $force, $found);
    }

    /**
     * Retrieve multiple values from cache.
     *
     * Gets multiple values from cache, including across multiple groups
     *
     * Usage: array( 'group0' => array( 'key0', 'key1', 'key2', ), 'group1' => array( 'key0' ) )
     *
     * Mirrors the Memcached Object Cache plugin's argument and return-value formats
     *
     * @param array            $groups Array of groups and keys to retrieve
     *
     * @return  bool|mixed           Array of cached values, keys in the format $group:$key. Non-existent keys false
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_get_multi($groups)
    {
        global $wp_object_cache;

        return $wp_object_cache->get_multi($groups);
    }

    /**
     * Increment a numeric item's value.
     *
     * @param string           $key    The key under which to store the value.
     * @param int              $offset The amount by which to increment the item's value.
     * @param string           $group  The group value appended to the $key.
     *
     * @return int|bool      Returns item's new value on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_incr($key, $offset = 1, $group = '')
    {
        global $wp_object_cache;

        return $wp_object_cache->increment($key, $offset, $group);
    }

    /**
     * Sets up Object Cache Global and assigns it.
     *
     * @return  void
     * @global  WP_Object_Cache $wp_object_cache WordPress Object Cache
     *
     */
    function wp_cache_init()
    {
        global $wp_object_cache;

        if (!($wp_object_cache instanceof WP_Object_Cache)) {
            $wp_object_cache = new WP_Object_Cache;
        }
    }

    /**
     * Replaces a value in cache.
     *
     * This method is similar to "add"; however, is does not successfully set a value if
     * the object's key is not already set in cache.
     *
     * @param string           $key        The key under which to store the value.
     * @param mixed            $value      The value to store.
     * @param string           $group      The group value appended to the $key.
     * @param int              $expiration The expiration time, defaults to 0.
     *
     * @return bool              Returns TRUE on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_replace($key, $value, $group = '', $expiration = 0)
    {
        global $wp_object_cache;

        return $wp_object_cache->replace($key, $value, $group, $expiration);
    }

    /**
     * Sets a value in cache.
     *
     * The value is set whether or not this key already exists in Redis.
     *
     * @param string           $key        The key under which to store the value.
     * @param mixed            $value      The value to store.
     * @param string           $group      The group value appended to the $key.
     * @param int              $expiration The expiration time, defaults to 0.
     *
     * @return bool              Returns TRUE on success or FALSE on failure.
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_set($key, $value, $group = '', $expiration = 0)
    {
        global $wp_object_cache;

        return $wp_object_cache->set($key, $value, $group, $expiration);
    }

    /**
     * Switch the interal blog id.
     *
     * This changes the blog id used to create keys in blog specific groups.
     *
     * @param int              $_blog_id Blog ID
     *
     * @return bool
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_switch_to_blog($_blog_id)
    {
        global $wp_object_cache;

        return $wp_object_cache->switch_to_blog($_blog_id);
    }

    /**
     * Adds a group or set of groups to the list of Redis groups.
     *
     * @param string|array     $groups A group or an array of groups to add.
     *
     * @return  void
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_add_global_groups($groups)
    {
        global $wp_object_cache;

        $wp_object_cache->add_global_groups($groups);
    }

    /**
     * Adds a group or set of groups to the list of non-Redis groups.
     *
     * @param string|array     $groups A group or an array of groups to add.
     *
     * @return  void
     * @global WP_Object_Cache $wp_object_cache
     *
     */
    function wp_cache_add_non_persistent_groups($groups)
    {
        global $wp_object_cache;

        $wp_object_cache->add_non_persistent_groups($groups);
    }

    class WP_Object_Cache
    {

        /**
         * The Redis client.
         *
         * @var mixed
         */
        private $redis;

        /**
         * Track if Redis is available
         *
         * @var bool
         */
        private $redis_connected = false;

        /**
         * Holds the non-Redis objects.
         *
         * @var array
         */
        public $cache = [];

        /**
         * Name of the used Redis client
         *
         * @var bool
         */
        public $redis_client = null;

        /**
         * List of global groups.
         *
         * @var array
         */
        public $global_groups = [
            'blog-details',
            'blog-id-cache',
            'blog-lookup',
            'global-posts',
            'networks',
            'rss',
            'sites',
            'site-details',
            'site-lookup',
            'site-options',
            'site-transient',
            'users',
            'useremail',
            'userlogins',
            'usermeta',
            'user_meta',
            'userslugs',
        ];

        /**
         * List of groups not saved to Redis.
         *
         * @var array
         */
        public $ignored_groups = ['counts', 'plugins'];

        /**
         * Prefix used for global groups.
         *
         * @var string
         */
        public $global_prefix = '';

        /**
         * Prefix used for non-global groups.
         *
         * @var string
         */
        public $blog_prefix = '';

        /**
         * Track how many requests were found in cache
         *
         * @var int
         */
        public $cache_hits = 0;

        /**
         * Track how may requests were not cached
         *
         * @var int
         */
        public $cache_misses = 0;

        /**
         * Instantiate the Redis class.
         *
         * Instantiates the Redis class.
         *
         * @param null $persistent_id To create an instance that persists between requests, use persistent_id to specify a unique ID for the instance.
         */
        public function __construct()
        {
            global $blog_id, $table_prefix;

            $parameters = [
                'scheme' => 'tcp',
                'host' => '127.0.0.1',
                'port' => 6379,
            ];

            foreach (['scheme', 'host', 'port', 'path', 'password', 'database'] as $setting) {
                $constant = sprintf('WP_REDIS_%s', strtoupper($setting));
                if (defined($constant)) {
                    $parameters[$setting] = constant($constant);
                }
            }

            if (defined('WP_REDIS_GLOBAL_GROUPS') && is_array(WP_REDIS_GLOBAL_GROUPS)) {
                $this->global_groups = WP_REDIS_GLOBAL_GROUPS;
            }

            if (defined('WP_REDIS_IGNORED_GROUPS') && is_array(WP_REDIS_IGNORED_GROUPS)) {
                $this->ignored_groups = WP_REDIS_IGNORED_GROUPS;
            }

            $client = defined('WP_REDIS_CLIENT') ? WP_REDIS_CLIENT : null;

            if (class_exists('Redis') && strcasecmp('predis', $client) !== 0) {
                $client = defined('HHVM_VERSION') ? 'hhvm' : 'pecl';
            } else {
                $client = 'predis';
            }

            try {

                if (strcasecmp('hhvm', $client) === 0) {

                    $this->redis_client = sprintf('HHVM Extension (v%s)', HHVM_VERSION);
                    $this->redis        = new Redis();

                    // Adjust host and port, if the scheme is `unix`
                    if (strcasecmp('unix', $parameters['scheme']) === 0) {
                        $parameters['host'] = 'unix://' . $parameters['path'];
                        $parameters['port'] = 0;
                    }

                    $this->redis->connect($parameters['host'], $parameters['port']);
                }

                if (strcasecmp('pecl', $client) === 0) {

                    $this->redis_client = sprintf('PECL Extension (v%s)', phpversion('redis'));
                    $this->redis        = new Redis();

                    if (strcasecmp('unix', $parameters['scheme']) === 0) {
                        $this->redis->connect($parameters['path']);
                    } else {
                        $this->redis->connect($parameters['host'], $parameters['port']);
                    }
                }

                if (strcasecmp('pecl', $client) === 0 || strcasecmp('hhvm', $client) === 0) {
                    if (isset($parameters['password'])) {
                        $this->redis->auth($parameters['password']);
                    }

                    if (isset($parameters['database'])) {
                        $this->redis->select($parameters['database']);
                    }
                }

                if (strcasecmp('predis', $client) === 0) {

                    $this->redis_client = 'Predis';

                    // Require PHP 5.4 or greater
                    if (version_compare(PHP_VERSION, '5.4.0', '<')) {
                        throw new Exception;
                    }

                    // Load bundled Predis library
                    if (!class_exists('Predis\Client')) {
                        $plugin_dir = defined('WPMU_PLUGIN_DIR') ? WPMU_PLUGIN_DIR : WP_CONTENT_DIR . '/mu-plugins';
                        require_once $plugin_dir . '/wp-nc-easywp/plugin/Http/Redis/includes/predis.php';
                        Predis\Autoloader::register();
                    }

                    $options = [];

                    if (defined('WP_REDIS_CLUSTER')) {
                        $parameters         = WP_REDIS_CLUSTER;
                        $options['cluster'] = 'redis';
                    }

                    if (defined('WP_REDIS_SERVERS')) {
                        $parameters             = WP_REDIS_SERVERS;
                        $options['replication'] = true;
                    }

                    if ((defined('WP_REDIS_SERVERS') || defined('WP_REDIS_CLUSTER')) && defined('WP_REDIS_PASSWORD')) {
                        $options['parameters']['password'] = WP_REDIS_PASSWORD;
                    }

                    $this->redis = new Predis\Client($parameters, $options);
                    $this->redis->connect();

                    $this->redis_client .= sprintf(' (v%s)', Predis\Client::VERSION);

                }

                // Throws exception if Redis is unavailable
                $this->redis->ping();

                $this->redis_connected = true;

            } catch (Exception $exception) {

                // When Redis is unavailable, fall back to the internal back by forcing all groups to be "no redis" groups
                $this->ignored_groups = array_unique(array_merge($this->ignored_groups, $this->global_groups));

                $this->redis_connected = false;

            }

            /**
             * This approach is borrowed from Sivel and Boren. Use the salt for easy cache invalidation and for
             * multi single WP installs on the same server.
             */
            if (!defined('WP_CACHE_KEY_SALT')) {
                define('WP_CACHE_KEY_SALT', '');
            }

            // Assign global and blog prefixes for use with keys
            if (function_exists('is_multisite')) {
                $this->global_prefix = (is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE')) ? '' : $table_prefix;
                $this->blog_prefix   = (is_multisite() ? $blog_id : $table_prefix);
            }
        }

        /**
         * Is Redis available?
         *
         * @return bool
         */
        public function redis_status()
        {
            return $this->redis_connected;
        }

        /**
         * Returns the Redis instance.
         *
         * @return mixed
         */
        public function redis_instance()
        {
            return $this->redis;
        }

        /**
         * Adds a value to cache.
         *
         * If the specified key already exists, the value is not stored and the function
         * returns false.
         *
         * @param string $key        The key under which to store the value.
         * @param mixed  $value      The value to store.
         * @param string $group      The group value appended to the $key.
         * @param int    $expiration The expiration time, defaults to 0.
         * @return  bool                   Returns TRUE on success or FALSE on failure.
         */
        public function add($key, $value, $group = 'default', $expiration = 0)
        {
            return $this->add_or_replace(true, $key, $value, $group, $expiration);
        }

        /**
         * Replace a value in the cache.
         *
         * If the specified key doesn't exist, the value is not stored and the function
         * returns false.
         *
         * @param string $key        The key under which to store the value.
         * @param mixed  $value      The value to store.
         * @param string $group      The group value appended to the $key.
         * @param int    $expiration The expiration time, defaults to 0.
         * @return  bool                   Returns TRUE on success or FALSE on failure.
         */
        public function replace($key, $value, $group = 'default', $expiration = 0)
        {
            return $this->add_or_replace(false, $key, $value, $group, $expiration);
        }

        /**
         * Add or replace a value in the cache.
         *
         * Add does not set the value if the key exists; replace does not replace if the value doesn't exist.
         *
         * @param bool   $add        True if should only add if value doesn't exist, false to only add when value already exists
         * @param string $key        The key under which to store the value.
         * @param mixed  $value      The value to store.
         * @param string $group      The group value appended to the $key.
         * @param int    $expiration The expiration time, defaults to 0.
         * @return  bool                   Returns TRUE on success or FALSE on failure.
         */
        protected function add_or_replace($add, $key, $value, $group = 'default', $expiration = 0)
        {
            $result      = true;
            $derived_key = $this->build_key($key, $group);

            // save if group not excluded and redis is up
            if (!in_array($group, $this->ignored_groups) && $this->redis_status()) {
                $exists = $this->redis->exists($derived_key);

                if ($add == $exists) {
                    return false;
                }

                $expiration = $this->validate_expiration($expiration);

                if ($expiration) {
                    $result = $this->parse_redis_response($this->redis->setex($derived_key, $expiration, $this->maybe_serialize($value)));
                } else {
                    $result = $this->parse_redis_response($this->redis->set($derived_key, $this->maybe_serialize($value)));
                }
            }

            $exists = isset($this->cache[$derived_key]);

            if ($add == $exists) {
                return false;
            }

            if ($result) {
                $this->add_to_internal_cache($derived_key, $value);
            }

            return $result;
        }

        /**
         * Remove the item from the cache.
         *
         * @param string $key   The key under which to store the value.
         * @param string $group The group value appended to the $key.
         * @return  bool               Returns TRUE on success or FALSE on failure.
         */
        public function delete($key, $group = 'default')
        {
            $result      = false;
            $derived_key = $this->build_key($key, $group);

            if (isset($this->cache[$derived_key])) {
                unset($this->cache[$derived_key]);
                $result = true;
            }

            if ($this->redis_status() && !in_array($group, $this->ignored_groups)) {
                $result = $this->parse_redis_response($this->redis->del($derived_key));
            }

            if (function_exists('do_action')) {
                do_action('redis_object_cache_delete', $key, $group);
            }

            return $result;
        }

        /**
         * Invalidate all items in the cache.
         *
         * @param int $delay Number of seconds to wait before invalidating the items.
         * @return  bool            Returns TRUE on success or FALSE on failure.
         */
        public function flush($delay = 0)
        {
            $delay = abs(intval($delay));

            if ($delay) {
                sleep($delay);
            }

            $result      = false;
            $this->cache = [];

            if ($this->redis_status()) {
                $result = $this->parse_redis_response($this->redis->flushdb());

                if (function_exists('do_action')) {
                    do_action('redis_object_cache_flush', $result, $delay);
                }
            }

            return $result;
        }

        /**
         * Retrieve object from cache.
         *
         * Gets an object from cache based on $key and $group.
         *
         * @param string  $key                The key under which to store the value.
         * @param string  $group              The group value appended to the $key.
         * @param string  $force              Optional. Whether to force a refetch rather than relying on the local
         *                                    cache. Default false.
         * @param bool   &$found              Optional. Whether the key was found in the cache. Disambiguates a return of
         *                                    false, a storable value. Passed by reference. Default null.
         * @return  bool|mixed                Cached object value.
         */
        public function get($key, $group = 'default', $force = false, &$found = null)
        {
            $derived_key = $this->build_key($key, $group);

            if (isset($this->cache[$derived_key]) && !$force) {
                $found = true;
                $this->cache_hits++;

                return is_object($this->cache[$derived_key]) ? clone $this->cache[$derived_key] : $this->cache[$derived_key];
            } elseif (in_array($group, $this->ignored_groups) || !$this->redis_status()) {
                $found = false;
                $this->cache_misses++;

                return false;
            }

            $result = $this->redis->get($derived_key);

            if ($result === null || $result === false) {
                $found = false;
                $this->cache_misses++;

                return false;
            } else {
                $found = true;
                $this->cache_hits++;
                $value = $this->maybe_unserialize($result);
            }

            $this->add_to_internal_cache($derived_key, $value);

            $value = is_object($value) ? clone $value : $value;

            if (function_exists('do_action')) {
                do_action('redis_object_cache_get', $key, $value, $group, $force, $found);
            }

            if (function_exists('apply_filters') && function_exists('has_filter')) {
                if (has_filter('redis_object_cache_get')) {
                    return apply_filters('redis_object_cache_get', $value, $key, $group, $force, $found);
                }
            }

            return $value;
        }

        /**
         * Retrieve multiple values from cache.
         *
         * Gets multiple values from cache, including across multiple groups
         *
         * Usage: array( 'group0' => array( 'key0', 'key1', 'key2', ), 'group1' => array( 'key0' ) )
         *
         * Mirrors the Memcached Object Cache plugin's argument and return-value formats
         *
         * @param array $groups Array of groups and keys to retrieve
         * @return  bool|mixed                               Array of cached values, keys in the format $group:$key. Non-existent keys null.
         */
        public function get_multi($groups)
        {
            if (empty($groups) || !is_array($groups)) {
                return false;
            }

            // Retrieve requested caches and reformat results to mimic Memcached Object Cache's output
            $cache = [];

            foreach ($groups as $group => $keys) {
                if (in_array($group, $this->ignored_groups) || !$this->redis_status()) {
                    foreach ($keys as $key) {
                        $cache[$this->build_key($key, $group)] = $this->get($key, $group);
                    }
                } else {
                    // Reformat arguments as expected by Redis
                    $derived_keys = [];

                    foreach ($keys as $key) {
                        $derived_keys[] = $this->build_key($key, $group);
                    }

                    // Retrieve from cache in a single request
                    $group_cache = $this->redis->mget($derived_keys);

                    // Build an array of values looked up, keyed by the derived cache key
                    $group_cache = array_combine($derived_keys, $group_cache);

                    // Restores cached data to its original data type
                    $group_cache = array_map([$this, 'maybe_unserialize'], $group_cache);

                    // Redis returns null for values not found in cache, but expected return value is false in this instance
                    $group_cache = array_map([$this, 'filter_redis_get_multi'], $group_cache);

                    $cache = array_merge($cache, $group_cache);
                }
            }

            // Add to the internal cache the found values from Redis
            foreach ($cache as $key => $value) {
                if ($value) {
                    $this->cache_hits++;
                    $this->add_to_internal_cache($key, $value);
                } else {
                    $this->cache_misses++;
                }
            }

            return $cache;
        }

        /**
         * Sets a value in cache.
         *
         * The value is set whether or not this key already exists in Redis.
         *
         * @param string $key        The key under which to store the value.
         * @param mixed  $value      The value to store.
         * @param string $group      The group value appended to the $key.
         * @param int    $expiration The expiration time, defaults to 0.
         * @return  bool               Returns TRUE on success or FALSE on failure.
         */
        public function set($key, $value, $group = 'default', $expiration = 0)
        {
            $result      = true;
            $derived_key = $this->build_key($key, $group);

            // save if group not excluded from redis and redis is up
            if (!in_array($group, $this->ignored_groups) && $this->redis_status()) {
                $expiration = $this->validate_expiration($expiration);

                if ($expiration) {
                    $result = $this->parse_redis_response($this->redis->setex($derived_key, $expiration, $this->maybe_serialize($value)));
                } else {
                    $result = $this->parse_redis_response($this->redis->set($derived_key, $this->maybe_serialize($value)));
                }
            }

            // if the set was successful, or we didn't go to redis
            if ($result) {
                $this->add_to_internal_cache($derived_key, $value);
            }

            if (function_exists('do_action')) {
                do_action('redis_object_cache_set', $key, $value, $group, $expiration);
            }

            return $result;
        }

        /**
         * Increment a Redis counter by the amount specified
         *
         * @param string $key
         * @param int    $offset
         * @param string $group
         * @return int|bool
         */
        public function increment($key, $offset = 1, $group = 'default')
        {
            $derived_key = $this->build_key($key, $group);
            $offset      = (int) $offset;

            // If group is a non-Redis group, save to internal cache, not Redis
            if (in_array($group, $this->ignored_groups) || !$this->redis_status()) {
                $value = $this->get_from_internal_cache($derived_key, $group);
                $value += $offset;
                $this->add_to_internal_cache($derived_key, $value);

                return $value;
            }

            // Save to Redis
            $result = $this->parse_redis_response($this->redis->incrBy($derived_key, $offset));

            $this->add_to_internal_cache($derived_key, (int) $this->redis->get($derived_key));

            return $result;
        }

        /**
         * Alias of `increment()`.
         *
         * @param string $key
         * @param int    $offset
         * @param string $group
         * @return bool
         */
        public function incr($key, $offset = 1, $group = 'default')
        {
            return $this->increment($key, $offset, $group);
        }

        /**
         * Decrement a Redis counter by the amount specified
         *
         * @param string $key
         * @param int    $offset
         * @param string $group
         * @return int|bool
         */
        public function decrement($key, $offset = 1, $group = 'default')
        {
            $derived_key = $this->build_key($key, $group);
            $offset      = (int) $offset;

            // If group is a non-Redis group, save to internal cache, not Redis
            if (in_array($group, $this->ignored_groups) || !$this->redis_status()) {
                $value = $this->get_from_internal_cache($derived_key, $group);
                $value -= $offset;
                $this->add_to_internal_cache($derived_key, $value);

                return $value;
            }

            // Save to Redis
            $result = $this->parse_redis_response($this->redis->decrBy($derived_key, $offset));

            $this->add_to_internal_cache($derived_key, (int) $this->redis->get($derived_key));

            return $result;
        }

        /**
         * Render data about current cache requests
         *
         * @return string
         */
        public function stats()
        { ?>

          <p>
            <strong>Redis Status:</strong> <?php echo $this->redis_status() ? 'Connected' : 'Not Connected'; ?><br/>
            <strong>Redis Client:</strong> <?php echo $this->redis_client; ?><br/>
            <strong>Cache Hits:</strong> <?php echo $this->cache_hits; ?><br/>
            <strong>Cache Misses:</strong> <?php echo $this->cache_misses; ?>
          </p>

          <ul>
            <?php foreach ($this->cache as $group => $cache) : ?>
          <li><?php printf('%s - %sk', strip_tags($group), number_format(strlen(serialize($cache)) / 1024, 2)); ?></li>
        <?php endforeach; ?>
          </ul><?php

        }

        /**
         * Builds a key for the cached object using the prefix, group and key.
         *
         * @param string $key   The key under which to store the value.
         * @param string $group The group value appended to the $key.
         *
         * @return  string
         */
        public function build_key($key, $group = 'default')
        {
            if (empty($group)) {
                $group = 'default';
            }

            if (in_array($group, $this->global_groups)) {
                $prefix = $this->global_prefix;
            } else {
                $prefix = $this->blog_prefix;
            }

            return WP_CACHE_KEY_SALT . "{$prefix}:{$group}:{$key}";
        }

        /**
         * Convert data types when using Redis MGET
         *
         * When requesting multiple keys, those not found in cache are assigned the value null upon return.
         * Expected value in this case is false, so we convert
         *
         * @param string $value Value to possibly convert
         * @return  string          Converted value
         */
        protected function filter_redis_get_multi($value)
        {
            if (is_null($value)) {
                $value = false;
            }

            return $value;
        }

        /**
         * Convert Redis responses into something meaningful
         *
         * @param mixed $response
         * @return mixed
         */
        protected function parse_redis_response($response)
        {
            if (is_bool($response)) {
                return $response;
            }

            if (is_numeric($response)) {
                return $response;
            }

            if (is_object($response) && method_exists($response, 'getPayload')) {
                return $response->getPayload() === 'OK';
            }

            return false;
        }

        /**
         * Simple wrapper for saving object to the internal cache.
         *
         * @param string $derived_key Key to save value under.
         * @param mixed  $value       Object value.
         */
        public function add_to_internal_cache($derived_key, $value)
        {
            $this->cache[$derived_key] = $value;
        }

        /**
         * Get a value specifically from the internal, run-time cache, not Redis.
         *
         * @param int|string $key   Key value.
         * @param int|string $group Group that the value belongs to.
         *
         * @return  bool|mixed              Value on success; false on failure.
         */
        public function get_from_internal_cache($key, $group)
        {
            $derived_key = $this->build_key($key, $group);

            if (isset($this->cache[$derived_key])) {
                return $this->cache[$derived_key];
            }

            return false;
        }

        /**
         * In multisite, switch blog prefix when switching blogs
         *
         * @param int $_blog_id
         * @return bool
         */
        public function switch_to_blog($_blog_id)
        {
            if (!function_exists('is_multisite') || !is_multisite()) {
                return false;
            }

            $this->blog_prefix = $_blog_id;

            return true;
        }

        /**
         * Sets the list of global groups.
         *
         * @param array $groups List of groups that are global.
         */
        public function add_global_groups($groups)
        {
            $groups = (array) $groups;

            if ($this->redis_status()) {
                $this->global_groups = array_unique(array_merge($this->global_groups, $groups));
            } else {
                $this->ignored_groups = array_unique(array_merge($this->ignored_groups, $groups));
            }
        }

        /**
         * Sets the list of groups not to be cached by Redis.
         *
         * @param array $groups List of groups that are to be ignored.
         */
        public function add_non_persistent_groups($groups)
        {
            $groups = (array) $groups;

            $this->ignored_groups = array_unique(array_merge($this->ignored_groups, $groups));
        }

        /**
         * Wrapper to validate the cache keys expiration value
         *
         * @param mixed $expiration Incomming expiration value (whatever it is)
         */
        protected function validate_expiration($expiration)
        {
            $expiration = (is_array($expiration) || is_object($expiration) ? 0 : abs(intval($expiration)));

            if ($expiration === 0 && defined('WP_REDIS_MAXTTL')) {
                $expiration = intval(WP_REDIS_MAXTTL);
            }

            return $expiration;
        }

        /**
         * Unserialize value only if it was serialized.
         *
         * @param string $original Maybe unserialized original, if is needed.
         * @return mixed Unserialized data can be any type.
         */
        protected function maybe_unserialize($original)
        {
            // don't attempt to unserialize data that wasn't serialized going in
            if ($this->is_serialized($original)) {
                return @unserialize($original);
            }

            return $original;
        }

        /**
         * Serialize data, if needed.
         *
         * @param string|array|object $data Data that might be serialized.
         * @return mixed A scalar data
         */
        protected function maybe_serialize($data)
        {
            if (is_array($data) || is_object($data)) {
                return serialize($data);
            }

            if ($this->is_serialized($data, false)) {
                return serialize($data);
            }

            return $data;
        }

        /**
         * Check value to find if it was serialized.
         *
         * If $data is not an string, then returned value will always be false.
         * Serialized data is always a string.
         *
         * @param string $data   Value to check to see if was serialized.
         * @param bool   $strict Optional. Whether to be strict about the end of the string. Default true.
         * @return bool False if not serialized and true if it was.
         */
        protected function is_serialized($data, $strict = true)
        {
            // if it isn't a string, it isn't serialized.
            if (!is_string($data)) {
                return false;
            }

            $data = trim($data);

            if ('N;' == $data) {
                return true;
            }

            if (strlen($data) < 4) {
                return false;
            }

            if (':' !== $data[1]) {
                return false;
            }

            if ($strict) {
                $lastc = substr($data, -1);

                if (';' !== $lastc && '}' !== $lastc) {
                    return false;
                }
            } else {
                $semicolon = strpos($data, ';');
                $brace     = strpos($data, '}');

                // Either ; or } must exist.
                if (false === $semicolon && false === $brace) {
                    return false;
                }

                // But neither must be in the first X characters.
                if (false !== $semicolon && $semicolon < 3) {
                    return false;
                }

                if (false !== $brace && $brace < 4) {
                    return false;
                }
            }
            $token = $data[0];

            switch ($token) {
                case 's':
                    if ($strict) {
                        if ('"' !== substr($data, -2, 1)) {
                            return false;
                        }
                    } elseif (false === strpos($data, '"')) {
                        return false;
                    }
                // or else fall through
                case 'a':
                case 'O':
                    return (bool) preg_match("/^{$token}:[0-9]+:/s", $data);
                case 'b':
                case 'i':
                case 'd':
                    $end = $strict ? '$' : '';

                    return (bool) preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
            }

            return false;
        }

    }

endif;

Zerion Mini Shell 1.0