PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / vendor / wpfluent / framework / src / WPFluent / Cache / Cache.php

Cache.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.14, at vendor/wpfluent/framework/src/WPFluent/Cache/Cache.php

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