PluginProbe
Docket Cache – Object Cache Accelerator / 22.07.02
Docket Cache – Object Cache Accelerator v22.07.02
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 22.07.02, at includes/src/Canopt.php

455 lines 13.6 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 'advcpost' => esc_html__('Advanced Post Caching', 'docket-cache'),
87 'advpost_posttype_all' => esc_html__('Post Caching Any Post Type', 'docket-cache'),
88 'menucache' => esc_html__('WordPress Menu Caching', 'docket-cache'),
89 'optermcount' => esc_html__('Optimize Term Count Queries', 'docket-cache'),
90 'precache' => esc_html__('Object Cache Precaching', 'docket-cache'),
91 'mocache' => esc_html__('WordPress Translation Caching', 'docket-cache'),
92 'misc_tweaks' => esc_html__('Misc Performance Tweaks', 'docket-cache'),
93 'postmissedschedule' => esc_html__('Post Missed Schedule Tweaks', 'docket-cache'),
94 'wootweaks' => esc_html__('Misc WooCommerce Tweaks', 'docket-cache'),
95 'wooadminoff' => esc_html__('Deactivate WooCommerce Admin', 'docket-cache'),
96 'woowidgetoff' => esc_html__('Deactivate WooCommerce Widget', 'docket-cache'),
97 'woowpdashboardoff' => esc_html__('Deactivate WooCommerce WP Dashboard', 'docket-cache'),
98 'wooextensionpageoff' => esc_html__('Deactivate WooCommerce Extensions Page', 'docket-cache'),
99 'woocartfragsoff' => esc_html__('Deactivate WooCommerce Cart Fragments', 'docket-cache'),
100 'wooaddtochartcrawling' => esc_html__('Prevent robots crawling add-to-cart links', 'docket-cache'),
101 'pageloader' => esc_html__('Admin Page Loader', 'docket-cache'),
102 'wpoptaload' => esc_html__('Suspend WP Options Autoload', 'docket-cache'),
103 'cronoptmzdb' => esc_html__('Optimize Database Tables', 'docket-cache'),
104 'cronbot' => esc_html__('Cronbot Service', 'docket-cache'),
105 'opcviewer' => esc_html__('OPcache Viewer', 'docket-cache'),
106 'stats' => esc_html__('Object Cache Data Stats', 'docket-cache'),
107 'gcaction' => esc_html__('Garbage Collector Action Button', 'docket-cache'),
108 'flushaction' => esc_html__('Additional Flush Cache Action Button', 'docket-cache'),
109 'autoupdate' => esc_html__('Docket Cache Auto Update', 'docket-cache'),
110 'checkversion' => esc_html__('Critical Version Checking', 'docket-cache'),
111 'optwpquery' => esc_html__('Optimize WP Query', 'docket-cache'),
112 'pingback' => esc_html__('Deactivate XML-RPC / Pingbacks', 'docket-cache'),
113 'headerjunk' => esc_html__('Deactivate WP Header Junk', 'docket-cache'),
114 'wpemoji' => esc_html__('Deactivate WP Emoji', 'docket-cache'),
115 'wpembed' => esc_html__('Deactivate WP Embed', 'docket-cache'),
116 'wpfeed' => esc_html__('Deactivate WP Feed', 'docket-cache'),
117 'wplazyload' => esc_html__('Deactivate WP Lazy Load', 'docket-cache'),
118 'wpsitemap' => esc_html__('Deactivate WP Sitemap', 'docket-cache'),
119 'wpapppassword' => esc_html__('Deactivate WP Application Passwords', 'docket-cache'),
120 'wpdashboardnews' => esc_html__('Deactivate WP Events & News Feed Dashboard', 'docket-cache'),
121 'wpbrowsehappy' => esc_html__('Deactivate Browse Happy Checking', 'docket-cache'),
122 'wpservehappy' => esc_html__('Deactivate Serve Happy Checking', '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 'chunkcachedir' => esc_html__('Chunk Cache Directory', 'docket-cache'),
129 'flush_stalecache' => esc_html__('Auto Remove Stale Cache', 'docket-cache'),
130 'limithttprequest' => esc_html__('Limit WP-Admin HTTP requests', 'docket-cache'),
131 'httpheadersexpect' => esc_html__('HTTP Request Expect header tweaks', 'docket-cache'),
132 'rtpostautosave' => esc_html__('Auto Save Interval', 'docket-cache'),
133 'rtpostrevision' => esc_html__('Post Revisions', 'docket-cache'),
134 'rtpostemptytrash' => esc_html__('Trash Bin', 'docket-cache'),
135 'rtpluginthemeeditor' => esc_html__('Disallows Plugin / Theme Editor', 'docket-cache'),
136 'rtpluginthemeinstall' => esc_html__('Disallows Plugin / Theme Update and Installation', 'docket-cache'),
137 'rtimageoverwrite' => esc_html__('Cleanup Image Edits', 'docket-cache'),
138 'rtwpdebug' => esc_html__('WP Debug', 'docket-cache'),
139 'rtwpdebugdisplay' => esc_html__('WP Debug Display', 'docket-cache'),
140 'rtwpdebuglog' => esc_html__('WP Debug Log', 'docket-cache'),
141 'rtwpcoreupdate' => esc_html__('Disallows WP Auto Update Core', 'docket-cache'),
142 ];
143
144 $data = apply_filters('docketcache/filter/optionkeys', $data);
145
146 if (false !== $key) {
147 if (!empty($data[$key])) {
148 return $data[$key];
149 }
150
151 return false;
152 }
153
154 return array_keys($data);
155 }
156
157 public function read_config($file = '', $force = false)
158 {
159 $file = empty($file) ? $this->file : $file;
160 $config = [];
161 if (@is_file($file) && is_readable($file)) {
162 // fresh
163 if ($force) {
164 $this->opcache_flush($file);
165 }
166
167 try {
168 $config = @include $file;
169 } catch (\Throwable $e) {
170 nwdcx_throwable(__METHOD__, $e);
171 }
172 }
173
174 return $config;
175 }
176
177 public function put_config($config, $file = '')
178 {
179 $file = empty($file) ? $this->file : $file;
180 if (empty($config) || !\is_array($config)) {
181 if (@is_file($file) && @is_writable($file)) {
182 @unlink($file);
183 }
184
185 clearstatcache();
186
187 return false;
188 }
189
190 $data = $this->export_var($config);
191 $code = $this->code_stub($data);
192
193 return $this->dump($file, $code);
194 }
195
196 public function config_cleanup($config)
197 {
198 if (!empty($config) && \is_array($config)) {
199 $keys = $this->keys();
200 foreach ($config as $name => $value) {
201 $nx = strtolower(nwdcx_constfx($name, true));
202 if (!\in_array($nx, $keys) || (\is_string($value) && 'default' === $value)) {
203 unset($config[$name]);
204 }
205 }
206 }
207
208 return $config;
209 }
210
211 public function get($name)
212 {
213 $config = $this->read_config();
214
215 if (!empty($config) && !empty($config[$name])) {
216 return $config[$name];
217 }
218
219 return false;
220 }
221
222 public function save($name, $value)
223 {
224 if (!$this->mkdir_p($this->path)) {
225 return false;
226 }
227
228 $this->placeholder($this->path);
229
230 $config = $this->read_config();
231 $config = $this->config_cleanup($config);
232
233 if (\in_array($name, $this->keys())) {
234 $nx = nwdcx_constfx($name);
235
236 if ('default' === $value) {
237 unset($config[$nx]);
238 } else {
239 $config[$nx] = $value;
240 }
241 }
242
243 $ret = $this->put_config($config);
244 do_action('docketcache/action/saveoption', $name, $value, $ret);
245
246 return $ret;
247 }
248
249 public function save_part($data, $file = 'part')
250 {
251 $file = $this->path.'/'.$file.'.php';
252
253 return $this->put_config($data, $file);
254 }
255
256 public function get_part($file = 'part', $force = false)
257 {
258 $file = $this->path.'/'.$file.'.php';
259
260 return $this->read_config($file, $force);
261 }
262
263 public function clear_part($file)
264 {
265 $file = $this->path.'/'.$file.'.php';
266 if (!@is_file($file)) {
267 return true;
268 }
269
270 $ret = @unlink($file);
271 clearstatcache();
272
273 return $ret;
274 }
275
276 public function clear_lock()
277 {
278 $path = $this->path_lock;
279 if (!@is_dir($path)) {
280 return false;
281 }
282
283 $files = @glob($path.'/lock-*.txt', \GLOB_MARK | \GLOB_NOSORT);
284 if (!empty($files) && \is_array($files)) {
285 foreach ($files as $file) {
286 if (@is_file($file) && @is_writable($file)) {
287 if (\defined('DocketCache_CLI') && DocketCache_CLI) {
288 @fwrite(\STDOUT, basename($file).\PHP_EOL);
289 }
290 @unlink($file);
291 }
292 }
293 }
294
295 $files = @glob($path.'/dump_*.txt', \GLOB_MARK | \GLOB_NOSORT);
296 if (!empty($files) && \is_array($files)) {
297 foreach ($files as $file) {
298 if (@is_file($file) && @is_writable($file)) {
299 @unlink($file);
300 }
301 }
302 }
303
304 clearstatcache();
305
306 return true;
307 }
308
309 private function lock_file($key)
310 {
311 $key = substr(md5($key), 0, 12);
312 $path = $this->path_lock;
313 if (!$this->mkdir_p($path.'/')) {
314 return false;
315 }
316 $this->placeholder($path);
317
318 return $path.'/lock-'.$key.'.txt';
319 }
320
321 public function setlock($key, $value)
322 {
323 $file = $this->lock_file($key);
324 if (!$file) {
325 return false;
326 }
327
328 if (true === $this->dump($file, $value)) {
329 return true;
330 }
331
332 return false;
333 }
334
335 public function unlock($key)
336 {
337 $file = $this->lock_file($key);
338 if (!$file || !@is_file($file)) {
339 return true;
340 }
341
342 $ret = @unlink($file);
343 clearstatcache();
344
345 return $ret;
346 }
347
348 public function locked($key, &$value = '')
349 {
350 clearstatcache();
351
352 $file = $this->lock_file($key);
353 if (!$file || !@is_file($file)) {
354 return false;
355 }
356
357 $value = @file_get_contents($file);
358
359 return true;
360 }
361
362 // locked and not expire
363 public function lockexp($key)
364 {
365 if ($this->locked($key, $locked)) {
366 if (!empty($locked) && (int) $locked > time()) {
367 return true;
368 }
369 }
370
371 return false;
372 }
373
374 // lock process
375 public function lockproc($key, $value)
376 {
377 // if locked and not expire
378 if ($this->lockexp($key)) {
379 return true;
380 }
381
382 // if expire set new lock
383 $this->setlock($key, $value);
384
385 return false;
386 }
387
388 public function lockreset($key)
389 {
390 return $this->setlock($key, 0);
391 }
392
393 // lookup
394 public function lookup_set($key, $value)
395 {
396 $fkey = 'lockup-'.$key;
397
398 return $this->setlock($fkey, maybe_serialize($value));
399 }
400
401 public function lookup_get($key, $forget = false)
402 {
403 $fkey = 'lockup-'.$key;
404 if ($this->locked($fkey, $value)) {
405 if (!empty($value)) {
406 if ($forget) {
407 $this->lookup_delete($key);
408 }
409
410 return maybe_unserialize($value);
411 }
412 }
413
414 if ($forget) {
415 $this->lookup_delete($key);
416 }
417
418 return false;
419 }
420
421 public function lookup_delete($key)
422 {
423 $fkey = 'lockup-'.$key;
424
425 return $this->unlock($fkey);
426 }
427
428 public function reset()
429 {
430 $this->clear_lock();
431
432 $parts = [
433 'options',
434 'runtime',
435 'pings',
436 'cronbot',
437 'checkversion',
438 'cachestats',
439 'gc',
440 ];
441
442 $ok = true;
443 foreach ($parts as $part) {
444 $file = $this->path.'/'.$part.'.php';
445 if (@is_file($file) && is_writable($file)) {
446 if (!@unlink($file)) {
447 $ok = false;
448 }
449 }
450 }
451
452 return $ok;
453 }
454 }
455