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 / View.php

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

737 lines 29.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 View
16 {
17 private $pt;
18 private $po;
19 private $info;
20 private $do_preload;
21 private $do_flush;
22 private $do_fetch;
23 private $log_enable;
24 private $log_max_size;
25 private $cache_max_size;
26 private $cronbot_enable;
27 private $opcviewer_enable;
28
29 public function __construct(Plugin $pt)
30 {
31 $this->pt = $pt;
32 $this->register();
33 }
34
35 public function vcf()
36 {
37 return $this->pt->cf();
38 }
39
40 public function register()
41 {
42 $this->log_enable = $this->vcf()->is_dctrue('LOG');
43 $this->log_max_size = $this->pt->normalize_size($this->vcf()->dcvalue('LOG_SIZE'));
44 $this->cache_max_size = $this->pt->normalize_size($this->vcf()->dcvalue('MAXSIZE'));
45 $this->cronbot_enable = $this->vcf()->is_dctrue('CRONBOT');
46 $this->opcviewer_enable = $this->vcf()->is_dctrue('OPCVIEWER');
47 }
48
49 /**
50 * tail.
51 */
52 public function tail($filename, $limit = 100, $do_last = true, &$error = '')
53 {
54 $limit = (int) $limit;
55 $object = [];
56
57 try {
58 $fileo = new \SplFileObject($filename, 'rb');
59 } catch (\Throwable $e) {
60 $error = $e->getMessage();
61
62 return $object;
63 }
64
65 $fileo->seek(\PHP_INT_MAX);
66 $total_lines = $fileo->key();
67
68 if ($limit > $total_lines) {
69 $limit = $total_lines;
70 }
71
72 if ($do_last) {
73 $total_lines = $total_lines > $limit ? $total_lines - $limit : $total_lines;
74 } else {
75 $total_lines = $limit;
76 }
77
78 if ($total_lines > 0) {
79 if ($do_last) {
80 $object = new \LimitIterator($fileo, $total_lines);
81 } else {
82 $object = new \LimitIterator($fileo, 0, $total_lines);
83 }
84 }
85
86 return $object;
87 }
88
89 private function parse_log_query()
90 {
91 $ret = (object) [];
92 $ret->default_order = 'last';
93 $ret->default_sort = 'desc';
94 $ret->default_line = 100;
95 $ret->output = '';
96 $ret->output_empty = true;
97 $ret->log_size = 0;
98 $ret->row_size = 15;
99
100 if ($this->has_vcache()) {
101 $cache_path = $this->pt->cache_path;
102 $vache = $this->idx_vcache();
103 if ($this->pt->cf()->is_dctrue('CHUNKCACHEDIR')) {
104 $part = explode('-', $vache);
105 if (isset($part[1])) {
106 $vache = $this->pt->get_chunk_path($part[0], $part[1]).$vache;
107 }
108 }
109 $file = $cache_path.$vache.'.php';
110 $file = sanitize_file_name($file);
111 if ($this->pt->filesize($file) > 0) {
112 $data = $this->pt->cache_get($file);
113 if (false !== $data) {
114 $ret->output = $this->pt->export_var($data);
115 $ret->output_empty = empty($ret->output);
116 $ret->log_size = $this->pt->normalize_size(\strlen(serialize($data)));
117 $ret->output_size = $ret->log_size;
118 if ($ret->output_size > 15) {
119 $ret->row_size = 25;
120 }
121 }
122 unset($data);
123 }
124 } else {
125 if (!empty($_GET['srt'])) {
126 $srt = explode('-', sanitize_text_field($_GET['srt']));
127 if (3 >= \count($srt)) {
128 $ret->default_order = $srt[0];
129 $ret->default_sort = $srt[1];
130 $ret->default_line = (int) $srt[2];
131 }
132 }
133
134 $ret->output = $this->read_log($ret->default_line, 'last' === $ret->default_order ? true : false);
135 $ret->output_empty = empty($ret->output);
136 $ret->output_size = !$ret->output_empty ? \count($ret->output) : 0;
137 $ret->log_size = $this->pt->get_logsize();
138 if ($ret->output_size < 15) {
139 $ret->row_size = $ret->output_size;
140 }
141 $ret->output = implode("\n", 'desc' === $ret->default_sort ? array_reverse($ret->output, true) : $ret->output);
142 }
143
144 return $ret;
145 }
146
147 private function cronbot_status()
148 {
149 $data = $this->pt->co()->get_part('cronbot');
150 if (!empty($data) && \is_array($data)) {
151 return $data;
152 }
153
154 return false;
155 }
156
157 private function cronbot_pings()
158 {
159 $data = $this->pt->co()->get_part('pings');
160 if (!empty($data) && \is_array($data)) {
161 return $data;
162 }
163
164 return false;
165 }
166
167 private function is_cronbot_connected()
168 {
169 $data = $this->cronbot_status();
170
171 return !empty($data) && !empty($data['connected']);
172 }
173
174 private function ping_next()
175 {
176 $data = $this->cronbot_pings();
177 if (!empty($data) && \is_array($data) && !empty($data['timestamp'])) {
178 $timestamp = strtotime($data['timestamp']);
179
180 return [
181 'last' => wp_date('Y-m-d H:i:s', $timestamp),
182 'next' => wp_date('Y-m-d H:i:s', strtotime('+1 hour', $timestamp)),
183 ];
184 }
185
186 return false;
187 }
188
189 private function parse_subpage()
190 {
191 $index = $this->pt->get_subpage();
192 if (!empty($index) && empty($_GET['idx'])) {
193 $_GET['idx'] = $index;
194 }
195 }
196
197 private function render($index)
198 {
199 $index = sanitize_file_name($index);
200
201 $this->info = (object) $this->pt->get_info();
202 $file = $this->pt->path.'/includes/admin/'.$index.'.php';
203
204 $file = apply_filters('docketcache/filter/view/render', $file, $index);
205 $file = preg_replace('@(\.\.\/|\.\/)@', '', $file);
206
207 if (@is_file($file)) {
208 include_once $file;
209 }
210 }
211
212 public function index($po = false)
213 {
214 if (!empty($_SERVER['REQUEST_URI']) && false === strpos($_SERVER['REQUEST_URI'], '/'.$this->pt->page)) {
215 $url = network_admin_url('/'.$this->pt->page);
216 echo '<meta http-equiv="refresh" content="3;url='.$url.'">';
217 echo '<script>window.setTimeout(function() { location.assign("'.$url.'"); }, 2000);</script>';
218 exit('<div class="wrap"><p>[ '.date('Y-m-d H:i:s').' ] Redirect to /'.$this->pt->page.'</p></div>');
219 }
220
221 $this->parse_subpage();
222
223 $this->do_preload = false;
224 $this->do_flush = false;
225 $this->do_fetch = false;
226
227 // for addon
228 $this->po = $po;
229
230 $this->render('wrap');
231 $this->pt->cx()->delay_expire();
232 }
233
234 private function tab_title($title, $cls = '')
235 {
236 $class = !empty($cls) ? ' '.$cls : '';
237 echo '<h2 class="title'.$class.'">'.$title.'</h2>';
238 $this->action_notice();
239 }
240
241 private function tab_content()
242 {
243 $this->render($this->is_index());
244 }
245
246 private function tab_query($index, $args_extra = [])
247 {
248 $args = array_merge(
249 [
250 'idx' => $index,
251 ],
252 $args_extra
253 );
254
255 $page = $this->pt->page;
256 if (!empty($args['idx']) && $this->pt->is_subpage($args['idx'])) {
257 $page = $page.'-'.$args['idx'];
258 }
259
260 return network_admin_url(add_query_arg($args, $page));
261 }
262
263 private function is_index()
264 {
265 $idx = !empty($_GET['idx']) ? sanitize_text_field($_GET['idx']) : 'overview';
266 switch ($idx) {
267 case 'log':
268 if (!$this->log_enable) {
269 $idx = 'config';
270 }
271 break;
272 case 'cronbot':
273 if (!$this->cronbot_enable) {
274 $idx = 'config';
275 }
276 break;
277 case 'opcviewer':
278 if (!$this->opcviewer_enable) {
279 $idx = 'config';
280 }
281 break;
282 }
283
284 return $idx;
285 }
286
287 private function tab_current($index)
288 {
289 return $index === $this->is_index();
290 }
291
292 private function tab_active($index)
293 {
294 if ($this->tab_current($index)) {
295 return ' nav-tab-active';
296 }
297
298 return '';
299 }
300
301 private function tab_nav()
302 {
303 $lists = [];
304 $lists['overview'] = esc_html__('Overview', 'docket-cache');
305
306 if ($this->cronbot_enable) {
307 $lists['cronbot'] = esc_html__('Cronbot', 'docket-cache');
308 }
309
310 if ($this->opcviewer_enable) {
311 $lists['opcviewer'] = esc_html__('OPcache', 'docket-cache');
312 }
313
314 $lists = apply_filters('docketcache/filter/view/tabnavbefore', $lists);
315
316 if ($this->log_enable) {
317 $lists['log'] = esc_html__('Cache Log', 'docket-cache');
318 }
319
320 $lists['config'] = esc_html__('Configuration', 'docket-cache');
321
322 $lists = apply_filters('docketcache/filter/view/tabnavafter', $lists);
323
324 $option = '';
325 $html = '<nav class="nav-tab-wrapper">';
326 $html .= '<div id="dclogo" style="background: url('.Resc::iconnav().') no-repeat left;"></div>';
327 foreach ($lists as $id => $text) {
328 $link = $this->tab_query($id);
329 $active = $this->tab_active($id);
330 $html .= '<a href="'.$link.'" class="nav-tab'.$active.'" title="'.$text.'">'.$text.'</a>';
331
332 $selected = $this->tab_current($id) ? ' selected' : '';
333 $option .= '<option value="'.$id.'" data-action-link="'.$link.'"'.$selected.'>'.$text.'</option>';
334 }
335
336 $html .= '<select class="nav-select" style="display:none;">';
337 $html .= $option;
338 $html .= '</select>';
339
340 $html .= '</nav>';
341
342 echo $html;
343 }
344
345 private function change_timestamp($time)
346 {
347 $timestamp = '';
348 $val = $this->vcf()->dcvalue('LOG_TIME');
349 if ('utc' !== $val) {
350 switch ($val) {
351 case 'local':
352 $timestamp = wp_date('Y-m-d H:i:s', $time);
353 break;
354 case 'wp':
355 $timestamp = wp_date(get_option('date_format'), $time).' '.wp_date(get_option('time_format'), $time);
356 break;
357 }
358 }
359
360 return $timestamp;
361 }
362
363 private function maybe_change_timestamp($data)
364 {
365 if (preg_match('@^\[([0-9A-Z\.\:\-\+ ]+)\]\s+@', $data, $mm)) {
366 $tm = strtotime($mm[1]);
367 $timestamp = $this->change_timestamp($tm);
368
369 if (!empty($timestamp)) {
370 $data = str_replace('['.$mm[1].']', '['.$timestamp.']', $data);
371 }
372 }
373
374 return $data;
375 }
376
377 private function parse_log($data)
378 {
379 if (preg_match('@^\[([^\]]+)\]\s+([a-zA-Z]+):\s+"([^"]+)"\s+"([^"]+)"\s+"([^"]+)"@', $data, $mm)) {
380 $tm = strtotime($mm[1]);
381 $timestamp = $this->change_timestamp($tm);
382
383 if (!empty($timestamp)) {
384 $mm[1] = $timestamp;
385 }
386
387 return $mm;
388 }
389
390 return $data;
391 }
392
393 private function read_log($limit = 100, $do_last = true)
394 {
395 $limit = (int) $limit;
396 $output = [];
397 if ($this->pt->has_log($logfile)) {
398 if (!@is_file($logfile)) {
399 $output = [];
400 }
401 foreach ($this->tail($logfile, $limit, $do_last) as $line) {
402 $line = trim($line);
403 if (empty($line)) {
404 continue;
405 }
406 $output[] = $this->maybe_change_timestamp($line);
407 }
408 }
409
410 return $output;
411 }
412
413 private function config_select_bool($name, $default = 'dcdefault', $idx = 'config', $quiet = false)
414 {
415 if (empty($default) || 'dcdefault' === $default) {
416 $default = $this->vcf()->dcvalue(strtoupper($name), true);
417 }
418
419 $args = [];
420 $args['idx'] = $idx;
421
422 if (\is_array($idx) && !empty($idx)) {
423 $args = array_merge($args, $idx);
424 }
425
426 if ($quiet) {
427 $args['quiet'] = 1;
428 }
429
430 if (empty($args['nodefault'])) {
431 $options['default'] = __('Default', 'docket-cache');
432 }
433
434 $options['enable'] = __('Enable', 'docket-cache');
435 $options['disable'] = __('Disable', 'docket-cache');
436
437 $cls = !empty($args['cls']) ? $args['cls'] : 'config-select';
438 $default = $default ? 'enable' : 'disable';
439 $html = '<select id="'.$name.'" class="'.$cls.'">';
440 foreach ($options as $n => $v) {
441 $action = $n.'-'.$name;
442 $url = $this->pt->action_query($action, $args);
443 $selected = $n === $default ? ' selected' : '';
444 $html .= '<option value="'.$n.'" data-action-link="'.$url.'"'.$selected.'>'.$v.'</option>';
445 }
446 $html .= '</select>';
447
448 return $html;
449 }
450
451 private function config_select_bool_e($name, $default = 'dcdefault', $idx = 'config', $quiet = false)
452 {
453 echo $this->config_select_bool($name, $default, $idx, $quiet);
454 }
455
456 private function config_select_set($name, $options, $default = 'dcdefault', $idx = 'config')
457 {
458 if (empty($default) || 'dcdefault' === $default) {
459 $default = $this->vcf()->dcvalue(strtoupper($name), true);
460 }
461
462 $args = [];
463 $args['idx'] = $idx;
464
465 if (\is_array($idx) && !empty($idx)) {
466 $args = array_merge($args, $idx);
467 }
468
469 $action = 'save-'.$name;
470 $html = '<select id="'.$name.'" class="config-select">';
471 foreach ((array) $options as $n => $v) {
472 $args['nv'] = $n;
473 $url = $this->pt->action_query($action, $args);
474 $selected = $n === $default ? ' selected' : '';
475 $html .= '<option value="'.$n.'" data-action-link="'.$url.'"'.$selected.'>'.$v.'</option>';
476 }
477 $html .= '</select>';
478
479 return $html;
480 }
481
482 private function config_select_set_e($name, $options, $default = 'dcdefault', $idx = 'config')
483 {
484 echo $this->config_select_set($name, $options, $default, $idx);
485 }
486
487 private function has_vcache()
488 {
489 return !empty($_GET['vcache']);
490 }
491
492 private function idx_vcache()
493 {
494 return $this->has_vcache() ? sanitize_text_field($_GET['vcache']) : '';
495 }
496
497 private function is_dropin_exists()
498 {
499 return $this->pt->cx()->exists();
500 }
501
502 private function is_dropin_validate()
503 {
504 return $this->pt->cx()->validate();
505 }
506
507 private function is_dropin_multinet()
508 {
509 return $this->pt->cx()->multinet_me();
510 }
511
512 private function cronbot_eventlist()
513 {
514 static $inst;
515
516 try {
517 if (!\is_object($inst)) {
518 $inst = new EventList($this->pt);
519 }
520
521 $inst->prepare_items();
522
523 return $inst;
524 } catch (\Throwable $e) {
525 nwdcx_throwable(__METHOD__, $e);
526 }
527
528 return false;
529 }
530
531 private function opcache_view()
532 {
533 static $inst;
534
535 try {
536 if (!\is_object($inst)) {
537 $inst = new OPcacheView($this->pt);
538 }
539
540 $inst->prepare_items();
541
542 return $inst;
543 } catch (\Throwable $e) {
544 nwdcx_throwable(__METHOD__, $e);
545 }
546
547 return false;
548 }
549
550 private function code_focus()
551 {
552 if (empty($_GET['nx'])) {
553 return;
554 }
555
556 $nx = sanitize_text_field($_GET['nx']);
557
558 if (WpConfig::is_runtimeconst($nx) && WpConfig::is_runtimefalse()) {
559 return;
560 }
561
562 $code = '<script data-cfasync="false" data-noptimize="1" data-no-minify="1" id="docket-cache-focus">'.\PHP_EOL;
563 $code .= '(function($) {';
564 $code .= '$(document).ready(function() {';
565 $code .= 'var fx = $(document).find("tr#'.$nx.'");';
566 $code .= 'if ( fx && fx[0]) {';
567 $code .= 'fx[0].scrollIntoView({block:"center"});';
568 $code .= 'if ( $(document).find("div").hasClass("notice") ) {';
569 $code .= 'fx.addClass("notice-focus");';
570 $code .= 'var mx = $(document).find("div.notice");';
571 $code .= 'var mg = mx.text();';
572 $code .= 'var tc = "";';
573 $code .= 'if ( mx.hasClass("notice-success") ) { tc = "text-green"; } else if ( mx.hasClass("notice-alert") ) { tc = "text-red"; } else if ( mx.hasClass("notice-warning") ) { tc = "text-maroon"; }';
574 $code .= 'fx.children("td").append("<p id=\"innotice\" class=\""+tc+"\">"+mg+"</p>");';
575 $code .= 'setTimeout(function() { fx.removeClass("notice-focus"); }, 3000);';
576 $code .= '}';
577 $code .= '}';
578 $code .= '});';
579 $code .= '})(jQuery);'.\PHP_EOL;
580 $code .= '</script>';
581
582 return $code;
583 }
584
585 private function tooltip($id)
586 {
587 $info = [
588 'cronbot' => esc_html__('The Cronbot is an external service that pings your website every hour to keep WordPress Cron running actively.', 'docket-cache'),
589 'log' => esc_html__('The cache log intends to provide information on how the cache works. For performance and security concerns, disable it if no longer needed.', 'docket-cache'),
590 'opcviewer' => esc_html__('OPcache Viewer allows you to view OPcache status and usage.', 'docket-cache'),
591 'menucache' => esc_html__('Cache the WordPress dynamic navigation menu.', 'docket-cache'),
592 'precache' => esc_html__('Increase cache performance by early loading cached objects based on the current URL.', 'docket-cache'),
593 'mocache' => esc_html__('Improve the performance of the WordPress Translation function.', 'docket-cache'),
594 'optwpquery' => esc_html__('Docket Cache will attempt to optimize WordPress core query when this option enabled.', 'docket-cache'),
595 'limitbulkedit' => esc_html__('Enable this option to disable Bulk Edit Actions when reaching the listed item limit. By default, the bulk edit limit is set to 100.', 'docket-cache'),
596 'optermcount' => esc_html__('Improve the performance of Word Term Count Update.', 'docket-cache'),
597 'cronoptmzdb' => esc_html__('Docket Cache will optimize WordPress database tables using SQL optimizing syntax at scheduled times.', 'docket-cache'),
598 'wpoptaload' => esc_html__('Reduce the size of Options Autoload by excluding non-WordPress Option from autoloading.', 'docket-cache'),
599 'postmissedschedule' => esc_html__('Fix the WordPress Missed Schedule Error after scheduling a future blog post.', 'docket-cache'),
600 'misc_tweaks' => esc_html__('Miscellaneous WordPress Tweaks. Including performance, security and user experience.', 'docket-cache'),
601 'wootweaks' => esc_html__('Miscellaneous WooCommerce Tweaks. Including performance, security and user experience.', 'docket-cache'),
602 'wooadminoff' => esc_html__('WooCommerce Admin or Analytics page is a new JavaScript-driven interface for managing stores. Enable this option to turn off any feature-related.', 'docket-cache'),
603 'woowidgetoff' => esc_html__('Deactivate WooCommerce Classic Widget feature.', 'docket-cache'),
604 'woowpdashboardoff' => esc_html__('Remove the WooCommerce meta box in the WordPress Dashboard.', 'docket-cache'),
605 'woocartfragsoff' => esc_html__('Remove the WooCommerce Cart Fragments.', 'docket-cache'),
606 'wooextensionpageoff' => esc_html__('Remove WooCommerce Extensions page that includes My Subscriptions page.', 'docket-cache'),
607 'wooaddtochartcrawling' => esc_html__('This option will add rules to robots.txt to prevent robots from crawling add-to-cart links.', 'docket-cache'),
608 'pingback' => esc_html__('Deactivate the WordPress XML-RPC and Pingbacks related features.', 'docket-cache'),
609 'headerjunk' => esc_html__('Remove WordPress features related to HTML header such as meta generators and feed links to reduce the page size.', 'docket-cache'),
610 'wpemoji' => esc_html__('Deactivate the WordPress Emoji feature.', 'docket-cache'),
611 'wpfeed' => esc_html__('Deactivate the WordPress Feed feature.', 'docket-cache'),
612 'wpembed' => esc_html__('Deactivate the WordPress Embed feature.', 'docket-cache'),
613 'wplazyload' => esc_html__('Deactivate the WordPress Lazy Load feature.', 'docket-cache'),
614 'wpsitemap' => esc_html__('Deactivate the WordPress Auto-generate Sitemap feature.', 'docket-cache'),
615 'wpapppassword' => esc_html__('Deactivate the WordPress Application Passwords feature.', 'docket-cache'),
616 'wpdashboardnews' => esc_html__('Deactivate the WordPress Events & News feed in Dashboard.', 'docket-cache'),
617 'wpbrowsehappy' => esc_html__('Enable this option to turn off Browse Happy HTTP API requests, which checks whether the user needs a browser update.', 'docket-cache'),
618 'wpservehappy' => esc_html__('Enable this option to turn off the Serve Happy HTTP API request, which checks whether the user needs to update PHP.', 'docket-cache'),
619 'postviaemail' => esc_html__('Enable this option to disable the post-via-email functionality.', 'docket-cache'),
620 'preload' => esc_html__('Preload Object Cache by fetching administrator-related pages.', 'docket-cache'),
621 'pageloader' => esc_html__('Display page loader when loading administrator pages.', 'docket-cache'),
622 'stats' => esc_html__('Display Object Cache stats at Overview page.', 'docket-cache'),
623 'gcaction' => esc_html__('Enable the Garbage Collector action button on the Overview page.', 'docket-cache'),
624 'flushaction' => esc_html__('Enable the additional Flush Cache action button on the Configuration page.', 'docket-cache'),
625 'autoupdate_toggle' => esc_html__('Enable automatic plugin updates for Docket Cache.', 'docket-cache'),
626 'checkversion' => esc_html__('Allows Docket Cache to check any critical future version that requires removing cache files after doing the updates, purposely to avoid error-prone.', 'docket-cache'),
627 'flush_shutdown' => esc_html__('Flush Object Cache when deactivate / uninstall.', 'docket-cache'),
628 'opcshutdown' => esc_html__('Flush OPcache when deactivate / uninstall.', 'docket-cache'),
629 'maxsize_disk' => esc_html__('Maximum size of the cache storage on disk. The garbage collector will remove the cache file to free up storage space.', 'docket-cache'),
630 'maxfile' => esc_html__('The maximum cache file can be stored on a disk. The cache file will free up by the garbage collector when triggered by WP Cron.', 'docket-cache'),
631 'maxfile_livecheck' => esc_html__('Enable this option to allow Docket Cache to monitor the cache file limit in real-time.', 'docket-cache'),
632 'chunkcachedir' => esc_html__('Enable this option to chunk cache files into smaller directories to avoid an excessive number of cache files in one directory. Only enable it if you have difficulty clearing the cache manually or experience slowdowns when the cache becomes too large.', 'docket-cache'),
633 'flush_stalecache' => esc_html__('Enable this option to allow GC immediately remove the stale cache abandoned by WordPress, WooCommerce and others after doing cache invalidation.', 'docket-cache'),
634 'stalecache_ignore' => esc_html__('Enable this option to exclude stale cache created by WordPress, WooCommerce, and others from being stored on disk. Only enable it if you have an issue with inode limits.', 'docket-cache'),
635 'emptycache_ignore' => esc_html__('Enable this option to exclude empty caches from being stored on disk. Only enable it if you have an issue with inode limits.', 'docket-cache'),
636 'limithttprequest' => esc_html__('Limit HTTP requests in WP Admin.', 'docket-cache'),
637 'transientdb' => esc_html__('WordPress by default converts Transients as persistent object caching when available. Enable this option to persist Transients in the Database.', 'docket-cache'),
638 'rtpostautosave' => esc_html__('WordPress by default automatically saves a draft every 1 minute when editing or create a new post. Changing this behaviour can reduce the usage of server resource.', 'docket-cache'),
639 'rtpostrevision' => esc_html__('Post revision is a copy of each edit made to a post or page, allowing the possibility of reverting to a previous version. However, have a revision too much can create a bad impact on database performance. Changing this behaviour can reduce the usage of server resource.', 'docket-cache'),
640 'rtpostemptytrash' => esc_html__('This option allows you to change the number of days before WordPress permanently deletes posts, pages, attachments, and comments, from the trash bin. The default is 30 days. There is no confirmation alert when someone clicks on "Delete Permanently" if this option is set to "Disable Trash Bin".', 'docket-cache'),
641 'rtpluginthemeeditor' => esc_html__('This option will completely disable the use of plugin and theme editor. If this option enabled, no plugins or theme file can be edited.', 'docket-cache'),
642 'rtpluginthemeinstall' => esc_html__('This option will block users being able to use the plugin and theme installation/update functionality from the WordPress admin area.', 'docket-cache'),
643 'rtimageoverwrite' => esc_html__('By default, WordPress creates a new set of images every time you edit image and restore the original. It leaves all the edits on the server. Enable this option to change this behaviour.', 'docket-cache'),
644 'rtwpdebug' => esc_html__('Enable this option to turn on WordPress debugging.', 'docket-cache'),
645 'rtwpdebugdisplay' => esc_html__('Enable this option to print debug info.', 'docket-cache'),
646 'rtwpdebuglog' => esc_html__('Enable this option to log debug info.', 'docket-cache'),
647 'rtwpcoreupdate' => esc_html__('This option will disable all core updates.', 'docket-cache'),
648 'rtconcatenatescripts' => esc_html__('Enable this option to disable compression and concatenation of WP-Admin Scripts and CSS.', 'docket-cache'),
649 'rtdisablewpcron' => esc_html__('Enable this option to disable the WP pseudo-cron. Only enable it if your site is already set up with real Cron.', 'docket-cache'),
650 ];
651
652 if (version_compare($GLOBALS['wp_version'], '6.1', '<')) {
653 $info['advcpost'] = esc_html__('Cache WP Queries for a post which results in faster data retrieval and reduced database workload. By default only for built-in Post Types.', 'docket-cache');
654 $info['advpost_posttype_all'] = esc_html__('Allow Advanced Post Caching to cache any Post Type.', 'docket-cache');
655 }
656
657 if (version_compare($GLOBALS['wp_version'], '5.8', '<')) {
658 $info['httpheadersexpect'] = esc_html__('By default, cURL sends the "Expect" header all the time which severely impacts performance. Enable this option, only send it if the body is larger than 1 MB.', 'docket-cache');
659 }
660
661 $info = apply_filters('docketcache/filter/view/tooltips', $info);
662
663 $text = isset($info[$id]) ? $info[$id] : esc_html__('No info available', 'docket-cache');
664
665 return '<span tabindex="0" data-tooltip="'.$text.'"><span class="dashicons dashicons-editor-help"></span></span>';
666 }
667
668 private function opt_title($id, $tooltip = true, $output = true)
669 {
670 $ret = $this->pt->co()->keys($id);
671 if ($tooltip) {
672 $ret .= $this->tooltip($id);
673 }
674
675 if ($output) {
676 echo $ret;
677 }
678
679 return $ret;
680 }
681
682 private function action_notice()
683 {
684 static $done = false;
685 if (!$done) {
686 if (!empty($this->pt->notice) && !empty($this->pt->token)) {
687 $type = 'success';
688 if (@preg_match('@\-(failed|warn|error|info|success)$@', $this->pt->token, $mm)) {
689 switch ($mm[1]) {
690 case 'failed':
691 case 'error':
692 $type = 'error';
693 break;
694 case 'info':
695 $type = 'info';
696 break;
697 case 'warn':
698 case 'warning':
699 $type = 'warning';
700 break;
701 }
702 }
703
704 echo Resc::boxmsg($this->pt->notice, $type);
705
706 if (WpConfig::is_runtimefalse() && !empty($this->pt->inruntime) && true === $this->pt->inruntime) {
707 $args['idx'] = 'config';
708 if (!empty($_GET['idx'])) {
709 $args['idx'] = sanitize_text_field($_GET['idx']);
710
711 if (!empty($_GET['adx'])) {
712 $args['adx'] = sanitize_text_field($_GET['adx']);
713 }
714 }
715 $action = $this->pt->action_query('runtime', $args);
716 echo Resc::runtimenotice($action);
717 }
718 } else {
719 if (!empty($_GET['idx']) && !empty($_GET['adx'])) {
720 $args['idx'] = sanitize_text_field($_GET['idx']);
721 $adx = sanitize_text_field($_GET['adx']);
722
723 if ('config' === $args['idx'] && 'rtcnf' === $adx) {
724 $args['st'] = time();
725 $action = $this->pt->action_query('runtime', $args);
726
727 $args['adr'] = 1;
728 $action_rm = $this->pt->action_query('runtime', $args);
729 echo Resc::runtimenotice($action, $action_rm);
730 }
731 }
732 }
733 $done = true;
734 }
735 }
736 }
737