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

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

618 lines 18.3 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 use WP_CLI;
16 use WP_CLI_Command;
17
18 /**
19 * Enables, disabled, updates, and checks the status of the Docket object cache.
20 */
21 class Command extends WP_CLI_Command
22 {
23 private $pt;
24
25 public function __construct(Plugin $pt)
26 {
27 if (empty($_SERVER['HTTP_HOST'])) {
28 $_SERVER['HTTP_HOST'] = wp_parse_url(site_url(), \PHP_URL_HOST);
29 }
30
31 $this->pt = $pt;
32 }
33
34 private function print_stdout($text, $nl = true)
35 {
36 if (!empty($_SERVER['argv']) && \in_array('--quiet', $_SERVER['argv'])) {
37 return;
38 }
39 fwrite(\STDOUT, $text.($nl ? "\n" : ''));
40 }
41
42 private function clear_line()
43 {
44 $this->print_stdout("\r".str_repeat(' ', 100)."\r", false);
45 }
46
47 private function halt_warning($warning)
48 {
49 WP_CLI::warning($warning);
50 WP_CLI::halt(2);
51 }
52
53 private function halt_error($error)
54 {
55 WP_CLI::error($error, false);
56 WP_CLI::halt(1);
57 }
58
59 private function halt_success($success)
60 {
61 WP_CLI::success($success, false);
62 WP_CLI::halt(0);
63 }
64
65 private function halt_status($text, $status = 0)
66 {
67 $this->print_stdout($text);
68 WP_CLI::halt($status);
69 }
70
71 private function title($text, $pad = 15)
72 {
73 return str_pad($text, $pad).': ';
74 }
75
76 private function status_color($status, $text)
77 {
78 switch ($status) {
79 case 1:
80 $text = WP_CLI::colorize("%g{$text}%n");
81 break;
82 default:
83 $text = WP_CLI::colorize("%r{$text}%n");
84 break;
85 }
86
87 return $text;
88 }
89
90 private function dropino_runtime_status()
91 {
92 $info = (object) $this->pt->get_info();
93 if (2 === $info->status_code) {
94 $this->print_stdout($this->title('Cache Status').$this->status_color($info->status_code, $info->status_text));
95 unset($info);
96 WP_CLI::halt(1);
97 }
98 unset($info);
99 }
100
101 /**
102 * Display the Docket Cache status.
103 *
104 * ## EXAMPLES
105 *
106 * wp cache status
107 */
108 public function status()
109 {
110 $info = (object) $this->pt->get_info();
111 $halt = $info->status_code ? 0 : 1;
112
113 $line = str_repeat('-', 15).':'.str_repeat('-', \strlen($info->cache_path) + 2);
114 $this->print_stdout($line);
115 $this->print_stdout($this->title('Cache Status').$this->status_color($info->status_code, $info->status_text));
116 $this->print_stdout($this->title('Cache Path').$info->cache_path);
117 if ($this->pt->cf()->is_dctrue('STATS')) {
118 $this->print_stdout($this->title('Cache Size').$info->cache_size);
119 }
120 $this->print_stdout($line);
121 unset($info);
122
123 WP_CLI::halt($halt);
124 }
125
126 /**
127 * Enables the Docket Cache Drop-In file.
128 *
129 * Default behavior is to create the object cache Drop-In,
130 * unless an unknown object cache Drop-In is present.
131 *
132 * ## EXAMPLES
133 *
134 * wp cache dropin:enable
135 */
136 public function dropino_enable()
137 {
138 $this->dropino_runtime_status();
139
140 if ($this->pt->cx()->exists()) {
141 if ($this->pt->cx()->validate()) {
142 $this->halt_success(__('Docket object cache already enabled.', 'docket-cache'));
143 }
144
145 $this->halt_error(__('An unknown object cache Drop-In was found. To use Docket object cache, run: wp cache dropin:update.', 'docket-cache'));
146 }
147
148 if ($this->pt->cx()->install()) {
149 $this->halt_success(__('Object cache enabled.', 'docket-cache'));
150 }
151
152 $this->halt_error(__('Object cache could not be enabled.', 'docket-cache'));
153 }
154
155 /**
156 * Disables the Docket Cache Drop-In file.
157 *
158 * Default behavior is to delete the object cache Drop-In,
159 * unless an unknown object cache Drop-In is present.
160 *
161 * ## EXAMPLES
162 *
163 * wp cache dropin:disable
164 */
165 public function dropino_disable()
166 {
167 $this->dropino_runtime_status();
168
169 if (!$this->pt->cx()->exists()) {
170 $this->halt_error(__('No object cache Drop-In found.', 'docket-cache'));
171 }
172
173 if (!$this->pt->cx()->validate()) {
174 $this->halt_error(__('An unknown object cache Drop-In was found. To use Docket run: wp cache dropin:update.', 'docket-cache'));
175 }
176
177 if ($this->pt->cx()->uninstall()) {
178 $this->halt_success(__('Object cache disabled.', 'docket-cache'));
179 }
180
181 $this->halt_error(__('Object cache could not be disabled.', 'docket-cache'));
182 }
183
184 /**
185 * Updates the Docket Cache Drop-In file.
186 *
187 * Default behavior is to overwrite any existing object cache Drop-In.
188 *
189 * ## EXAMPLES
190 *
191 * wp cache update
192 *
193 * @subcommand dropin:update
194 */
195 public function dropino_update()
196 {
197 $this->dropino_runtime_status();
198
199 if ($this->pt->cx()->install()) {
200 $this->halt_success(__('Updated object cache Drop-In and enabled Docket object cache.', 'docket-cache'));
201 }
202 $this->halt_error(__('Object cache Drop-In could not be updated.', 'docket-cache'));
203 }
204
205 /**
206 * Flushes the object cache.
207 *
208 * Remove the object cache files.
209 *
210 * ## EXAMPLES
211 *
212 * wp cache flush
213 *
214 * @subcommand flush
215 */
216 public function flush_cache()
217 {
218 $this->print_stdout(__('Flushing cache. Please wait..', 'docket-cache'), false);
219 sleep(1);
220
221 $is_timeout = false;
222
223 $total = $this->pt->flush_cache(true, $is_timeout);
224
225 $this->clear_line();
226
227 $this->pt->cx()->undelay();
228
229 if ($is_timeout) {
230 /* translators: %d = seconds */
231 $this->halt_error(sprintf(__('Process aborted. The object cache is not fully flushed. The maximum execution time of %d seconds was exceeded.', 'docket-cache'), $result));
232 }
233
234 if (empty($total)) {
235 $this->halt_error(__('The cache is empty, no cache needs to be flushed.', 'docket-cache'));
236 }
237
238 /* translators: %d = count */
239 $this->halt_success(sprintf(__('The cache was flushed. Total cache flushed: %d', 'docket-cache'), $total));
240 }
241
242 /**
243 * Removes the Docket Cache lock files.
244 *
245 * Remove lock file.
246 *
247 * ## EXAMPLES
248 *
249 * wp cache reset:lock
250 *
251 * @subcommand reset:lock
252 */
253 public function reset_lock()
254 {
255 $this->pt->co()->clear_lock();
256 $this->halt_success(__('The lock has been removed.', 'docket-cache'));
257 }
258
259 /**
260 * Reset the Docket Cache cron event.
261 *
262 * Reset cron event.
263 *
264 * ## EXAMPLES
265 *
266 * wp cache reset:cron
267 *
268 * @subcommand reset:cron
269 */
270 public function reset_cron()
271 {
272 $this->print_stdout(__('Resetting cron event. Please wait..', 'docket-cache'), false);
273
274 ( new Event($this->pt) )->reset();
275 sleep(1);
276
277 $this->clear_line();
278
279 WP_CLI::runcommand('cron event list');
280 $this->halt_success(__('Cron event has been reset.', 'docket-cache'));
281 }
282
283 /**
284 * Removes the Docket Cache runtime code.
285 *
286 * Remove runtime code.
287 *
288 * ## EXAMPLES
289 *
290 * wp cache runtime:remove
291 *
292 * @subcommand runtime:remove
293 */
294 public function runtime_remove()
295 {
296 if (WpConfig::is_bedrock()) {
297 $this->print_stdout(__('This command does not support Bedrock. Please manually remove the runtime code.', 'docket-cache'));
298 WP_CLI::halt(1);
299 }
300
301 if (WpConfig::runtime_remove()) {
302 $this->halt_success(__('The runtime code has been removed.', 'docket-cache'));
303 }
304 $this->halt_error(__('Failed to remove runtime code.', 'docket-cache'));
305 }
306
307 /**
308 * Install the Docket Cache runtime code.
309 *
310 * Install runtime code in wp-config file.
311 *
312 * ## EXAMPLES
313 *
314 * wp cache runtime:install
315 *
316 * @subcommand runtime:install
317 */
318 public function runtime_install()
319 {
320 if (WpConfig::is_bedrock()) {
321 $this->print_stdout(__('This command does not support Bedrock. Please manually install the runtime code.', 'docket-cache'));
322 WP_CLI::halt(1);
323 }
324
325 if (WpConfig::runtime_install()) {
326 $this->halt_success(__('Updating wp-config.php file successful', 'docket-cache'));
327 }
328 $this->halt_error(__('Failed to update wp-config.php file.', 'docket-cache'));
329 }
330
331 /**
332 * Flushes the precaching files.
333 *
334 * Remove the precaching files.
335 *
336 * ## EXAMPLES
337 *
338 * wp cache flush:precache
339 *
340 * @subcommand flush:precache
341 */
342 public function flush_precache()
343 {
344 if (!\function_exists('wp_cache_flush_group') || !method_exists('WP_Object_Cache', 'dc_remove_group')) {
345 $this->halt_error(__('Object Precache could not be flushed. Docket Cache object-cache.php Drop-in is inactive.', 'docket-cache'));
346 }
347
348 $this->print_stdout(__('Flushing precache. Please wait..', 'docket-cache'), false);
349 sleep(1);
350
351 $total = wp_cache_flush_group(['docketcache-precache', 'docketcache-precache-gc']);
352 $this->clear_line();
353
354 /* translators: %d = count */
355 $this->halt_success(sprintf(__('The precache was flushed. Total cache flushed: %d', 'docket-cache'), $total));
356 }
357
358 /**
359 * Flushes the transient files.
360 *
361 * Remove the transient files.
362 *
363 * ## EXAMPLES
364 *
365 * wp cache flush:transient
366 *
367 * @subcommand flush:transient
368 */
369 public function flush_transient()
370 {
371 if (!\function_exists('wp_cache_flush_group') || !method_exists('WP_Object_Cache', 'dc_remove_group')) {
372 $this->halt_error(__('Transient could not be flushed. Docket Cache object-cache.php Drop-in is inactive.', 'docket-cache'));
373 }
374
375 $this->print_stdout(__('Flushing transient. Please wait..', 'docket-cache'), false);
376 sleep(1);
377
378 $total = wp_cache_flush_group(['transient', 'site-transient']);
379 $this->clear_line();
380
381 /* translators: %d = couint */
382 $this->halt_success(sprintf(__('The transient was flushed. Total cache flushed: %d', 'docket-cache'), $total));
383 }
384
385 /**
386 * Flushes the Advanced Post Cache files.
387 *
388 * Remove the Advanced Post Cache files.
389 *
390 * ## EXAMPLES
391 *
392 * wp cache flush:advcpost
393 *
394 * @subcommand flush:advcpost
395 */
396 public function flush_advcpost()
397 {
398 if (!\function_exists('wp_cache_flush_group_match') || !method_exists('WP_Object_Cache', 'dc_remove_group')) {
399 $this->halt_error(__('Advanced Post Cache could not be flushed. Docket Cache object-cache.php Drop-in is inactive.', 'docket-cache'));
400 }
401
402 $this->print_stdout(__('Flushing Advanced Post Cache. Please wait..', 'docket-cache'), false);
403 sleep(1);
404 $total = wp_cache_flush_group_match('docketcache-post');
405
406 $this->clear_line();
407
408 /* translators: %d = count */
409 $this->halt_success(sprintf(__('The Advanced Post Cache was flushed. Total cache flushed: %d', 'docket-cache'), $total));
410 }
411
412 /**
413 * Flushes the Menu Cache files.
414 *
415 * Remove the Menu Cache files.
416 *
417 * ## EXAMPLES
418 *
419 * wp cache flush:menucache
420 *
421 * @subcommand flush:menucache
422 */
423 public function flush_menucache()
424 {
425 if (!\function_exists('wp_cache_flush_group') || !method_exists('WP_Object_Cache', 'dc_remove_group')) {
426 $this->halt_error(__('Menu Cache could not be flushed. Docket Cache object-cache.php Drop-in is inactive.', 'docket-cache'));
427 }
428
429 $this->print_stdout(__('Flushing Menu Cache. Please wait..', 'docket-cache'), false);
430 sleep(1);
431 $total = wp_cache_flush_group('docketcache-menu');
432
433 $this->clear_line();
434
435 /* translators: %d = count */
436 $this->halt_success(sprintf(__('The Menu Cache was flushed. Total cache flushed: %d', 'docket-cache'), $total));
437 }
438
439 /**
440 * Flushes the Translation Cache files.
441 *
442 * Remove the Translation Cache files.
443 *
444 * ## EXAMPLES
445 *
446 * wp cache flush:mocache
447 *
448 * @subcommand flush:mocache
449 */
450 public function flush_mocache()
451 {
452 if (!\function_exists('wp_cache_flush_group') || !method_exists('WP_Object_Cache', 'dc_remove_group')) {
453 $this->halt_error(__('Translation Cache could not be flushed. Docket Cache object-cache.php Drop-in is inactive.', 'docket-cache'));
454 }
455
456 $this->print_stdout(__('Flushing Translation Cache. Please wait..', 'docket-cache'), false);
457 sleep(1);
458 $total = wp_cache_flush_group('docketcache-mo');
459
460 $this->clear_line();
461
462 /* translators: %d = count */
463 $this->halt_success(sprintf(__('The Translation Cache was flushed. Total cache flushed: %d', 'docket-cache'), $total));
464 }
465
466 /**
467 * Runs all cron event.
468 *
469 * Runs all cron event.
470 *
471 * ## EXAMPLES
472 *
473 * wp cache run:cron
474 *
475 * @subcommand run:cron
476 */
477 public function run_cron()
478 {
479 $this->print_stdout(__('Executing the cron event. Please wait..', 'docket-cache'), false);
480 sleep(1);
481
482 $this->clear_line();
483
484 WP_CLI::runcommand('cron event run --all');
485 WP_CLI::runcommand('cron event list');
486 }
487
488 /**
489 * Runs the Docket Cache cache stats.
490 *
491 * Collect cache stats data.
492 *
493 * ## EXAMPLES
494 *
495 * wp cache run:stats
496 *
497 * @subcommand run:stats
498 */
499 public function run_stats()
500 {
501 $this->print_stdout(__('Executing the cache stats. Please wait..', 'docket-cache'), false);
502 sleep(1);
503
504 $pad = 15;
505 $stats = $this->pt->get_cache_stats(true);
506
507 $this->clear_line();
508
509 $padr = 10;
510 if (\strlen($stats->files) > 10) {
511 $padr = \strlen($stats->files);
512 }
513
514 $line = str_repeat('-', $pad).':'.str_repeat('-', $padr);
515 $this->print_stdout($line);
516 $this->print_stdout($this->title(__('Object size', 'docket-cache'), $pad).$this->pt->normalize_size($stats->size));
517 $this->print_stdout($this->title(__('File size', 'docket-cache'), $pad).$this->pt->normalize_size($stats->filesize));
518 $this->print_stdout($this->title(__('Total file', 'docket-cache'), $pad).$stats->files);
519 $this->print_stdout($line);
520 $this->halt_success(__('Executing the cache stats completed.', 'docket-cache'));
521 }
522
523 /**
524 * Runs the Docket Cache Optimizedb.
525 *
526 * Optimize DB.
527 *
528 * ## EXAMPLES
529 *
530 * wp cache run:optimizedb
531 *
532 * @subcommand run:stats
533 */
534 public function run_optimizedb()
535 {
536 $this->print_stdout(__('Executing the optimizedb. Please wait..', 'docket-cache'), false);
537 sleep(1);
538
539 ( new Event($this->pt) )->optimizedb();
540
541 $this->clear_line();
542
543 $this->halt_success(__('Executing the optimizedb completed.', 'docket-cache'));
544 }
545
546 /**
547 * Runs the Docket Cache garbage collector (GC).
548 *
549 * Remove empty and older files, and execute various actions.
550 *
551 * ## EXAMPLES
552 *
553 * wp cache run:gc
554 *
555 * @subcommand run:gc
556 */
557 public function run_gc()
558 {
559 $this->print_stdout(__('Executing the garbage collector. Please wait..', 'docket-cache'), false);
560 sleep(1);
561
562 $pad = 35;
563 $collect = ( new Event($this->pt) )->garbage_collector(true);
564
565 $this->clear_line();
566
567 if ($collect->is_locked) {
568 $this->halt_warning(__('Process locked. The garbage collector is in process. Try again in a few seconds.', 'docket-cache'));
569 }
570
571 $line = str_repeat('-', $pad).':'.str_repeat('-', 10);
572 $this->print_stdout($line);
573 $this->print_stdout($this->title(__('Cache MaxTTL', 'docket-cache'), $pad).$collect->cache_maxttl);
574 $this->print_stdout($this->title(__('Cache File Limit', 'docket-cache'), $pad).$collect->cache_maxfile);
575 $this->print_stdout($this->title(__('Cache Disk Limit', 'docket-cache'), $pad).$this->pt->normalize_size($collect->cache_maxdisk));
576 $this->print_stdout($line);
577 $this->print_stdout($this->title(__('Cleanup Cache MaxTTL', 'docket-cache'), $pad).$collect->cleanup_maxttl);
578 $this->print_stdout($this->title(__('Cleanup Cache File Limit', 'docket-cache'), $pad).$collect->cleanup_maxfile);
579 $this->print_stdout($this->title(__('Cleanup Cache Disk Limit', 'docket-cache'), $pad).$collect->cleanup_maxdisk);
580
581 if ($collect->cleanup_expire > 0) {
582 $this->print_stdout($this->title(__('Cleanup Cache Expire', 'docket-cache'), $pad).$collect->cleanup_expire);
583 }
584
585 if ($this->pt->get_precache_maxfile() > 0 && $collect->cleanup_precache_maxfile > 0) {
586 $this->print_stdout($this->title(__('Cleanup Precache Limit', 'docket-cache'), $pad).$collect->cleanup_precache_maxfile);
587 }
588
589 if ($this->pt->cf()->is_dctrue('FLUSH_STALECACHE') && $collect->cleanup_stalecache > 0) {
590 $this->print_stdout($this->title(__('Cleanup Stale Cache', 'docket-cache'), $pad).$collect->cleanup_stalecache);
591 }
592
593 $this->print_stdout($line);
594 $this->print_stdout($this->title(__('Total Cache Cleanup', 'docket-cache'), $pad).$collect->cache_cleanup);
595 $this->print_stdout($this->title(__('Total Cache Ignored', 'docket-cache'), $pad).$collect->cache_ignore);
596 $this->print_stdout($this->title(__('Total Cache File', 'docket-cache'), $pad).$collect->cache_file);
597 $this->print_stdout($line);
598 $this->halt_success(__('Executing the garbage collector completed.', 'docket-cache'));
599 }
600
601 /**
602 * Attempts to determine which object cache is being used.
603 *
604 * Note that the guesses made by this function are based on the
605 * WP_Object_Cache classes that define the 3rd party object cache extension.
606 * Changes to those classes could render problems with this function's
607 * ability to determine which object cache is being used.
608 *
609 * ## EXAMPLES
610 *
611 * wp cache type
612 */
613 public function type()
614 {
615 $this->halt_status($this->pt->slug.' (v'.$this->pt->version().')');
616 }
617 }
618