1<?php
2class memcache_fakecache implements memcache_interface{
3//	--- helper methods / properties ----
4	protected static $cache_dir, $ttl_dir;
5	/* prepares a key name to be valid filename */
6	protected static function normalize_key($key){
7		return preg_replace_callback('/(\W)/',
8			function($m){ return "-".ord($m[1])."-"; },
9			$key);
10	}
11	/* undos the filename normalization */
12	protected static function denormalize_key($key){
13		return preg_replace_callback('/-(\d+)-/',
14			function($m){ return chr($m[1]); },
15			$key);
16	}
17	public static function gc(){	// deletes all entries which are over of their TTL.
18		$dh = opendir(static::$ttl_dir);
19		while ($file = readdir($dh)){
20			if ($file == "." || $file == "..") continue;
21			if (file_get_contents(static::$ttl_dir.$file) < time()){
22				@unlink(static::$ttl_dir.$file);
23				@unlink(static::$cache_dir.$file);
24			}
25		}
26		closedir($dh);
27	}
28//	---- standard methods ----
29	public static function init(){
30		global $conf;
31		static::$cache_dir = $conf['tmpdir'].'/cachewrapper/';
32		static::$ttl_dir = $conf['tmpdir'].'/cachewrapper_ttl/';
33		if (!file_exists(static::$cache_dir)) mkdir(static::$cache_dir);
34		elseif (!is_dir(static::$cache_dir)) trigger_error("The cache directory '".static::$cache_dir."' is not a directory!",E_USER_ERROR);
35		if (!file_exists(static::$ttl_dir)) mkdir(static::$ttl_dir);
36		elseif (!is_dir(static::$ttl_dir)) trigger_error("The cache directory '".static::$cache_dir."' is not a directory!",E_USER_ERROR);
37		static::gc();
38		//register_shutdown_function(array(__CLASS__,'gc'));	// registering shutdown function to do garbage collections.
39	}
40
41	public static function emulated() { return true; }
42
43	public static function driver(){ return "fake";}
44
45	public static function add($key, $val,$ttl = 0){
46		if (MEMCACHE_CHECK_KEYS && !is_string($key)) trigger_error("The key needs to be string! (note: not even numbers are accepted)",E_USER_ERROR);
47		if ($result = (!file_exists(static::$cache_dir.static::normalize_key($key)) && @file_put_contents(static::$cache_dir.static::normalize_key($key),gzcompress(serialize($val),3)) !== false)){
48			if ($ttl > 0) 			file_put_contents(static::$ttl_dir.static::normalize_key($key),time()+$ttl);
49			else 					@unlink(static::$ttl_dir.static::normalize_key($key));
50		}
51		return (bool)$result;
52	}
53
54	public static function set($key, $val,$ttl = 0){
55		if (MEMCACHE_CHECK_KEYS && !is_string($key)) trigger_error("The key needs to be string! (note: not even numbers are accepted)",E_USER_ERROR);
56		if ($result = (@file_put_contents(static::$cache_dir.static::normalize_key($key),gzcompress(serialize($val),3)) !== false)){
57			if ($ttl > 0)			file_put_contents(static::$ttl_dir.static::normalize_key($key),time()+$ttl);
58			else 					@unlink(static::$ttl_dir.static::normalize_key($key));
59		}
60		return (bool)$result;
61	}
62
63	public static function exists($key){
64		if (MEMCACHE_CHECK_KEYS && !is_string($key)) trigger_error("The key needs to be string! (note: not even numbers are accepted)",E_USER_ERROR);
65		return file_exists(static::$cache_dir.static::normalize_key($key));
66	}
67
68	public static function del($key){
69		if (MEMCACHE_CHECK_KEYS && !is_string($key)) trigger_error("The key needs to be string! (note: not even numbers are accepted)",E_USER_ERROR);
70		@unlink(static::$ttl_dir.static::normalize_key($key));
71		return @unlink(static::$cache_dir.static::normalize_key($key));
72	}
73
74	public static function get($key,&$success = false){
75		if (MEMCACHE_CHECK_KEYS && !is_string($key)) trigger_error("The key needs to be string! (note: not even numbers are accepted)",E_USER_ERROR);
76		$val = null;
77		$success = (																						// success is based on evaluation order to detect unsuccessful event early and prevent later instructions
78				file_exists(static::$cache_dir.static::normalize_key($key)) 								// file exists? (if not, abort with fail, as in every other step bellow)
79				&& ($cnt = file_get_contents(static::$cache_dir.static::normalize_key($key))) !== false		// file can be read?
80				&& ($ucnt = @gzuncompress($cnt)) !== false													// file is uncompressable
81				&& (																						// the resulted var is:
82					($val = @unserialize($ucnt)) !== false 													// not boolean false
83					|| $ucnt == serialize(false)															// is boolean false, but it should be.
84					)
85			);
86		return $val;
87	}
88
89	public static function clear(){
90		$dh = opendir(static::$cache_dir);
91		while ($file = readdir($dh)){
92			if ($file == "." || $file == "..") continue;
93			@unlink(static::$cache_dir.$file);
94		}
95		closedir($dh);
96		$dh = opendir(static::$ttl_dir);
97		while ($file = readdir($dh)){
98			if ($file == "." || $file == "..") continue;
99			@unlink(static::$ttl_dir.$file);
100		}
101		closedir($dh);
102		return true;
103	}
104
105
106}
107
108memcache_fakecache::init();