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: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 
<?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...');

/**
 * Interface cache_api_interface
 */
interface cache_api_interface
{
    /**
     * Checks whether we can use the cache method performed by this API.
     *
     * @access public
     * @param boolean $test Test if this is supported or enabled.
     * @return boolean Whether or not the cache is supported
     */
    public function isSupported($test = false);

    /**
     * Connects to the cache method. This defines our $key. If this fails, we return false, otherwise we return true.
     *
     * @access public
     * @return boolean Whether or not the cache method was connected to.
     */
    public function connect();

    /**
     * Overrides the default prefix. If left alone, this will use the default key defined in the class.
     *
     * @access public
     * @param string $key The key to use
     * @return boolean If this was successful or not.
     */
    public function setPrefix($key = '');

    /**
     * Gets the prefix as defined from set or the default.
     *
     * @access public
     * @return string the value of $key.
     */
    public function getPrefix();

    /**
     * Sets a default Time To Live, if this isn't specified we let the class define it.
     *
     * @access public
     * @param int $ttl The default TTL
     * @return boolean If this was successful or not.
     */
    public function setDefaultTTL($ttl = 120);

    /**
     * Gets the TTL as defined from set or the default.
     *
     * @access public
     * @return string the value of $ttl.
     */
    public function getDefaultTTL();

    /**
     * Gets data from the cache.
     *
     * @access public
     * @param string $key The key to use, the prefix is applied to the key name.
     * @param string $ttl Overrides the default TTL.
     * @return mixed The result from the cache, if there is no data or it is invalid, we return null.
     */
    public function getData($key, $ttl = null);

    /**
     * Saves to data the cache.
     *
     * @access public
     * @param string $key The key to use, the prefix is applied to the key name.
     * @param mixed $value The data we wish to save.
     * @param string $ttl Overrides the default TTL.
     * @return bool Whether or not we could save this to the cache.
     */
    public function putData($key, $value, $ttl = null);

    /**
     * Clean out the cache.
     *
     * @param string $type If supported, the type of cache to clear, blank/data or user.
     * @return bool Whether or not we could clean the cache.
     */
    public function cleanCache($type = '');

    /**
     * Invalidate all cached data.
     *
     * @return bool Whether or not we could invalidate the cache.
     */
    public function invalidateCache();

    /**
     * Closes connections to the cache method.
     *
     * @access public
     * @return bool Whether or not we could close connections.
     */
    public function quit();

    /**
     * Specify custom settings that the cache API supports.
     *
     * @access public
     * @param array $config_vars Additional config_vars, see ManageSettings.php for usage.
     * @return void No return is needed.
     */
    public function cacheSettings(array &$config_vars);

    /**
     * Gets the latest version of SMF this is compatible with.
     *
     * @access public
     * @return string the value of $key.
     */
    public function getCompatibleVersion();

    /**
     * Gets the min version that we support.
     *
     * @access public
     * @return string the value of $key.
     */
    public function getMiniumnVersion();

    /**
     * Gets the Version of the Caching API.
     *
     * @access public
     * @return string the value of $key.
     */
    public function getVersion();

    /**
     * Run housekeeping of this cache
     * exp. clean up old data or do optimization
     *
     * @access public
     * @return void
     */
    public function housekeeping();
}

/**
 * Class cache_api
 */
abstract class cache_api implements cache_api_interface
{
    /**
     * @var string The last version of SMF that this was tested on. Helps protect against API changes.
     */
    protected $version_compatible = 'SMF 2.1 RC1';

    /**
     * @var string The minimum SMF version that this will work with
     */
    protected $min_smf_version = 'SMF 2.1 RC1';

    /**
     * @var string The prefix for all keys.
     */
    protected $prefix = '';

    /**
     * @var int The default TTL.
     */
    protected $ttl = 120;

    /**
     * Does basic setup of a cache method when we create the object but before we call connect.
     *
     * @access public
     */
    public function __construct()
    {
        $this->setPrefix('');
    }

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

        if ($test)
            return true;
        return !empty($cache_enable);
    }

    /**
     * {@inheritDoc}
     */
    public function connect()
    {
    }

    /**
     * {@inheritDoc}
     */
    public function setPrefix($prefix = '')
    {
        global $boardurl, $cachedir;

        // Find a valid good file to do mtime checks on.
        if (file_exists($cachedir . '/' . 'index.php'))
            $filemtime = $cachedir . '/' . 'index.php';
        elseif (is_dir($cachedir . '/'))
            $filemtime = $cachedir . '/';
        else
            $filemtime = $boardurl . '/index.php';

        // Set the default if no prefix was specified.
        if (empty($prefix))
            $this->prefix = md5($boardurl . filemtime($filemtime)) . '-SMF-';
        else
            $this->prefix = $prefix;

        return true;
    }

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

    /**
     * {@inheritDoc}
     */
    public function setDefaultTTL($ttl = 120)
    {
        $this->ttl = $ttl;

        return true;
    }

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

    /**
     * {@inheritDoc}
     */
    public function getData($key, $ttl = null)
    {
    }

    /**
     * {@inheritDoc}
     */
    public function putData($key, $value, $ttl = null)
    {
    }

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

    /**
     * Invalidate all cached data.
     *
     * @return bool Whether or not we could invalidate the cache.
     */
    public function invalidateCache()
    {
        global $cachedir;

        // Invalidate cache, to be sure!
        // ... as long as index.php can be modified, anyway.
        if (is_writable($cachedir . '/' . 'index.php'))
            @touch($cachedir . '/' . 'index.php');

        return true;
    }

    /**
     * {@inheritDoc}
     */
    public function quit()
    {
    }

    /**
     * {@inheritDoc}
     */
    public function cacheSettings(array &$config_vars)
    {
    }

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

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

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

    /**
     * {@inheritDoc}
     */
    public function housekeeping()
    {
    }
}

?>