<?php
namespace CCDN\Helpers;
use FilesystemIterator;
/**
* Class Cache
* This class save cache only in file and save only string data
*
* @package CCDN\Helpers
*/
class Cache
{
/**
* @var string Path to DLE cache folder
*/
private $folder = ENGINE_DIR.'/cache';
/**
* @var string
*/
private $fileExtension = '.bin';
/**
* @var string
*/
private $prefix;
/**
* @var FilesystemIterator
*/
private $filesystemIterator;
/**
* Cache constructor.
*/
public function __construct()
{
$version = str_replace('.', '_', Settings::PLUGIN_VERSION);
$this->prefix = Settings::PLUGIN_NAME.'_'.$version.'_';
$this->filesystemIterator = new FilesystemIterator($this->folder);
}
/**
* Fetches a value from the cache.
*
* @param string $key The unique key of this item in the cache.
* @param mixed $default Default value to return if the key does not exist.
*
* @return string|null The value of the item from the cache, or $default in case of cache miss.
*/
public function get($key, $default = null)
{
$cacheFile = $this->getFilePath($key);
if (@filemtime($cacheFile) > time()) {
$fp = @fopen($cacheFile, 'rb');
if ($fp !== false) {
@flock($fp, LOCK_SH);
$cacheValue = @stream_get_contents($fp);
@flock($fp, LOCK_UN);
@fclose($fp);
return $cacheValue !== false ? $cacheValue : $default;
}
}
return $default;
}
/**
* Return full path to cache file
*
* @param string $key
*
* @return string
*/
protected function getFilePath($key)
{
$key = $this->buildKey($key);
return $this->folder.'/'.$key.$this->fileExtension;
}
/**
* @param string $key
*
* @return string
*/
protected function buildKey($key)
{
return $this->prefix.md5($key);
}
/**
* Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
*
* @param string $key The key of the item to store.
* @param string $value The value of the item to store. Must be string.
* @param int $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*/
public function set($key, $value, $ttl = 0)
{
$this->gc();
$cacheFile = $this->getFilePath($key);
if (is_file($cacheFile)) {
@unlink($cacheFile);
}
if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) {
@chmod($cacheFile, 0666);
if ($ttl <= 0) {
$ttl = 31536000;
}
return @touch($cacheFile, $ttl + time());
}
return false;
}
/**
* Garbage collector Removing expired cache files under a directory.
*
* @return void
*/
protected function gc()
{
$time = time();
foreach ($this->filesystemIterator as $file) {
if ($file->isDir() || strpos($file->getFilename(), $this->prefix) === false) {
continue;
}
if ($file->getMTime() < $time) {
@unlink($file->getRealPath());
}
}
}
/**
* Determines whether an item is present in the cache.
*
* @param string $key The cache item key.
*
* @return bool
*/
public function has($key)
{
return @filemtime($this->getFilePath($key)) > time();
}
/**
* Wipes all cache.
*
* @return bool True on success and false on failure.
*/
public function clear()
{
foreach ($this->filesystemIterator as $file) {
if ($file->isDir() || strpos($file->getFilename(), $this->prefix) === false) {
continue;
}
@unlink($file->getPathname());
}
return true;
}
/**
* Delete cache file by key
*
* @param $key
* @return bool
*/
public function delete($key)
{
return @unlink($this->getFilePath($key));
}
}