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

compat.php in Docket Cache – Object Cache Accelerator 24.07.03, at includes/compat.php

613 lines 17.9 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 \defined('ABSPATH') || exit;
11
12 if (class_exists('Nawawi\\Symfony\\Component\\VarExporter\\VarExporter')) {
13 class_alias('Nawawi\Symfony\Component\VarExporter\VarExporter', 'Nawawi\DocketCache\Exporter\VarExporter', false);
14 }
15 if (class_exists('Nawawi\\Symfony\\Component\\VarExporter\\Internal\\Hydrator')) {
16 class_alias('Nawawi\Symfony\Component\VarExporter\Internal\Hydrator', 'Nawawi\DocketCache\Exporter\Hydrator', false);
17 }
18 if (class_exists('Nawawi\\Symfony\\Component\\VarExporter\\Internal\\Registry')) {
19 class_alias('Nawawi\Symfony\Component\VarExporter\Internal\Registry', 'Nawawi\DocketCache\Exporter\Registry', false);
20 }
21
22 if (!\function_exists('nwdcx_constfx')) {
23 function nwdcx_constfx($name, $is_strip = false)
24 {
25 if (!$is_strip) {
26 return strtoupper('docket_cache_'.$name);
27 }
28
29 // strip prefix, see Canopt().
30 return substr($name, 13);
31 }
32 }
33
34 if (!\function_exists('nwdcx_construe')) {
35 function nwdcx_construe($name)
36 {
37 $name = nwdcx_constfx($name);
38 if (\defined($name)) {
39 $value = (bool) \constant($name);
40 if (true === $value || 1 === $value) {
41 return true;
42 }
43 }
44
45 return false;
46 }
47 }
48
49 if (!\function_exists('nwdcx_consfalse')) {
50 function nwdcx_consfalse($name)
51 {
52 $name = nwdcx_constfx($name);
53
54 return !\defined($name) || !\constant($name);
55 }
56 }
57
58 if (!\function_exists('nwdcx_constval')) {
59 function nwdcx_constval($name)
60 {
61 $name = nwdcx_constfx($name);
62 $value = '';
63 if (\defined($name)) {
64 $value = \constant($name);
65 }
66
67 return $value;
68 }
69 }
70
71 if (!\function_exists('nwdcx_consdef')) {
72 function nwdcx_consdef($name, $value)
73 {
74 $name = nwdcx_constfx($name);
75
76 return !\defined($name) && \define($name, $value);
77 }
78 }
79
80 if (!\function_exists('nwdcx_arraymap')) {
81 function nwdcx_arraymap($func, $arr)
82 {
83 $new = [];
84 foreach ($arr as $key => $value) {
85 $new[$key] = (\is_array($value) ? nwdcx_arraymap($func, $value) : (\is_array($func) ? \call_user_func_array($func, $value) : $func($value)));
86 }
87
88 return $new;
89 }
90 }
91
92 if (!\function_exists('nwdcx_arraysimilar')) {
93 function nwdcx_arraysimilar($actual, $expected)
94 {
95 if (!\is_array($expected) || !\is_array($actual)) {
96 return $actual === $expected;
97 }
98 foreach ($expected as $key => $value) {
99 if (!isset($actual[$key]) || !isset($expected[$key])) {
100 return false;
101 }
102
103 if (!nwdcx_arraysimilar($actual[$key], $expected[$key])) {
104 return false;
105 }
106 }
107 foreach ($actual as $key => $value) {
108 if (!isset($actual[$key]) || !isset($expected[$key])) {
109 return false;
110 }
111 if (!nwdcx_arraysimilar($actual[$key], $expected[$key])) {
112 return false;
113 }
114 }
115
116 return true;
117 }
118 }
119
120 if (!\function_exists('nwdcx_serialized')) {
121 function nwdcx_serialized($data)
122 {
123 // short-circuit the checking.
124 if (!\is_string($data) || false === strpbrk($data, '{:;}')) {
125 return false;
126 }
127
128 if (!\function_exists('is_serialized')) {
129 // 16072021: rare opcache issue with some hosting ABSPATH not defined.
130 if (\defined('ABSPATH') && \defined('WPINC')) {
131 @include_once ABSPATH.WPINC.'/functions.php';
132 }
133 }
134
135 if (!\function_exists('is_serialized')) {
136 return false;
137 }
138
139 return is_serialized($data);
140 }
141 }
142
143 if (!\function_exists('nwdcx_unserialize')) {
144 function nwdcx_unserialize($data)
145 {
146 if (!nwdcx_serialized($data)) {
147 return $data;
148 }
149
150 // If the string has an object format, check if it has a stdClass, otherwise return the original data.
151 // The logic here is, if we "unserialize" it, we can't use the cache since the VarExporter can't detect
152 // the Class instance in objects which may lead to "class not found".
153 if (false !== strpos($data, 'O:') && @preg_match_all('@O:\d+:"([^"]+)"@', $data, $mm)) {
154 if (!empty($mm) && !empty($mm[1])) {
155 foreach ($mm[1] as $v) {
156 if ('stdClass' !== $v) {
157 return $data;
158 }
159 }
160 unset($mm);
161 }
162 }
163
164 // To make query monitor happy.
165 set_error_handler(function () {});
166 $data = unserialize(trim($data));
167 restore_error_handler();
168
169 return $data;
170 }
171 }
172
173 if (!\function_exists('nwdcx_fixhost')) {
174 function nwdcx_fixhost($hostname)
175 {
176 if (false !== strpos($hostname, ':')) {
177 return @preg_replace('@:\d+$@', '', $hostname);
178 }
179
180 return $hostname;
181 }
182 }
183
184 if (!\function_exists('nwdcx_fixscheme')) {
185 // replace http scheme
186 function nwdcx_fixscheme($url, $scheme = 'http://')
187 {
188 return @preg_replace('@^((([a-zA-Z]+)?:)?(//))?@', $scheme, trim($url));
189 }
190 }
191
192 if (!\function_exists('nwdcx_noscheme')) {
193 // replace http scheme
194 function nwdcx_noscheme($url)
195 {
196 return nwdcx_fixscheme($url, '');
197 }
198 }
199
200 if (!\function_exists('nwdcx_wpdb')) {
201 function nwdcx_wpdb(&$wpdb = '')
202 {
203 if (!isset($GLOBALS['wpdb']) || !\is_object($GLOBALS['wpdb']) || (isset($GLOBALS['wpdb']->ready) && !$GLOBALS['wpdb']->ready)) {
204 $wpdb = false;
205
206 return false;
207 }
208
209 $wpdb = $GLOBALS['wpdb'];
210
211 return $wpdb;
212 }
213 }
214
215 if (!\function_exists('nwdcx_optget')) {
216 function nwdcx_optget($key)
217 {
218 if (!nwdcx_wpdb($wpdb)) {
219 return false;
220 }
221
222 static $cache = [];
223
224 if (isset($cache[$key])) {
225 return $cache[$key];
226 }
227
228 $suppress = $wpdb->suppress_errors(true);
229
230 $query = $wpdb->prepare('SELECT option_value FROM `'.$wpdb->options.'` WHERE option_name=%s ORDER BY option_id ASC LIMIT 1', $key);
231 $option = $wpdb->get_var($query);
232 $cache[$key] = !empty($option) ? nwdcx_unserialize($option) : false;
233
234 $wpdb->suppress_errors($suppress);
235
236 return $cache[$key];
237 }
238 }
239
240 if (!\function_exists('nwdcx_cleanuptransient')) {
241 function nwdcx_cleanuptransient()
242 {
243 if (!nwdcx_wpdb($wpdb)) {
244 return false;
245 }
246
247 $count = 0;
248 $qlimit = 1000;
249 $suppress = $wpdb->suppress_errors(true);
250
251 $collect = [];
252
253 // $results = $wpdb->get_results('SELECT `option_id`,`option_name`,`option_value` FROM `'.$wpdb->options.'` WHERE `option_name` LIKE "_transient_%" OR `option_name` LIKE "_site_transient_%" ORDER BY `option_id` ASC LIMIT 1000', ARRAY_A);
254 $results = $wpdb->get_results('SELECT `option_id`,`option_name`,`option_value` FROM `'.$wpdb->options.'` WHERE `option_name` RLIKE "^(_site)?(_transient)(_timeout)?_.*?" ORDER BY `option_id` ASC LIMIT '.$qlimit, ARRAY_A);
255
256 if (!empty($results) && \is_array($results)) {
257 while ($row = @array_shift($results)) {
258 $key = @preg_replace('@^(_site)?(_transient)(_timeout)?_@', '', $row['option_name']);
259 $collect[$key] = $key;
260
261 if (false !== strpos($row['option_name'], '_transient_timeout_') && (int) $row['option_value'] > time()) {
262 unset($collect[$key]);
263 }
264 }
265
266 if (!empty($collect)) {
267 $wpdb->query('START TRANSACTION');
268 foreach ($collect as $key) {
269 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_transient_{$key}'");
270 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_transient_timeout_{$key}'");
271 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_site_transient_{$key}'");
272 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_site_transient_timeout_{$key}'");
273 ++$count;
274 }
275 $wpdb->query('COMMIT');
276 }
277 }
278
279 $collect = [];
280
281 if (is_multisite() && isset($wpdb->sitemeta)) {
282 // $results = $wpdb->get_results('SELECT `meta_id`,`meta_key`,`meta_value` FROM `'.$wpdb->sitemeta.'` WHERE `meta_key` LIKE "_site_transient_%" ORDER BY `meta_id` ASC LIMIT 1000', ARRAY_A);
283 $results = $wpdb->get_results('SELECT `meta_id`,`meta_key`,`meta_value` FROM `'.$wpdb->sitemeta.'` WHERE `meta_key` RLIKE "^(_site_transient)(_timeout)?_.*?" ORDER BY `meta_id` ASC LIMIT '.$qlimit, ARRAY_A);
284 if (!empty($results) && \is_array($results)) {
285 while ($row = @array_shift($results)) {
286 $key = @preg_replace('@^(_site)?(_transient)(_timeout)?_@', '', $row['meta_key']);
287 $collect[$key] = $key;
288
289 if (false !== strpos($row['meta_key'], '_site_transient_timeout_') && (int) $row['meta_value'] > time()) {
290 unset($collect[$key]);
291 }
292 }
293
294 if (!empty($collect)) {
295 $wpdb->query('START TRANSACTION');
296 foreach ($collect as $key) {
297 $wpdb->query("DELETE FROM `{$wpdb->sitemeta}` WHERE `meta_key`='_site_transient_{$key}'");
298 $wpdb->query("DELETE FROM `{$wpdb->sitemeta}` WHERE `meta_key`='_site_transient_timeout_{$key}'");
299 ++$count;
300 }
301 $wpdb->query('COMMIT');
302 }
303 }
304 }
305
306 unset($collect, $results);
307 $wpdb->suppress_errors($suppress);
308
309 return $count;
310 }
311 }
312
313 if (!\function_exists('nwdcx_runaction')) {
314 function nwdcx_runaction(...$args)
315 {
316 add_action(
317 'plugins_loaded',
318 function () use ($args) {
319 \call_user_func_array('do_action', $args);
320 }
321 );
322 }
323 }
324
325 if (!\function_exists('nwdcx_throwable')) {
326 function nwdcx_throwable($name, $error)
327 {
328 if (\defined('WP_DEBUG') && WP_DEBUG) {
329 do_action('docketcache/action/nwdcx/throwable', $name, $error);
330 }
331 }
332 }
333
334 if (!\function_exists('nwdcx_debuglog')) {
335 function nwdcx_debuglog($text)
336 {
337 if (nwdcx_construe('dev')) {
338 $logfile = WP_CONTENT_DIR.'/dcdev-debug.log';
339 error_log('['.date('Y-m-d H:i:s').'] '.$text."\n", 3, $logfile);
340 }
341 }
342 }
343
344 if (!\function_exists('nwdcx_cliverbose')) {
345 function nwdcx_cliverbose($text)
346 {
347 static $is_verbose = false;
348
349 if (!$is_verbose) {
350 $is_verbose = 'cli' === \PHP_SAPI && !empty($_SERVER['argv']) && \in_array('--verbose', $_SERVER['argv']) && !\in_array('--quiet', $_SERVER['argv']);
351 }
352
353 if ($is_verbose && \defined('STDOUT')) {
354 fwrite(\STDOUT, $text);
355 }
356 }
357 }
358
359 if (!\function_exists('nwdcx_microtimetofloat')) {
360 function nwdcx_microtimetofloat($second)
361 {
362 list($usec, $sec) = explode(' ', $second);
363
364 return (float) $usec + (float) $sec;
365 }
366 }
367
368 if (!\function_exists('nwdcx_suppresserrors')) {
369 function nwdcx_suppresserrors($level = true)
370 {
371 $errlevel = error_reporting();
372 $erropt = true === $level ? 0 : $level;
373 error_reporting($erropt);
374
375 return $errlevel;
376 }
377 }
378
379 if (!\function_exists('nwdcx_normalizepath')) {
380 function nwdcx_normalizepath($path)
381 {
382 if (false === strpos($path, '\\')) {
383 return $path;
384 }
385
386 if (\function_exists('wp_normalize_path')) {
387 return wp_normalize_path($path);
388 }
389
390 return str_replace('\\', '/', $path);
391 }
392 }
393
394 // network specific
395
396 if (!\function_exists('nwdcx_network_multi')) {
397 function nwdcx_network_multi()
398 {
399 if (!is_multisite()) {
400 return false;
401 }
402
403 if (\defined('MULTINETWORK')) {
404 return MULTINETWORK;
405 }
406
407 if (\defined('DOCKET_CACHE_MULTINETWORK')) {
408 return DOCKET_CACHE_MULTINETWORK;
409 }
410
411 if (!nwdcx_wpdb($wpdb)) {
412 return false;
413 }
414
415 static $ok = null;
416
417 if (\is_bool($ok)) {
418 return $ok;
419 }
420
421 // this lock file should only exists if network more than 1
422 // see Dropino::multinet_active
423 $lock_file = nwdcx_normalizepath(DOCKET_CACHE_CONTENT_PATH).'/.object-cache-network-multi.txt';
424 $timeout = time() + 86400;
425 if (@is_file($lock_file) && @is_readable($lock_file) && $timeout > @filemtime($lock_file)) {
426 $ok = !empty(@file_get_contents($lock_file)) ? true : false;
427
428 return $ok;
429 }
430
431 $table = $wpdb->base_prefix.'site';
432
433 $suppress = $wpdb->suppress_errors(true);
434 $query = "SELECT id FROM `{$table}` WHERE id > 0 ORDER BY id ASC LIMIT 2";
435 $check = $wpdb->query($query);
436 $wpdb->suppress_errors($suppress);
437 $ok = !empty($check) && $check > 1 ? true : false;
438
439 return $ok;
440 }
441 }
442
443 if (!\function_exists('nwdcx_network_ignore')) {
444 function nwdcx_network_ignore()
445 {
446 if (nwdcx_network_multi()) {
447 if (!@is_file(nwdcx_normalizepath(DOCKET_CACHE_CONTENT_PATH).'/.object-cache-network-'.nwdcx_network_id().'.txt')) {
448 return true;
449 }
450
451 return false;
452 }
453 }
454 }
455
456 if (!\function_exists('nwdcx_network_main')) {
457 function nwdcx_network_main()
458 {
459 if (!is_multisite()) {
460 return true;
461 }
462
463 if (\defined('PRIMARY_NETWORK_ID') && PRIMARY_NETWORK_ID === nwdcx_network_id()) {
464 return true;
465 }
466
467 if (\defined('SITE_ID_CURRENT_SITE') && SITE_ID_CURRENT_SITE === nwdcx_network_id()) {
468 return true;
469 }
470
471 if (empty($_SERVER['HTTP_HOST'])) {
472 return true;
473 }
474
475 if (!nwdcx_wpdb($wpdb)) {
476 return true;
477 }
478
479 $hostname = nwdcx_fixhost($_SERVER['HTTP_HOST']);
480
481 if (\defined('DOMAIN_CURRENT_SITE') && DOMAIN_CURRENT_SITE === $hostname) {
482 return true;
483 }
484
485 $lock_file = nwdcx_normalizepath(DOCKET_CACHE_CONTENT_PATH).'/.object-cache-network-main.txt';
486 $timeout = time() + 86400;
487 if (@is_file($lock_file) && @is_readable($lock_file) && $timeout > @filemtime($lock_file)) {
488 $data = @file_get_contents($lock_file);
489 if (!empty($data) && trim($data) === $hostname) {
490 return true;
491 }
492 }
493
494 static $cache = [];
495
496 if (isset($cache[$hostname])) {
497 return $cache[$hostname];
498 }
499
500 $table = $wpdb->base_prefix.'site';
501
502 $suppress = $wpdb->suppress_errors(true);
503 $query = "SELECT domain FROM `{$table}` WHERE id > 0 ORDER BY id ASC LIMIT 1";
504 $domain = $wpdb->get_var($query);
505 $wpdb->suppress_errors($suppress);
506
507 if ($hostname === $domain) {
508 $cache[$hostname] = true;
509 } elseif (@preg_match('@(.*?\.)?'.preg_quote($domain, '@').'@', $hostname)) {
510 $cache[$hostname] = true;
511 } else {
512 $cache[$hostname] = false;
513 }
514
515 if ($cache[$hostname] && !@is_file($lock_file)) {
516 @file_put_contents($lock_file, $hostname, \LOCK_EX);
517 }
518
519 return $cache[$hostname];
520 }
521 }
522
523 if (!\function_exists('nwdcx_network_id')) {
524 function nwdcx_network_id()
525 {
526 $network_id = \defined('SITE_ID_CURRENT_SITE') ? SITE_ID_CURRENT_SITE : 1;
527
528 if (!is_multisite()) {
529 return $network_id;
530 }
531
532 if (!nwdcx_wpdb($wpdb)) {
533 return $network_id;
534 }
535
536 if (empty($_SERVER['HTTP_HOST'])) {
537 return $network_id;
538 }
539
540 static $cache = [];
541
542 $hostname = nwdcx_fixhost($_SERVER['HTTP_HOST']);
543
544 if (isset($cache[$hostname])) {
545 return $cache[$hostname];
546 }
547
548 $table = $wpdb->base_prefix.'site';
549 $suppress = $wpdb->suppress_errors(true);
550
551 $query = "SELECT `id`,`domain`,`path` FROM `{$table}` ORDER BY id ASC LIMIT 100";
552 $networks = $wpdb->get_results($query, ARRAY_A);
553
554 if (!empty($networks) && \is_array($networks)) {
555 while ($row = @array_shift($networks)) {
556 $id = $row['id'];
557 $domain = $row['domain'];
558 $path = $row['path'];
559
560 if ($hostname === $domain) {
561 $network_id = $id;
562 break;
563 }
564
565 if (false !== strpos($hostname, $domain) && @preg_match('@(.*?\.)?'.preg_quote($domain, '@').'$@', $hostname)) {
566 $network_id = $id;
567 break;
568 }
569 }
570 }
571 $wpdb->suppress_errors($suppress);
572
573 $cache[$hostname] = $network_id;
574
575 return $cache[$hostname];
576 }
577 }
578
579 if (!\function_exists('nwdcx_network_dirpath')) {
580 function nwdcx_network_dirpath($save_path)
581 {
582 if (nwdcx_network_multi() && !nwdcx_network_main()) {
583 $network_id = nwdcx_network_id();
584 $cache_dir = sprintf('network-%s', $network_id);
585
586 if (false === strpos($save_path, 'docket-cache-data')) {
587 $cache_path_constant = sprintf('DOCKET_CACHE_PATH_NETWORK_%s', $network_id);
588 if (\defined($cache_path_constant)) {
589 $save_path = \constant($cache_path_constant);
590 }
591 }
592
593 $save_path = rtrim($save_path, '/').'/'.$cache_dir.'/';
594 }
595
596 return $save_path;
597 }
598 }
599
600 if (!\function_exists('nwdcx_network_filepath')) {
601 function nwdcx_network_filepath($file_path)
602 {
603 if (nwdcx_network_multi() && !nwdcx_network_main()) {
604 $ext = substr($file_path, -4);
605 $fname = substr($file_path, 0, -4);
606
607 $file_path = $fname.'-'.nwdcx_network_id().$ext;
608 }
609
610 return $file_path;
611 }
612 }
613