1<?php
2	/* libraries/cache.php
3	 *
4	 * Copyright (C) by Hugo Leisink <hugo@leisink.net>
5	 * This file is part of the Banshee PHP framework
6	 * http://www.banshee-php.org/
7	 */
8
9	class cache {
10		private $db = null;
11		private $section = null;
12		private $cache = array();
13
14		/* Constructor
15		 *
16		 * INPUT:  object database, string section
17		 * OUTPUT: -
18		 * ERROR:  -
19		 */
20		public function __construct($db, $section) {
21			$this->db = $db;
22			$this->section = $section."_";
23		}
24
25		/* Magic method get
26		 *
27		 * INPUT:  string key
28		 * OUTPUT: mixed value
29		 * ERROR:  null
30		 */
31		public function __get($orig_key) {
32			$key = $this->section.$orig_key;
33
34			$now = time();
35
36			/* In memory cache?
37			 */
38			if (isset($this->cache[$key])) {
39				if ($now > $this->cache[$key]["timeout"]) {
40					$this->delete($orig_key);
41					return null;
42				}
43
44				return $this->cache[$key]["value"];
45			}
46
47			/* Fetch from database
48			 */
49			$query = "select value, UNIX_TIMESTAMP(timeout) as timeout ".
50			         "from cache where %S=%s limit 1";
51			if (($result = $this->db->execute($query, "key", $key)) == false) {
52				return null;
53			}
54
55			$value = json_decode($result[0]["value"], true);
56			$timeout = (int)$result[0]["timeout"];
57
58			/* Timeout?
59			 */
60			if ($now > $timeout) {
61				$this->delete($orig_key);
62				return null;
63			}
64
65			$this->cache[$key] = array(
66				"value"   => $value,
67				"timeout" => $timeout);
68
69			return $value;
70		}
71
72		/* Magic method set
73		 *
74		 * INPUT:  string key, string value
75		 * OUTPUT: -
76		 * ERROR:  -
77		 */
78		public function __set($key, $value) {
79			$this->store($key, $value, CACHE_TIMEOUT);
80		}
81
82		/* Store data in cache
83		 *
84		 * INPUT:  string key, mixed value[, int timeout]
85		 * OUTPUT: true
86		 * ERROR:  false
87		 */
88		public function store($key, $value, $timeout = null) {
89			if ($this->delete($key) == false) {
90				return false;
91			} else if ($value === null) {
92				return true;
93			}
94
95			$key = $this->section.$key;
96
97			if ($timeout === null) {
98				$timeout = CACHE_TIMEOUT;
99			} else if ((int)$timeout <= 0) {
100				return false;
101			}
102			$timeout += time();
103
104			$data = array(
105				"key"     => $key,
106				"value"   => json_encode($value),
107				"timeout" => date("Y-m-d H:i:s", $timeout));
108
109			if ($this->db->insert("cache", $data) === false) {
110				return false;
111			}
112
113			$this->cache[$key] = array(
114				"value"   => $value,
115				"timeout" => $timeout);
116
117			return true;
118		}
119
120		/* Delete key
121		 *
122		 * INPUT:  string key
123		 * OUTPUT: true
124		 * ERROR:  false
125		 */
126		private function delete($key) {
127			$key = $this->section.$key;
128
129			if (isset($this->cache[$key])) {
130				unset($this->cache[$key]);
131			}
132
133			$query = "delete from cache where %S=%s limit 1";
134			return $this->db->query($query, "key", $key) !== false;
135		}
136	}
137?>
138