diff options
Diffstat (limited to 'engine/lib')
| -rw-r--r-- | engine/lib/cache.php | 805 | 
1 files changed, 400 insertions, 405 deletions
diff --git a/engine/lib/cache.php b/engine/lib/cache.php index e7ed6c73c..fd13bf3c7 100644 --- a/engine/lib/cache.php +++ b/engine/lib/cache.php @@ -1,439 +1,434 @@  <?php +/** + * Elgg cache + * Cache file interface for caching data. + * + * @package Elgg + * @subpackage API + * @author Curverider Ltd <info@elgg.com> + * @link http://elgg.org/ + */ + +/** + * ElggCache The elgg cache superclass. + * This defines the interface for a cache (wherever that cache is stored). + * + * @author Curverider Ltd <info@elgg.com> + * @package Elgg + * @subpackage API + */ +abstract class ElggCache implements +	// Override for array access +	ArrayAccess  {  	/** -	 * Elgg cache -	 * Cache file interface for caching data. -	 *  -	 * @package Elgg -	 * @subpackage API -	 * @author Curverider Ltd <info@elgg.com> -	 * @link http://elgg.org/ +	 * Variables for the cache object. +	 * +	 * @var array  	 */ +	private $variables;  	/** -	 * ElggCache The elgg cache superclass. -	 * This defines the interface for a cache (wherever that cache is stored). -	 *  -	 * @author Curverider Ltd <info@elgg.com> -	 * @package Elgg -	 * @subpackage API +	 * Set the constructor.  	 */ -	abstract class ElggCache implements -		ArrayAccess // Override for array access -	{ -		/** -		 * Variables for the cache object. -		 * -		 * @var array -		 */ -		private $variables; -		 -		/** -		 * Set the constructor. -		 */ -		function __construct() { $this->variables = array(); } -		 -		/** -		 * Set a cache variable. -		 * -		 * @param string $variable -		 * @param string $value -		 */ -		public function set_variable($variable, $value)  -		{ -			if (!is_array($this->variables)) -				$this->variables = array(); -			 -			$this->variables[$variable] = $value;	 -		} -		 -		/** -		 * Get variables for this cache. -		 * -		 * @param string $variable -		 * @return mixed The variable or null; -		 */ -		public function get_variable($variable)  -		{ -			if (isset($this->variables[$variable])) -				return $this->variables[$variable]; -				 -			return null;  +	function __construct() { +		$this->variables = array(); +	} + +	/** +	 * Set a cache variable. +	 * +	 * @param string $variable +	 * @param string $value +	 */ +	public function set_variable($variable, $value) { +		if (!is_array($this->variables)) { +			$this->variables = array();  		} -		 -		/** -		 * Class member get overloading, returning key using $this->load defaults. -		 * -		 * @param string $key -		 * @return mixed -		 */ -		function __get($key) { return $this->load($key); } -		 -		/** -		 * Class member set overloading, setting a key using $this->save defaults. -		 * -		 * @param string $key -		 * @param mixed $value -		 * @return mixed -		 */ -		function __set($key, $value) { return $this->save($key, $value); } -		 -		/** -		 * Supporting isset, using $this->load() with default values. -		 * -		 * @param string $key The name of the attribute or metadata. -		 * @return bool -		 */ -		function __isset($key) { return (bool)$this->load($key); } -		 -		/** -		 * Supporting unsetting of magic attributes. -		 * -		 * @param string $key The name of the attribute or metadata. -		 */ -		function __unset($key) { return $this->delete($key); } -		 -		/** -		 * Save data in a cache. -		 * -		 * @param string $key -		 * @param string $data -		 * @return bool -		 */ -		abstract public function save($key, $data); -		 -		/** -		 * Load data from the cache using a given key. -		 * -		 * @param string $key -		 * @param int $offset  -		 * @param int $limit -		 * @return mixed The stored data or false. -		 */ -		abstract public function load($key, $offset = 0, $limit = null); -		 -		/** -		 * Invalidate a key -		 * -		 * @param string $key -		 * @return bool -		 */ -		abstract public function delete($key); -		 -		/** -		 * Clear out all the contents of the cache. -		 * -		 */ -		abstract public function clear(); -		 -		/** -		 * Add a key only if it doesn't already exist.  -		 * Implemented simply here, if you extend this class and your caching engine provides a better way then  -		 * override this accordingly. -		 * -		 * @param string $key -		 * @param string $data -		 * @return bool -		 */ -		public function add($key, $data) -		{ -			if (!isset($this[$key]))  -				return $this->save($key, $data); -				 -			return false; + +		$this->variables[$variable] = $value; +	} + +	/** +	 * Get variables for this cache. +	 * +	 * @param string $variable +	 * @return mixed The variable or null; +	 */ +	public function get_variable($variable) { +		if (isset($this->variables[$variable])) { +			return $this->variables[$variable];  		} -		 -		// ARRAY ACCESS INTERFACE ////////////////////////////////////////////////////////// -		function offsetSet($key, $value) -		{ -     		$this->save($key, $value); - 		}  - 		 - 		function offsetGet($key)  - 		{ -   			return $this->load($key); - 		}  - 		 - 		function offsetUnset($key)  - 		{ -   			if ( isset($this->key) ) { -     			unset($this->key); -   			} - 		}  - 		 - 		function offsetExists($offset)  - 		{ -   			return isset($this->$offset); - 		}  + +		return null;  	} -	 +  	/** -	 * Shared memory cache description. -	 * Extends ElggCache with functions useful to shared memory style caches (static variables, memcache etc) +	 * Class member get overloading, returning key using $this->load defaults. +	 * +	 * @param string $key +	 * @return mixed  	 */ -	abstract class ElggSharedMemoryCache extends ElggCache -	{ -		/** -		 * Namespace variable used to keep various bits of the cache -		 * separate. -		 * -		 * @var string -		 */ -		private $namespace; -		 -		/** -		 * Set the namespace of this cache. -		 * This is useful for cache types (like memcache or static variables) where there is one large -		 * flat area of memory shared across all instances of the cache. -		 * -		 * @param string $namespace -		 */ -		public function setNamespace($namespace = "default") { $this->namespace = $namespace; } -		/** -		 * Get the namespace currently defined. -		 * -		 * @return string -		 */ -		public function getNamespace() { return $this->namespace; } +	function __get($key) { +		return $this->load($key);  	} -	 +  	/** -	 * ElggStaticVariableCache -	 * Dummy cache which stores values in a static array. Using this makes future replacements to other caching back  -	 * ends (eg memcache) much easier. -	 *  -	 * @author Curverider Ltd <info@elgg.com> -	 * @package Elgg -	 * @subpackage API +	 * Class member set overloading, setting a key using $this->save defaults. +	 * +	 * @param string $key +	 * @param mixed $value +	 * @return mixed  	 */ -	class ElggStaticVariableCache extends ElggSharedMemoryCache -	{ -		/** -		 * The cache. -		 * -		 * @var unknown_type -		 */ -		private static $__cache; -		 -		/** -		 * Create the variable cache. -		 *  -		 * This function creates a variable cache in a static variable in memory, optionally with a given namespace (to avoid overlap). -		 * -		 * @param string $namespace The namespace for this cache to write to - note, namespaces of the same name are shared! -		 */ -		function __construct($namespace = 'default') -		{	 -			$this->setNamespace($namespace); -			$this->clear(); -		} -		 -		public function save($key, $data)  -		{ -			$namespace = $this->getNamespace(); -			 -			ElggStaticVariableCache::$__cache[$namespace][$key] = $data; -			 -			return true; +	function __set($key, $value) { +		return $this->save($key, $value); +	} + +	/** +	 * Supporting isset, using $this->load() with default values. +	 * +	 * @param string $key The name of the attribute or metadata. +	 * @return bool +	 */ +	function __isset($key) { +		return (bool)$this->load($key); +	} + +	/** +	 * Supporting unsetting of magic attributes. +	 * +	 * @param string $key The name of the attribute or metadata. +	 */ +	function __unset($key) { +		return $this->delete($key); +	} + +	/** +	 * Save data in a cache. +	 * +	 * @param string $key +	 * @param string $data +	 * @return bool +	 */ +	abstract public function save($key, $data); + +	/** +	 * Load data from the cache using a given key. +	 * +	 * @param string $key +	 * @param int $offset +	 * @param int $limit +	 * @return mixed The stored data or false. +	 */ +	abstract public function load($key, $offset = 0, $limit = null); + +	/** +	 * Invalidate a key +	 * +	 * @param string $key +	 * @return bool +	 */ +	abstract public function delete($key); + +	/** +	 * Clear out all the contents of the cache. +	 * +	 */ +	abstract public function clear(); + +	/** +	 * Add a key only if it doesn't already exist. +	 * Implemented simply here, if you extend this class and your caching engine provides a better way then +	 * override this accordingly. +	 * +	 * @param string $key +	 * @param string $data +	 * @return bool +	 */ +	public function add($key, $data) { +		if (!isset($this[$key])) { +			return $this->save($key, $data);  		} -		 -		public function load($key, $offset = 0, $limit = null) -		{ -			$namespace = $this->getNamespace(); -			 -			if (isset(ElggStaticVariableCache::$__cache[$namespace][$key])) -				return ElggStaticVariableCache::$__cache[$namespace][$key]; -				 -			return false; + +		return false; +	} + +	// ARRAY ACCESS INTERFACE ////////////////////////////////////////////////////////// +	function offsetSet($key, $value) { +		$this->save($key, $value); +	} + +	function offsetGet($key) { +		return $this->load($key); +	} + +	function offsetUnset($key) { +		if ( isset($this->key) ) { +			unset($this->key);  		} -		 -		public function delete($key)  -		{ -			$namespace = $this->getNamespace(); -			 -			unset(ElggStaticVariableCache::$__cache[$namespace][$key]); -			 -			return true; +	} + +	function offsetExists($offset) { +		return isset($this->$offset); +	} +} + +/** + * Shared memory cache description. + * Extends ElggCache with functions useful to shared memory style caches (static variables, memcache etc) + */ +abstract class ElggSharedMemoryCache extends ElggCache { +	/** +	 * Namespace variable used to keep various bits of the cache +	 * separate. +	 * +	 * @var string +	 */ +	private $namespace; + +	/** +	 * Set the namespace of this cache. +	 * This is useful for cache types (like memcache or static variables) where there is one large +	 * flat area of memory shared across all instances of the cache. +	 * +	 * @param string $namespace +	 */ +	public function setNamespace($namespace = "default") { +		$this->namespace = $namespace; +	} + +	/** +	 * Get the namespace currently defined. +	 * +	 * @return string +	 */ +	public function getNamespace() { +		return $this->namespace; +	} +} + +/** + * ElggStaticVariableCache + * Dummy cache which stores values in a static array. Using this makes future replacements to other caching back + * ends (eg memcache) much easier. + * + * @author Curverider Ltd <info@elgg.com> + * @package Elgg + * @subpackage API + */ +class ElggStaticVariableCache extends ElggSharedMemoryCache { +	/** +	 * The cache. +	 * +	 * @var unknown_type +	 */ +	private static $__cache; + +	/** +	 * Create the variable cache. +	 * +	 * This function creates a variable cache in a static variable in memory, optionally with a given namespace (to avoid overlap). +	 * +	 * @param string $namespace The namespace for this cache to write to - note, namespaces of the same name are shared! +	 */ +	function __construct($namespace = 'default') { +		$this->setNamespace($namespace); +		$this->clear(); +	} + +	public function save($key, $data) { +		$namespace = $this->getNamespace(); + +		ElggStaticVariableCache::$__cache[$namespace][$key] = $data; + +		return true; +	} + +	public function load($key, $offset = 0, $limit = null) { +		$namespace = $this->getNamespace(); + +		if (isset(ElggStaticVariableCache::$__cache[$namespace][$key])) { +			return ElggStaticVariableCache::$__cache[$namespace][$key];  		} -		 -		public function clear() -		{ -			$namespace = $this->getNamespace(); -			 -			if (!isset(ElggStaticVariableCache::$__cache)) -				ElggStaticVariableCache::$__cache = array(); -				 -			//if (!isset(ElggStaticVariableCache::$__cache[$namespace])) -				ElggStaticVariableCache::$__cache[$namespace] = array(); + +		return false; +	} + +	public function delete($key) { +		$namespace = $this->getNamespace(); + +		unset(ElggStaticVariableCache::$__cache[$namespace][$key]); + +		return true; +	} + +	public function clear() { +		$namespace = $this->getNamespace(); + +		if (!isset(ElggStaticVariableCache::$__cache)) { +			ElggStaticVariableCache::$__cache = array();  		} + +		ElggStaticVariableCache::$__cache[$namespace] = array();  	} -	 +} + +/** + * ElggFileCache + * Store cached data in a file store. + * + * @author Curverider Ltd <info@elgg.com> + * @package Elgg + * @subpackage API + */ +class ElggFileCache extends ElggCache {  	/** -	 * ElggFileCache -	 * Store cached data in a file store. -	 *  -	 * @author Curverider Ltd <info@elgg.com> -	 * @package Elgg -	 * @subpackage API +	 * 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.  	 */ -	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->set_variable("cache_path", $cache_path); -			$this->set_variable("max_age", $max_age); -			$this->set_variable("max_size", $max_size);	 - -			if ($cache_path=="") throw new ConfigurationException(elgg_echo('ConfigurationException:NoCachePath')); +	function __construct($cache_path, $max_age = 0, $max_size = 0) { +		$this->set_variable("cache_path", $cache_path); +		$this->set_variable("max_age", $max_age); +		$this->set_variable("max_size", $max_size); + +		if ($cache_path=="") { +			throw new ConfigurationException(elgg_echo('ConfigurationException:NoCachePath'));  		} -		 -		/** -		 * Create and return a handle to a file. -		 * -		 * @param string $filename -		 * @param string $rw -		 */ -		protected function create_file($filename, $rw = "rb") -		{ -			// Create a filename matrix -			$matrix = ""; -			$depth = strlen($filename); -			if ($depth > 5) $depth = 5; -			  -		//	for ($n = 0; $n < $depth; $n++) -		//		$matrix .= $filename[$n] . "/";	 -				 -			// Create full path -			$path = $this->get_variable("cache_path") . $matrix; -			if (!is_dir($path)) -				mkdir($path, 0700, true); -			 -	//		if (!mkdir($path, 0700, true)) throw new IOException("Could not make $path"); -			 -			// Open the file -			if ((!file_exists($path . $filename)) && ($rw=="rb")) return false; -			 -			return fopen($path . $filename, $rw); +	} + +	/** +	 * Create and return a handle to a file. +	 * +	 * @param string $filename +	 * @param string $rw +	 */ +	protected function create_file($filename, $rw = "rb") { +		// Create a filename matrix +		$matrix = ""; +		$depth = strlen($filename); +		if ($depth > 5) { +			$depth = 5;  		} -		 -		/** -		 * Create a sanitised filename for the file. -		 * -		 * @param string $filename -		 */ -		protected function sanitise_filename($filename) -		{ -			// TODO : Writeme - -			return $filename; + +		// Create full path +		$path = $this->get_variable("cache_path") . $matrix; +		if (!is_dir($path)) { +			mkdir($path, 0700, true);  		} -		 -		/** -		 * Save a key -		 * -		 * @param string $key -		 * @param string $data -		 * @return boolean -		 */ -		public function save($key, $data) -		{ -			$f = $this->create_file($this->sanitise_filename($key), "wb"); -			if ($f) -			{ -				$result = fwrite($f, $data); -				fclose($f); -				 -				return $result; -			} -			 + +		// Open the file +		if ((!file_exists($path . $filename)) && ($rw=="rb")) {  			return false;  		} -		 -		/** -		 * Load a key -		 * -		 * @param string $key -		 * @param int $offset -		 * @param int $limit -		 * @return string -		 */ -		public function load($key, $offset = 0, $limit = null) -		{ -			$f = $this->create_file($this->sanitise_filename($key)); -			if ($f)  -			{ -				//fseek($f, $offset); -				if (!$limit) $limit = -1; -				$data = stream_get_contents($f, $limit, $offset); -				 -				fclose($f); -				 -				return $data; + +		return fopen($path . $filename, $rw); +	} + +	/** +	 * Create a sanitised filename for the file. +	 * +	 * @param string $filename +	 */ +	protected function sanitise_filename($filename) { +		// TODO : Writeme + +		return $filename; +	} + +	/** +	 * Save a key +	 * +	 * @param string $key +	 * @param string $data +	 * @return boolean +	 */ +	public function save($key, $data) { +		$f = $this->create_file($this->sanitise_filename($key), "wb"); +		if ($f) { +			$result = fwrite($f, $data); +			fclose($f); + +			return $result; +		} + +		return false; +	} + +	/** +	 * Load a key +	 * +	 * @param string $key +	 * @param int $offset +	 * @param int $limit +	 * @return string +	 */ +	public function load($key, $offset = 0, $limit = null) { +		$f = $this->create_file($this->sanitise_filename($key)); +		if ($f) { +			//fseek($f, $offset); +			if (!$limit) { +				$limit = -1;  			} -			 -			return false; +			$data = stream_get_contents($f, $limit, $offset); + +			fclose($f); + +			return $data;  		} -		 -		/** -		 * Invalidate a given key. -		 * -		 * @param string $key -		 * @return bool -		 */ -		public function delete($key) -		{ -			$dir = $this->get_variable("cache_path"); -			 -			return unlink($dir.$key); + +		return false; +	} + +	/** +	 * Invalidate a given key. +	 * +	 * @param string $key +	 * @return bool +	 */ +	public function delete($key) { +		$dir = $this->get_variable("cache_path"); + +		return unlink($dir.$key); +	} + +	public function clear() { +		// TODO : writeme +	} + +	public function __destruct() { +		// TODO: Check size and age, clean up accordingly +		$size = 0; +		$dir = $this->get_variable("cache_path"); + +		// Short circuit if both size and age are unlimited +		if (($this->get_variable("max_age")==0) && ($this->get_variable("max_size")==0)) { +			return;  		} -		 -		public function clear() -		{ -			// TODO : writeme + +		$exclude = array(".",".."); + +		$files = scandir($dir); +		if (!$files) { +			throw new IOException(sprintf(elgg_echo('IOException:NotDirectory'), $dir));  		} -		 -		public function __destruct() -		{ -			// TODO: Check size and age, clean up accordingly -			$size = 0; -			$dir = $this->get_variable("cache_path"); -			 -			// Short circuit if both size and age are unlimited -			if (($this->get_variable("max_age")==0) && ($this->get_variable("max_size")==0)) -				return; -			 -			$exclude = array(".",".."); -			 -			$files = scandir($dir); -			if (!$files) throw new IOException(sprintf(elgg_echo('IOException:NotDirectory'), $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->get_variable("max_age")>0) && (time() - $stat['mtime'] > $this->get_variable("max_age"))) -						unlink($dir.$f); -					 -					 -					 -					// TODO: Size -					 + +		// 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->get_variable("max_age")>0) && (time() - $stat['mtime'] > $this->get_variable("max_age"))) { +					unlink($dir.$f);  				} + +				// TODO: Size  			}  		}  	} -	 -?> +}  | 
