diff options
Diffstat (limited to 'engine/classes/ElggFileCache.php')
-rw-r--r-- | engine/classes/ElggFileCache.php | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/engine/classes/ElggFileCache.php b/engine/classes/ElggFileCache.php new file mode 100644 index 000000000..94143f777 --- /dev/null +++ b/engine/classes/ElggFileCache.php @@ -0,0 +1,230 @@ +<?php +/** + * ElggFileCache + * Store cached data in a file store. + * + * @package Elgg.Core + * @subpackage Caches + */ +class ElggFileCache extends ElggCache { + /** + * Set the Elgg cache. + * + * @param string $cache_path The cache path. + * @param int $max_age Maximum age in seconds, 0 if no limit. + * @param int $max_size Maximum size of cache in seconds, 0 if no limit. + * + * @throws ConfigurationException + */ + function __construct($cache_path, $max_age = 0, $max_size = 0) { + $this->setVariable("cache_path", $cache_path); + $this->setVariable("max_age", $max_age); + $this->setVariable("max_size", $max_size); + + if ($cache_path == "") { + throw new ConfigurationException(elgg_echo('ConfigurationException:NoCachePath')); + } + } + + // @codingStandardsIgnoreStart + /** + * Create and return a handle to a file. + * + * @deprecated 1.8 Use ElggFileCache::createFile() + * + * @param string $filename Filename to save as + * @param string $rw Write mode + * + * @return mixed + */ + protected function create_file($filename, $rw = "rb") { + elgg_deprecated_notice('ElggFileCache::create_file() is deprecated by ::createFile()', 1.8); + + return $this->createFile($filename, $rw); + } + // @codingStandardsIgnoreEnd + + /** + * Create and return a handle to a file. + * + * @param string $filename Filename to save as + * @param string $rw Write mode + * + * @return mixed + */ + protected function createFile($filename, $rw = "rb") { + // Create a filename matrix + $matrix = ""; + $depth = strlen($filename); + if ($depth > 5) { + $depth = 5; + } + + // Create full path + $path = $this->getVariable("cache_path") . $matrix; + if (!is_dir($path)) { + mkdir($path, 0700, true); + } + + // Open the file + if ((!file_exists($path . $filename)) && ($rw == "rb")) { + return false; + } + + return fopen($path . $filename, $rw); + } + + // @codingStandardsIgnoreStart + /** + * Create a sanitised filename for the file. + * + * @deprecated 1.8 Use ElggFileCache::sanitizeFilename() + * + * @param string $filename The filename + * + * @return string + */ + protected function sanitise_filename($filename) { + // @todo : Writeme + + return $filename; + } + // @codingStandardsIgnoreEnd + + /** + * Create a sanitised filename for the file. + * + * @param string $filename The filename + * + * @return string + */ + protected function sanitizeFilename($filename) { + // @todo : Writeme + + return $filename; + } + + /** + * Save a key + * + * @param string $key Name + * @param string $data Value + * + * @return boolean + */ + public function save($key, $data) { + $f = $this->createFile($this->sanitizeFilename($key), "wb"); + if ($f) { + $result = fwrite($f, $data); + fclose($f); + + return $result; + } + + return false; + } + + /** + * Load a key + * + * @param string $key Name + * @param int $offset Offset + * @param int $limit Limit + * + * @return string + */ + public function load($key, $offset = 0, $limit = null) { + $f = $this->createFile($this->sanitizeFilename($key)); + if ($f) { + if (!$limit) { + $limit = -1; + } + + $data = stream_get_contents($f, $limit, $offset); + + fclose($f); + + return $data; + } + + return false; + } + + /** + * Invalidate a given key. + * + * @param string $key Name + * + * @return bool + */ + public function delete($key) { + $dir = $this->getVariable("cache_path"); + + if (file_exists($dir . $key)) { + return unlink($dir . $key); + } + return TRUE; + } + + /** + * Delete all files in the directory of this file cache + * + * @return void + */ + public function clear() { + $dir = $this->getVariable("cache_path"); + + $exclude = array(".", ".."); + + $files = scandir($dir); + if (!$files) { + return; + } + + foreach ($files as $f) { + if (!in_array($f, $exclude)) { + unlink($dir . $f); + } + } + } + + /** + * Preform cleanup and invalidates cache upon object destruction + * + * @throws IOException + */ + public function __destruct() { + // @todo Check size and age, clean up accordingly + $size = 0; + $dir = $this->getVariable("cache_path"); + + // Short circuit if both size and age are unlimited + if (($this->getVariable("max_age") == 0) && ($this->getVariable("max_size") == 0)) { + return; + } + + $exclude = array(".", ".."); + + $files = scandir($dir); + if (!$files) { + throw new IOException(elgg_echo('IOException:NotDirectory', array($dir))); + } + + // Perform cleanup + foreach ($files as $f) { + if (!in_array($f, $exclude)) { + $stat = stat($dir . $f); + + // Add size + $size .= $stat['size']; + + // Is this older than my maximum date? + if (($this->getVariable("max_age") > 0) && (time() - $stat['mtime'] > $this->getVariable("max_age"))) { + unlink($dir . $f); + } + + // @todo Size + } + } + } +} |