* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT */ abstract class Cache { /** * Stores all options for the driver * @var array */ protected $options = []; /** * Sets all parameters which are needed to connect to the cache storage * * @param array $options */ public function __construct(array $options = []) { $this->options = $options; } /** * Writes an item to the cache for a given number of minutes and * returns whether the operation was successful; * this needs to be defined by the driver * * * // put an item in the cache for 15 minutes * $cache->set('value', 'my value', 15); * * * @param string $key * @param mixed $value * @param int $minutes * @return bool */ abstract public function set(string $key, $value, int $minutes = 0): bool; /** * Adds the prefix to the key if given * * @param string $key * @return string */ protected function key(string $key): string { if (empty($this->options['prefix']) === false) { $key = $this->options['prefix'] . '/' . $key; } return $key; } /** * Internal method to retrieve the raw cache value; * needs to return a Value object or null if not found; * this needs to be defined by the driver * * @param string $key * @return \Kirby\Cache\Value|null */ abstract public function retrieve(string $key); /** * Gets an item from the cache * * * // get an item from the cache driver * $value = $cache->get('value'); * * // return a default value if the requested item isn't cached * $value = $cache->get('value', 'default value'); * * * @param string $key * @param mixed $default * @return mixed */ public function get(string $key, $default = null) { // get the Value $value = $this->retrieve($key); // check for a valid cache value if (!is_a($value, 'Kirby\Cache\Value')) { return $default; } // remove the item if it is expired if ($value->expires() > 0 && time() >= $value->expires()) { $this->remove($key); return $default; } // return the pure value return $value->value(); } /** * Calculates the expiration timestamp * * @param int $minutes * @return int */ protected function expiration(int $minutes = 0): int { // 0 = keep forever if ($minutes === 0) { return 0; } // calculate the time return time() + ($minutes * 60); } /** * Checks when an item in the cache expires; * returns the expiry timestamp on success, null if the * item never expires and false if the item does not exist * * @param string $key * @return int|null|false */ public function expires(string $key) { // get the Value object $value = $this->retrieve($key); // check for a valid Value object if (!is_a($value, 'Kirby\Cache\Value')) { return false; } // return the expires timestamp return $value->expires(); } /** * Checks if an item in the cache is expired * * @param string $key * @return bool */ public function expired(string $key): bool { $expires = $this->expires($key); if ($expires === null) { return false; } elseif (!is_int($expires)) { return true; } else { return time() >= $expires; } } /** * Checks when the cache has been created; * returns the creation timestamp on success * and false if the item does not exist * * @param string $key * @return int|false */ public function created(string $key) { // get the Value object $value = $this->retrieve($key); // check for a valid Value object if (!is_a($value, 'Kirby\Cache\Value')) { return false; } // return the expires timestamp return $value->created(); } /** * Alternate version for Cache::created($key) * * @param string $key * @return int|false */ public function modified(string $key) { return static::created($key); } /** * Determines if an item exists in the cache * * @param string $key * @return bool */ public function exists(string $key): bool { return $this->expired($key) === false; } /** * Removes an item from the cache and returns * whether the operation was successful; * this needs to be defined by the driver * * @param string $key * @return bool */ abstract public function remove(string $key): bool; /** * Flushes the entire cache and returns * whether the operation was successful; * this needs to be defined by the driver * * @return bool */ abstract public function flush(): bool; /** * Returns all passed cache options * * @return array */ public function options(): array { return $this->options; } }