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 / src / Tweaks.php

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

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