PluginProbe
Docket Cache – Object Cache Accelerator / trunk
Docket Cache – Object Cache Accelerator vtrunk
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 / Tweaks.php

Tweaks.php in Docket Cache – Object Cache Accelerator trunk, at includes/src/Tweaks.php

1,235 lines 43.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 final class Tweaks
16 {
17 public function wpquery()
18 {
19 // vipcom: prevent core from doing filename lookups for media search.
20 // https://core.trac.wordpress.org/ticket/39358
21 add_action(
22 'pre_get_posts',
23 function () {
24 if (version_compare($GLOBALS['wp_version'], '6.0.3', '>')) {
25 add_filter('wp_allow_query_attachment_by_filename', '__return_false', \PHP_INT_MAX);
26 } else {
27 remove_filter('posts_clauses', '_filter_query_attachment_filenames');
28 }
29 },
30 \PHP_INT_MAX
31 );
32
33 // vipcom: improve perfomance of the _WP_Editors::wp_link_query method
34 add_filter(
35 'wp_link_query_args',
36 function ($query) {
37 $query['no_found_rows'] = true;
38
39 return $query;
40 },
41 \PHP_INT_MAX
42 );
43
44 // vipcom: disable custom fields meta box dropdown (very slow)
45 add_filter('postmeta_form_keys', '__return_false');
46
47 add_filter(
48 'dashboard_recent_posts_query_args',
49 function ($query_args) {
50 $query_args['cache_results'] = true;
51 $query_args['suppress_filters'] = false;
52
53 return $query_args;
54 },
55 10,
56 1
57 );
58
59 add_filter(
60 'dashboard_recent_drafts_query_args',
61 function ($query_args) {
62 $query_args['suppress_filters'] = false;
63
64 return $query_args;
65 },
66 10,
67 1
68 );
69
70 add_action('load-edit.php', function () {
71 if (isset($_REQUEST['bulk_edit'])) {
72 wp_defer_term_counting(true);
73 add_action('shutdown', function () {
74 wp_defer_term_counting(false);
75 });
76 }
77 }, \PHP_INT_MIN);
78
79 if (wp_using_ext_object_cache()) {
80 if (nwdcx_consfalse('TWEAKS_WPQUERY_NOFOUNDROWS_DISABLED')) {
81 add_action(
82 'pre_get_posts',
83 function (&$args) {
84 if (\is_object($args)) {
85 $args->no_found_rows = true;
86 $args->order = 'ASC';
87 } elseif (\is_array($args)) {
88 $args['no_found_rows'] = true;
89 $args['order'] = 'ASC';
90 }
91 },
92 \PHP_INT_MIN
93 );
94
95 add_action(
96 'parse_query',
97 function (&$args) {
98 if (\is_object($args)) {
99 $args->no_found_rows = true;
100 $args->order = 'ASC';
101 } elseif (\is_array($args)) {
102 $args['no_found_rows'] = true;
103 $args['order'] = 'ASC';
104 }
105 },
106 \PHP_INT_MIN
107 );
108
109 add_action(
110 'pre_get_users',
111 function ($wpq) {
112 if (nwdcx_wpdb($wpdb) && !empty($wpq->query_vars['count_total'])) {
113 $wpq->query_vars['count_total'] = false;
114 $wpq->query_vars['nwdcx_count_total'] = true;
115 }
116 },
117 \PHP_INT_MIN
118 );
119
120 add_action(
121 'pre_user_query',
122 function ($wpq) {
123 if (nwdcx_wpdb($wpdb) && !empty($wpq->query_vars['nwdcx_count_total'])) {
124 unset($wpq->query_vars['nwdcx_count_total']);
125 $sql = "SELECT COUNT(*) {$wpq->query_from} {$wpq->query_where}";
126 $wpq->total_users = $wpdb->get_var($sql);
127 }
128 },
129 \PHP_INT_MIN
130 );
131 }
132
133 if (nwdcx_consfalse('TWEAKS_COUNT_COMMENTS_DISABLED')) {
134 add_filter(
135 'wp_count_comments',
136 function ($counts = false, $post_id = 0) {
137 if (0 !== $post_id) {
138 return $counts;
139 }
140
141 $cache_group = 'docketcache-wpquery';
142 $cache_key = 'comments-0';
143 $stats_object = wp_cache_get($cache_key, $cache_group);
144
145 if (false === $stats_object) {
146 $stats = get_comment_count(0);
147 $stats['moderated'] = $stats['awaiting_moderation'];
148 unset($stats['awaiting_moderation']);
149 $stats_object = $stats;
150
151 wp_cache_set($cache_key, $stats_object, $cache_group, 1800); // 1800 = 30min
152 }
153
154 return (object) $stats_object;
155 },
156 \PHP_INT_MAX,
157 2
158 );
159
160 // core
161 foreach (['comment_post', 'wp_set_comment_status'] as $fx) {
162 add_action(
163 $fx,
164 function () {
165 wp_cache_delete('comments-0', 'docketcache-wpquery');
166 }
167 );
168 }
169
170 // jetpack
171 foreach (['unapproved_to_approved', 'approved_to_unapproved', 'spam_to_approved', 'approved_to_spam'] as $fx) {
172 add_action(
173 'comment_'.$fx,
174 function () {
175 wp_cache_delete('comments-0', 'docketcache-wpquery');
176 }
177 );
178 }
179 }
180
181 if (nwdcx_consfalse('TWEAKS_COUNT_MEDIA_LIBRARY_DISABLED')) {
182 add_filter(
183 'media_library_months_with_files',
184 function () {
185 $cache_group = 'docketcache-wpquery';
186
187 $months = wp_cache_get('media_library_months_with_files', $cache_group);
188
189 if (false === $months) {
190 if (!nwdcx_wpdb($wpdb)) {
191 return $months;
192 }
193
194 $months = $wpdb->get_results(
195 $wpdb->prepare(
196 "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month FROM `{$wpdb->posts}` WHERE post_type = %s ORDER BY post_date DESC",
197 'attachment'
198 )
199 );
200 wp_cache_set('media_library_months_with_files', $months, $cache_group, 2592000); // 2592000 = 1month
201 }
202
203 return $months;
204 }
205 );
206
207 add_action(
208 'add_attachment',
209 function ($post_id) {
210 if (\defined('WP_IMPORTING') && WP_IMPORTING) {
211 return;
212 }
213
214 if (!nwdcx_wpdb($wpdb)) {
215 return;
216 }
217
218 $months = $wpdb->get_results(
219 $wpdb->prepare(
220 "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month FROM `{$wpdb->posts}` WHERE post_type = %s ORDER BY post_date DESC LIMIT 1",
221 'attachment'
222 ),
223 ARRAY_A
224 );
225
226 if (empty($months) || !\is_array($months)) {
227 return;
228 }
229
230 $cache_group = 'docketcache-wpquery';
231 $months = array_values($months);
232 $months = array_shift($months);
233
234 $months = (object) $months;
235
236 if (!$months->year == get_the_time('Y', $post_id) && !$months->month == get_the_time('m', $post_id)) {
237 wp_cache_delete('media_library_months_with_files', $cache_group);
238 }
239 }
240 );
241 }
242 } // wp_using_ext_object_cache
243 }
244
245 public function misc()
246 {
247 // wp: if only one post is found by the search results, redirect user to that post
248 if (nwdcx_consfalse('TWEAKS_SINGLESEARCHREDIRECT_DISABLED')) {
249 add_action(
250 'template_redirect',
251 function () {
252 if (is_search()) {
253 global $wp_query;
254 if (1 === (int) $wp_query->post_count && 1 === (int) $wp_query->max_num_pages) {
255 wp_redirect(get_permalink($wp_query->posts['0']->ID));
256 exit;
257 }
258 }
259 },
260 \PHP_INT_MAX
261 );
262 }
263
264 // wp: hide update notifications to non-admin users
265 add_action(
266 'admin_head',
267 function () {
268 if (!current_user_can('update_core')) {
269 remove_action('admin_notices', 'update_nag', 3);
270 }
271 },
272 \PHP_INT_MAX
273 );
274
275 // jetpack: enables object caching for the response sent by instagram when querying for instagram image html
276 // https://developer.jetpack.com/hooks/instagram_cache_oembed_api_response_body/
277 // Removed in Jetpack 9.1.0
278 // add_filter('instagram_cache_oembed_api_response_body', '__return_true');
279
280 if (nwdcx_consfalse('TWEAKS_WPCOOKIE_DISABLED')) {
281 // wp: comment cookie lifetime, default to 30000000 second = 12 months
282 add_filter(
283 'comment_cookie_lifetime',
284 function () {
285 return 12 * HOUR_IN_SECONDS;
286 },
287 \PHP_INT_MIN
288 );
289
290 // wp: protected post, expire when browser close
291 add_filter(
292 'post_password_expires',
293 function () {
294 return 0;
295 },
296 \PHP_INT_MIN
297 );
298 }
299
300 if (nwdcx_consfalse('TWEAKS_WPLOGIN_TRANSLATIONAPI_DISABLED')) {
301 add_action(
302 'init',
303 function () {
304 add_filter(
305 'translations_api',
306 function ($type, $args) {
307 if (false !== strpos($_SERVER['REQUEST_URI'], '/wp-login.php')) {
308 return true;
309 }
310
311 return false;
312 },
313 \PHP_INT_MAX,
314 2
315 );
316 },
317 \PHP_INT_MAX
318 );
319 }
320 }
321
322 public function headerjunk()
323 {
324 // wp: header junk
325 add_action(
326 'after_setup_theme',
327 function () {
328 remove_action('wp_head', 'rsd_link');
329 remove_action('wp_head', 'wp_generator');
330 remove_action('wp_head', 'feed_links', 2);
331 remove_action('wp_head', 'feed_links_extra', 3);
332 remove_action('wp_head', 'index_rel_link');
333 remove_action('wp_head', 'wlwmanifest_link');
334 remove_action('wp_head', 'start_post_rel_link', 10, 0);
335 remove_action('wp_head', 'parent_post_rel_link', 10, 0);
336 remove_action('wp_head', 'adjacent_posts_rel_link', 10, 0);
337 remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0);
338 remove_action('wp_head', 'wp_shortlink_wp_head', 10, 0);
339 },
340 \PHP_INT_MAX
341 );
342
343 add_filter('the_generator', '__return_empty_string', \PHP_INT_MAX);
344 add_filter('x_redirect_by', '__return_false', \PHP_INT_MAX);
345 }
346
347 public function pingback()
348 {
349 // wp: disable pingback
350 add_action(
351 'pre_ping',
352 function (&$links) {
353 foreach ($links as $l => $link) {
354 if (0 === strpos($link, get_option('home'))) {
355 unset($links[$l]);
356 }
357 }
358 },
359 \PHP_INT_MAX
360 );
361
362 // wp: disable and remove do_pings
363 // https://wp-mix.com/wordpress-clean-up-do_pings/
364 add_action(
365 'plugins_loaded',
366 function () {
367 if (isset($_GET['doing_wp_cron'])) {
368 remove_action('do_pings', 'do_all_pings');
369 wp_clear_scheduled_hook('do_pings');
370 }
371 },
372 \PHP_INT_MAX
373 );
374
375 // vipcom: performance/do-pings.php
376 // Disable pings by default.
377 add_action('schedule_event', function ($event) {
378 if (!\is_object($event)) {
379 return $event;
380 }
381
382 if ('do_pings' === $event->hook) {
383 return false;
384 }
385
386 return $event;
387 });
388
389 // vipcom: performance/do-pings.php : pre_disable_pings.
390 // Hooking at 0 to get in before cron control on pre_schedule_event.
391 add_filter('pre_schedule_event', function ($scheduled, $event) {
392 if (null !== $scheduled) {
393 return $scheduled;
394 }
395
396 if ('do_pings' === $event->hook) {
397 return false;
398 }
399
400 return $scheduled;
401 }, 0, 2);
402
403 // vipcom: performance/do-pings.php : avoid new _encloseme metas.
404 // https://wordpress.stackexchange.com/questions/20904/the-encloseme-meta-key-conundrum
405 add_filter('add_post_metadata', function ($should_update, $object_id, $meta_key) {
406 if ('_encloseme' === $meta_key) {
407 $should_update = false;
408 }
409
410 return $should_update;
411 }, 10, 3);
412
413 // wp: disable xmlrpc
414 // https://www.wpbeginner.com/plugins/how-to-disable-xml-rpc-in-wordpress/
415 // https://kinsta.com/blog/xmlrpc-php/
416 add_filter('xmlrpc_enabled', '__return_false');
417 add_filter('pre_update_option_enable_xmlrpc', '__return_false');
418 add_filter('pre_option_enable_xmlrpc', '__return_zero');
419
420 // additional
421 add_filter('pings_open', '__return_false');
422 add_filter('pre_option_default_ping_status', '__return_zero');
423 add_filter('pre_option_default_pingback_flag', '__return_zero');
424 add_filter(
425 'xmlrpc_methods',
426 function ($methods) {
427 unset($methods['pingback.ping']);
428 unset($methods['pingback.extensions.getPingbacks']);
429 unset($methods['wp.getUsersBlogs']);
430 unset($methods['system.multicall']);
431 unset($methods['system.listMethods']);
432 unset($methods['system.getCapabilities']);
433 unset($methods['demo.sayHello']);
434
435 return $methods;
436 }
437 );
438
439 add_action(
440 'xmlrpc_call',
441 function ($method) {
442 if ('pingback.ping' !== $method) {
443 return;
444 }
445 http_response_code(403);
446 exit('This site does not have pingback.');
447 }
448 );
449
450 add_filter(
451 'template_redirect',
452 function () {
453 header_remove('X-Pingback');
454 },
455 \PHP_INT_MAX
456 );
457
458 add_filter(
459 'wp_headers',
460 function ($headers) {
461 unset($headers['X-Pingback']);
462
463 return $headers;
464 },
465 \PHP_INT_MAX
466 );
467
468 add_action(
469 'plugins_loaded',
470 function () {
471 if (isset($_SERVER['REQUEST_URI']) && '/xmlrpc.php' === $_SERVER['REQUEST_URI']) {
472 http_response_code(403);
473 exit('xmlrpc.php not available.');
474 }
475
476 // additional
477 if (isset($_SERVER['SCRIPT_FILENAME']) && 'xmlrpc.php' === basename($_SERVER['SCRIPT_FILENAME'])) {
478 http_response_code(403);
479 exit('xmlrpc.php not available.');
480 }
481 },
482 \PHP_INT_MAX
483 );
484 }
485
486 private function has_woocommerce()
487 {
488 return isset($GLOBALS['woocommerce']) && \is_object($GLOBALS['woocommerce']);
489 }
490
491 public function woocommerce_misc()
492 {
493 // wc: action_scheduler_migration_dependencies_met
494 if ('complete' === get_option('action_scheduler_migration_status')) {
495 add_filter('action_scheduler_migration_dependencies_met', '__return_false', \PHP_INT_MAX);
496 }
497
498 // wc: disable background image regeneration
499 add_filter('woocommerce_background_image_regeneration', '__return_false', \PHP_INT_MAX);
500
501 // wc: remove marketplace suggestions
502 // https://rudrastyh.com/woocommerce/remove-marketplace-suggestions.html
503 add_filter('woocommerce_allow_marketplace_suggestions', '__return_false', \PHP_INT_MAX);
504
505 // wc: remove connect your store to WooCommerce.com admin notice
506 add_filter('woocommerce_helper_suppress_admin_notices', '__return_true', \PHP_INT_MAX);
507
508 // wc: disable the WooCommere Marketing Hub
509 add_filter(
510 'woocommerce_admin_features',
511 function ($features) {
512 $marketing = array_search('marketing', $features);
513 unset($features[$marketing]);
514
515 return $features;
516 },
517 \PHP_INT_MAX
518 );
519 add_filter('woocommerce_marketing_menu_items', '__return_empty_array', \PHP_INT_MAX);
520
521 // wc: Enable WooCommerce no-cache headers
522 // includes/class-wc-cache-helper.php
523 add_filter('woocommerce_enable_nocache_headers', '__return_false');
524
525 // wc: remove the WooCommerce usage tracker cron event
526 wp_clear_scheduled_hook('woocommerce_tracker_send_event');
527
528 // jetpack
529 add_filter('jetpack_just_in_time_msgs', '__return_false', \PHP_INT_MAX);
530 add_filter('jetpack_show_promotions', '__return_false', \PHP_INT_MAX);
531 }
532
533 public function woocommerce_admin_disabled()
534 {
535 // wc: disable the WooCommerce Admin
536 add_filter('woocommerce_admin_disabled', '__return_true', \PHP_INT_MAX);
537
538 // 09052022: line 1048 packages/woocommerce-admin/src/Loader.php -> Undefined index: id, value
539 add_filter('woocommerce_admin_preload_settings', '__return_empty_array', \PHP_INT_MAX);
540 }
541
542 public function woocommerce_dashboard_status_remove()
543 {
544 add_action(
545 'wp_dashboard_setup',
546 function () {
547 if (!$this->has_woocommerce()) {
548 return;
549 }
550
551 remove_meta_box('woocommerce_dashboard_status', 'dashboard', 'normal');
552 remove_meta_box('woocommerce_dashboard_recent_reviews', 'dashboard', 'normal');
553 remove_meta_box('woocommerce_network_orders', 'dashboard', 'normal');
554 remove_meta_box('wc_admin_dashboard_setup', 'dashboard', 'normal');
555 },
556 \PHP_INT_MAX
557 );
558 }
559
560 public function woocommerce_widget_remove()
561 {
562 add_action(
563 'widgets_init',
564 function () {
565 if (!$this->has_woocommerce()) {
566 return;
567 }
568
569 // plugins/woocommerce/includes/wc-widget-functions.php
570 $widgets = [
571 'WC_Widget_Cart',
572 'WC_Widget_Layered_Nav_Filters',
573 'WC_Widget_Layered_Nav',
574 'WC_Widget_Price_Filter',
575 'WC_Widget_Product_Categories',
576 'WC_Widget_Product_Search',
577 'WC_Widget_Product_Tag_Cloud',
578 'WC_Widget_Products',
579 'WC_Widget_Recently_Viewed',
580 'WC_Widget_Top_Rated_Products',
581 'WC_Widget_Recent_Reviews',
582 'WC_Widget_Rating_Filter',
583 ];
584 foreach ($widgets as $widget) {
585 // remove
586 unregister_widget($widget);
587
588 // prevent error notice _doing_it_wrong
589 // see wp-includes/widgets.php -> the_widget()
590 register_widget($widget, null);
591 }
592 },
593 \PHP_INT_MAX
594 );
595
596 add_action('plugins_loaded', function () {
597 if (!$this->has_woocommerce()) {
598 return;
599 }
600 remove_action('widgets_init', 'wc_register_widgets');
601 }, \PHP_INT_MAX);
602 }
603
604 public function woocommerce_cart_fragments_remove()
605 {
606 add_action(
607 'wp_enqueue_scripts',
608 function () {
609 $id = 'wc-cart-fragments';
610 $wp_scripts = $GLOBALS['wp_scripts'];
611 if (!\is_object($wp_scripts) || !isset($wp_scripts->registered[$id])) {
612 return;
613 }
614
615 $src = $wp_scripts->registered[$id]->src;
616 $wp_scripts->registered[$id]->src = null;
617
618 $code = '(function() {';
619 $code .= 'var checkhash = function() {';
620 $code .= 'var n = "woocommerce_cart_hash";';
621 $code .= 'var h = document.cookie.match("(^|;) ?" + n + "=([^;]*)(;|$)");';
622 $code .= 'return h ? h[2] : null;';
623 $code .= '};';
624 $code .= 'var checkscript = function() {';
625 $code .= 'var src = "'.$src.'";';
626 $code .= 'var id = "docket-cache-wccartfragment";';
627 $code .= 'if ( null !== document.getElementById(id) ) {';
628 $code .= 'return false;';
629 $code .= 'if ( checkhash() ) {';
630 $code .= 'var script = document.createElement("script");';
631 $code .= 'script.id = id;';
632 $code .= 'script.src = src;';
633 $code .= 'script.async = true;';
634 $code .= 'document.head.appendChild(script);';
635 $code .= '}';
636 $code .= '}';
637 $code .= '};';
638 $code .= 'checkscript();';
639 $code .= 'document.addEventListener("click", function(){setTimeout(checkscript,1000);});';
640 $code .= '})();';
641 wp_add_inline_script('jquery', $code);
642 },
643 \PHP_INT_MAX
644 );
645 }
646
647 public function woocommerce_crawling_addtochart_links()
648 {
649 add_filter('robots_txt', function ($output, $public) {
650 if (!$this->has_woocommerce()) {
651 return $output;
652 }
653
654 $append = '';
655 if (!@preg_match('@^Disallow:\s+/\*add\-to\-cart=\*@is', $output)) {
656 $append .= 'Disallow: /*'."add-to-cart=*\n";
657 }
658
659 if (!@preg_match('@^Disallow:\s+/cart/@is', $output)) {
660 $append .= "Disallow: /cart/\n";
661 } else {
662 $cart = basename(wc_get_cart_url());
663 if (!@preg_match('@^Disallow:\s+/'.$cart.'/@is', $output)) {
664 $append .= 'Disallow: /'.$cart."/\n";
665 }
666 }
667
668 if (!@preg_match('@^Disallow:\s+/checkout/@is', $output)) {
669 $append .= "Disallow: /checkout/\n";
670 } else {
671 $checkout = basename(wc_get_checkout_url());
672 if (!@preg_match('@^Disallow:\s+/'.$checkout.'/@is', $output)) {
673 $append .= 'Disallow: /'.$checkout."/\n";
674 }
675 }
676
677 if (!@preg_match('@^Disallow:\s+/my\-account/@is', $output)) {
678 $append .= "Disallow: /my-account/\n";
679 } else {
680 $myaccount = basename(wc_get_page_permalink('myaccount'));
681 if (!@preg_match('@^Disallow:\s+/'.$myaccount.'/@is', $output)) {
682 $append .= 'Disallow: /'.$myaccount."/\n";
683 }
684 }
685
686 if (!empty($append)) {
687 $addua = true;
688 if (@preg_match_all('@User-agent:\s+\S+@is', $output, $mm, \PREG_SET_ORDER)) {
689 $last = end($mm);
690 if (@preg_match('@User-agent:\s+\*@i', $last[0])) {
691 $addua = false;
692 }
693 }
694
695 $output .= "\n# Added by Docket Cache\n";
696
697 if ($addua) {
698 $output .= "User-agent: *\n";
699 }
700
701 $output .= $append;
702 }
703
704 return $output;
705 }, \PHP_INT_MAX, 2);
706 }
707
708 public function woocommerce_extensionpage_remove()
709 {
710 add_action('admin_menu', function () {
711 remove_submenu_page('woocommerce', 'wc-addons');
712 remove_submenu_page('woocommerce', 'wc-addons&section=helper');
713 }, \PHP_INT_MAX);
714 }
715
716 public function post_missed_schedule()
717 {
718 if (!nwdcx_wpdb($wpdb)) {
719 return false;
720 }
721
722 $suppress = $wpdb->suppress_errors(true);
723
724 // check
725 $query = "SELECT ID FROM `{$wpdb->posts}` WHERE post_status='future' ORDER BY ID ASC LIMIT 1";
726 $check = $wpdb->query($query);
727
728 if ($check < 1) {
729 return false;
730 }
731
732 $limit = 1000;
733 $args = [
734 'public' => true,
735 'exclude_from_search' => false,
736 '_builtin' => false,
737 ];
738
739 $post_types = get_post_types($args, 'names', 'and');
740 $current_datetime = date('Y-m-d H:i:s');
741 if (!empty($post_types) && \is_array($post_types)) {
742 $types = implode("','", $post_types);
743 $query = $wpdb->prepare("SELECT ID FROM `{$wpdb->posts}` WHERE post_type in ('post','page','%s') AND post_status='future' AND %s >= post_date_gmt ORDER BY ID ASC LIMIT %d", $types, $current_datetime, $limit);
744 } else {
745 $query = $wpdb->prepare("SELECT ID FROM `{$wpdb->posts}` WHERE post_type in ('post','page') AND post_status='future' AND %s >= post_date_gmt ORDER BY ID ASC LIMIT %d", $current_datetime, $limit);
746 }
747
748 $results = $wpdb->get_results($query, ARRAY_A);
749
750 if (!empty($results)) {
751 while ($row = @array_shift($results)) {
752 $id = $row['ID'];
753 wp_publish_post($id);
754 }
755 }
756
757 $wpdb->suppress_errors($suppress);
758
759 return true;
760 }
761
762 public function wpemoji()
763 {
764 remove_action('wp_head', 'print_emoji_detection_script', 7);
765 remove_action('admin_print_scripts', 'print_emoji_detection_script');
766 remove_action('wp_print_styles', 'print_emoji_styles');
767 remove_action('admin_print_styles', 'print_emoji_styles');
768 remove_filter('the_content_feed', 'wp_staticize_emoji');
769 remove_filter('comment_text_rss', 'wp_staticize_emoji');
770 remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
771
772 add_filter('emoji_svg_url', '__return_false');
773
774 add_filter(
775 'tiny_mce_plugins',
776 function ($plugins) {
777 if (\is_array($plugins)) {
778 return array_diff($plugins, ['wpemoji']);
779 }
780
781 return [];
782 }
783 );
784
785 add_filter(
786 'wp_resource_hints',
787 function ($urls, $relation_type) {
788 if ('dns-prefetch' === (string) $relation_type) {
789 $emoji_url = 'https://s.w.org/images/core/emoji/';
790 foreach ($urls as $key => $url) {
791 if (false !== strpos($url, $emoji_url)) {
792 unset($urls[$key]);
793 }
794 }
795 }
796
797 return $urls;
798 },
799 10,
800 2
801 );
802 }
803
804 // ref: https://wordpress.org/support/topic/syntax-error-222/
805 public function wpembed_bodyclass($classes, $class = [])
806 {
807 foreach ($classes as $num => $name) {
808 if ('wp-embed-responsive' === $name) {
809 unset($classes[$num]);
810 }
811 }
812
813 return $classes;
814 }
815
816 public function wpembed()
817 {
818 if (isset($GLOBALS['wp']) && \is_object($GLOBALS['wp']) && isset($GLOBALS['wp']->public_query_vars)) {
819 $GLOBALS['wp']->public_query_vars = array_diff($GLOBALS['wp']->public_query_vars, ['embed']);
820 }
821
822 if (isset($GLOBALS['wp_embed']) && \is_object($GLOBALS['wp_embed'])) {
823 remove_filter('the_content', [$GLOBALS['wp_embed'], 'autoembed'], 8);
824 }
825
826 remove_filter('the_content_feed', '_oembed_filter_feed_content');
827 remove_action('plugins_loaded', 'wp_maybe_load_embeds', 0);
828 add_filter('pre_option_embed_autourls', '__return_false');
829 add_filter('embed_oembed_discover', '__return_false');
830 remove_action('rest_api_init', 'wp_oembed_register_route');
831 remove_filter('rest_pre_serve_request', '_oembed_rest_pre_serve_request');
832 remove_action('wp_head', 'wp_oembed_add_discovery_links');
833 remove_action('wp_head', 'wp_oembed_add_host_js');
834 remove_action('embed_head', 'enqueue_embed_scripts', 1);
835 remove_action('embed_head', 'print_emoji_detection_script');
836 remove_action('embed_head', 'print_embed_styles');
837 remove_action('embed_head', 'wp_print_head_scripts', 20);
838 remove_action('embed_head', 'wp_print_styles', 20);
839 remove_action('embed_head', 'wp_no_robots');
840 remove_action('embed_head', 'rel_canonical');
841 remove_action('embed_head', 'locale_stylesheet', 30);
842 remove_action('embed_content_meta', 'print_embed_comments_button');
843 remove_action('embed_content_meta', 'print_embed_sharing_button');
844 remove_action('embed_footer', 'print_embed_sharing_dialog');
845 remove_action('embed_footer', 'print_embed_scripts');
846 remove_action('embed_footer', 'wp_print_footer_scripts', 20);
847 remove_filter('excerpt_more', 'wp_embed_excerpt_more', 20);
848 remove_filter('the_excerpt_embed', 'wptexturize');
849 remove_filter('the_excerpt_embed', 'convert_chars');
850 remove_filter('the_excerpt_embed', 'wpautop');
851 remove_filter('the_excerpt_embed', 'shortcode_unautop');
852 remove_filter('the_excerpt_embed', 'wp_embed_excerpt_attachment');
853 remove_filter('oembed_dataparse', 'wp_filter_oembed_result');
854 remove_filter('oembed_response_data', 'get_oembed_response_data_rich');
855 remove_filter('pre_oembed_result', 'wp_filter_pre_oembed_result');
856 remove_filter('woocommerce_short_description', 'wc_do_oembeds');
857
858 add_filter(
859 'tiny_mce_plugins',
860 function ($plugins) {
861 return array_diff($plugins, ['wpembed', 'wpview']);
862 }
863 );
864
865 add_filter(
866 'rewrite_rules_array',
867 function ($rules) {
868 $results = [];
869 foreach ($rules as $rule => $val) {
870 if (false !== ($pos = strpos($val, '?'))) {
871 $args = explode('&', substr($val, $pos + 1));
872 if (\in_array('embed=true', $args)) {
873 continue;
874 }
875 }
876 $results[$rule] = $val;
877 }
878
879 return $results;
880 }
881 );
882
883 if (\defined('DOCKET_CACHE_WPEMBED_BODYCLASS_FILTER') && DOCKET_CACHE_WPEMBED_BODYCLASS_FILTER) {
884 add_filter(
885 'body_class', [$this, 'wpembed_bodyclass'],
886 \PHP_INT_MAX,
887 2
888 );
889 }
890
891 add_action(
892 'wp_footer',
893 function () {
894 wp_dequeue_script('wp-embed');
895 },
896 \PHP_INT_MAX
897 );
898 }
899
900 public function wpfeed()
901 {
902 add_action(
903 'wp_loaded',
904 function () {
905 remove_action('wp_head', 'feed_links', 2);
906 remove_action('wp_head', 'feed_links_extra', 3);
907 }
908 );
909
910 add_action(
911 'init',
912 function () {
913 if (isset($GLOBALS['wp_rewrite']) && \is_object($GLOBALS['wp_rewrite']) && isset($GLOBALS['wp_rewrite']->feeds)) {
914 $GLOBALS['wp_rewrite']->feeds = [];
915 }
916 }
917 );
918
919 foreach (['rdf', 'rss', 'rss2', 'atom', 'rss2_comments', 'atom_comments'] as $feed) {
920 add_action(
921 'do_feed_'.$feed,
922 function () {
923 wp_redirect(home_url(), 302);
924 exit;
925 },
926 1
927 );
928 }
929 }
930
931 public function wplazyload()
932 {
933 add_filter('wp_lazy_loading_enabled', '__return_false', \PHP_INT_MAX);
934 add_filter('wp_get_attachment_image_attributes', function ($attr, $attachment, $size) {
935 $attr['loading'] = 'eager';
936
937 return $attr;
938 }, \PHP_INT_MAX, 3);
939 }
940
941 public function wpsitemap()
942 {
943 add_action(
944 'init',
945 function () {
946 add_filter('wp_sitemaps_enabled', '__return_false');
947 remove_filter('robots_txt', ['WP_Sitemaps', 'add_robots']);
948 },
949 \PHP_INT_MIN
950 );
951 }
952
953 public function wpapppassword()
954 {
955 add_filter('wp_is_application_passwords_available', '__return_false', \PHP_INT_MAX);
956 }
957
958 public function wpdashboardnews()
959 {
960 add_action(
961 'wp_dashboard_setup',
962 function () {
963 remove_meta_box('dashboard_primary', 'dashboard', 'side');
964 },
965 \PHP_INT_MAX
966 );
967
968 add_action(
969 'admin_init',
970 function () {
971 remove_meta_box('dashboard_primary', 'dashboard-network', 'side');
972 },
973 \PHP_INT_MAX
974 );
975 }
976
977 public function postviaemail()
978 {
979 add_filter('enable_post_by_email_configuration', '__return_false', \PHP_INT_MAX);
980 }
981
982 // reference:
983 // wp-admin/includes/dashboard.php -> wp_check_browser_version()
984 public function wpbrowsehappy()
985 {
986 if (empty($_SERVER['HTTP_USER_AGENT'])) {
987 return;
988 }
989
990 $key = md5($_SERVER['HTTP_USER_AGENT']);
991
992 // reference: wp-includes/option.php -> get_site_transient( $transient )
993 // return an array to implying it always exists and never expires.
994 add_filter('pre_site_transient_browser_'.$key, function () {
995 // return an array instead of true to avoid php error
996 // "Trying to access array offset on value of type bool".
997 return [];
998 }, \PHP_INT_MAX);
999 }
1000
1001 // reference:
1002 // wp-admin/includes/misc.php -> wp_check_php_version()
1003 public function wpservehappy()
1004 {
1005 $key = md5(\PHP_VERSION);
1006 add_filter('pre_site_transient_php_check_'.$key, function () {
1007 /*
1008 * Response should be an array with:
1009 * 'recommended_version' - string - The PHP version recommended by WordPress.
1010 * 'is_supported' - boolean - Whether the PHP version is actively supported.
1011 * 'is_secure' - boolean - Whether the PHP version receives security updates.
1012 * 'is_acceptable' - boolean - Whether the PHP version is still acceptable or warnings
1013 * should be shown and an update recommended.
1014 */
1015
1016 return [
1017 'recommended_version' => '',
1018 'is_supported' => '',
1019 'is_secure' => '',
1020 'is_lower_than_future_minimum' => '',
1021 'is_acceptable' => '',
1022 ];
1023 }, \PHP_INT_MAX);
1024
1025 add_action('wp_dashboard_setup', function () {
1026 remove_meta_box('dashboard_php_nag', 'dashboard', 'normal');
1027 });
1028 }
1029
1030 // wp < 5.8
1031 public function http_headers_expect()
1032 {
1033 // https://github.com/WordPress/Requests/pull/454
1034 if (version_compare($GLOBALS['wp_version'], '5.8', '>')) {
1035 return false;
1036 }
1037
1038 add_filter('http_request_args', function ($args) {
1039 if (!isset($args['headers']['expect'])) {
1040 $args['headers']['expect'] = '';
1041
1042 if (\is_array($args['body'])) {
1043 $bytesize = 0;
1044 $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($args['body']));
1045
1046 foreach ($iterator as $datum) {
1047 $bytesize += \strlen((string) $datum);
1048
1049 if ($bytesize >= 1048576) {
1050 $args['headers']['expect'] = '100-Continue';
1051 break;
1052 }
1053 }
1054 } elseif (!empty($args['body']) && \strlen((string) $args['body']) > 1048576) {
1055 $args['headers']['expect'] = '100-Continue';
1056 }
1057 }
1058
1059 return $args;
1060 }, \PHP_INT_MAX);
1061 }
1062
1063 public function limit_http_request()
1064 {
1065 add_action(
1066 'admin_init',
1067 function () {
1068 add_filter(
1069 'pre_http_request',
1070 function ($preempt, $parsed_args, $url) {
1071 if (!is_admin()) {
1072 return false;
1073 }
1074
1075 if (/* 'GET' !== $parsed_args['method'] || */ $this->http_filter_bypass_url($url)) {
1076 return false;
1077 }
1078
1079 if (empty($GLOBALS['pagenow'])) {
1080 return false;
1081 }
1082
1083 $pagenow = $GLOBALS['pagenow'];
1084 $pageok = [
1085 'index.php' => 1,
1086 'plugins.php' => 1,
1087 'plugin-install.php' => 1,
1088 'update.php' => 1,
1089 'themes.php' => 1,
1090 'admin.php' => 1,
1091 'update-core.php' => 1,
1092 'admin-ajax.php' => 1,
1093 ];
1094
1095 if (\array_key_exists($pagenow, $pageok)) {
1096 return false;
1097 }
1098
1099 /*$site_host = parse_url(site_url(), \PHP_URL_HOST);
1100 if ('.local' === substr($site_host, -\strlen('.local')) || '.test' === substr($site_host, -\strlen('.test'))) {
1101 return false;
1102 }*/
1103
1104 $url_host = parse_url($url, \PHP_URL_HOST);
1105
1106 $is_block = true;
1107 $wkey = nwdcx_constfx('LIMITHTTPREQUEST_WHITELIST');
1108 if (\defined($wkey)) {
1109 $whitelist = \constant($wkey);
1110 if (!empty($whitelist) && \is_array($whitelist)) {
1111 foreach ($whitelist as $host) {
1112 $host = nwdcx_noscheme($host);
1113 if ($url_host === $host) {
1114 $is_block = false;
1115 break;
1116 }
1117
1118 if ('.' === $host[0] && $host === substr($url_host, -\strlen($host))) {
1119 $is_block = false;
1120 break;
1121 }
1122 }
1123 }
1124 }
1125
1126 if ($is_block) {
1127 nwdcx_debuglog('Tweaks::limit_http_request(): Blocked -> '.$url_host);
1128 }
1129
1130 return $is_block;
1131 },
1132 \PHP_INT_MIN,
1133 3
1134 );
1135 },
1136 \PHP_INT_MAX
1137 );
1138 }
1139
1140 public function cache_http_response()
1141 {
1142 add_action('init', function () {
1143 add_filter('http_response', function ($response, $parsed_args, $url) {
1144 if (/* 'GET' !== $parsed_args['method'] || */ $this->http_filter_bypass_url($url)) {
1145 return $response;
1146 }
1147
1148 $cache_key = 'docketcache-httpresponse_'.md5($url);
1149
1150 if (200 !== $response['response']['code']) {
1151 delete_transient($cache_key);
1152
1153 return $response;
1154 }
1155
1156 $cache_ttl = (int) nwdcx_constval('CACHEHTTPRESPONSE_TTL');
1157 if (empty($cache_ttl)) {
1158 $cache_ttl = 300;
1159 }
1160
1161 $include_list = nwdcx_constval('CACHEHTTPRESPONSE_INCLUDE');
1162 $exclude_list = nwdcx_constval('CACHEHTTPRESPONSE_EXCLUDE');
1163
1164 if (empty($include_list) && empty($exclude_list)) {
1165 set_transient($cache_key, $response, $cache_ttl);
1166
1167 return $response;
1168 }
1169
1170 if (!empty($include_list) && \is_array($include_list) && \in_array($url, $include_list)) {
1171 if (!empty($exclude_list) && \is_array($exclude_list) && !\in_array($url, $exclude_list)) {
1172 set_transient($cache_key, $response, $cache_ttl);
1173 }
1174
1175 return $response;
1176 }
1177
1178 if (!empty($exclude_list) && \is_array($exclude_list) && !\in_array($url, $exclude_list)) {
1179 set_transient($cache_key, $response, $cache_ttl);
1180
1181 return $response;
1182 }
1183
1184 return $response;
1185 }, \PHP_INT_MIN, 3);
1186
1187 add_filter('pre_http_request', function ($preempt, $parsed_args, $url) {
1188 if (/* 'GET' !== $parsed_args['method'] || */ $this->http_filter_bypass_url($url)) {
1189 return $preempt;
1190 }
1191
1192 $cache_key = 'docketcache-httpresponse_'.md5($url);
1193 $data = get_transient($cache_key);
1194 if (!empty($data) && \is_array($data)) {
1195 nwdcx_debuglog('Tweaks::cache_http_response(): Cached -> '.$url);
1196
1197 return $data;
1198 }
1199
1200 return $preempt;
1201 }, \PHP_INT_MIN, 3);
1202 }, \PHP_INT_MAX);
1203 }
1204
1205 private function http_filter_bypass_url($url)
1206 {
1207 $hosts = [
1208 'wordpress.org',
1209 'docketcache.com',
1210 'paypal.com',
1211 'braintree-api.com',
1212 'stripe.com',
1213 'cloudflare.com',
1214 'woocommerce.com',
1215 ];
1216
1217 $hosts = apply_filters('docketcache/filter/cache_http_response_bypass_url', $hosts);
1218
1219 $site_host = wp_parse_url(site_url(), \PHP_URL_HOST);
1220 $url_host = wp_parse_url($url, \PHP_URL_HOST);
1221
1222 if ('127.0.0.1' === $url_host || 'localhost' === $url_host || $site_host === $url_host) {
1223 return true;
1224 }
1225
1226 foreach ($hosts as $host) {
1227 if ($host === $url_host || '.'.$host === substr($url_host, -\strlen('.'.$host))) {
1228 return true;
1229 }
1230 }
1231
1232 return false;
1233 }
1234 }
1235