diff --git a/classes/Cache.class.php b/classes/Cache.class.php index 4770abe..1754e7f 100644 --- a/classes/Cache.class.php +++ b/classes/Cache.class.php @@ -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() { - return file_get_contents($this->cache_file); + 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 false; + } + + /** + * Удаление файлов старше суток + * + */ + 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); } - return true; } }