|
|
@ -14,22 +14,61 @@ |
|
|
|
final class Cache |
|
|
|
{ |
|
|
|
private $cache_file; |
|
|
|
private $cache_folder; |
|
|
|
private $cache_time; |
|
|
|
|
|
|
|
private $mode = 0777; |
|
|
|
private $infofile = '_infofile'; |
|
|
|
|
|
|
|
const HASH_ENABLE = true; |
|
|
|
|
|
|
|
function __construct($cache_name, $cache_time) |
|
|
|
{ |
|
|
|
if (!preg_match('/[a-zA-Z0-9_]/', $cache_name)) { |
|
|
|
throw new MJException('Wrong cache identifier "'.$cache_name.'". Must use only [a-zA-Z0-9_]'); |
|
|
|
} |
|
|
|
|
|
|
|
if ($cache_name == $this->infofile) { |
|
|
|
throw new MJException('Name "'.$this->infofile.'" is reserved. Try another one.'); |
|
|
|
} |
|
|
|
|
|
|
|
if ($cache_time == 0) { |
|
|
|
throw new MJException('cache_time must be non-zero'); |
|
|
|
} |
|
|
|
|
|
|
|
if ($cache_time > 86400) { |
|
|
|
throw new MJException('cache_time cannot be greater than 86400 sec (24 hours)'); |
|
|
|
} |
|
|
|
|
|
|
|
if (substr($cache_name, 0, 1) == '_') { |
|
|
|
$this->cache_folder = CACHE_PATH; |
|
|
|
} else { |
|
|
|
$parts = explode('_', $cache_name, 2); |
|
|
|
$this->cache_folder = CACHE_PATH.'/'.(isset($parts[1]) ? $parts[0] : '_all'); |
|
|
|
if (self::HASH_ENABLE) { |
|
|
|
$hash = md5($cache_name); |
|
|
|
$this->cache_folder .= '/'.substr($hash, 0, 1).'/'.substr($hash, 0, 2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$this->cache_file = $this->cache_folder.'/'.$cache_name; |
|
|
|
if (!is_writable($this->cache_folder)) { |
|
|
|
mkdir($this->cache_folder, $this->mode, true); |
|
|
|
} |
|
|
|
|
|
|
|
$this->cache_time = (int) $cache_time; |
|
|
|
$this->cache_file = CACHE_PATH.'/'.$cache_name; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Сохраняет кэш в файл |
|
|
|
* |
|
|
|
* @param string/array $data - строка (либо одномерный массив) сохраняемых данных |
|
|
|
* @return boolean - сохранил или нет |
|
|
|
*/ |
|
|
|
function save($data) |
|
|
|
{ |
|
|
|
if ($this->cache_time != 0) { |
|
|
|
if ($this->cache_time != 0 && is_writable($this->cache_folder)) { |
|
|
|
$this->clearOld(); //очистка старых файлов.
|
|
|
|
return (bool) file_put_contents($this->cache_file, $data); |
|
|
|
} |
|
|
|
return false; |
|
|
@ -42,9 +81,16 @@ final class Cache |
|
|
|
*/ |
|
|
|
function load() |
|
|
|
{ |
|
|
|
if ($this->cache_time != 0) { |
|
|
|
return file_get_contents($this->cache_file); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Принудительно очистить кеш |
|
|
|
* |
|
|
|
*/ |
|
|
|
function reset() |
|
|
|
{ |
|
|
|
@unlink($this->cache_file); |
|
|
@ -57,13 +103,26 @@ final class Cache |
|
|
|
*/ |
|
|
|
function isCached() |
|
|
|
{ |
|
|
|
if (! file_exists($this->cache_file)) { |
|
|
|
return false; |
|
|
|
if (is_readable($this->cache_file)) { |
|
|
|
if ($this->cache_time < 0 || $this->cache_time + filemtime($this->cache_file) > time()) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
$this->reset(); //удалим просроченый файл
|
|
|
|
} |
|
|
|
if ($this->cache_time > 0 && $this->cache_time + filemtime($this->cache_file) < TIME_NOW) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
|
|
|
|
/** |
|
|
|
* Удаление файлов старше суток |
|
|
|
* |
|
|
|
*/ |
|
|
|
function clearOld() |
|
|
|
{ |
|
|
|
$file = CACHE_PATH.'/'.$this->infofile; |
|
|
|
if (!file_exists($file) || date('Ymd', filemtime($file)) != date('Ymd')) { |
|
|
|
exec('find '.CACHE_PATH.'/ -mtime +1 -delete'); //не удаляет папки сохраняя структуру
|
|
|
|
touch($file); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|