PluginProbe
Docket Cache – Object Cache Accelerator / 24.07.06
Docket Cache – Object Cache Accelerator v24.07.06
26.04.05 trunk 22.07.01 22.07.02 22.07.03 22.07.04 22.07.05 23.08.01 23.08.02 24.07.01 24.07.02 24.07.03 24.07.04 24.07.05 24.07.06 24.07.07 26.04.03 26.04.04
docket-cache / includes / src / Canopt.php

Canopt.php in Docket Cache – Object Cache Accelerator 24.07.06, at includes/src/Canopt.php

472 lines 14.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Docket Cache.
4 *
5 * @author Nawawi Jamili
6 * @license MIT
7 *
8 * @see https://github.com/nawawi/docket-cache
9 */
10
11 namespace Nawawi\DocketCache;
12
13 \defined('ABSPATH') || exit;
14
15 final class Canopt extends Bepart
16 {
17 public $file;
18 public $path;
19 public $path_lock;
20
21 private static $inst;
22
23 public function __construct()
24 {
25 $this->define_path();
26 }
27
28 private function define_path()
29 {
30 $path = '';
31 $constfx = nwdcx_constfx('DATA_PATH');
32 if (\defined($constfx)) {
33 $path = \constant($constfx);
34 }
35
36 if (!empty($path)) {
37 if ('docket-cache-data' !== basename($path)) {
38 $path = rtrim($path, '/\\').'/docket-cache-data';
39 }
40 } else {
41 $path = rtrim(DOCKET_CACHE_CONTENT_PATH, '/\\').'/docket-cache-data';
42 }
43
44 $path = wp_normalize_path($path);
45
46 if (is_multisite()) {
47 $path = nwdcx_network_dirpath($path);
48 }
49
50 $this->path = rtrim($path, '/\\');
51
52 $this->file = $this->path.'/options.php';
53 $this->path_lock = $this->path.'/lock';
54 }
55
56 public static function init()
57 {
58 if (!isset(self::$inst)) {
59 self::$inst = new self();
60 }
61
62 return self::$inst;
63 }
64
65 public function is_options_writable()
66 {
67 if (@is_file($this->file)) {
68 return @is_writable($this->file);
69 }
70
71 if (@is_dir($this->path)) {
72 return @is_writable($this->path);
73 }
74
75 return @is_writable(\dirname($this->path));
76 }
77
78 public function keys($key = false)
79 {
80 // key = title
81 $data = [
82 'log' => esc_html__('Cache Log', 'docket-cache'),
83 'log_time' => esc_html__('Log Timestamp', 'docket-cache'),
84 'log_all' => esc_html__('Log All', 'docket-cache'),
85 'preload' => esc_html__('Admin Page Cache Preloading', 'docket-cache'),
86 'menucache' => esc_html__('WordPress Menu Caching', 'docket-cache'),
87 'optermcount' => esc_html__('Optimize Term Count Queries', 'docket-cache'),
88 'precache' => esc_html__('Object Cache Precaching', 'docket-cache'),
89 'mocache' => esc_html__('WordPress Translation Caching', 'docket-cache'),
90 'misc_tweaks' => esc_html__('Misc Performance Tweaks', 'docket-cache'),
91 'postmissedschedule' => esc_html__('Post Missed Schedule Tweaks', 'docket-cache'),
92 'wootweaks' => esc_html__('Misc WooCommerce Tweaks', 'docket-cache'),
93 'wooadminoff' => esc_html__('Deactivate WooCommerce Admin', 'docket-cache'),
94 'woowidgetoff' => esc_html__('Deactivate WooCommerce Classic Widget', 'docket-cache'),
95 'woowpdashboardoff' => esc_html__('Deactivate WooCommerce WP Dashboard', 'docket-cache'),
96 'wooextensionpageoff' => esc_html__('Deactivate WooCommerce Extensions Page', 'docket-cache'),
97 'woocartfragsoff' => esc_html__('Deactivate WooCommerce Cart Fragments', 'docket-cache'),
98 'wooaddtochartcrawling' => esc_html__('Prevent robots crawling add-to-cart links', 'docket-cache'),
99 'pageloader' => esc_html__('Admin Page Loader', 'docket-cache'),
100 'wpoptaload' => esc_html__('Suspend WP Options Autoload', 'docket-cache'),
101 'cronoptmzdb' => esc_html__('Optimize Database Tables', 'docket-cache'),
102 'cronbot' => esc_html__('Cronbot Service', 'docket-cache'),
103 'opcviewer' => esc_html__('OPcache Viewer', 'docket-cache'),
104 'stats' => esc_html__('Object Cache Data Stats', 'docket-cache'),
105 'gcaction' => esc_html__('Garbage Collector Action Button', 'docket-cache'),
106 'flushaction' => esc_html__('Additional Flush Cache Action Button', 'docket-cache'),
107 'autoupdate_toggle' => esc_html__('Docket Cache Auto Update', 'docket-cache'),
108 'checkversion' => esc_html__('Critical Version Checking', 'docket-cache'),
109 'optwpquery' => esc_html__('Optimize WP Query', 'docket-cache'),
110 'limitbulkedit' => esc_html__('Limit Bulk Edit Actions', 'docket-cache'),
111 'pingback' => esc_html__('Deactivate XML-RPC / Pingbacks', 'docket-cache'),
112 'headerjunk' => esc_html__('Deactivate WP Header Junk', 'docket-cache'),
113 'wpemoji' => esc_html__('Deactivate WP Emoji', 'docket-cache'),
114 'wpembed' => esc_html__('Deactivate WP Embed', 'docket-cache'),
115 'wpfeed' => esc_html__('Deactivate WP Feed', 'docket-cache'),
116 'wplazyload' => esc_html__('Deactivate WP Lazy Load', 'docket-cache'),
117 'wpsitemap' => esc_html__('Deactivate WP Sitemap', 'docket-cache'),
118 'wpapppassword' => esc_html__('Deactivate WP Application Passwords', 'docket-cache'),
119 'wpdashboardnews' => esc_html__('Deactivate WP Events & News Feed Dashboard', 'docket-cache'),
120 'wpbrowsehappy' => esc_html__('Deactivate Browse Happy Checking', 'docket-cache'),
121 'wpservehappy' => esc_html__('Deactivate Serve Happy Checking', 'docket-cache'),
122 'postviaemail' => esc_html__('Deactivate Post Via Email', 'docket-cache'),
123 'objectcacheoff' => esc_html__('Suspend Object Cache', 'docket-cache'),
124 'flush_shutdown' => esc_html__('Flush Object Cache During Deactivation', 'docket-cache'),
125 'opcshutdown' => esc_html__('Flush OPcache During Deactivation', 'docket-cache'),
126 'maxsize_disk' => esc_html__('Cache Disk Limit', 'docket-cache'),
127 'maxfile' => esc_html__('Cache Files Limit', 'docket-cache'),
128 'maxfile_livecheck' => esc_html__('Real-time File Limit Checking', 'docket-cache'),
129 'chunkcachedir' => esc_html__('Chunk Cache Directory', 'docket-cache'),
130 'flush_stalecache' => esc_html__('Auto Remove Stale Cache', 'docket-cache'),
131 'stalecache_ignore' => esc_html__('Exclude Stale Cache', 'docket-cache'),
132 'emptycache_ignore' => esc_html__('Exclude Empty Object Data', 'docket-cache'),
133 'transientdb' => esc_html__('Retain Transients in Db', 'docket-cache'),
134 'limithttprequest' => esc_html__('Limit WP-Admin HTTP requests', 'docket-cache'),
135 'rtpostautosave' => esc_html__('Auto Save Interval', 'docket-cache'),
136 'rtpostrevision' => esc_html__('Post Revisions', 'docket-cache'),
137 'rtpostemptytrash' => esc_html__('Trash Bin', 'docket-cache'),
138 'rtpluginthemeeditor' => esc_html__('Disallows Plugin / Theme Editor', 'docket-cache'),
139 'rtpluginthemeinstall' => esc_html__('Disallows Plugin / Theme Update and Installation', 'docket-cache'),
140 'rtimageoverwrite' => esc_html__('Cleanup Image Edits', 'docket-cache'),
141 'rtwpdebug' => esc_html__('WP Debug', 'docket-cache'),
142 'rtwpdebugdisplay' => esc_html__('WP Debug Display', 'docket-cache'),
143 'rtwpdebuglog' => esc_html__('WP Debug Log', 'docket-cache'),
144 'rtwpcoreupdate' => esc_html__('Disallows WP Auto Update Core', 'docket-cache'),
145 'rtconcatenatescripts' => esc_html__('Deactivate Concatenate WP-Admin Scripts', 'docket-cache'),
146 'rtdisablewpcron' => esc_html__('Deactivate WP Cron', 'docket-cache'),
147 ];
148
149 if (version_compare($GLOBALS['wp_version'], '6.1', '<')) {
150 $data['advcpost'] = esc_html__('Advanced Post Caching', 'docket-cache');
151 $data['advpost_posttype_all'] = esc_html__('Post Caching Any Post Type', 'docket-cache');
152 }
153
154 if (version_compare($GLOBALS['wp_version'], '5.8', '<')) {
155 $data['httpheadersexpect'] = esc_html__('HTTP Request Expect header tweaks', 'docket-cache');
156 }
157
158 $data = apply_filters('docketcache/filter/optionkeys', $data);
159
160 if (false !== $key) {
161 if (!empty($data[$key])) {
162 return $data[$key];
163 }
164
165 return false;
166 }
167
168 return array_keys($data);
169 }
170
171 public function read_config($file = '', $force = false)
172 {
173 $file = empty($file) ? $this->file : $file;
174 $config = [];
175 if (@is_file($file) && is_readable($file)) {
176 // fresh
177 if ($force) {
178 $this->opcache_flush($file);
179 }
180
181 try {
182 $config = @include $file;
183 } catch (\Throwable $e) {
184 nwdcx_throwable(__METHOD__, $e);
185 }
186 }
187
188 return $config;
189 }
190
191 public function put_config($config, $file = '')
192 {
193 $file = empty($file) ? $this->file : $file;
194 if (empty($config) || !\is_array($config)) {
195 if (@is_file($file) && @is_writable($file)) {
196 @unlink($file);
197 }
198
199 clearstatcache();
200
201 return false;
202 }
203
204 $data = $this->export_var($config);
205 $code = $this->code_stub($data);
206
207 return $this->dump($file, $code);
208 }
209
210 public function config_cleanup($config)
211 {
212 if (!empty($config) && \is_array($config)) {
213 $keys = $this->keys();
214 foreach ($config as $name => $value) {
215 $nx = strtolower(nwdcx_constfx($name, true));
216 if (!\in_array($nx, $keys) || (\is_string($value) && 'default' === $value)) {
217 unset($config[$name]);
218 }
219 }
220 }
221
222 return $config;
223 }
224
225 public function get($name)
226 {
227 $config = $this->read_config();
228
229 if (!empty($config) && !empty($config[$name])) {
230 return $config[$name];
231 }
232
233 return false;
234 }
235
236 public function save($name, $value, $do_action = true)
237 {
238 if (!$this->mkdir_p($this->path)) {
239 return false;
240 }
241
242 $this->placeholder($this->path);
243
244 $config = $this->read_config();
245 $config = $this->config_cleanup($config);
246
247 if (\in_array($name, $this->keys())) {
248 $nx = nwdcx_constfx($name);
249
250 if ('default' === $value) {
251 unset($config[$nx]);
252 } else {
253 $config[$nx] = $value;
254 }
255 }
256
257 $ret = $this->put_config($config);
258
259 if ($do_action) {
260 do_action('docketcache/action/saveoption', $name, $value, $ret);
261 }
262
263 return $ret;
264 }
265
266 public function save_part($data, $file = 'part')
267 {
268 $file = $this->path.'/'.$file.'.php';
269
270 return $this->put_config($data, $file);
271 }
272
273 public function get_part($file = 'part', $force = false)
274 {
275 $file = $this->path.'/'.$file.'.php';
276
277 return $this->read_config($file, $force);
278 }
279
280 public function clear_part($file)
281 {
282 $file = $this->path.'/'.$file.'.php';
283 if (!@is_file($file)) {
284 return true;
285 }
286
287 $ret = @unlink($file);
288 clearstatcache();
289
290 return $ret;
291 }
292
293 public function clear_lock()
294 {
295 $path = $this->path_lock;
296 if (!@is_dir($path)) {
297 return false;
298 }
299
300 $files = @glob($path.'/lock-*.txt', \GLOB_MARK | \GLOB_NOSORT);
301 if (!empty($files) && \is_array($files)) {
302 foreach ($files as $file) {
303 if (@is_file($file) && @is_writable($file)) {
304 nwdcx_cliverbose(basename($file)."\n");
305 @unlink($file);
306 }
307 }
308 }
309
310 $files = @glob($path.'/dump_*.txt', \GLOB_MARK | \GLOB_NOSORT);
311 if (!empty($files) && \is_array($files)) {
312 foreach ($files as $file) {
313 if (@is_file($file) && @is_writable($file)) {
314 @unlink($file);
315 }
316 }
317 }
318
319 clearstatcache();
320
321 return true;
322 }
323
324 private function lock_file($key)
325 {
326 $key = substr(md5($key), 0, 12);
327 $path = $this->path_lock;
328 if (!$this->mkdir_p($path.'/')) {
329 return false;
330 }
331 $this->placeholder($path);
332
333 return $path.'/lock-'.$key.'.txt';
334 }
335
336 public function setlock($key, $value)
337 {
338 $file = $this->lock_file($key);
339 if (!$file) {
340 return false;
341 }
342
343 if (true === $this->dump($file, $value)) {
344 return true;
345 }
346
347 return false;
348 }
349
350 public function unlock($key)
351 {
352 $file = $this->lock_file($key);
353 if (!$file || !@is_file($file)) {
354 return true;
355 }
356
357 $ret = @unlink($file);
358 clearstatcache();
359
360 return $ret;
361 }
362
363 public function locked($key, &$value = '')
364 {
365 clearstatcache();
366
367 $file = $this->lock_file($key);
368 if (!$file || !@is_file($file)) {
369 return false;
370 }
371
372 $value = @file_get_contents($file);
373
374 return true;
375 }
376
377 // locked and not expire
378 public function lockexp($key)
379 {
380 if ($this->locked($key, $locked)) {
381 if (!empty($locked) && (int) $locked > time()) {
382 return true;
383 }
384 }
385
386 return false;
387 }
388
389 // lock process
390 public function lockproc($key, $value)
391 {
392 // if locked and not expire
393 if ($this->lockexp($key)) {
394 return true;
395 }
396
397 // if expire set new lock
398 $this->setlock($key, $value);
399
400 return false;
401 }
402
403 public function lockreset($key)
404 {
405 return $this->setlock($key, 0);
406 }
407
408 // lookup
409 public function lookup_set($key, $value)
410 {
411 $fkey = 'lockup-'.$key;
412
413 return $this->setlock($fkey, maybe_serialize($value));
414 }
415
416 public function lookup_get($key, $forget = false)
417 {
418 $fkey = 'lockup-'.$key;
419 if ($this->locked($fkey, $value)) {
420 if (!empty($value)) {
421 if ($forget) {
422 $this->lookup_delete($key);
423 }
424
425 return maybe_unserialize($value);
426 }
427 }
428
429 if ($forget) {
430 $this->lookup_delete($key);
431 }
432
433 return false;
434 }
435
436 public function lookup_delete($key)
437 {
438 $fkey = 'lockup-'.$key;
439
440 return $this->unlock($fkey);
441 }
442
443 public function reset()
444 {
445 $this->clear_lock();
446
447 $parts = [
448 'options',
449 'runtime',
450 'pings',
451 'cronbot',
452 'checkversion',
453 'cachestats',
454 'gc',
455 ];
456
457 $ok = true;
458 foreach ($parts as $part) {
459 $file = $this->path.'/'.$part.'.php';
460 if (@is_file($file) && is_writable($file)) {
461 if (!@unlink($file)) {
462 $ok = false;
463 }
464 }
465 }
466
467 clearstatcache(true);
468
469 return $ok;
470 }
471 }
472