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