1 <?php
2
3 namespace Alo\Cache;
4
5 use Alo;
6
7 if (!defined('GEN_START')) {
8 http_response_code(404);
9 } else {
10 /**
11 * The abstract cache class
12 *
13 * @author Art <a.molcanovas@gmail.com>
14 * @package Cache
15 */
16 abstract class AbstractCache {
17
18 /**
19 * Static reference to the last instance of the class
20 *
21 * @var AbstractCache
22 */
23 static $this;
24 /**
25 * Classes to check in "isAvailable()"
26 *
27 * @var array
28 */
29 private static $classes = ['Memcache', 'Memcached', 'Redis'];
30 /**
31 * The abstract client
32 *
33 * @var \Redis|\Memcache|\Memcached
34 */
35 protected $client;
36
37 /**
38 * Instantiates the class
39 *
40 * @author Art <a.molcanovas@gmail.com>
41 */
42 function __construct() {
43 if (!Alo::$cache) {
44 Alo::$cache = &$this;
45 }
46
47 self::$this = &$this;
48 }
49
50 /**
51 * Checks if a caching extension is available
52 *
53 * @author Art <a.molcanovas@gmail.com>
54 * @return boolean
55 */
56 static function isAvailable() {
57 foreach (self::$classes as $class) {
58 if (class_exists('\\' . $class)) {
59 return true;
60 }
61 }
62
63 return false;
64 }
65
66 /**
67 * Calls a method of the caching client
68 *
69 * @author Art <a.molcanovas@gmail.com>
70 *
71 * @param string $method The method
72 * @param array $args Method args
73 *
74 * @return mixed Whatever the method returns
75 */
76 function __call($method, $args) {
77 return call_user_func_array([$this->client, $method], $args);
78 }
79
80 /**
81 * Key getter
82 *
83 * @author Art <a.molcanovas@gmail.com>
84 *
85 * @param string $key The key
86 *
87 * @return mixed
88 */
89 function __get($key) {
90 return $this->get($key);
91 }
92
93 /**
94 * Sets a value with its default expiration time
95 *
96 * @author Art <a.molcanovas@gmail.com>
97 *
98 * @param string $key The key
99 * @param mixed $val The value
100 *
101 * @return bool
102 */
103 function __set($key, $val) {
104 return $this->set($key, $val);
105 }
106
107 /**
108 * Gets a cached value
109 *
110 * @author Art <a.molcanovas@gmail.com>
111 *
112 * @param string $id The value's key
113 *
114 * @return mixed
115 */
116 abstract function get($id);
117
118 /**
119 * Sets a cached key/value pair
120 *
121 * @author Art <a.molcanovas@gmail.com>
122 *
123 * @param string $key The key identifier
124 * @param mixed $var The value to set
125 * @param int $expire When to expire the set data. Defaults to 3600s.
126 *
127 * @return boolean
128 */
129 abstract function set($key, $var, $expire = 3600);
130
131 /**
132 * Checks if a key is set in cache
133 *
134 * @author Art <a.molcanovas@gmail.com>
135 *
136 * @param string $key The key
137 *
138 * @return bool
139 */
140 function __isset($key) {
141 return $this->get($key) ? true : false;
142 }
143
144 /**
145 * Removes a key from cache
146 *
147 * @author Art <a.molcanovas@gmail.com>
148 *
149 * @param string $key The key
150 */
151 function __unset($key) {
152 $this->delete($key);
153 }
154
155 /**
156 * Deletes a memcache key
157 *
158 * @author Art <a.molcanovas@gmail.com>
159 *
160 * @param string $key The key
161 *
162 * @return boolean
163 */
164 abstract function delete($key);
165
166 /**
167 * Clears all items from cache
168 *
169 * @author Art <a.molcanovas@gmail.com>
170 * @return boolean
171 */
172 abstract function purge();
173
174 /**
175 * Adds a server to the pool
176 *
177 * @author Art <a.molcanovas@gmail.com>
178 *
179 * @param string $ip The server IP
180 * @param int $port The server port
181 * @param int $weight The server's weight, ie how likely it is to be used
182 *
183 * @return boolean
184 */
185 abstract function addServer($ip, $port, $weight);
186
187 /**
188 * Deletes all cached entries with the supplied prefix
189 *
190 * @author Art <a.molcanovas@gmail.com>
191 *
192 * @param string $prefix The prefix
193 *
194 * @return AbstractCache
195 */
196 function deleteWithPrefix($prefix) {
197 $length = strlen($prefix);
198 $entries = array_keys($this->getAll());
199
200 \Log::debug('Deleting all cache entries with prefix ' . $prefix);
201 foreach ($entries as $key) {
202 if (substr($key, 0, $length) == $prefix) {
203 $this->delete($key);
204 }
205 }
206
207 return $this;
208 }
209
210 /**
211 * Return all cached keys and values
212 *
213 * @author Art <a.molcanovas@gmail.com>
214 * @return array
215 */
216 abstract function getAll();
217
218 /**
219 * Deletes all cached entries with the supplied suffix
220 *
221 * @author Art <a.molcanovas@gmail.com>
222 *
223 * @param string $suffix The suffix
224 *
225 * @return AbstractCache
226 */
227 function deleteWithSuffix($suffix) {
228 $length = strlen($suffix) * -1;
229 $entries = array_keys($this->getAll());
230
231 \Log::debug('Deleting all cache entries with suffix ' . $suffix);
232 foreach ($entries as $key) {
233 if (substr($key, $length) == $suffix) {
234 $this->delete($key);
235 }
236 }
237
238 return $this;
239 }
240
241 }
242 }
243