settings = \QWSpeedCache\Plugin::instance()->get_all_settings(); // Head cleanup (emoji + junk) always gated on should_optimize for front, // but admin emoji removal is intentional when toggle is on. $this->maybe_remove_emoji(); $this->maybe_remove_head_junk(); if ( ! empty( $this->settings['disable_xmlrpc'] ) ) { $this->disable_xmlrpc(); } if ( ! empty( $this->settings['disable_feeds'] ) ) { $this->disable_feeds(); } if ( ! empty( $this->settings['disable_rest_nonauth'] ) ) { add_filter( 'rest_authentication_errors', array( $this, 'rest_nonauth' ), 20 ); } if ( ! empty( $this->settings['remove_query_strings'] ) ) { add_filter( 'script_loader_src', array( $this, 'strip_ver' ), 15, 1 ); add_filter( 'style_loader_src', array( $this, 'strip_ver' ), 15, 1 ); } if ( ! empty( $this->settings['disable_dashicons_front'] ) && ! is_admin() ) { add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_dashicons' ), 100 ); } if ( isset( $this->settings['limit_revisions'] ) && (int) $this->settings['limit_revisions'] >= 0 ) { add_filter( 'wp_revisions_to_keep', array( $this, 'revisions_to_keep' ), 10, 2 ); } if ( ! empty( $this->settings['disable_self_pingbacks'] ) ) { add_action( 'pre_ping', array( $this, 'no_self_ping' ) ); } if ( ! empty( $this->settings['disable_comments'] ) ) { $this->disable_comments(); } if ( ! empty( $this->settings['disable_block_directory'] ) ) { add_action( 'admin_init', static function () { remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' ); } ); add_filter( 'block_editor_settings_all', static function ( $settings ) { if ( is_array( $settings ) ) { $settings['enableBlockDirectory'] = false; } return $settings; } ); } if ( ! empty( $this->settings['nofollow_external'] ) ) { add_filter( 'the_content', array( $this, 'nofollow_external_links' ), 20 ); } if ( ! empty( $this->settings['local_avatars'] ) ) { add_filter( 'pre_get_avatar_data', array( $this, 'local_avatar_data' ), 10, 2 ); } if ( ! empty( $this->settings['disable_gravatar'] ) ) { add_filter( 'get_avatar', array( $this, 'blank_avatar' ), 10, 5 ); add_filter( 'get_avatar_url', array( $this, 'blank_avatar_url' ), 10, 2 ); } } private function maybe_remove_emoji() { if ( empty( $this->settings['remove_emoji'] ) ) { return; } remove_action( 'wp_head', 'print_emoji_detection_script', 7 ); remove_action( 'wp_print_styles', 'print_emoji_styles' ); remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); remove_action( 'admin_print_styles', 'print_emoji_styles' ); add_filter( 'emoji_svg_url', '__return_false' ); remove_filter( 'the_content_feed', 'wp_staticize_emoji' ); remove_filter( 'comment_text_rss', 'wp_staticize_emoji' ); remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' ); } private function maybe_remove_head_junk() { if ( empty( $this->settings['remove_head_junk'] ) ) { return; } if ( ! \QWSpeedCache\Plugin::should_optimize() && ! is_admin() ) { // Still allow on front when optimize is on; if should_optimize false, skip front junk. } remove_action( 'wp_head', 'rsd_link' ); remove_action( 'wp_head', 'wlwmanifest_link' ); remove_action( 'wp_head', 'wp_shortlink_wp_head' ); remove_action( 'wp_head', 'wp_generator' ); remove_action( 'wp_head', 'rest_output_link_wp_head', 10 ); remove_action( 'wp_head', 'wp_oembed_add_discovery_links' ); remove_action( 'template_redirect', 'rest_output_link_header', 11 ); remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 ); } private function disable_xmlrpc() { add_filter( 'xmlrpc_enabled', '__return_false' ); add_filter( 'xmlrpc_methods', '__return_empty_array' ); add_filter( 'wp_headers', static function ( $headers ) { unset( $headers['X-Pingback'] ); return $headers; } ); add_action( 'init', static function () { if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { status_header( 403 ); exit; } }, 1 ); } private function disable_feeds() { $kill = static function () { wp_die( esc_html__( 'Feeds are disabled.', 'qw-optimize' ), esc_html__( 'Feeds disabled', 'qw-optimize' ), array( 'response' => 403 ) ); }; add_action( 'do_feed', $kill, 1 ); add_action( 'do_feed_rdf', $kill, 1 ); add_action( 'do_feed_rss', $kill, 1 ); add_action( 'do_feed_rss2', $kill, 1 ); add_action( 'do_feed_atom', $kill, 1 ); add_action( 'do_feed_rss2_comments', $kill, 1 ); add_action( 'do_feed_atom_comments', $kill, 1 ); remove_action( 'wp_head', 'feed_links', 2 ); remove_action( 'wp_head', 'feed_links_extra', 3 ); } /** * Block unauthenticated REST API access. Logged-in users and requests * that already authenticated remain allowed. * * @param mixed $result Prior auth result. * @return mixed */ public function rest_nonauth( $result ) { if ( true === $result || is_wp_error( $result ) ) { return $result; } if ( is_user_logged_in() ) { return $result; } return new \WP_Error( 'qwsc_rest_disabled', __( 'REST API is restricted to authenticated users.', 'qw-optimize' ), array( 'status' => 401 ) ); } /** * Strip ?ver= query args from script/style URLs (static cache friendliness). * * @param string $src URL. * @return string */ public function strip_ver( $src ) { if ( ! is_string( $src ) || $src === '' ) { return $src; } if ( strpos( $src, 'ver=' ) === false ) { return $src; } return remove_query_arg( 'ver', $src ); } public function dequeue_dashicons() { if ( is_user_logged_in() ) { return; } wp_dequeue_style( 'dashicons' ); wp_deregister_style( 'dashicons' ); } /** * @param int $num Default number. * @param \WP_Post $post Post. * @return int */ public function revisions_to_keep( $num, $post ) { $limit = (int) ( $this->settings['limit_revisions'] ?? -1 ); if ( $limit < 0 ) { return $num; } return $limit; } /** * @param string[] $links URLs about to be pinged. */ public function no_self_ping( &$links ) { $home = home_url(); foreach ( $links as $i => $link ) { if ( 0 === strpos( $link, $home ) ) { unset( $links[ $i ] ); } } } private function disable_comments() { add_filter( 'comments_open', '__return_false', 20, 2 ); add_filter( 'pings_open', '__return_false', 20, 2 ); add_filter( 'comments_array', '__return_empty_array', 10, 2 ); add_action( 'admin_init', static function () { if ( is_admin_bar_showing() ) { remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 ); } } ); add_action( 'wp_before_admin_bar_render', static function () { global $wp_admin_bar; if ( is_object( $wp_admin_bar ) ) { $wp_admin_bar->remove_menu( 'comments' ); } } ); add_filter( 'widget_types_to_hide_from_legacy_widget_block', static function ( $types ) { $types[] = 'recent-comments'; return $types; } ); add_action( 'admin_menu', static function () { remove_menu_page( 'edit-comments.php' ); }, 999 ); add_action( 'admin_init', static function () { foreach ( get_post_types() as $type ) { if ( post_type_supports( $type, 'comments' ) ) { remove_post_type_support( $type, 'comments' ); remove_post_type_support( $type, 'trackbacks' ); } } } ); add_filter( 'dashboard_glance_items', static function ( $items ) { return is_array( $items ) ? array_filter( $items, static function ( $i ) { return false === strpos( (string) $i, 'comment' ); } ) : $items; } ); } /** * @param string $avatar HTML. * @return string */ public function blank_avatar( $avatar, $id_or_email = null, $size = 96, $default = '', $alt = '' ) { $size = (int) $size; if ( $size <= 0 ) { $size = 96; } $alt = $alt ? esc_attr( $alt ) : ''; return '' . $alt . ''; } /** * @param string $url URL. * @return string */ public function blank_avatar_url( $url, $id_or_email = null ) { return 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; } /** * @param string $content Content. * @return string */ public function nofollow_external_links( $content ) { if ( ! is_string( $content ) || false === stripos( $content, ']*href=["\'](https?:\/\/[^"\']+)["\'][^>]*>/i', static function ( $m ) use ( $host ) { $tag = $m[0]; $href = $m[1]; $h = wp_parse_url( $href, PHP_URL_HOST ); if ( ! $h || 0 === strcasecmp( (string) $h, (string) $host ) ) { return $tag; } if ( false !== stripos( $tag, 'rel=' ) ) { if ( false === stripos( $tag, 'nofollow' ) ) { $tag = preg_replace( '/rel=(["\'])([^"\']*)\1/i', 'rel=$1$2 nofollow noopener$1', $tag, 1 ); } } else { $tag = rtrim( substr( $tag, 0, -1 ) ) . ' rel="nofollow noopener">'; } return $tag; }, $content ); } /** * Prefer attached local avatar when available (user meta qwsc_local_avatar). * * @param array $args Args. * @param mixed $id_or_email ID. * @return array */ public function local_avatar_data( $args, $id_or_email ) { $user_id = 0; if ( is_numeric( $id_or_email ) ) { $user_id = (int) $id_or_email; } elseif ( is_object( $id_or_email ) && isset( $id_or_email->user_id ) ) { $user_id = (int) $id_or_email->user_id; } elseif ( is_string( $id_or_email ) && is_email( $id_or_email ) ) { $u = get_user_by( 'email', $id_or_email ); $user_id = $u ? (int) $u->ID : 0; } if ( $user_id ) { $url = get_user_meta( $user_id, 'qwsc_local_avatar', true ); if ( is_string( $url ) && $url ) { $args['url'] = esc_url_raw( $url ); $args['found_avatar'] = true; } } return $args; } }