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: 
<?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 xcache_cache extends cache_api
{
    /**
     * {@inheritDoc}
     */
    public function __construct()
    {
        global $modSettings;

        parent::__construct();

        // Xcache requuires a admin username and password in order to issue a clear.
        if (!empty($modSettings['xcache_adminuser']) && !empty($modSettings['xcache_adminpass']))
        {
            ini_set('xcache.admin.user', $modSettings['xcache_adminuser']);
            ini_set('xcache.admin.pass', md5($modSettings['xcache_adminpass']));
        }
    }

    /**
     * {@inheritDoc}
     */
    public function isSupported($test = false)
    {
        $supported = function_exists('xcache_get') && function_exists('xcache_set') && ini_get('xcache.var_size') > 0;

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

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

        return xcache_get($key);
    }

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

        if ($value === null)
            return xcache_unset($key);
        else
            return xcache_set($key, $value, $ttl);
    }

    /**
     * {@inheritDoc}
     */
    public function cleanCache($type = '')
    {
        global $modSettings;

        // Xcache requuires a admin username and password in order to issue a clear. Ideally this would log an error, but it seems like something that could fill up the error log quickly.
        if (empty($modSettings['xcache_adminuser']) || empty($modSettings['xcache_adminpass']))
        {
            // We are going to at least invalidate it.
            $this->invalidateCache();
            return false;
        }

        // if passed a type, clear that type out
        if ($type === '' || $type === 'user')
            xcache_clear_cache(XC_TYPE_VAR, 0);
        if ($type === '' || $type === 'data')
            xcache_clear_cache(XC_TYPE_PHP, 0);

        $this->invalidateCache();
        return true;
    }

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

        $config_vars[] = $txt['cache_xcache_settings'];
        $config_vars[] = array('xcache_adminuser', $txt['cache_xcache_adminuser'], 'db', 'text', 0, 'xcache_adminuser');

        // While we could md5 this when saving, this could be tricky to be sure it doesn't get corrupted on additional saves.
        $config_vars[] = array('xcache_adminpass', $txt['cache_xcache_adminpass'], 'db', 'text', 0);

        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;
                $("#xcache_adminuser").prop("disabled", cache_type != "xcache");
                $("#xcache_adminpass").prop("disabled", cache_type != "xcache");
            });';
    }

    /**
     * {@inheritDoc}
     */
    public function getVersion()
    {
        return XCACHE_VERSION;
    }
}

?>