get_all_settings(); if ( empty( $s['dns_prefetch'] ) && empty( $s['dns_prefetch_auto'] ) && empty( $s['modulepreload_enabled'] ) ) { return; } add_action( 'wp_head', array( $this, 'emit' ), 1 ); } public function emit() { // The queried post is unavailable during plugins_loaded. if ( ! \QWSpeedCache\Plugin::should_optimize() ) { return; } $s = \QWSpeedCache\Plugin::instance()->get_all_settings(); $seen = array(); // Manual lines: "https://cdn.example.com" or "preconnect https://..." $manual = isset( $s['dns_prefetch'] ) ? (string) $s['dns_prefetch'] : ''; foreach ( preg_split( '/\r\n|\r|\n/', $manual ) as $line ) { $line = trim( $line ); if ( '' === $line || 0 === strpos( $line, '#' ) ) { continue; } $preconnect = false; if ( 0 === stripos( $line, 'preconnect ' ) ) { $preconnect = true; $line = trim( substr( $line, 11 ) ); } $host = self::origin_from( $line ); if ( ! $host || isset( $seen[ $host ] ) ) { continue; } $seen[ $host ] = true; if ( $preconnect || ! empty( $s['dns_preconnect'] ) ) { echo '' . "\n"; } else { echo '' . "\n"; } } if ( ! empty( $s['dns_prefetch_auto'] ) ) { $limit = isset( $s['dns_prefetch_auto_limit'] ) ? max( 1, min( 20, (int) $s['dns_prefetch_auto_limit'] ) ) : 8; foreach ( self::auto_origins( $limit ) as $origin ) { if ( isset( $seen[ $origin ] ) ) { continue; } $seen[ $origin ] = true; if ( ! empty( $s['dns_preconnect'] ) ) { echo '' . "\n"; } else { echo '' . "\n"; } } } if ( ! empty( $s['modulepreload_enabled'] ) ) { foreach ( self::modulepreload_urls( 5 ) as $url ) { echo '' . "\n"; } } } /** * @param string $url URL or host. * @return string Origin https://host or empty. */ public static function origin_from( $url ) { $url = trim( (string) $url ); if ( '' === $url ) { return ''; } if ( 0 === strpos( $url, '//' ) ) { $url = 'https:' . $url; } if ( ! preg_match( '#^https?://#i', $url ) ) { $url = 'https://' . ltrim( $url, '/' ); } $url = esc_url_raw( $url, array( 'http', 'https' ) ); $parts = wp_parse_url( $url ); if ( ! is_array( $parts ) || empty( $parts['host'] ) || ! is_string( $parts['host'] ) ) { return ''; } // Do not emit preconnect origins containing credentials or malformed hosts. if ( isset( $parts['user'] ) || isset( $parts['pass'] ) || ! preg_match( '/^[a-z0-9.-]+$/i', $parts['host'] ) ) { return ''; } $scheme = isset( $parts['scheme'] ) ? $parts['scheme'] : 'https'; if ( ! in_array( $scheme, array( 'http', 'https' ), true ) ) { $scheme = 'https'; } return $scheme . '://' . strtolower( $parts['host'] ); } /** * Third-party origins from enqueued assets. * * @param int $limit Max origins. * @return string[] */ public static function auto_origins( $limit = 8 ) { $home = function_exists( 'home_url' ) ? wp_parse_url( home_url(), PHP_URL_HOST ) : ''; $home = $home ? strtolower( (string) $home ) : ''; $out = array(); global $wp_scripts, $wp_styles; foreach ( array( $wp_scripts, $wp_styles ) as $reg ) { if ( ! is_object( $reg ) || empty( $reg->queue ) || empty( $reg->registered ) ) { continue; } foreach ( (array) $reg->queue as $handle ) { if ( empty( $reg->registered[ $handle ]->src ) ) { continue; } $src = (string) $reg->registered[ $handle ]->src; $origin = self::origin_from( $src ); if ( ! $origin ) { continue; } $host = wp_parse_url( $origin, PHP_URL_HOST ); if ( $home && strtolower( (string) $host ) === $home ) { continue; } $out[ $origin ] = true; if ( count( $out ) >= $limit ) { return array_keys( $out ); } } } return array_keys( $out ); } /** * First N type=module script srcs. * * @param int $limit Max. * @return string[] */ public static function modulepreload_urls( $limit = 5 ) { $out = array(); global $wp_scripts; if ( ! is_object( $wp_scripts ) || empty( $wp_scripts->queue ) ) { return $out; } foreach ( (array) $wp_scripts->queue as $handle ) { if ( empty( $wp_scripts->registered[ $handle ] ) ) { continue; } $obj = $wp_scripts->registered[ $handle ]; $src = isset( $obj->src ) ? (string) $obj->src : ''; if ( ! $src ) { continue; } // Heuristic: handle or extra data marks module. $extra = isset( $obj->extra['strategy'] ) ? $obj->extra['strategy'] : ''; $type = isset( $obj->extra['type'] ) ? $obj->extra['type'] : ''; if ( 'module' !== $type && 'module' !== $extra && false === strpos( $handle, 'module' ) ) { continue; } if ( 0 === strpos( $src, '/' ) && function_exists( 'home_url' ) ) { $src = home_url( $src ); } $out[] = $src; if ( count( $out ) >= $limit ) { break; } } return $out; } }