PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.95
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.95
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Cache / Cache.php

Cache.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.95, at vendor/wpfluent/framework/src/WPFluent/Cache/Cache.php

382 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Cache;
4
5 use Closure;
6 use Throwable;
7 use RuntimeException;
8 use FluentBoards\Framework\Support\Path;
9 use FluentBoards\Framework\Foundation\App;
10
11 class Cache
12 {
13 protected static $cacheDir = null;
14
15 /**
16 * Initialize the cache directory.
17 */
18 public static function init($cacheDir = null)
19 {
20 if (static::isPersistent()) return;
21
22 static::$cacheDir = static::getDir($cacheDir);
23
24 if (!is_dir(static::$cacheDir) && !mkdir(static::$cacheDir, 0755, true)) {
25 throw new RuntimeException(
26 "Unable to create cache directory: " . static::$cacheDir
27 );
28 }
29
30 return new static;
31 }
32
33 /**
34 * Resolve cache directory.
35 *
36 * @param string|null $cacheDir
37 * @return string
38 */
39 public static function getDir($cacheDir = null)
40 {
41 $slug = App::config()->get('app.slug');
42
43 $cacheDir ??= WP_CONTENT_DIR . "/uploads/{$slug}/storage/app/cache";
44
45 return rtrim($cacheDir, '/');
46 }
47
48 /**
49 * Store data in the cache using transients.
50 *
51 * @param string $key
52 * @param mixed $value
53 * @param int $ttl Time to live (in seconds)
54 * @return bool
55 */
56 public static function put($key, $value, $ttl = HOUR_IN_SECONDS)
57 {
58 $key = static::key($key);
59
60 if (static::isPersistent()) {
61 return wp_cache_set($key, $value, static::cacheGroup(), $ttl);
62 } else {
63 return static::filePut($key, $value, $ttl);
64 }
65 }
66
67 /**
68 * Store data in the cache using transients.
69 *
70 * @param string $key
71 * @param mixed $value
72 * @param int $ttl Time to live (in seconds)
73 * @return bool
74 */
75 public static function set($key, $value, $ttl = HOUR_IN_SECONDS)
76 {
77 return static::put($key, $value, $ttl);
78 }
79
80 /**
81 * Retrieve data from the cache.
82 *
83 * @param string $key
84 * @return mixed
85 */
86 public static function get($key)
87 {
88 $key = static::key($key);
89
90 if (static::isPersistent()) {
91 $value = wp_cache_get($key, static::cacheGroup(), false, $found);
92 $value = $found ? $value : null;
93 } else {
94 $value = static::fileGet($key) ?: null;
95 }
96
97 return $value;
98 }
99
100 /**
101 * Remove data from the cache.
102 *
103 * @param string $key
104 * @return bool
105 */
106 public static function forget($key)
107 {
108 $key = static::key($key);
109
110 if (static::isPersistent()) {
111 return wp_cache_delete($key, static::cacheGroup());
112 }
113
114 return static::fileForget($key);
115 }
116
117 /**
118 * The group key for the cache.
119 *
120 * @return string
121 */
122 public static function cacheGroup()
123 {
124 $slug = App::config()->get('app.slug');
125
126 return 'wpfluent_cache_group_' . $slug;
127 }
128
129 /**
130 * Store data in the cache "forever" using 5 years of expiry time.
131 *
132 * @param string $key
133 * @param mixed $value
134 * @return bool
135 */
136 public static function forever($key, $value)
137 {
138 $key = static::key($key);
139
140 if (static::isPersistent()) {
141 return wp_cache_set($key, $value, static::cacheGroup(), 0);
142 } else {
143 return static::filePut($key, $value, 0);
144 }
145 }
146
147 /**
148 * Get an item from the cache, or store the default value if not present.
149 *
150 * @param string $key
151 * @param \Closure $callback
152 * @param int $ttl Time to live (in seconds)
153 * @return mixed
154 */
155 public static function remember(
156 $key, Closure $callback, $ttl = HOUR_IN_SECONDS
157 )
158 {
159 $value = static::get($key);
160
161 if ($value !== null) {
162 return $value;
163 }
164
165 try {
166 $value = $callback();
167 if (!is_wp_error($value)) {
168 static::set($key, $value, $ttl);
169 return $value;
170 }
171 } catch (Throwable $e) {
172 error_log("Cache callback error [{$key}]: " . $e->getMessage());
173 }
174 }
175
176 /**
177 * Increment the value of an item in the cache.
178 *
179 * @param string $key
180 * @param integer $count
181 * @return bool
182 */
183 public static function increment($key, $count = 1)
184 {
185 $value = static::get($key);
186
187 if (is_numeric($value)) {
188 return static::set($key, $value + $count);
189 }
190
191 return false;
192 }
193
194 /**
195 * Decrement the value of an item in the cache.
196 *
197 * @param string $key
198 * @param integer $count
199 * @return bool
200 */
201 public static function decrement($key, $count = 1)
202 {
203 $value = static::get($key);
204
205 if (is_numeric($value)) {
206 return static::set($key, $value - $count);
207 }
208
209 return false;
210 }
211
212 /**
213 * Delete all cached items for the plugin.
214 *
215 * @return void
216 */
217 public static function flush()
218 {
219 if (static::isPersistent()) {
220 // Preferred: Use wp_cache_flush_group if available
221 if (function_exists('wp_cache_flush_group')) {
222 return wp_cache_flush_group(static::cacheGroup());
223 }
224
225 // Fallback: Manual flush for in-memory cache
226 global $wp_object_cache;
227 $group = static::cacheGroup();
228
229 if (!isset($wp_object_cache->cache[$group])) {
230 return false;
231 }
232
233 foreach (array_keys($wp_object_cache->cache[$group]) as $key) {
234 unset($wp_object_cache->cache[$group][$key]);
235 }
236
237 return true;
238 }
239
240 // For non-persistent cache (e.g., file cache fallback)
241 return static::fileFlush();
242 }
243
244 /**
245 * Check if a key exists in the cache.
246 *
247 * @param string $key
248 * @return bool
249 */
250 public static function has($key)
251 {
252 return static::get($key) !== null;
253 }
254
255 /**
256 * Make unique key with config.app.slug
257 *
258 * @param string $key
259 * @return string
260 */
261 protected static function key($key)
262 {
263 $slug = App::config()->get('app.slug');
264
265 return $slug . '_wpfluent_cache_' . sanitize_key($key);
266 }
267
268 /**
269 * Check if persistent cache is available.
270 *
271 * @return bool
272 */
273 protected static function isPersistent()
274 {
275 return wp_using_ext_object_cache();
276 }
277
278 /**
279 * Store data in a file if no persistent cache is available.
280 *
281 * @param string $key
282 * @param mixed $data
283 * @param int $expiration
284 */
285 protected static function filePut($key, $data, $expiration)
286 {
287 try {
288 return static::store($key, [
289 'data' => $data,
290 'expiration' => time() + $expiration,
291 ]);
292 } catch (Throwable $e) {
293 error_log(__METHOD__ .' - '. $e->getMessage());
294 throw $e;
295 }
296
297 }
298
299 /**
300 * Store the data in a file if no persistent cache is available.
301 *
302 * @param string $key
303 * @param mixed $payload
304 * @return bool
305 */
306 protected static function store($key, $payload)
307 {
308 if (!static::$cacheDir || !is_readable(static::$cacheDir)) {
309 static::init();
310 }
311
312 $data = $payload['data'];
313
314 if (is_object($data) && method_exists($data, 'toArray')) {
315 $payload['data'] = $data->toArray();
316 }
317
318 $filePath = static::$cacheDir . '/' . md5($key) . '.cache';
319
320 return file_put_contents($filePath, serialize($payload)) !== false;
321 }
322
323 /**
324 * Retrieve data from the file cache.
325 *
326 * @param string $key
327 * @return mixed|null
328 */
329 protected static function fileGet($key)
330 {
331 $filePath = static::$cacheDir . '/' . md5($key) . '.cache';
332
333 if (file_exists($filePath)) {
334 $data = unserialize(file_get_contents($filePath));
335 if ($data['expiration'] >= time()) {
336 return $data['data'];
337 }
338 static::fileForget($key);
339 }
340
341 return false;
342 }
343
344 /**
345 * Remove an item from the file cache.
346 *
347 * @param string $key
348 * @return bool
349 */
350 protected static function fileForget($key)
351 {
352 $filePath = static::$cacheDir . '/' . md5($key) . '.cache';
353
354 if (file_exists($filePath)) {
355 unlink($filePath);
356 return true;
357 }
358
359 return false;
360 }
361
362 /**
363 * Flush all file cache entries.
364 *
365 * @return bool
366 */
367 protected static function fileFlush()
368 {
369 if (!is_dir(static::$cacheDir)) {
370 return false;
371 }
372
373 $files = glob(static::$cacheDir . '/*.cache');
374
375 foreach ($files as $file) {
376 @unlink($file);
377 }
378
379 return true;
380 }
381 }
382