PluginProbe
Docket Cache – Object Cache Accelerator / 24.07.03
Docket Cache – Object Cache Accelerator v24.07.03
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.03, at includes/src/View.php

736 lines 29.4 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 if ($this->pt->filesize($file) > 0) {
111 $data = $this->pt->cache_get($file);
112 if (false !== $data) {
113 $ret->output = $this->pt->export_var($data);
114 $ret->output_empty = empty($ret->output);
115 $ret->log_size = $this->pt->normalize_size(\strlen(serialize($data)));
116 $ret->output_size = $ret->log_size;
117 if ($ret->output_size > 15) {
118 $ret->row_size = 25;
119 }
120 }
121 unset($data);
122 }
123 } else {
124 if (!empty($_GET['srt'])) {
125 $srt = explode('-', sanitize_text_field($_GET['srt']));
126 if (3 >= \count($srt)) {
127 $ret->default_order = $srt[0];
128 $ret->default_sort = $srt[1];
129 $ret->default_line = (int) $srt[2];
130 }
131 }
132
133 $ret->output = $this->read_log($ret->default_line, 'last' === $ret->default_order ? true : false);
134 $ret->output_empty = empty($ret->output);
135 $ret->output_size = !$ret->output_empty ? \count($ret->output) : 0;
136 $ret->log_size = $this->pt->get_logsize();
137 if ($ret->output_size < 15) {
138 $ret->row_size = $ret->output_size;
139 }
140 $ret->output = implode("\n", 'desc' === $ret->default_sort ? array_reverse($ret->output, true) : $ret->output);
141 }
142
143 return $ret;
144 }
145
146 private function cronbot_status()
147 {
148 $data = $this->pt->co()->get_part('cronbot');
149 if (!empty($data) && \is_array($data)) {
150 return $data;
151 }
152
153 return false;
154 }
155
156 private function cronbot_pings()
157 {
158 $data = $this->pt->co()->get_part('pings');
159 if (!empty($data) && \is_array($data)) {
160 return $data;
161 }
162
163 return false;
164 }
165
166 private function is_cronbot_connected()
167 {
168 $data = $this->cronbot_status();
169
170 return !empty($data) && !empty($data['connected']);
171 }
172
173 private function ping_next()
174 {
175 $data = $this->cronbot_pings();
176 if (!empty($data) && \is_array($data) && !empty($data['timestamp'])) {
177 $timestamp = strtotime($data['timestamp']);
178
179 return [
180 'last' => wp_date('Y-m-d H:i:s', $timestamp),
181 'next' => wp_date('Y-m-d H:i:s', strtotime('+1 hour', $timestamp)),
182 ];
183 }
184
185 return false;
186 }
187
188 private function parse_subpage()
189 {
190 $index = $this->pt->get_subpage();
191 if (!empty($index) && empty($_GET['idx'])) {
192 $_GET['idx'] = $index;
193 }
194 }
195
196 private function render($index)
197 {
198 $index = sanitize_file_name($index);
199
200 $this->info = (object) $this->pt->get_info();
201 $file = $this->pt->path.'/includes/admin/'.$index.'.php';
202
203 $file = apply_filters('docketcache/filter/view/render', $file, $index);
204 $file = preg_replace('@(\.\.\/|\.\/)@', '', $file);
205
206 if (@is_file($file)) {
207 include_once $file;
208 }
209 }
210
211 public function index($po = false)
212 {
213 if (!empty($_SERVER['REQUEST_URI']) && false === strpos($_SERVER['REQUEST_URI'], '/'.$this->pt->page)) {
214 $url = network_admin_url('/'.$this->pt->page);
215 echo '<meta http-equiv="refresh" content="3;url='.$url.'">';
216 echo '<script>window.setTimeout(function() { location.assign("'.$url.'"); }, 2000);</script>';
217 exit('<div class="wrap"><p>[ '.date('Y-m-d H:i:s').' ] Redirect to /'.$this->pt->page.'</p></div>');
218 }
219
220 $this->parse_subpage();
221
222 $this->do_preload = false;
223 $this->do_flush = false;
224 $this->do_fetch = false;
225
226 // for addon
227 $this->po = $po;
228
229 $this->render('wrap');
230 $this->pt->cx()->delay_expire();
231 }
232
233 private function tab_title($title, $cls = '')
234 {
235 $class = !empty($cls) ? ' '.$cls : '';
236 echo '<h2 class="title'.$class.'">'.$title.'</h2>';
237 $this->action_notice();
238 }
239
240 private function tab_content()
241 {
242 $this->render($this->is_index());
243 }
244
245 private function tab_query($index, $args_extra = [])
246 {
247 $args = array_merge(
248 [
249 'idx' => $index,
250 ],
251 $args_extra
252 );
253
254 $page = $this->pt->page;
255 if (!empty($args['idx']) && $this->pt->is_subpage($args['idx'])) {
256 $page = $page.'-'.$args['idx'];
257 }
258
259 return network_admin_url(add_query_arg($args, $page));
260 }
261
262 private function is_index()
263 {
264 $idx = !empty($_GET['idx']) ? sanitize_text_field($_GET['idx']) : 'overview';
265 switch ($idx) {
266 case 'log':
267 if (!$this->log_enable) {
268 $idx = 'config';
269 }
270 break;
271 case 'cronbot':
272 if (!$this->cronbot_enable) {
273 $idx = 'config';
274 }
275 break;
276 case 'opcviewer':
277 if (!$this->opcviewer_enable) {
278 $idx = 'config';
279 }
280 break;
281 }
282
283 return $idx;
284 }
285
286 private function tab_current($index)
287 {
288 return $index === $this->is_index();
289 }
290
291 private function tab_active($index)
292 {
293 if ($this->tab_current($index)) {
294 return ' nav-tab-active';
295 }
296
297 return '';
298 }
299
300 private function tab_nav()
301 {
302 $lists = [];
303 $lists['overview'] = esc_html__('Overview', 'docket-cache');
304
305 if ($this->cronbot_enable) {
306 $lists['cronbot'] = esc_html__('Cronbot', 'docket-cache');
307 }
308
309 if ($this->opcviewer_enable) {
310 $lists['opcviewer'] = esc_html__('OPcache', 'docket-cache');
311 }
312
313 $lists = apply_filters('docketcache/filter/view/tabnavbefore', $lists);
314
315 if ($this->log_enable) {
316 $lists['log'] = esc_html__('Cache Log', 'docket-cache');
317 }
318
319 $lists['config'] = esc_html__('Configuration', 'docket-cache');
320
321 $lists = apply_filters('docketcache/filter/view/tabnavafter', $lists);
322
323 $option = '';
324 $html = '<nav class="nav-tab-wrapper">';
325 $html .= '<div id="dclogo" style="background: url('.Resc::iconnav().') no-repeat left;"></div>';
326 foreach ($lists as $id => $text) {
327 $link = $this->tab_query($id);
328 $active = $this->tab_active($id);
329 $html .= '<a href="'.$link.'" class="nav-tab'.$active.'" title="'.$text.'">'.$text.'</a>';
330
331 $selected = $this->tab_current($id) ? ' selected' : '';
332 $option .= '<option value="'.$id.'" data-action-link="'.$link.'"'.$selected.'>'.$text.'</option>';
333 }
334
335 $html .= '<select class="nav-select" style="display:none;">';
336 $html .= $option;
337 $html .= '</select>';
338
339 $html .= '</nav>';
340
341 echo $html;
342 }
343
344 private function change_timestamp($time)
345 {
346 $timestamp = '';
347 $val = $this->vcf()->dcvalue('LOG_TIME');
348 if ('utc' !== $val) {
349 switch ($val) {
350 case 'local':
351 $timestamp = wp_date('Y-m-d H:i:s', $time);
352 break;
353 case 'wp':
354 $timestamp = wp_date(get_option('date_format'), $time).' '.wp_date(get_option('time_format'), $time);
355 break;
356 }
357 }
358
359 return $timestamp;
360 }
361
362 private function maybe_change_timestamp($data)
363 {
364 if (preg_match('@^\[([0-9A-Z\.\:\-\+ ]+)\]\s+@', $data, $mm)) {
365 $tm = strtotime($mm[1]);
366 $timestamp = $this->change_timestamp($tm);
367
368 if (!empty($timestamp)) {
369 $data = str_replace('['.$mm[1].']', '['.$timestamp.']', $data);
370 }
371 }
372
373 return $data;
374 }
375
376 private function parse_log($data)
377 {
378 if (preg_match('@^\[([^\]]+)\]\s+([a-zA-Z]+):\s+"([^"]+)"\s+"([^"]+)"\s+"([^"]+)"@', $data, $mm)) {
379 $tm = strtotime($mm[1]);
380 $timestamp = $this->change_timestamp($tm);
381
382 if (!empty($timestamp)) {
383 $mm[1] = $timestamp;
384 }
385
386 return $mm;
387 }
388
389 return $data;
390 }
391
392 private function read_log($limit = 100, $do_last = true)
393 {
394 $limit = (int) $limit;
395 $output = [];
396 if ($this->pt->has_log($logfile)) {
397 if (!@is_file($logfile)) {
398 $output = [];
399 }
400 foreach ($this->tail($logfile, $limit, $do_last) as $line) {
401 $line = trim($line);
402 if (empty($line)) {
403 continue;
404 }
405 $output[] = $this->maybe_change_timestamp($line);
406 }
407 }
408
409 return $output;
410 }
411
412 private function config_select_bool($name, $default = 'dcdefault', $idx = 'config', $quiet = false)
413 {
414 if (empty($default) || 'dcdefault' === $default) {
415 $default = $this->vcf()->dcvalue(strtoupper($name), true);
416 }
417
418 $args = [];
419 $args['idx'] = $idx;
420
421 if (\is_array($idx) && !empty($idx)) {
422 $args = array_merge($args, $idx);
423 }
424
425 if ($quiet) {
426 $args['quiet'] = 1;
427 }
428
429 if (empty($args['nodefault'])) {
430 $options['default'] = __('Default', 'docket-cache');
431 }
432
433 $options['enable'] = __('Enable', 'docket-cache');
434 $options['disable'] = __('Disable', 'docket-cache');
435
436 $cls = !empty($args['cls']) ? $args['cls'] : 'config-select';
437 $default = $default ? 'enable' : 'disable';
438 $html = '<select id="'.$name.'" class="'.$cls.'">';
439 foreach ($options as $n => $v) {
440 $action = $n.'-'.$name;
441 $url = $this->pt->action_query($action, $args);
442 $selected = $n === $default ? ' selected' : '';
443 $html .= '<option value="'.$n.'" data-action-link="'.$url.'"'.$selected.'>'.$v.'</option>';
444 }
445 $html .= '</select>';
446
447 return $html;
448 }
449
450 private function config_select_bool_e($name, $default = 'dcdefault', $idx = 'config', $quiet = false)
451 {
452 echo $this->config_select_bool($name, $default, $idx, $quiet);
453 }
454
455 private function config_select_set($name, $options, $default = 'dcdefault', $idx = 'config')
456 {
457 if (empty($default) || 'dcdefault' === $default) {
458 $default = $this->vcf()->dcvalue(strtoupper($name), true);
459 }
460
461 $args = [];
462 $args['idx'] = $idx;
463
464 if (\is_array($idx) && !empty($idx)) {
465 $args = array_merge($args, $idx);
466 }
467
468 $action = 'save-'.$name;
469 $html = '<select id="'.$name.'" class="config-select">';
470 foreach ((array) $options as $n => $v) {
471 $args['nv'] = $n;
472 $url = $this->pt->action_query($action, $args);
473 $selected = $n === $default ? ' selected' : '';
474 $html .= '<option value="'.$n.'" data-action-link="'.$url.'"'.$selected.'>'.$v.'</option>';
475 }
476 $html .= '</select>';
477
478 return $html;
479 }
480
481 private function config_select_set_e($name, $options, $default = 'dcdefault', $idx = 'config')
482 {
483 echo $this->config_select_set($name, $options, $default, $idx);
484 }
485
486 private function has_vcache()
487 {
488 return !empty($_GET['vcache']);
489 }
490
491 private function idx_vcache()
492 {
493 return $this->has_vcache() ? sanitize_text_field($_GET['vcache']) : '';
494 }
495
496 private function is_dropin_exists()
497 {
498 return $this->pt->cx()->exists();
499 }
500
501 private function is_dropin_validate()
502 {
503 return $this->pt->cx()->validate();
504 }
505
506 private function is_dropin_multinet()
507 {
508 return $this->pt->cx()->multinet_me();
509 }
510
511 private function cronbot_eventlist()
512 {
513 static $inst;
514
515 try {
516 if (!\is_object($inst)) {
517 $inst = new EventList($this->pt);
518 }
519
520 $inst->prepare_items();
521
522 return $inst;
523 } catch (\Throwable $e) {
524 nwdcx_throwable(__METHOD__, $e);
525 }
526
527 return false;
528 }
529
530 private function opcache_view()
531 {
532 static $inst;
533
534 try {
535 if (!\is_object($inst)) {
536 $inst = new OPcacheView($this->pt);
537 }
538
539 $inst->prepare_items();
540
541 return $inst;
542 } catch (\Throwable $e) {
543 nwdcx_throwable(__METHOD__, $e);
544 }
545
546 return false;
547 }
548
549 private function code_focus()
550 {
551 if (empty($_GET['nx'])) {
552 return;
553 }
554
555 $nx = sanitize_text_field($_GET['nx']);
556
557 if (WpConfig::is_runtimeconst($nx) && WpConfig::is_runtimefalse()) {
558 return;
559 }
560
561 $code = '<script data-cfasync="false" data-noptimize="1" data-no-minify="1" id="docket-cache-focus">'.\PHP_EOL;
562 $code .= '(function($) {';
563 $code .= '$(document).ready(function() {';
564 $code .= 'var fx = $(document).find("tr#'.$nx.'");';
565 $code .= 'if ( fx && fx[0]) {';
566 $code .= 'fx[0].scrollIntoView({block:"center"});';
567 $code .= 'if ( $(document).find("div").hasClass("notice") ) {';
568 $code .= 'fx.addClass("notice-focus");';
569 $code .= 'var mx = $(document).find("div.notice");';
570 $code .= 'var mg = mx.text();';
571 $code .= 'var tc = "";';
572 $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"; }';
573 $code .= 'fx.children("td").append("<p id=\"innotice\" class=\""+tc+"\">"+mg+"</p>");';
574 $code .= 'setTimeout(function() { fx.removeClass("notice-focus"); }, 3000);';
575 $code .= '}';
576 $code .= '}';
577 $code .= '});';
578 $code .= '})(jQuery);'.\PHP_EOL;
579 $code .= '</script>';
580
581 return $code;
582 }
583
584 private function tooltip($id)
585 {
586 $info = [
587 'cronbot' => esc_html__('The Cronbot is an external service that pings your website every hour to keep WordPress Cron running actively.', 'docket-cache'),
588 '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'),
589 'opcviewer' => esc_html__('OPcache Viewer allows you to view OPcache status and usage.', 'docket-cache'),
590 'menucache' => esc_html__('Cache the WordPress dynamic navigation menu.', 'docket-cache'),
591 'precache' => esc_html__('Increase cache performance by early loading cached objects based on the current URL.', 'docket-cache'),
592 'mocache' => esc_html__('Improve the performance of the WordPress Translation function.', 'docket-cache'),
593 'optwpquery' => esc_html__('Docket Cache will attempt to optimize WordPress core query when this option enabled.', 'docket-cache'),
594 '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'),
595 'optermcount' => esc_html__('Improve the performance of Word Term Count Update.', 'docket-cache'),
596 'cronoptmzdb' => esc_html__('Docket Cache will optimize WordPress database tables using SQL optimizing syntax at scheduled times.', 'docket-cache'),
597 'wpoptaload' => esc_html__('Reduce the size of Options Autoload by excluding non-WordPress Option from autoloading.', 'docket-cache'),
598 'postmissedschedule' => esc_html__('Fix the WordPress Missed Schedule Error after scheduling a future blog post.', 'docket-cache'),
599 'misc_tweaks' => esc_html__('Miscellaneous WordPress Tweaks. Including performance, security and user experience.', 'docket-cache'),
600 'wootweaks' => esc_html__('Miscellaneous WooCommerce Tweaks. Including performance, security and user experience.', 'docket-cache'),
601 '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'),
602 'woowidgetoff' => esc_html__('Deactivate WooCommerce Classic Widget feature.', 'docket-cache'),
603 'woowpdashboardoff' => esc_html__('Remove the WooCommerce meta box in the WordPress Dashboard.', 'docket-cache'),
604 'woocartfragsoff' => esc_html__('Remove the WooCommerce Cart Fragments.', 'docket-cache'),
605 'wooextensionpageoff' => esc_html__('Remove WooCommerce Extensions page that includes My Subscriptions page.', 'docket-cache'),
606 'wooaddtochartcrawling' => esc_html__('This option will add rules to robots.txt to prevent robots from crawling add-to-cart links.', 'docket-cache'),
607 'pingback' => esc_html__('Deactivate the WordPress XML-RPC and Pingbacks related features.', 'docket-cache'),
608 'headerjunk' => esc_html__('Remove WordPress features related to HTML header such as meta generators and feed links to reduce the page size.', 'docket-cache'),
609 'wpemoji' => esc_html__('Deactivate the WordPress Emoji feature.', 'docket-cache'),
610 'wpfeed' => esc_html__('Deactivate the WordPress Feed feature.', 'docket-cache'),
611 'wpembed' => esc_html__('Deactivate the WordPress Embed feature.', 'docket-cache'),
612 'wplazyload' => esc_html__('Deactivate the WordPress Lazy Load feature.', 'docket-cache'),
613 'wpsitemap' => esc_html__('Deactivate the WordPress Auto-generate Sitemap feature.', 'docket-cache'),
614 'wpapppassword' => esc_html__('Deactivate the WordPress Application Passwords feature.', 'docket-cache'),
615 'wpdashboardnews' => esc_html__('Deactivate the WordPress Events & News feed in Dashboard.', 'docket-cache'),
616 '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'),
617 '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'),
618 'postviaemail' => esc_html__('Enable this option to disable the post-via-email functionality.', 'docket-cache'),
619 'preload' => esc_html__('Preload Object Cache by fetching administrator-related pages.', 'docket-cache'),
620 'pageloader' => esc_html__('Display page loader when loading administrator pages.', 'docket-cache'),
621 'stats' => esc_html__('Display Object Cache stats at Overview page.', 'docket-cache'),
622 'gcaction' => esc_html__('Enable the Garbage Collector action button on the Overview page.', 'docket-cache'),
623 'flushaction' => esc_html__('Enable the additional Flush Cache action button on the Configuration page.', 'docket-cache'),
624 'autoupdate_toggle' => esc_html__('Enable automatic plugin updates for Docket Cache.', 'docket-cache'),
625 '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'),
626 'flush_shutdown' => esc_html__('Flush Object Cache when deactivate / uninstall.', 'docket-cache'),
627 'opcshutdown' => esc_html__('Flush OPcache when deactivate / uninstall.', 'docket-cache'),
628 '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'),
629 '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'),
630 'maxfile_livecheck' => esc_html__('Enable this option to allow Docket Cache to monitor the cache file limit in real-time.', 'docket-cache'),
631 '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'),
632 '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'),
633 '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'),
634 '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'),
635 'limithttprequest' => esc_html__('Limit HTTP requests in WP Admin.', 'docket-cache'),
636 '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'),
637 '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'),
638 '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'),
639 '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'),
640 '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'),
641 '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'),
642 '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'),
643 'rtwpdebug' => esc_html__('Enable this option to turn on WordPress debugging.', 'docket-cache'),
644 'rtwpdebugdisplay' => esc_html__('Enable this option to print debug info.', 'docket-cache'),
645 'rtwpdebuglog' => esc_html__('Enable this option to log debug info.', 'docket-cache'),
646 'rtwpcoreupdate' => esc_html__('This option will disable all core updates.', 'docket-cache'),
647 'rtconcatenatescripts' => esc_html__('Enable this option to disable compression and concatenation of WP-Admin Scripts and CSS.', 'docket-cache'),
648 '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'),
649 ];
650
651 if (version_compare($GLOBALS['wp_version'], '6.1', '<')) {
652 $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');
653 $info['advpost_posttype_all'] = esc_html__('Allow Advanced Post Caching to cache any Post Type.', 'docket-cache');
654 }
655
656 if (version_compare($GLOBALS['wp_version'], '5.8', '<')) {
657 $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');
658 }
659
660 $info = apply_filters('docketcache/filter/view/tooltips', $info);
661
662 $text = isset($info[$id]) ? $info[$id] : esc_html__('No info available', 'docket-cache');
663
664 return '<span tabindex="0" data-tooltip="'.$text.'"><span class="dashicons dashicons-editor-help"></span></span>';
665 }
666
667 private function opt_title($id, $tooltip = true, $output = true)
668 {
669 $ret = $this->pt->co()->keys($id);
670 if ($tooltip) {
671 $ret .= $this->tooltip($id);
672 }
673
674 if ($output) {
675 echo $ret;
676 }
677
678 return $ret;
679 }
680
681 private function action_notice()
682 {
683 static $done = false;
684 if (!$done) {
685 if (!empty($this->pt->notice) && !empty($this->pt->token)) {
686 $type = 'success';
687 if (@preg_match('@\-(failed|warn|error|info|success)$@', $this->pt->token, $mm)) {
688 switch ($mm[1]) {
689 case 'failed':
690 case 'error':
691 $type = 'error';
692 break;
693 case 'info':
694 $type = 'info';
695 break;
696 case 'warn':
697 case 'warning':
698 $type = 'warning';
699 break;
700 }
701 }
702
703 echo Resc::boxmsg($this->pt->notice, $type);
704
705 if (WpConfig::is_runtimefalse() && !empty($this->pt->inruntime) && true === $this->pt->inruntime) {
706 $args['idx'] = 'config';
707 if (!empty($_GET['idx'])) {
708 $args['idx'] = sanitize_text_field($_GET['idx']);
709
710 if (!empty($_GET['adx'])) {
711 $args['adx'] = sanitize_text_field($_GET['adx']);
712 }
713 }
714 $action = $this->pt->action_query('runtime', $args);
715 echo Resc::runtimenotice($action);
716 }
717 } else {
718 if (!empty($_GET['idx']) && !empty($_GET['adx'])) {
719 $args['idx'] = sanitize_text_field($_GET['idx']);
720 $adx = sanitize_text_field($_GET['adx']);
721
722 if ('config' === $args['idx'] && 'rtcnf' === $adx) {
723 $args['st'] = time();
724 $action = $this->pt->action_query('runtime', $args);
725
726 $args['adr'] = 1;
727 $action_rm = $this->pt->action_query('runtime', $args);
728 echo Resc::runtimenotice($action, $action_rm);
729 }
730 }
731 }
732 $done = true;
733 }
734 }
735 }
736