1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 
<?php

/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2019 Simple Machines and individual contributors
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.1 RC1
 */

if (!defined('SMF'))
    die('Hacking attempt...');

/**
 * Our Cache API class
 *
 * @package cacheAPI
 */
class memcached_cache extends cache_api
{
    /**
     * @var \Memcached The memcache instance.
     */
    private $memcached = null;

    /**
     * {@inheritDoc}
     */
    public function isSupported($test = false)
    {
        global $cache_memcached;

        $supported = class_exists('memcached');

        if ($test)
            return $supported;
        return parent::isSupported() && $supported && !empty($cache_memcached);
    }

    /**
     * {@inheritDoc}
     */
    public function connect()
    {
        global $cache_memcached;

        $servers = explode(',', $cache_memcached);

        // memcached does not remove servers from the list upon completing the script under modes like FastCGI. So check to see if servers exist or not.
        $this->memcached = new Memcached;
        $currentServers = $this->memcached->getServerList();
        foreach ($servers as $server)
        {
            if (strpos($server, '/') !== false)
                $tempServer = array($server, 0);
            else
            {
                $server = explode(':', $server);
                $tempServer = array($server[0], isset($server[1]) ? $server[1] : 11211);
            }

            // Figure out if we have this server or not
            $foundServer = false;
            foreach ($currentServers as $currentServer)
            {
                if ($tempServer[0] == $currentServer['host'] && $tempServer[1] == $currentServer['port'])
                {
                    $foundServer = true;
                    break;
                }
            }

            // Found it?
            if (empty($foundServer))
                $this->memcached->addServer($tempServer[0], $tempServer[1]);
        }

        // Best guess is this worked.
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public function getData($key, $ttl = null)
    {
        $key = $this->prefix . strtr($key, ':/', '-_');

        $value = $this->memcached->get($key);

        // $value should return either data or false (from failure, key not found or empty array).
        if ($value === false)
            return null;
        return $value;
    }

    /**
     * {@inheritDoc}
     */
    public function putData($key, $value, $ttl = null)
    {
        $key = $this->prefix . strtr($key, ':/', '-_');

        return $this->memcached->set($key, $value, $ttl);
    }

    /**
     * {@inheritDoc}
     */
    public function cleanCache($type = '')
    {
        $this->invalidateCache();

        // Memcached accepts a delay parameter, always use 0 (instant).
        return $this->memcached->flush(0);
    }

    /**
     * {@inheritDoc}
     */
    public function quit()
    {
        return $this->memcached->quit();
    }

    /**
     * {@inheritDoc}
     */
    public function cacheSettings(array &$config_vars)
    {
        global $context, $txt;

        $config_vars[] = $txt['cache_memcache_settings'];
        $config_vars[] = array('cache_memcached', $txt['cache_memcache_servers'], 'file', 'text', 0, 'cache_memcached', 'postinput' => '<br><div class="smalltext"><em>' . $txt['cache_memcache_servers_subtext'] . '</em></div>');

        if (!isset($context['settings_post_javascript']))
            $context['settings_post_javascript'] = '';

        $context['settings_post_javascript'] .= '
            $("#cache_accelerator").change(function (e) {
                var cache_type = e.currentTarget.value;
                $("#cache_memcached").prop("disabled", cache_type != "memcached");
            });';
    }

    /**
     * {@inheritDoc}
     */
    public function getVersion()
    {
        return $this->memcached->getVersion();
    }
}

?>