aboutsummaryrefslogtreecommitdiff
path: root/engine/classes/ElggFileCache.php
diff options
context:
space:
mode:
Diffstat (limited to 'engine/classes/ElggFileCache.php')
-rw-r--r--engine/classes/ElggFileCache.php224
1 files changed, 224 insertions, 0 deletions
diff --git a/engine/classes/ElggFileCache.php b/engine/classes/ElggFileCache.php
new file mode 100644
index 000000000..34178d452
--- /dev/null
+++ b/engine/classes/ElggFileCache.php
@@ -0,0 +1,224 @@
+<?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.
+ */
+ 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'));
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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
+ }
+ }
+ }
+}