PluginProbe
Docket Cache – Object Cache Accelerator / 23.08.01
Docket Cache – Object Cache Accelerator v23.08.01
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 23.08.01, at includes/compat.php

604 lines 17.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 \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 $nwdcx_suppresserrors = nwdcx_suppresserrors(true);
166 $data = @unserialize(trim($data));
167
168 nwdcx_suppresserrors($nwdcx_suppresserrors);
169
170 return $data;
171 }
172 }
173
174 if (!\function_exists('nwdcx_fixhost')) {
175 function nwdcx_fixhost($hostname)
176 {
177 if (false !== strpos($hostname, ':')) {
178 return @preg_replace('@:\d+$@', '', $hostname);
179 }
180
181 return $hostname;
182 }
183 }
184
185 if (!\function_exists('nwdcx_fixscheme')) {
186 // replace http scheme
187 function nwdcx_fixscheme($url, $scheme = 'http://')
188 {
189 return @preg_replace('@^((([a-zA-Z]+)?:)?(//))?@', $scheme, trim($url));
190 }
191 }
192
193 if (!\function_exists('nwdcx_noscheme')) {
194 // replace http scheme
195 function nwdcx_noscheme($url)
196 {
197 return nwdcx_fixscheme($url, '');
198 }
199 }
200
201 if (!\function_exists('nwdcx_wpdb')) {
202 function nwdcx_wpdb(&$wpdb = '')
203 {
204 if (!isset($GLOBALS['wpdb']) || !\is_object($GLOBALS['wpdb']) || (isset($GLOBALS['wpdb']->ready) && !$GLOBALS['wpdb']->ready)) {
205 $wpdb = false;
206
207 return false;
208 }
209
210 $wpdb = $GLOBALS['wpdb'];
211
212 return $wpdb;
213 }
214 }
215
216 if (!\function_exists('nwdcx_optget')) {
217 function nwdcx_optget($key)
218 {
219 if (!nwdcx_wpdb($wpdb)) {
220 return false;
221 }
222
223 static $cache = [];
224
225 if (isset($cache[$key])) {
226 return $cache[$key];
227 }
228
229 $suppress = $wpdb->suppress_errors(true);
230
231 $query = $wpdb->prepare('SELECT option_value FROM `'.$wpdb->options.'` WHERE option_name=%s ORDER BY option_id ASC LIMIT 1', $key);
232 $option = $wpdb->get_var($query);
233 $cache[$key] = !empty($option) ? nwdcx_unserialize($option) : false;
234
235 $wpdb->suppress_errors($suppress);
236
237 return $cache[$key];
238 }
239 }
240
241 if (!\function_exists('nwdcx_cleanuptransient')) {
242 function nwdcx_cleanuptransient()
243 {
244 if (!nwdcx_wpdb($wpdb)) {
245 return false;
246 }
247
248 $count = 0;
249 $qlimit = 1000;
250 $suppress = $wpdb->suppress_errors(true);
251
252 $collect = [];
253
254 // $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);
255 $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);
256
257 if (!empty($results) && \is_array($results)) {
258 while ($row = @array_shift($results)) {
259 $key = @preg_replace('@^(_site)?(_transient)(_timeout)?_@', '', $row['option_name']);
260 $collect[$key] = $key;
261
262 if (false !== strpos($row['option_name'], '_transient_timeout_') && (int) $row['option_value'] > time()) {
263 unset($collect[$key]);
264 }
265 }
266
267 if (!empty($collect)) {
268 $wpdb->query('START TRANSACTION');
269 foreach ($collect as $key) {
270 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_transient_{$key}'");
271 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_transient_timeout_{$key}'");
272 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_site_transient_{$key}'");
273 $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name`='_site_transient_timeout_{$key}'");
274 ++$count;
275 }
276 $wpdb->query('COMMIT');
277 }
278 }
279
280 $collect = [];
281
282 if (is_multisite() && isset($wpdb->sitemeta)) {
283 // $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);
284 $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);
285 if (!empty($results) && \is_array($results)) {
286 while ($row = @array_shift($results)) {
287 $key = @preg_replace('@^(_site)?(_transient)(_timeout)?_@', '', $row['meta_key']);
288 $collect[$key] = $key;
289
290 if (false !== strpos($row['meta_key'], '_site_transient_timeout_') && (int) $row['meta_value'] > time()) {
291 unset($collect[$key]);
292 }
293 }
294
295 if (!empty($collect)) {
296 $wpdb->query('START TRANSACTION');
297 foreach ($collect as $key) {
298 $wpdb->query("DELETE FROM `{$wpdb->sitemeta}` WHERE `meta_key`='_site_transient_{$key}'");
299 $wpdb->query("DELETE FROM `{$wpdb->sitemeta}` WHERE `meta_key`='_site_transient_timeout_{$key}'");
300 ++$count;
301 }
302 $wpdb->query('COMMIT');
303 }
304 }
305 }
306
307 unset($collect, $results);
308 $wpdb->suppress_errors($suppress);
309
310 return $count;
311 }
312 }
313
314 if (!\function_exists('nwdcx_runaction')) {
315 function nwdcx_runaction(...$args)
316 {
317 add_action(
318 'plugins_loaded',
319 function () use ($args) {
320 \call_user_func_array('do_action', $args);
321 }
322 );
323 }
324 }
325
326 if (!\function_exists('nwdcx_throwable')) {
327 function nwdcx_throwable($name, $error)
328 {
329 if (\defined('WP_DEBUG') && WP_DEBUG) {
330 do_action('docketcache/action/nwdcx/throwable', $name, $error);
331 }
332 }
333 }
334
335 if (!\function_exists('nwdcx_debuglog')) {
336 function nwdcx_debuglog($text)
337 {
338 if (nwdcx_construe('dev')) {
339 $logfile = WP_CONTENT_DIR.'/dcdev-debug.log';
340 error_log('['.date('Y-m-d H:i:s').'] '.$text."\n", 3, $logfile);
341 }
342 }
343 }
344
345 if (!\function_exists('nwdcx_cliverbose')) {
346 function nwdcx_cliverbose($text)
347 {
348 static $is_verbose = false;
349
350 if (!$is_verbose) {
351 $is_verbose = 'cli' === \PHP_SAPI && !empty($_SERVER['argv']) && \in_array('--verbose', $_SERVER['argv']) && !\in_array('--quiet', $_SERVER['argv']);
352 }
353
354 if ($is_verbose && \defined('STDOUT')) {
355 fwrite(\STDOUT, $text);
356 }
357 }
358 }
359
360 if (!\function_exists('nwdcx_microtimetofloat')) {
361 function nwdcx_microtimetofloat($second)
362 {
363 list($usec, $sec) = explode(' ', $second);
364
365 return (float) $usec + (float) $sec;
366 }
367 }
368
369 if (!\function_exists('nwdcx_suppresserrors')) {
370 function nwdcx_suppresserrors($level = true)
371 {
372 $errlevel = error_reporting();
373 $erropt = true === $level ? 0 : $level;
374 error_reporting($erropt);
375
376 return $errlevel;
377 }
378 }
379
380 if (!\function_exists('nwdcx_normalizepath')) {
381 function nwdcx_normalizepath($path)
382 {
383 if (false === strpos($path, '\\')) {
384 return $path;
385 }
386
387 if (\function_exists('wp_normalize_path')) {
388 return wp_normalize_path($path);
389 }
390
391 return str_replace('\\', '/', $path);
392 }
393 }
394
395 // network specific
396
397 if (!\function_exists('nwdcx_network_multi')) {
398 function nwdcx_network_multi()
399 {
400 if (!is_multisite()) {
401 return false;
402 }
403
404 if (\defined('MULTINETWORK')) {
405 return MULTINETWORK;
406 }
407
408 if (\defined('DOCKET_CACHE_MULTINETWORK')) {
409 return DOCKET_CACHE_MULTINETWORK;
410 }
411
412 if (!nwdcx_wpdb($wpdb)) {
413 return false;
414 }
415
416 static $ok = null;
417
418 if (\is_bool($ok)) {
419 return $ok;
420 }
421
422 // this lock file should only exists if network more than 1
423 // see Dropino::multinet_active
424 $lock_file = nwdcx_normalizepath(DOCKET_CACHE_CONTENT_PATH).'/.object-cache-network-multi.txt';
425 $timeout = time() + 86400;
426 if (@is_file($lock_file) && @is_readable($lock_file) && $timeout > @filemtime($lock_file)) {
427 $ok = !empty(@file_get_contents($lock_file)) ? true : false;
428
429 return $ok;
430 }
431
432 $table = $wpdb->base_prefix.'site';
433
434 $suppress = $wpdb->suppress_errors(true);
435 $query = "SELECT id FROM `{$table}` WHERE id > 0 ORDER BY id ASC LIMIT 2";
436 $check = $wpdb->query($query);
437 $wpdb->suppress_errors($suppress);
438 $ok = !empty($check) && $check > 1 ? true : false;
439
440 return $ok;
441 }
442 }
443
444 if (!\function_exists('nwdcx_network_ignore')) {
445 function nwdcx_network_ignore()
446 {
447 if (nwdcx_network_multi()) {
448 if (!@is_file(nwdcx_normalizepath(DOCKET_CACHE_CONTENT_PATH).'/.object-cache-network-'.nwdcx_network_id().'.txt')) {
449 return true;
450 }
451
452 return false;
453 }
454 }
455 }
456
457 if (!\function_exists('nwdcx_network_main')) {
458 function nwdcx_network_main()
459 {
460 if (!is_multisite()) {
461 return true;
462 }
463
464 if (\defined('PRIMARY_NETWORK_ID') && PRIMARY_NETWORK_ID === nwdcx_network_id()) {
465 return true;
466 }
467
468 if (\defined('SITE_ID_CURRENT_SITE') && SITE_ID_CURRENT_SITE === nwdcx_network_id()) {
469 return true;
470 }
471
472 if (empty($_SERVER['HTTP_HOST'])) {
473 return true;
474 }
475
476 if (!nwdcx_wpdb($wpdb)) {
477 return true;
478 }
479
480 $hostname = nwdcx_fixhost($_SERVER['HTTP_HOST']);
481
482 if (\defined('DOMAIN_CURRENT_SITE') && DOMAIN_CURRENT_SITE === $hostname) {
483 return true;
484 }
485
486 $lock_file = nwdcx_normalizepath(DOCKET_CACHE_CONTENT_PATH).'/.object-cache-network-main.txt';
487 $timeout = time() + 86400;
488 if (@is_file($lock_file) && @is_readable($lock_file) && $timeout > @filemtime($lock_file)) {
489 $data = @file_get_contents($lock_file);
490 if (!empty($data) && trim($data) === $hostname) {
491 return true;
492 }
493 }
494
495 static $cache = [];
496
497 if (isset($cache[$hostname])) {
498 return $cache[$hostname];
499 }
500
501 $table = $wpdb->base_prefix.'site';
502
503 $suppress = $wpdb->suppress_errors(true);
504 $query = "SELECT domain FROM `{$table}` WHERE id > 0 ORDER BY id ASC LIMIT 1";
505 $domain = $wpdb->get_var($query);
506 $wpdb->suppress_errors($suppress);
507
508 if ($hostname === $domain) {
509 $cache[$hostname] = true;
510 } elseif (@preg_match('@(.*?\.)?'.preg_quote($domain, '@').'@', $hostname)) {
511 $cache[$hostname] = true;
512 } else {
513 $cache[$hostname] = false;
514 }
515
516 if ($cache[$hostname] && !@is_file($lock_file)) {
517 @file_put_contents($lock_file, $hostname, \LOCK_EX);
518 }
519
520 return $cache[$hostname];
521 }
522 }
523
524 if (!\function_exists('nwdcx_network_id')) {
525 function nwdcx_network_id()
526 {
527 $network_id = \defined('SITE_ID_CURRENT_SITE') ? SITE_ID_CURRENT_SITE : 1;
528
529 if (!is_multisite()) {
530 return $network_id;
531 }
532
533 if (!nwdcx_wpdb($wpdb)) {
534 return $network_id;
535 }
536
537 if (empty($_SERVER['HTTP_HOST'])) {
538 return $network_id;
539 }
540
541 static $cache = [];
542
543 $hostname = nwdcx_fixhost($_SERVER['HTTP_HOST']);
544
545 if (isset($cache[$hostname])) {
546 return $cache[$hostname];
547 }
548
549 $table = $wpdb->base_prefix.'site';
550 $suppress = $wpdb->suppress_errors(true);
551
552 $query = "SELECT `id`,`domain`,`path` FROM `{$table}` ORDER BY id ASC LIMIT 100";
553 $networks = $wpdb->get_results($query, ARRAY_A);
554
555 if (!empty($networks) && \is_array($networks)) {
556 while ($row = @array_shift($networks)) {
557 $id = $row['id'];
558 $domain = $row['domain'];
559 $path = $row['path'];
560
561 if ($hostname === $domain) {
562 $network_id = $id;
563 break;
564 }
565
566 if (false !== strpos($hostname, $domain) && @preg_match('@(.*?\.)?'.preg_quote($domain, '@').'$@', $hostname)) {
567 $network_id = $id;
568 break;
569 }
570 }
571 }
572 $wpdb->suppress_errors($suppress);
573
574 $cache[$hostname] = $network_id;
575
576 return $cache[$hostname];
577 }
578 }
579
580 if (!\function_exists('nwdcx_network_dirpath')) {
581 function nwdcx_network_dirpath($save_path)
582 {
583 if (nwdcx_network_multi() && !nwdcx_network_main()) {
584 $save_path = rtrim($save_path, '/').'/network-'.nwdcx_network_id().'/';
585 }
586
587 return $save_path;
588 }
589 }
590
591 if (!\function_exists('nwdcx_network_filepath')) {
592 function nwdcx_network_filepath($file_path)
593 {
594 if (nwdcx_network_multi() && !nwdcx_network_main()) {
595 $ext = substr($file_path, -4);
596 $fname = substr($file_path, 0, -4);
597
598 $file_path = $fname.'-'.nwdcx_network_id().$ext;
599 }
600
601 return $file_path;
602 }
603 }
604