PluginProbe
Docket Cache – Object Cache Accelerator / 26.04.03
Docket Cache – Object Cache Accelerator v26.04.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 / Event.php

Event.php in Docket Cache – Object Cache Accelerator 26.04.03, at includes/src/Event.php

800 lines 28.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 Event
16 {
17 private $pt;
18 private $is_optimizedb;
19 private $max_execution_time = 0;
20 private $wp_start_timestamp = 0;
21
22 public function __construct(Plugin $pt)
23 {
24 $this->pt = $pt;
25 $this->is_optimizedb = false;
26 $this->wp_start_timestamp = \defined('WP_START_TIMESTAMP') ? WP_START_TIMESTAMP : microtime(true);
27 $this->max_execution_time = $this->pt->get_max_execution_time();
28 }
29
30 /**
31 * register.
32 */
33 public function register()
34 {
35 // global
36 add_filter('docketcache/filter/garbagecollector', [$this, 'garbage_collector']);
37
38 add_filter(
39 'cron_schedules',
40 function ($schedules) {
41 $is_after_init = did_action('init') > 0;
42
43 $schedules['halfhour'] = [
44 'interval' => 30 * MINUTE_IN_SECONDS,
45 'display' => $is_after_init ? esc_html__('Every 30 Minutes', 'docket-cache') : 'Every 30 Minutes',
46 ];
47
48 if (empty($schedules['hourly'])) {
49 $schedules['hourly'] = [
50 'interval' => HOUR_IN_SECONDS,
51 'display' => $is_after_init ? esc_html__('Once Hourly', 'docket-cache') : 'Once Hourly',
52 ];
53 }
54
55 if (empty($schedules['monthly'])) {
56 $schedules['monthly'] = [
57 'interval' => MONTH_IN_SECONDS,
58 'display' => $is_after_init ? esc_html__('Once Monthly', 'docket-cache') : 'Once Monthly',
59 ];
60 }
61
62 $schedules['docketcache_gc_schedule'] = [
63 'interval' => 5 * MINUTE_IN_SECONDS,
64 'display' => $is_after_init ? esc_html__('Every 5 Minutes', 'docket-cache') : 'Every 5 Minutes',
65 ];
66
67 $schedules['docketcache_checkversion_schedule'] = [
68 'interval' => 15 * DAY_IN_SECONDS,
69 'display' => $is_after_init ? esc_html__('Every 15 Days', 'docket-cache') : 'Every 15 Days',
70 ];
71
72 return $schedules;
73 },
74 \PHP_INT_MAX
75 );
76
77 add_action(
78 'init',
79 function () {
80 // 19092020: standardize. rename hooks.
81 // 19012023: remove docketcache_watchproc.
82 foreach (['docket_cache_gc', 'docket_cache_optimizedb', 'docket_cache_monitor', 'docketcache_watchproc'] as $hx) {
83 if (false !== wp_get_scheduled_event($hx)) {
84 wp_clear_scheduled_hook($hx);
85 }
86 }
87
88 // garbage collector
89 // 27012023: added disable constant
90 if ($this->pt->cf()->is_dcfalse('GCRON_DISABLED')) {
91 add_action('docketcache_gc', [$this, 'garbage_collector']);
92 if (!wp_next_scheduled('docketcache_gc')) {
93 wp_schedule_event(time(), 'docketcache_gc_schedule', 'docketcache_gc');
94 }
95 } else {
96 if (wp_get_schedule('docketcache_gc')) {
97 wp_clear_scheduled_hook('docketcache_gc');
98 }
99 }
100
101 // optimize db
102 $cronoptmzdb = $this->pt->cf()->dcvalue('CRONOPTMZDB');
103 if (!empty($cronoptmzdb) && 'never' !== $cronoptmzdb && is_main_site()) {
104 $recurrence = '';
105 switch ($cronoptmzdb) {
106 case 'daily':
107 $recurrence = 'daily';
108 break;
109 case 'weekly':
110 $recurrence = 'weekly';
111 break;
112 case 'monthly':
113 $recurrence = 'monthly';
114 break;
115 }
116
117 if (empty($recurrence)) {
118 wp_clear_scheduled_hook('docketcache_optimizedb');
119 } else {
120 $this->is_optimizedb = true;
121 add_action('docketcache_optimizedb', [$this, 'optimizedb']);
122
123 if (!wp_next_scheduled('docketcache_optimizedb')) {
124 wp_schedule_event(time(), $recurrence, 'docketcache_optimizedb');
125 }
126 }
127 } else {
128 if (wp_get_schedule('docketcache_optimizedb')) {
129 wp_clear_scheduled_hook('docketcache_optimizedb');
130 }
131 }
132
133 // check version
134 if ($this->pt->cf()->is_dctrue('CHECKVERSION', true)) {
135 // 06102020: reset old schedule
136 $check = wp_get_scheduled_event('docketcache_checkversion');
137 if (\is_object($check) && 'docketcache_checkversion_schedule' !== $check->schedule) {
138 wp_clear_scheduled_hook('docketcache_checkversion');
139 }
140
141 if (is_main_site() && is_main_network()) {
142 add_action('docketcache_checkversion', [$this, 'checkversion']);
143 if (!wp_next_scheduled('docketcache_checkversion')) {
144 wp_schedule_event(time(), 'docketcache_checkversion_schedule', 'docketcache_checkversion');
145 }
146 }
147 } else {
148 if (wp_get_schedule('docketcache_checkversion')) {
149 wp_clear_scheduled_hook('docketcache_checkversion');
150 }
151 }
152
153 // expired transient in DB
154 if (has_action('delete_expired_transients') && wp_using_ext_object_cache()) {
155 add_action('delete_expired_transients', [$this, 'delete_expired_transients_db']);
156 }
157 }
158 );
159 }
160
161 /**
162 * unregister.
163 */
164 public function unregister()
165 {
166 foreach (['docketcache_gc', 'docketcache_optimizedb', 'docketcache_watchproc', 'docketcache_checkversion'] as $hx) {
167 wp_clear_scheduled_hook($hx);
168 }
169 }
170
171 /**
172 * reset.
173 */
174 public function reset()
175 {
176 $this->unregister();
177 $this->register();
178 }
179
180 /**
181 * garbage_collector.
182 */
183 public function garbage_collector($force = false)
184 {
185 static $is_done = false;
186
187 $maxfile_default = (int) $this->pt->get_cache_maxfile();
188 $maxfile = $maxfile_default;
189
190 if ($maxfile_default > 10000) {
191 $maxfile = $maxfile_default - 1000;
192 }
193
194 $maxfile_precache_default = (int) $this->pt->get_precache_maxfile();
195 $maxfile_precache = $maxfile_precache_default;
196
197 if ($maxfile_precache_default > 10000) {
198 $maxfile_precache = $maxfile_precache_default - 1000;
199 }
200
201 $maxttl_default = (int) $this->pt->get_cache_maxttl();
202 $maxttl = $maxttl_default;
203 if (!empty($maxttl)) {
204 $maxttl = time() - $maxttl;
205 }
206
207 $chkmaxdisk = false;
208 $maxsizedisk_default = (int) $this->pt->get_cache_maxsize_disk();
209 $maxsizedisk = $maxsizedisk_default;
210 if (!empty($maxsizedisk)) {
211 $maxsizedisk = $maxsizedisk - 1048576;
212
213 if ($maxsizedisk > 1048576) {
214 $chkmaxdisk = true;
215 }
216 }
217
218 $collect = (object) [
219 'is_locked' => false,
220 'cache_maxttl' => $maxttl_default,
221 'cache_maxfile' => $maxfile_default,
222 'cache_maxdisk' => $maxsizedisk_default,
223 'cleanup_maxfile' => 0,
224 'cleanup_precache_maxfile' => 0,
225 'cleanup_maxttl' => 0,
226 'cleanup_expire' => 0,
227 'cleanup_maxdisk' => 0,
228 'cache_file' => 0,
229 'cache_cleanup' => 0,
230 'cache_ignore' => 0,
231 'cleanup_failed' => 0,
232 'cleanup_stalecache' => 0,
233 ];
234
235 clearstatcache();
236 if (!$this->pt->is_docketcachedir($this->pt->cache_path) || @is_file(DOCKET_CACHE_CONTENT_PATH.'/.object-cache-flush.txt')) {
237 $collect->is_locked = true;
238
239 return $collect;
240 }
241
242 // try to set max execution time to 3 minutes if not 0 or lower than 180 seconds.
243 $max_execution_time = $this->pt->get_max_execution_time(180);
244
245 // lock process.
246 $lock_expiry = $max_execution_time > 0 ? $max_execution_time : 180;
247 $lock_expiry = time() + $lock_expiry;
248 if ($is_done || $this->pt->co()->lockproc('garbage_collector', $lock_expiry)) {
249 $collect->is_locked = true;
250
251 return $collect;
252 }
253
254 // Stalecache
255 $is_flush_stalecache = $this->pt->cf()->is_dctrue('FLUSH_STALECACHE', true);
256 $is_ignore_stalecache = $this->pt->cf()->is_dctrue('STALECACHE_IGNORE', true);
257
258 $wp_cache_last_changed = [];
259 $wp_cache_last_changed_match = [
260 'posts' => 'wp_query',
261 'terms' => 'get_terms',
262 'comment' => 'get_comments',
263 'sites' => 'get_sites',
264 'networks' => 'get_network_ids',
265 ];
266 foreach ($wp_cache_last_changed_match as $grp => $kk) {
267 $wp_cache_last_changed[$grp] = wp_cache_get_last_changed($grp);
268 // wp >= 6.3
269 // remove ending 's' -> posts = post-queries.
270 $grpq = strtok($grp, 's').'-queries';
271 $wp_cache_last_changed[$grpq] = $wp_cache_last_changed[$grp];
272 }
273
274 $wp_cache_last_changed['advpost'] = wp_cache_get('cache_incr', 'docketcache-post');
275 $wc_has_cache_helper = method_exists('WC_Cache_Helper', 'get_cache_prefix');
276 $wc_session_cache_group = \defined('WC_SESSION_CACHE_GROUP') ? WC_SESSION_CACHE_GROUP : 'wc_session_id';
277
278 $delay = $force ? 650 : 5000;
279 if ('cli' === \PHP_SAPI) {
280 $delay = 100;
281 }
282
283 // hold cache write
284 $this->pt->suspend_cache_write(true);
285
286 $filesize_total = 0;
287 $file_cache_count = 0;
288 $file_precache_count = 0;
289 $bytes_total = 0;
290 $slowdown = 0;
291
292 $gcisrun_lock = $this->pt->cache_path.'/.gc-is-run.txt';
293 $this->pt->touch($gcisrun_lock);
294
295 foreach ($this->pt->scanfiles($this->pt->cache_path) as $object) {
296 if ($max_execution_time > 0 && (microtime(true) - $this->wp_start_timestamp) > $max_execution_time) {
297 break;
298 }
299
300 if ($slowdown > 10) {
301 $slowdown = 0;
302 usleep($delay);
303 }
304
305 ++$slowdown;
306
307 try {
308 if (!$object->isFile()) {
309 ++$collect->cache_ignore;
310 continue;
311 }
312
313 $fx = $object->getPathName();
314 $fn = $object->getFileName();
315 $fs = $object->getSize();
316 $fm = time() + 300;
317 $ft = filemtime($fx);
318
319 $this->pt->remove_non_chunk_cache($this->pt->cache_path, $fx);
320 } catch (\Throwable $e) {
321 nwdcx_throwable(__METHOD__, $e);
322 continue;
323 }
324
325 nwdcx_cliverbose('run-gc: '.$fx."\n");
326
327 if ($fm >= $ft && (0 === $fs || 'dump_' === substr($fn, 0, 5))) {
328 $this->pt->unlink($fx, true);
329
330 if ($force && @is_file($fx)) {
331 ++$collect->cleanup_failed;
332 }
333 continue;
334 }
335
336 // 03022023: timeout 0 was set to maxtll, see WP_Object_Cache::maybe_expire
337 // cleanup first to reduce memory usage
338 if ($maxttl > 0 && $maxttl > $ft) {
339 $this->pt->unlink($fx, true);
340
341 if ($force && @is_file($fx)) {
342 ++$collect->cleanup_failed;
343 }
344
345 ++$collect->cleanup_maxttl;
346 continue;
347 }
348
349 // 032e9f2c5b60- = docketcache-precache-
350 if ($maxfile_precache > 0 && '032e9f2c5b60-' === substr($fn, 0, 13)) {
351 ++$file_precache_count;
352
353 if ($file_precache_count > $maxfile_precache) {
354 $this->pt->unlink($fx, true);
355
356 if ($force && @is_file($fx)) {
357 ++$collect->cleanup_failed;
358 }
359
360 ++$collect->cleanup_precache_maxfile;
361 continue;
362 }
363 }
364
365 if ($file_cache_count >= $maxfile) {
366 $this->pt->unlink($fx, true);
367
368 if ($force && @is_file($fx)) {
369 ++$collect->cleanup_failed;
370 }
371
372 ++$collect->cleanup_maxfile;
373 continue;
374 }
375
376 if ($chkmaxdisk && $filesize_total > $maxsizedisk) {
377 $this->pt->unlink($fx, true);
378
379 if ($force && @is_file($fx)) {
380 ++$collect->cleanup_failed;
381 }
382
383 ++$collect->cleanup_maxdisk;
384 continue;
385 }
386
387 $data = $this->pt->cache_get($fx);
388 $is_timeout = false;
389 if (false !== $data) {
390 unset($data['data']);
391
392 $is_timeout = !empty($data['timeout']) && $this->pt->valid_timestamp($data['timeout']) ? true : false;
393 if ($is_timeout) {
394 if ($fm >= (int) $data['timeout']) {
395 $this->pt->unlink($fx, true);
396
397 if ($force && @is_file($fx)) {
398 ++$collect->cleanup_failed;
399 }
400
401 unset($data);
402 ++$collect->cleanup_expire;
403 continue;
404 }
405 } else {
406 if (!empty($data['timestamp']) && $this->pt->valid_timestamp($data['timestamp']) && $maxttl > $data['timestamp']) {
407 $this->pt->unlink($fx, true);
408
409 if ($force && @is_file($fx)) {
410 ++$collect->cleanup_failed;
411 }
412
413 unset($data);
414 ++$collect->cleanup_maxttl;
415 continue;
416 }
417 }
418
419 if ($is_flush_stalecache) {
420 // wp stale cache
421 // wp >= 6.3
422 if ($is_ignore_stalecache && $this->pt->is_wp_cache_group_queries($data['group'])) {
423 if (@unlink($fx)) {
424 clearstatcache(true, $fx);
425
426 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
427
428 ++$collect->cleanup_stalecache;
429 continue;
430 }
431 }
432
433 // wp stale cache
434 // prefix:hash:timestamp timestamp
435 if (!empty($wp_cache_last_changed_match[$data['group']]) && preg_match('@^(wp_query|get_terms|get_comments|comment_feed|get_sites|get_network_ids|get_page_by_path|adjacent_post|wp_get_archives):([0-9a-f]{32}):([0-9\. ]{21})([0-9\. ]+)?$@', $data['key'], $mm)) {
436 // main type
437 switch ($mm[1]) {
438 case 'get_page_by_path':
439 case 'adjacent_post':
440 $mm[1] = 'wp_query';
441 break;
442 case 'comment_feed':
443 $mm[1] = 'get_comments';
444 break;
445 }
446
447 $km = $wp_cache_last_changed_match[$data['group']];
448
449 if (($km === $mm[1] && $wp_cache_last_changed[$data['group']] !== $mm[3]) || $is_ignore_stalecache) {
450 if (@unlink($fx)) {
451 clearstatcache(true, $fx);
452
453 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
454
455 ++$collect->cleanup_stalecache;
456 continue;
457 }
458 }
459 }
460
461 // wp stale cache
462 // get_comment_child_ids:int:hash:timestamp timestamp
463 // get_comment_child_ids:1654:5247020d1a40e3b2e9a40de1139bc5c9:0.48761900 1678553206
464 if (!empty($wp_cache_last_changed_match[$data['group']]) && preg_match('@^(get_comment_child_ids):(\d+):([0-9a-f]{32}):([0-9\. ]{21})([0-9\. ]+)?$@', $data['key'], $mm)) {
465 $mm[1] = 'get_comments';
466 $km = $wp_cache_last_changed_match[$data['group']];
467
468 if (($km === $mm[1] && $wp_cache_last_changed[$data['group']] !== $mm[4]) || $is_ignore_stalecache) {
469 if (@unlink($fx)) {
470 clearstatcache(true, $fx);
471
472 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
473
474 ++$collect->cleanup_stalecache;
475 continue;
476 }
477 }
478 }
479
480 // advpost stale cache
481 if (false !== strpos($data['group'], 'docketcache-post-') && preg_match('@^docketcache-post-(\d+)$@', $data['group'], $mm)) {
482 if ((int) $wp_cache_last_changed['advpost'] !== (int) $mm[1] || $is_ignore_stalecache) {
483 if (@unlink($fx)) {
484 clearstatcache(true, $fx);
485
486 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
487
488 ++$collect->cleanup_stalecache;
489 continue;
490 }
491 }
492 }
493
494 // wc stale cache
495 if (false !== strpos($data['key'], 'wc_cache_') && preg_match('@^(wc_cache_[0-9\. ]+_)@', $data['key'], $mm)) {
496 if (!$wc_has_cache_helper || $is_ignore_stalecache) {
497 if (@unlink($fx)) {
498 clearstatcache(true, $fx);
499
500 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
501
502 ++$collect->cleanup_stalecache;
503 }
504 continue;
505 }
506
507 $current_prefix = $mm[1];
508 static $cache_prefix_cached = [];
509
510 // wc product
511 if ('products' === $data['group'] && preg_match('@.*?_type_(\d+)$@', $data['key'], $nn)) {
512 $grp = 'product_'.$nn[1];
513
514 if (!empty($cache_prefix_cached[$grp])) {
515 $cache_prefix = $cache_prefix_cached;
516 } else {
517 $cache_prefix = \WC_Cache_Helper::get_cache_prefix($grp);
518 $cache_prefix_cached[$grp] = $cache_prefix;
519 }
520
521 if ($cache_prefix !== $current_prefix) {
522 if (@unlink($fx)) {
523 clearstatcache(true, $fx);
524
525 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
526
527 ++$collect->cleanup_stalecache;
528 continue;
529 }
530 }
531 }
532
533 if (\in_array($data['group'],
534 [
535 'products', 'coupons', 'orders', 'webhooks', 'taxes', 'shipping_zones',
536 'woocommerce-attributes', 'store_api_rate_limit', $wc_session_cache_group,
537 ])) {
538 $grp = $data['group'];
539
540 if (!empty($cache_prefix_cached[$grp])) {
541 $cache_prefix = $cache_prefix_cached;
542 } else {
543 $cache_prefix = \WC_Cache_Helper::get_cache_prefix($grp);
544 $cache_prefix_cached[$grp] = $cache_prefix;
545 }
546
547 if ($cache_prefix !== $current_prefix) {
548 if (@unlink($fx)) {
549 clearstatcache(true, $fx);
550
551 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
552
553 ++$collect->cleanup_stalecache;
554 continue;
555 }
556 }
557 }
558
559 if ('wc_rate_limit' === $data['group'] && 'rate_limit' === substr($data['key'], 0, 10)) {
560 $grp = $data['group'];
561
562 if (!empty($cache_prefix_cached[$grp])) {
563 $cache_prefix = $cache_prefix_cached;
564 } else {
565 $cache_prefix = \WC_Cache_Helper::get_cache_prefix($grp);
566 $cache_prefix_cached[$grp] = $cache_prefix;
567 }
568
569 if ($cache_prefix !== $current_prefix) {
570 if (@unlink($fx)) {
571 clearstatcache(true, $fx);
572
573 nwdcx_cliverbose('run-gc:stale-cache: '.$fx."\n");
574
575 ++$collect->cleanup_stalecache;
576 continue;
577 }
578 }
579 }
580 }
581 }
582 $bytes_total += \strlen(serialize($data));
583 } // data
584
585 // no timeout data or 0
586 // 03022023: timeout 0 was set to maxtll, see WP_Object_Cache::maybe_expire
587 /*if (false === $is_timeout && $maxttl > 0 && $maxttl > $ft) {
588 $this->pt->unlink($fx, true);
589
590 if ($force && @is_file($fx)) {
591 ++$collect->cleanup_failed;
592 }
593
594 ++$collect->cleanup_maxttl;
595 continue;
596 }*/
597
598 unset($data);
599
600 $filesize_total += $fs;
601 ++$file_cache_count;
602 } // foreach1
603
604 @unlink($gcisrun_lock);
605
606 $collect->cache_file = $file_cache_count;
607
608 $collect->cache_cleanup = $collect->cleanup_maxttl + $collect->cleanup_expire + $collect->cleanup_maxfile + $collect->cleanup_maxdisk + $collect->cleanup_precache_maxfile + $collect->cleanup_stalecache;
609
610 // release
611 $this->pt->suspend_cache_write(false);
612
613 if ($this->pt->cf()->is_dcfalse('TRANSIENTDB') && \function_exists('nwdcx_cleanuptransient')) {
614 nwdcx_cliverbose("run-gc: cleanup expired transients in DB\n");
615 nwdcx_cleanuptransient();
616 }
617
618 // reset gc
619 $count_file = $collect->cache_file;
620 $count_file = $count_file < 0 ? 0 : $count_file;
621 wp_cache_set('count_file', $count_file, 'docketcache-gc', 86400);
622
623 // reset precache
624 $count_file = $file_precache_count - $collect->cleanup_precache_maxfile;
625 $count_file = $count_file < 0 ? 0 : $count_file;
626 wp_cache_set('count_file', $count_file, 'docketcache-precache-gc', 86400);
627
628 // stats
629 $this->pt->co()->save_part([
630 'timestamp' => time(),
631 'size' => $bytes_total,
632 'filesize' => $filesize_total,
633 'files' => $collect->cache_file,
634 ], 'cachestats');
635
636 // done
637 $this->pt->co()->lockreset('garbage_collector');
638 $this->pt->cx()->delay_expire();
639 $is_done = true;
640
641 return $collect;
642 }
643
644 /**
645 * optimizedb.
646 */
647 public function optimizedb()
648 {
649 if (!nwdcx_wpdb($wpdb)) {
650 return false;
651 }
652
653 if ($this->pt->co()->lockproc('optimizedb', time() + 3600)) {
654 return false;
655 }
656
657 $suppress = $wpdb->suppress_errors(true);
658
659 @set_time_limit(300);
660 $max_execution_time = $this->pt->get_max_execution_time();
661 $this->delete_expired_transients_db();
662
663 if (is_main_site() && is_main_network()) {
664 $dbname = $wpdb->dbname;
665 $tables = $wpdb->get_results('SHOW TABLES FROM '.$dbname, ARRAY_A);
666 if (!empty($tables) && \is_array($tables)) {
667 foreach ($tables as $table) {
668 $tbl = $table['Tables_in_'.$dbname];
669 $sql = 'OPTIMIZE TABLE `'.$tbl.'`';
670 $ret = $wpdb->query($sql);
671
672 nwdcx_cliverbose(str_replace('`', '', $sql)."\n");
673 if ($max_execution_time > 0 && (microtime(true) - $this->wp_start_timestamp) > $max_execution_time) {
674 break;
675 }
676 }
677 }
678 unset($tables);
679 }
680
681 $wpdb->suppress_errors($suppress);
682
683 $this->pt->co()->lockreset('optimizedb');
684
685 return true;
686 }
687
688 /**
689 * delete_expired_transients_db.
690 */
691 public function delete_expired_transients_db()
692 {
693 if (!nwdcx_wpdb($wpdb)) {
694 return false;
695 }
696
697 if ($this->pt->cf()->is_dcfalse('TRANSIENTDB') && \function_exists('nwdcx_cleanuptransient')) {
698 nwdcx_cleanuptransient();
699 } elseif (\function_exists('delete_expired_transients')) {
700 delete_expired_transients(true);
701 }
702
703 return true;
704 }
705
706 /**
707 * checkversion.
708 */
709 public function checkversion()
710 {
711 if (!is_main_site()) {
712 return false;
713 }
714
715 $part = 'checkversion';
716
717 if ($this->pt->co()->lockproc($part, time() + 3600)) {
718 return false;
719 }
720
721 $checkdata = $this->pt->co()->get_part($part, true);
722 if (!empty($checkdata) && \is_array($checkdata) && !empty($checkdata['selfcheck'])) {
723 $selfcheck = $checkdata['selfcheck'];
724 if (0 === $this->pt->sanitize_timestamp($selfcheck)) {
725 return false;
726 }
727
728 if ($selfcheck > 0 && $selfcheck > time()) {
729 return false;
730 }
731 }
732
733 $main_site_url = $this->pt->site_url();
734 $site_url = $this->pt->site_url(true);
735 $home_url = $this->pt->site_url(true, true);
736 $stmp = time() + 120;
737 $api_endpoint = $this->pt->api_endpoint.'/'.$part.'?v='.$stmp;
738
739 $args = [
740 'blocking' => true,
741 'body' => [
742 'timestamp' => date('Y-m-d H:i:s T'),
743 'timezone' => wp_timezone_string(),
744 'site' => $site_url,
745 'token' => $this->pt->nw_encrypt($main_site_url, md5($site_url)),
746 'meta' => $this->pt->site_meta(),
747 ],
748 'headers' => [
749 'REFERER' => $home_url,
750 'Cache-Control' => 'no-cache',
751 ],
752 ];
753
754 $results = Crawler::post($api_endpoint, $args);
755
756 $output = [
757 'timestamp' => time(),
758 'endpoint' => $api_endpoint,
759 'request' => [
760 'headers' => $args['headers'],
761 'content' => $args['body'],
762 ],
763 'selfcheck' => time() + 86400,
764 ];
765
766 if (is_wp_error($results)) {
767 $output['error'] = $results->get_error_message();
768 $this->pt->co()->save_part($output, $part);
769
770 return false;
771 }
772
773 $output['response'] = wp_remote_retrieve_body($results);
774 if (!empty($output['response'])) {
775 $output['response'] = json_decode($output['response'], true);
776 if (\JSON_ERROR_NONE === json_last_error()) {
777 if (!empty($output['response']['error'])) {
778 $output['error'] = $output['response']['error'];
779 $this->pt->co()->save_part($output, $part);
780
781 return false;
782 }
783 }
784 }
785
786 $code = (int) wp_remote_retrieve_response_code($results);
787 if ($code > 400) {
788 $output['error'] = $code;
789 $this->pt->co()->save_part($output, $part);
790
791 return false;
792 }
793
794 $this->pt->co()->save_part($output, $part);
795 $this->pt->co()->lockreset($part);
796
797 return true;
798 }
799 }
800