From a415242136ac72f11ecac7241b57be4236b70ac8 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 29 Jan 2025 14:57:37 +0200 Subject: [PATCH 01/30] WIP --- inc/Engine/Common/Head/ServiceProvider.php | 39 +++++++++++ inc/Engine/Common/Head/Subscriber.php | 67 +++++++++++++++++++ .../Optimization/Buffer/Optimization.php | 7 ++ 3 files changed, 113 insertions(+) create mode 100644 inc/Engine/Common/Head/ServiceProvider.php create mode 100644 inc/Engine/Common/Head/Subscriber.php diff --git a/inc/Engine/Common/Head/ServiceProvider.php b/inc/Engine/Common/Head/ServiceProvider.php new file mode 100644 index 0000000000..885943fe7f --- /dev/null +++ b/inc/Engine/Common/Head/ServiceProvider.php @@ -0,0 +1,39 @@ +provides, true ); + } + + /** + * Registers items with the container + * + * @return void + */ + public function register(): void { + $this->getContainer()->addShared( 'common_head_subscriber', Subscriber::class ); + } +} diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php new file mode 100644 index 0000000000..aa69fa7d8b --- /dev/null +++ b/inc/Engine/Common/Head/Subscriber.php @@ -0,0 +1,67 @@ + 'method_name') + * * array('hook_name' => array('method_name', $priority)) + * * array('hook_name' => array('method_name', $priority, $accepted_args)) + * * array('hook_name' => array(array('method_name_1', $priority_1, $accepted_args_1)), array('method_name_2', $priority_2, $accepted_args_2))) + * + * @return array + */ + public static function get_subscribed_events() { + return [ + 'rocket_head' => 'print_head_elements', + 'rocket_head_items' => [ + [ 'preload_resources', 10 ], + [ 'resource_hints', 11 ], + ], + ]; + } + + public function print_head_elements( $content ) { + $items = wpm_apply_filters_typed( 'array','rocket_head_items', [] ); + if ( empty( $items ) ) { + return $content; + } + + // Combine elements. + $elements = ''; + foreach ( $items as $item ) { + // Make sure that we don't have duplication based on `href` inside each `rel`. + foreach ( $item as $key => $value ) { + if ( in_array( $key, [ 'open_tag', 'close_tag', 'inner_content' ], true ) ) { + $elements .= $value; + continue; + } + $elements .= '"' . $key . '"="' . esc_attr( $value ) . '" '; + } + + $elements .= "\n"; + } + + return $content . $elements; + } + + public function preload_resources( $items ) { + return $items; + } + + public function resource_hints( $items ) { + return $items; + } +} diff --git a/inc/Engine/Optimization/Buffer/Optimization.php b/inc/Engine/Optimization/Buffer/Optimization.php index 356de45529..7f242c06e6 100755 --- a/inc/Engine/Optimization/Buffer/Optimization.php +++ b/inc/Engine/Optimization/Buffer/Optimization.php @@ -105,6 +105,13 @@ public function maybe_process_buffer( $buffer ) { return $buffer; } + $filtered_buffer = preg_replace( + '##iU', + '' . wpm_apply_filters_typed( 'string', 'rocket_head', '' ), + $filtered_buffer, + 1 + ); + $this->log( 'Page optimized.', [], 'info' ); /** From 7ea59ac9a93c07d3a27f5c2a1249c598cba79869 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 29 Jan 2025 17:25:53 +0200 Subject: [PATCH 02/30] make it works --- inc/Engine/Common/Head/Subscriber.php | 34 ++++++++++++++++++--------- inc/Plugin.php | 3 +++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index aa69fa7d8b..8a70a4cc48 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -5,6 +5,8 @@ class Subscriber implements Subscriber_Interface { + private $head_items = []; + /** * Returns an array of events that this subscriber wants to listen to. * @@ -26,15 +28,12 @@ class Subscriber implements Subscriber_Interface { public static function get_subscribed_events() { return [ 'rocket_head' => 'print_head_elements', - 'rocket_head_items' => [ - [ 'preload_resources', 10 ], - [ 'resource_hints', 11 ], - ], ]; } public function print_head_elements( $content ) { $items = wpm_apply_filters_typed( 'array','rocket_head_items', [] ); + error_log( print_r( $items, true ) ); if ( empty( $items ) ) { return $content; } @@ -43,12 +42,16 @@ public function print_head_elements( $content ) { $elements = ''; foreach ( $items as $item ) { // Make sure that we don't have duplication based on `href` inside each `rel`. + if ( $this->is_duplicate( $item ) ) { + continue; + } + foreach ( $item as $key => $value ) { if ( in_array( $key, [ 'open_tag', 'close_tag', 'inner_content' ], true ) ) { - $elements .= $value; + $elements .= $value . ' '; continue; } - $elements .= '"' . $key . '"="' . esc_attr( $value ) . '" '; + $elements .= $key . '="' . esc_attr( $value ) . '" '; } $elements .= "\n"; @@ -57,11 +60,20 @@ public function print_head_elements( $content ) { return $content . $elements; } - public function preload_resources( $items ) { - return $items; - } + private function is_duplicate( $item ) { + if ( empty( $item['rel'] ) || empty( $item['href'] ) ) { + return false; + } + + if ( ! isset( $this->head_items[ $item['rel'] ] ) ) { + $this->head_items[ $item['rel'] ] = []; + } + + if ( ! isset( $this->head_items[ $item['rel'] ][ $item['href'] ] ) ) { + $this->head_items[ $item['rel'] ][ $item['href'] ] = true; + return false; + } - public function resource_hints( $items ) { - return $items; + return true; } } diff --git a/inc/Plugin.php b/inc/Plugin.php index 1300cbc134..84768715fc 100644 --- a/inc/Plugin.php +++ b/inc/Plugin.php @@ -7,6 +7,7 @@ use WP_Rocket\Admin\Options; use WP_Rocket\Engine\Admin\API\ServiceProvider as APIServiceProvider; use WP_Rocket\Engine\Common\ExtractCSS\ServiceProvider as CommonExtractCSSServiceProvider; +use WP_Rocket\Engine\Common\Head\ServiceProvider as CommonHeadServiceProvider; use WP_Rocket\Engine\Common\JobManager\ServiceProvider as JobManagerServiceProvider; use WP_Rocket\Engine\Media\Lazyload\CSS\ServiceProvider as LazyloadCSSServiceProvider; use WP_Rocket\Engine\Media\Lazyload\CSS\Admin\ServiceProvider as AdminLazyloadCSSServiceProvider; @@ -303,6 +304,7 @@ private function init_common_subscribers() { $this->container->addServiceProvider( new ThemesServiceProvider() ); $this->container->addServiceProvider( new APIServiceProvider() ); $this->container->addServiceProvider( new CommonExtractCSSServiceProvider() ); + $this->container->addServiceProvider( new CommonHeadServiceProvider() ); $this->container->addServiceProvider( new LazyloadCSSServiceProvider() ); $this->container->addServiceProvider( new DebugServiceProvider() ); $this->container->addServiceProvider( new ATFServiceProvider() ); @@ -319,6 +321,7 @@ private function init_common_subscribers() { 'critical_css_subscriber', 'sucuri_subscriber', 'common_extractcss_subscriber', + 'common_head_subscriber', 'expired_cache_purge_subscriber', 'fonts_preload_subscriber', 'heartbeat_subscriber', From 2cd14122d36aec0deb5cd48db52cb0cc3d2c1bb0 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Mon, 3 Feb 2025 15:14:03 +0200 Subject: [PATCH 03/30] add ElementTrait to make it easier to add elements into head --- inc/Engine/Common/Head/ElementTrait.php | 54 +++++++++++++++++++++++++ inc/Engine/Common/Head/Subscriber.php | 1 - 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 inc/Engine/Common/Head/ElementTrait.php diff --git a/inc/Engine/Common/Head/ElementTrait.php b/inc/Engine/Common/Head/ElementTrait.php new file mode 100644 index 0000000000..07906184cd --- /dev/null +++ b/inc/Engine/Common/Head/ElementTrait.php @@ -0,0 +1,54 @@ +link( $args ); + } + + protected function preconnect_link( array $args = [] ) { + $args['rel'] = 'preconnect'; + return $this->link( $args ); + } + + protected function dns_prefetch_link( array $args = [] ) { + $args['rel'] = 'dns-prefetch'; + return $this->link( $args ); + } + + protected function prefetch_link( array $args = [] ) { + $args['rel'] = 'prefetch'; + return $this->link( $args ); + } + + protected function prerender_link( array $args = [] ) { + $args['rel'] = 'prerender'; + return $this->link( $args ); + } + + protected function style_tag( string $css = '', array $args = [] ) { + $element = [ + 'open_tag' => ' $css, + ] ); + $element[ 'close_tag' ] = ''; + + return $element; + } + + private function link( array $args = [] ) { + $element = [ + 'open_tag' => ' '', + ] ); + $element[ 'close_tag' ] = '/>'; + + return $element; + } +} diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index 8a70a4cc48..17a0245f35 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -33,7 +33,6 @@ public static function get_subscribed_events() { public function print_head_elements( $content ) { $items = wpm_apply_filters_typed( 'array','rocket_head_items', [] ); - error_log( print_r( $items, true ) ); if ( empty( $items ) ) { return $content; } From 740b8e47ed8b3e7f9608fe1697095db714a96035 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Tue, 4 Feb 2025 08:37:13 +0200 Subject: [PATCH 04/30] add docs for priorities and start refactoring --- inc/Engine/Common/Head/Subscriber.php | 10 +++++++ .../CriticalPath/CriticalCSSSubscriber.php | 26 +++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index 17a0245f35..df4d2b6866 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -32,6 +32,16 @@ public static function get_subscribed_events() { } public function print_head_elements( $content ) { + /** + * Filter Head elements array. + * + * @param array $head_items Elements to be added to head after closing of title tag. + * + * Priority 10: preconnect + * Priority 30: preload + * Priority 50: styles + * @returns array + */ $items = wpm_apply_filters_typed( 'array','rocket_head_items', [] ); if ( empty( $items ) ) { return $content; diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index 8d663f8e99..db8bd024c4 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -4,6 +4,7 @@ use WP_Rocket\Admin\Options; use WP_Rocket\Admin\Options_Data; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\License\API\User; use WP_Rocket\Engine\Optimization\RegexTrait; use WP_Rocket\Event_Management\Subscriber_Interface; @@ -18,6 +19,7 @@ class CriticalCSSSubscriber implements Subscriber_Interface { use RegexTrait; use CommentTrait; + use ElementTrait; /** * Instance of Critical CSS. @@ -61,6 +63,8 @@ class CriticalCSSSubscriber implements Subscriber_Interface { */ protected $user; + private $critical_css_content = ''; + /** * Creates an instance of the Critical CSS Subscriber. * @@ -113,6 +117,8 @@ public static function get_subscribed_events() { [ 'async_css', 32 ], ], + 'rocket_head_items' => [ 'insert_css_in_head', 50 ], + 'switch_theme' => 'maybe_regenerate_cpcss', 'rocket_excluded_inline_js_content' => 'exclude_inline_js', 'before_delete_post' => 'delete_cpcss', @@ -595,20 +601,24 @@ public function insert_critical_css_buffer( $buffer ) { return $buffer; } - $critical_css_content = str_replace( '\\', '\\\\', $critical_css_content ); - - $buffer = preg_replace( - '##iU', - '', - $buffer, - 1 - ); + $this->critical_css_content = str_replace( '\\', '\\\\', $critical_css_content ); $buffer = preg_replace( '##iU', $this->return_remove_cpcss_script() . '', $buffer, 1 ); return $this->add_meta_comment( 'async_css', $buffer ); } + public function insert_css_in_head( $items ) { + if ( empty( $this->critical_css_content ) ) { + return $items; + } + + $items += $this->style_tag( $this->critical_css_content, [ + 'id' => 'rocket-critical-css', + ] ); + return $items; + } + /** * Returns JS script to remove the critical css style from frontend. * From b71d24eb1e6d7ce3c636dc6e2f3fcf14ba7d9250 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Tue, 4 Feb 2025 08:49:17 +0200 Subject: [PATCH 05/30] refactor RUCSS --- .../CriticalPath/CriticalCSSSubscriber.php | 9 ++--- .../Optimization/RUCSS/Controller/UsedCSS.php | 39 ++++++++----------- .../RUCSS/Frontend/Subscriber.php | 5 +++ 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index db8bd024c4..a09ccf4d65 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -117,14 +117,13 @@ public static function get_subscribed_events() { [ 'async_css', 32 ], ], - 'rocket_head_items' => [ 'insert_css_in_head', 50 ], - + 'rocket_head_items' => [ 'insert_css_in_head', 50 ], 'switch_theme' => 'maybe_regenerate_cpcss', 'rocket_excluded_inline_js_content' => 'exclude_inline_js', 'before_delete_post' => 'delete_cpcss', - 'rocket_before_rollback' => [ 'stop_critical_css_generation', 9 ], - 'wp_rocket_upgrade' => [ 'stop_critical_css_generation', 9 ], - 'admin_post_switch_to_rucss' => 'switch_to_rucss', + 'rocket_before_rollback' => [ 'stop_critical_css_generation', 9 ], + 'wp_rocket_upgrade' => [ 'stop_critical_css_generation', 9 ], + 'admin_post_switch_to_rucss' => 'switch_to_rucss', ]; // phpcs:enable WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned } diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index 6c19692474..b1f94b9204 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -5,6 +5,7 @@ use WP_Rocket\Admin\Options_Data; use WP_Rocket\Engine\Common\Context\ContextInterface; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\Optimization\CSSTrait; use WP_Rocket\Engine\Optimization\DynamicLists\DefaultLists\DataManager; use WP_Rocket\Engine\Optimization\RegexTrait; @@ -16,6 +17,7 @@ class UsedCSS { use RegexTrait; use CSSTrait; use CommentTrait; + use ElementTrait; /** * UsedCss Query instance. @@ -80,6 +82,8 @@ class UsedCSS { */ private $manager; + private $used_css_content = ''; + /** * Instantiate the class. * @@ -158,8 +162,9 @@ public function treeshake( string $html ): string { return $html; } + $this->used_css_content = $used_css_content; + $html = $this->remove_used_css_from_html( $clean_html, $html ); - $html = $this->add_used_css_to_html( $html, $used_css_content ); $html = $this->add_used_fonts_preload( $html, $used_css_content ); $html = $this->remove_google_font_preconnect( $html ); @@ -354,26 +359,21 @@ private function remove_internal_styles_from_html( string $clean_html, string $h } /** - * Alter HTML string and add the used CSS style in tag, + * Add the used CSS style in tag, * - * @param string $html HTML content. - * @param string $used_css Used CSS content. + * @param array $items Head items. * - * @return string HTML content. + * @return array Filtered head items. */ - private function add_used_css_to_html( string $html, string $used_css ): string { - $replace = preg_replace( - '##iU', - '' . $this->get_used_css_markup( $used_css ), - $html, - 1 - ); - - if ( null === $replace ) { - return $html; + private function add_used_css_to_html( array $items ): array { + if ( empty( $this->used_css_content ) ) { + return $items; } - return $replace; + $items += $this->style_tag( $this->get_used_css_markup( $this->used_css_content ), [ + 'id' => 'wpr-usedcss', + ] ); + return $items; } /** @@ -394,12 +394,7 @@ private function get_used_css_markup( string $used_css ): string { $used_css = apply_filters( 'rocket_usedcss_content', $used_css ); $used_css = str_replace( '\\', '\\\\', $used_css );// Guard the backslashes before passing the content to preg_replace. - $used_css = $this->handle_charsets( $used_css, false ); - - return sprintf( - '', - $used_css - ); + return $this->handle_charsets( $used_css, false ); } /** diff --git a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php index 751b2f153b..0a90a97d5b 100644 --- a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php +++ b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php @@ -46,6 +46,7 @@ public static function get_subscribed_events(): array { 'rocket_disable_preload_fonts' => 'maybe_disable_preload_fonts', 'rocket_first_install_options' => 'on_install', 'wp_rocket_upgrade' => [ 'on_update', 10, 2 ], + 'rocket_head_items' => [ 'insert_css_in_head', 50 ], ]; } @@ -113,4 +114,8 @@ public function on_install( $options ) { return $options; } + + public function insert_css_in_head( $items ) { + $this->used_css->add_used_css_to_html( $items ); + } } From 838dafa00b0dc9c94a2c25c79dd297cf7a267fea Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 5 Feb 2025 11:35:28 +0200 Subject: [PATCH 06/30] refactor google fonts --- inc/Engine/Common/Head/ElementTrait.php | 18 ++++++ inc/Engine/Common/Head/Subscriber.php | 45 +++++++++++---- .../CriticalPath/CriticalCSSSubscriber.php | 2 +- .../GoogleFonts/AbstractGFOptimization.php | 56 +++++++++++++++++++ .../Optimization/GoogleFonts/Combine.php | 2 +- .../Optimization/GoogleFonts/CombineV2.php | 6 +- .../Optimization/GoogleFonts/Subscriber.php | 14 +++++ .../Optimization/RUCSS/Controller/UsedCSS.php | 4 +- 8 files changed, 130 insertions(+), 17 deletions(-) diff --git a/inc/Engine/Common/Head/ElementTrait.php b/inc/Engine/Common/Head/ElementTrait.php index 07906184cd..86901718b7 100644 --- a/inc/Engine/Common/Head/ElementTrait.php +++ b/inc/Engine/Common/Head/ElementTrait.php @@ -5,6 +5,7 @@ trait ElementTrait { protected function preload_link( array $args = [] ) { $args['rel'] = 'preload'; + $args[ 1 ] = 'data-rocket-preload'; return $this->link( $args ); } @@ -28,6 +29,11 @@ protected function prerender_link( array $args = [] ) { return $this->link( $args ); } + protected function stylesheet_link( array $args = [] ) { + $args['rel'] = 'stylesheet'; + return $this->link( $args ); + } + protected function style_tag( string $css = '', array $args = [] ) { $element = [ 'open_tag' => ' ' $content, + ] ); + $element[ 'close_tag' ] = ''; + + return $element; + } + private function link( array $args = [] ) { $element = [ 'open_tag' => 'is_duplicate( $item ) ) { continue; } - - foreach ( $item as $key => $value ) { - if ( in_array( $key, [ 'open_tag', 'close_tag', 'inner_content' ], true ) ) { - $elements .= $value . ' '; - continue; - } - $elements .= $key . '="' . esc_attr( $value ) . '" '; - } - - $elements .= "\n"; + $elements .= $this->prepare_element( $item ) . "\n"; } return $content . $elements; @@ -85,4 +76,38 @@ private function is_duplicate( $item ) { return true; } + + private function prepare_element( $element ) { + $open_tag = ''; + if ( ! empty( $element['open_tag'] ) ) { + $open_tag = $element['open_tag']; + unset( $element['open_tag'] ); + } + + $close_tag = ''; + if ( ! empty( $element['close_tag'] ) ) { + $close_tag = $element['close_tag']; + unset( $element['close_tag'] ); + } + + $inner_content = ''; + if ( ! empty( $element['inner_content'] ) ) { + $inner_content = $element['inner_content']; + unset( $element['inner_content'] ); + } + + $attributes = []; + + foreach ( $element as $key => $value ) { + if (is_int( $key ) ) { + $attributes[] = $value; + continue; + } + $attributes[] = $key . '="' . esc_attr( $value ) . '"'; + } + + $attributes_html = ! empty( $attributes ) ? implode( ' ', $attributes ) : ''; + + return $open_tag . ' ' . $attributes_html . '>' . $inner_content . $close_tag; + } } diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index a09ccf4d65..7c1f3bcb2c 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -612,7 +612,7 @@ public function insert_css_in_head( $items ) { return $items; } - $items += $this->style_tag( $this->critical_css_content, [ + $items[] = $this->style_tag( $this->critical_css_content, [ 'id' => 'rocket-critical-css', ] ); return $items; diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index 271f94e6f7..99db995206 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -3,6 +3,7 @@ namespace WP_Rocket\Engine\Optimization\GoogleFonts; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\Media\Fonts\FontsTrait; /** @@ -12,6 +13,7 @@ */ abstract class AbstractGFOptimization { use FontsTrait; + use ElementTrait; /** * Allowed display values. @@ -37,6 +39,8 @@ abstract class AbstractGFOptimization { */ protected $has_google_fonts = true; + public $font_urls = []; + /** * Optimize Google Fonts * @@ -134,4 +138,56 @@ protected function get_optimized_markup( string $url ): string { $url ); } + + private function is_preload_enabled() { + return ! wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ); + } + + public function insert_font_stylesheet_into_head( $items ) { + if ( empty( $this->font_urls ) ) { + return $items; + } + + $preload_enabled = $this->is_preload_enabled(); + + foreach ( $this->font_urls as $font_url ) { + $item = $this->stylesheet_link( [ + 'href' => $font_url, + ] ); + + if ( ! $preload_enabled ) { + $items[] = $item; + continue; + } + + $item['media'] = 'print'; + $item['onload'] = 'this.media=\'all\''; + $items[] = $item; + + $items[] = $this->noscript_tag( + sprintf( '', $font_url ) + ); + } + + return $items; + } + + public function insert_font_preload_into_head( $items ) { + if ( empty( $this->font_urls ) ) { + return $items; + } + + if ( ! $this->is_preload_enabled() ) { + return $items; + } + + foreach ( $this->font_urls as $font_url ) { + $items[] = $this->preload_link( [ + 'href' => $font_url, + 'as' => 'style', + ] ); + } + + return $items; + } } diff --git a/inc/Engine/Optimization/GoogleFonts/Combine.php b/inc/Engine/Optimization/GoogleFonts/Combine.php index 9308f811ef..0e9a39152c 100644 --- a/inc/Engine/Optimization/GoogleFonts/Combine.php +++ b/inc/Engine/Optimization/GoogleFonts/Combine.php @@ -84,7 +84,7 @@ function ( $font ) use ( $exclusions ) { return $html; } - $html = preg_replace( '@<\/title>@i', '$0' . $this->get_optimized_markup( $this->get_combined_url() ), $html, 1 ); + $this->font_urls[] = $this->get_combined_url(); foreach ( $filtered_fonts as $font ) { $html = str_replace( $font[0], '', $html ); diff --git a/inc/Engine/Optimization/GoogleFonts/CombineV2.php b/inc/Engine/Optimization/GoogleFonts/CombineV2.php index b3878f064a..10e4f15d68 100644 --- a/inc/Engine/Optimization/GoogleFonts/CombineV2.php +++ b/inc/Engine/Optimization/GoogleFonts/CombineV2.php @@ -74,8 +74,8 @@ function ( $tag ) use ( $exclusions ) { } $families = array_unique( $families ); - $combined_tag = $this->get_optimized_markup( $this->get_combined_url( $families ) ); - $html = preg_replace( '@<\/title>@i', '$0' . $combined_tag, $html, 1 ); + $combined_url = $this->get_combined_url( $families ); + $this->font_urls[] = $combined_url; foreach ( $processed_tags as $font ) { $html = str_replace( $font[0], '', $html ); @@ -85,7 +85,7 @@ function ( $tag ) use ( $exclusions ) { 'V2 Google Fonts successfully combined.', [ 'GF combine process', - 'url' => $combined_tag, + 'url' => $combined_url, ] ); diff --git a/inc/Engine/Optimization/GoogleFonts/Subscriber.php b/inc/Engine/Optimization/GoogleFonts/Subscriber.php index 19232d36e8..7c65982bbc 100644 --- a/inc/Engine/Optimization/GoogleFonts/Subscriber.php +++ b/inc/Engine/Optimization/GoogleFonts/Subscriber.php @@ -55,6 +55,10 @@ public static function get_subscribed_events() { return [ 'wp_resource_hints' => [ 'preconnect', 10, 2 ], 'rocket_buffer' => [ 'process', 17 ], + 'rocket_head_items' => [ + [ 'insert_fonts_preload', 30 ], + [ 'insert_fonts_stylesheets', 50 ], + ], ]; } @@ -126,4 +130,14 @@ protected function is_allowed() { return ! is_user_logged_in() || (bool) $this->options->get( 'cache_logged_user', 0 ); } + + public function insert_fonts_stylesheets( $items ) { + $items = $this->combine->insert_font_stylesheet_into_head( $items ); + return $this->combine_v2->insert_font_stylesheet_into_head( $items ); + } + + public function insert_fonts_preload( $items ) { + $items = $this->combine->insert_font_preload_into_head( $items ); + return $this->combine_v2->insert_font_preload_into_head( $items ); + } } diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index b1f94b9204..08c6b5f9bc 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -365,12 +365,12 @@ private function remove_internal_styles_from_html( string $clean_html, string $h * * @return array Filtered head items. */ - private function add_used_css_to_html( array $items ): array { + public function add_used_css_to_html( array $items ): array { if ( empty( $this->used_css_content ) ) { return $items; } - $items += $this->style_tag( $this->get_used_css_markup( $this->used_css_content ), [ + $items[] = $this->style_tag( $this->get_used_css_markup( $this->used_css_content ), [ 'id' => 'wpr-usedcss', ] ); return $items; From 27c7d74eadc4c6e9b73669bf1ddc90f938c0f087 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 12 Feb 2025 22:33:55 +0200 Subject: [PATCH 07/30] finish all instances, before testing --- .../Optimization/RUCSS/Controller/UsedCSS.php | 47 ++++++++++--------- .../RUCSS/Frontend/Subscriber.php | 11 ++++- inc/Engine/Preload/Fonts.php | 35 ++++++++------ 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index 08c6b5f9bc..e35f73ada4 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -84,6 +84,8 @@ class UsedCSS { private $used_css_content = ''; + private $preloaded_fonts = []; + /** * Instantiate the class. * @@ -165,7 +167,7 @@ public function treeshake( string $html ): string { $this->used_css_content = $used_css_content; $html = $this->remove_used_css_from_html( $clean_html, $html ); - $html = $this->add_used_fonts_preload( $html, $used_css_content ); + $this->add_used_fonts_preload( $used_css_content ); $html = $this->remove_google_font_preconnect( $html ); if ( ! empty( $used_css->id ) ) { @@ -376,6 +378,21 @@ public function add_used_css_to_html( array $items ): array { return $items; } + public function insert_preload_fonts( $items ) { + if ( empty( $this->preloaded_fonts ) ) { + return $items; + } + foreach ( $this->preloaded_fonts as $font ) { + $items[] = $this->preload_link( [ + 'href' => esc_url( $font ), + 'as' => 'font', + 1 => 'crossorigin', + ] ); + } + + return $items; + } + /** * Return Markup for used_css into the page. * @@ -440,12 +457,11 @@ public function get_not_completed_count() { /** * Add preload links for the fonts in the used CSS * - * @param string $html HTML content. * @param string $used_css Used CSS content. * - * @return string + * @return void */ - private function add_used_fonts_preload( string $html, string $used_css ): string { + private function add_used_fonts_preload( string $used_css ): void { /** * Filters the fonts preload from the used CSS * @@ -454,15 +470,15 @@ private function add_used_fonts_preload( string $html, string $used_css ): strin * @param bool $enable True to enable, false to disable. */ if ( ! apply_filters( 'rocket_enable_rucss_fonts_preload', true ) ) { - return $html; + return; } if ( ! preg_match_all( '/@font-face\s*{\s*(?[^}]+)}/is', $used_css, $font_faces, PREG_SET_ORDER ) ) { - return $html; + return; } if ( empty( $font_faces ) ) { - return $html; + return; } /** @@ -521,23 +537,10 @@ function ( $item ) { } if ( empty( $urls ) ) { - return $html; - } - - $urls = array_unique( $urls ); - - $replace = preg_replace( - '##iU', - '' . $this->preload_links( $urls ), - $html, - 1 - ); - - if ( null === $replace ) { - return $html; + return; } - return $replace; + $this->preloaded_fonts = array_unique( $urls ); } /** diff --git a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php index 0a90a97d5b..845e087b23 100644 --- a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php +++ b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php @@ -46,7 +46,10 @@ public static function get_subscribed_events(): array { 'rocket_disable_preload_fonts' => 'maybe_disable_preload_fonts', 'rocket_first_install_options' => 'on_install', 'wp_rocket_upgrade' => [ 'on_update', 10, 2 ], - 'rocket_head_items' => [ 'insert_css_in_head', 50 ], + 'rocket_head_items' => [ + [ 'insert_preload_fonts', 30 ], + [ 'insert_css_in_head', 50 ], + ], ]; } @@ -116,6 +119,10 @@ public function on_install( $options ) { } public function insert_css_in_head( $items ) { - $this->used_css->add_used_css_to_html( $items ); + return $this->used_css->add_used_css_to_html( $items ); + } + + public function insert_preload_fonts( $items ) { + return $this->used_css->insert_preload_fonts( $items ); } } diff --git a/inc/Engine/Preload/Fonts.php b/inc/Engine/Preload/Fonts.php index ae190ab932..b2aac8140d 100644 --- a/inc/Engine/Preload/Fonts.php +++ b/inc/Engine/Preload/Fonts.php @@ -4,6 +4,7 @@ use WP_Rocket\Admin\Options_Data; use WP_Rocket\Engine\CDN\CDN; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\Support\CommentTrait; use WP_Rocket\Event_Management\Subscriber_Interface; @@ -14,6 +15,7 @@ */ class Fonts implements Subscriber_Interface { use CommentTrait; + use ElementTrait; /** * WP Rocket Options instance. @@ -49,6 +51,8 @@ class Fonts implements Subscriber_Interface { 'woff2', ]; + private $fonts = []; + /** * Return an array of events that this subscriber wants to listen to. * @@ -71,7 +75,8 @@ public function __construct( Options_Data $options, CDN $cdn ) { */ public static function get_subscribed_events() { return [ - 'rocket_buffer' => [ 'preload_fonts', 20 ], + 'rocket_head_items' => [ 'preload_fonts', 30 ], + 'rocket_buffer' => [ 'insert_meta_comment', 20 ], ]; } @@ -83,7 +88,7 @@ public static function get_subscribed_events() { * * @since 3.6 */ - public function preload_fonts( $html ): string { + public function insert_meta_comment( $html ): string { if ( ! $this->is_allowed() ) { return $html; } @@ -107,24 +112,26 @@ public function preload_fonts( $html ): string { $base_url = get_rocket_parse_url( home_url() ); $base_url = "{$base_url['scheme']}://{$base_url['host']}"; - $preloads = ''; - foreach ( array_unique( $fonts ) as $font ) { - $preloads .= sprintf( - "\n", - esc_url( $this->cdn->rewrite_url( $base_url . $font ) ) - ); + $this->fonts[] = esc_url( $this->cdn->rewrite_url( $base_url . $font ) ); } - $result = preg_replace( '##', $preloads, $html, 1 ); + return $this->add_meta_comment( 'preload_fonts', $html ); + } - if ( null === $result ) { - return $html; + public function preload_fonts( $items ): array { + if ( empty( $this->fonts ) ) { + return $items; } - $result = $this->add_meta_comment( 'preload_fonts', $result ); - - return $result; + foreach ( $this->fonts as $font ) { + $items[] = $this->preload_link( [ + 'href' => $font, + 'as' => 'font', + 1 => 'crossorigin', + ] ); + } + return $items; } /** From 83e78ce5fcd50240dfb8fd325d05a6bd95a211c8 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 12 Feb 2025 22:42:02 +0200 Subject: [PATCH 08/30] remove not used method anymore --- .../Optimization/RUCSS/Controller/UsedCSS.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index e35f73ada4..8e4b62459e 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -608,23 +608,6 @@ private function extract_first_font( string $font_face ): string { return ''; } - /** - * Converts an array of URLs to preload link tags - * - * @param array $urls An array of URLs. - * - * @return string - */ - private function preload_links( array $urls ): string { - $links = ''; - - foreach ( $urls as $url ) { - $links .= ''; - } - - return $links; - } - /** * Set Rucss inline attr exclusions * From e3c99db6633b94fc879ef8f9dad590e2f5652f3d Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 12 Feb 2025 23:29:45 +0200 Subject: [PATCH 09/30] minor fixes with testing --- inc/Engine/Common/Head/ElementTrait.php | 3 +- .../GoogleFonts/AbstractGFOptimization.php | 30 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/inc/Engine/Common/Head/ElementTrait.php b/inc/Engine/Common/Head/ElementTrait.php index 86901718b7..4f9c16149f 100644 --- a/inc/Engine/Common/Head/ElementTrait.php +++ b/inc/Engine/Common/Head/ElementTrait.php @@ -5,7 +5,7 @@ trait ElementTrait { protected function preload_link( array $args = [] ) { $args['rel'] = 'preload'; - $args[ 1 ] = 'data-rocket-preload'; + $args[ 2 ] = 'data-rocket-preload'; return $this->link( $args ); } @@ -65,7 +65,6 @@ private function link( array $args = [] ) { $element += wp_parse_args( $args, [ 'href' => '', ] ); - $element[ 'close_tag' ] = '/>'; return $element; } diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index 99db995206..a9e190080d 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -109,36 +109,6 @@ protected function get_font_display_value(): string { return isset( $this->display_values[ $display ] ) ? $display : 'swap'; } - /** - * Returns the optimized markup for Google Fonts - * - * @since 3.9.1 - * - * @param string $url Google Fonts URL. - * - * @return string - */ - protected function get_optimized_markup( string $url ): string { - /** - * Filters whether to disable Google Fonts preloading. - * - * @since 3.18 - * - * @param bool $disable_google_fonts_preload Whether to disable Google Fonts preloading. Default false. - */ - if ( wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ) ) { - return sprintf( - '', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet - $url - ); - } - - return sprintf( - '', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet - $url - ); - } - private function is_preload_enabled() { return ! wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ); } From aedcec706adef40c2f453b204e79c362bb3251f5 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 12 Feb 2025 23:35:41 +0200 Subject: [PATCH 10/30] move the new line before element --- inc/Engine/Common/Head/Subscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index d3cd1061b4..0024db6e10 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -54,7 +54,7 @@ public function print_head_elements( $content ) { if ( $this->is_duplicate( $item ) ) { continue; } - $elements .= $this->prepare_element( $item ) . "\n"; + $elements .= "\n" . $this->prepare_element( $item ); } return $content . $elements; From 2cfd353a311e764d2be6448d6ec8b35c09b9a42a Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Thu, 13 Feb 2025 00:18:30 +0200 Subject: [PATCH 11/30] fix phpcs --- inc/Engine/Common/Head/ElementTrait.php | 100 +++++++++++++++--- inc/Engine/Common/Head/Subscriber.php | 50 ++++++--- .../CriticalPath/CriticalCSSSubscriber.php | 20 +++- .../GoogleFonts/AbstractGFOptimization.php | 46 ++++++-- .../Optimization/GoogleFonts/CombineV2.php | 4 +- .../Optimization/GoogleFonts/Subscriber.php | 14 ++- .../Optimization/RUCSS/Controller/UsedCSS.php | 37 +++++-- .../RUCSS/Frontend/Subscriber.php | 12 +++ inc/Engine/Preload/Fonts.php | 23 +++- 9 files changed, 249 insertions(+), 57 deletions(-) diff --git a/inc/Engine/Common/Head/ElementTrait.php b/inc/Engine/Common/Head/ElementTrait.php index 4f9c16149f..9511a1250c 100644 --- a/inc/Engine/Common/Head/ElementTrait.php +++ b/inc/Engine/Common/Head/ElementTrait.php @@ -1,70 +1,138 @@ link( $args ); } + /** + * Preconnect link. + * + * @param array $args Element args. + * @return array|string[] + */ protected function preconnect_link( array $args = [] ) { $args['rel'] = 'preconnect'; return $this->link( $args ); } + /** + * Dns_prefetch link. + * + * @param array $args Element args. + * @return array|string[] + */ protected function dns_prefetch_link( array $args = [] ) { $args['rel'] = 'dns-prefetch'; return $this->link( $args ); } + /** + * Prefetch link. + * + * @param array $args Element args. + * @return array|string[] + */ protected function prefetch_link( array $args = [] ) { $args['rel'] = 'prefetch'; return $this->link( $args ); } + /** + * Prerender link. + * + * @param array $args Element args. + * @return array|string[] + */ protected function prerender_link( array $args = [] ) { $args['rel'] = 'prerender'; return $this->link( $args ); } + /** + * Stylesheet link. + * + * @param array $args Element args. + * @return array|string[] + */ protected function stylesheet_link( array $args = [] ) { $args['rel'] = 'stylesheet'; return $this->link( $args ); } + /** + * Style tag. + * + * @param string $css CSS content. + * @param array $args Element args. + * @return array|string[] + */ protected function style_tag( string $css = '', array $args = [] ) { - $element = [ + $element = [ 'open_tag' => ' $css, - ] ); - $element[ 'close_tag' ] = ''; + $element += wp_parse_args( + $args, + [ + 'inner_content' => $css, + ] + ); + $element['close_tag'] = ''; return $element; } + /** + * Noscript tag. + * + * @param string $content Element contents. + * @param array $args Element args. + * @return array|string[] + */ protected function noscript_tag( string $content = '', array $args = [] ) { - $element = [ + $element = [ 'open_tag' => ' $content, - ] ); - $element[ 'close_tag' ] = ''; + $element += wp_parse_args( + $args, + [ + 'inner_content' => $content, + ] + ); + $element['close_tag'] = ''; return $element; } + /** + * Generic link tag. + * + * @param array $args Element args. + * @return array|string[] + */ private function link( array $args = [] ) { - $element = [ + $element = [ 'open_tag' => ' '', - ] ); + $element += wp_parse_args( + $args, + [ + 'href' => '', + ] + ); return $element; } diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index 0024db6e10..48772d3cbc 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -3,8 +3,16 @@ use WP_Rocket\Event_Management\Subscriber_Interface; +/** + * Head subscriber class. + */ class Subscriber implements Subscriber_Interface { + /** + * Head elements array. + * + * @var array + */ private $head_items = []; /** @@ -31,18 +39,24 @@ public static function get_subscribed_events() { ]; } + /** + * Print all head elements. + * + * @param string $content Head elements HTML. + * @return string + */ public function print_head_elements( $content ) { - /** - * Filter Head elements array. - * - * @param array $head_items Elements to be added to head after closing of title tag. - * - * Priority 10: preconnect - * Priority 30: preload - * Priority 50: styles - * @returns array - */ - $items = wpm_apply_filters_typed( 'array','rocket_head_items', [] ); + /** + * Filter Head elements array. + * + * @param array $head_items Elements to be added to head after closing of title tag. + * + * Priority 10: preconnect + * Priority 30: preload + * Priority 50: styles + * @returns array + */ + $items = wpm_apply_filters_typed( 'array', 'rocket_head_items', [] ); if ( empty( $items ) ) { return $content; } @@ -60,6 +74,12 @@ public function print_head_elements( $content ) { return $content . $elements; } + /** + * Check if the item is duplicate. + * + * @param array $item Item to check. + * @return bool + */ private function is_duplicate( $item ) { if ( empty( $item['rel'] ) || empty( $item['href'] ) ) { return false; @@ -77,6 +97,12 @@ private function is_duplicate( $item ) { return true; } + /** + * Prepare element HTML from the item array. + * + * @param array $element Item element. + * @return string + */ private function prepare_element( $element ) { $open_tag = ''; if ( ! empty( $element['open_tag'] ) ) { @@ -99,7 +125,7 @@ private function prepare_element( $element ) { $attributes = []; foreach ( $element as $key => $value ) { - if (is_int( $key ) ) { + if ( is_int( $key ) ) { $attributes[] = $value; continue; } diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index 7c1f3bcb2c..586749900e 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -63,6 +63,11 @@ class CriticalCSSSubscriber implements Subscriber_Interface { */ protected $user; + /** + * Critical CSS contents. + * + * @var string + */ private $critical_css_content = ''; /** @@ -607,14 +612,23 @@ public function insert_critical_css_buffer( $buffer ) { return $this->add_meta_comment( 'async_css', $buffer ); } + /** + * Insert critical CSS into head. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_css_in_head( $items ) { if ( empty( $this->critical_css_content ) ) { return $items; } - $items[] = $this->style_tag( $this->critical_css_content, [ - 'id' => 'rocket-critical-css', - ] ); + $items[] = $this->style_tag( + $this->critical_css_content, + [ + 'id' => 'rocket-critical-css', + ] + ); return $items; } diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index a9e190080d..7de8033c09 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -39,6 +39,11 @@ abstract class AbstractGFOptimization { */ protected $has_google_fonts = true; + /** + * Font urls. + * + * @var array + */ public $font_urls = []; /** @@ -109,10 +114,21 @@ protected function get_font_display_value(): string { return isset( $this->display_values[ $display ] ) ? $display : 'swap'; } + /** + * Check if preload google fonts is enabled or not using filter. + * + * @return bool + */ private function is_preload_enabled() { return ! wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ); } + /** + * Insert font stylesheets into head. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_font_stylesheet_into_head( $items ) { if ( empty( $this->font_urls ) ) { return $items; @@ -121,27 +137,35 @@ public function insert_font_stylesheet_into_head( $items ) { $preload_enabled = $this->is_preload_enabled(); foreach ( $this->font_urls as $font_url ) { - $item = $this->stylesheet_link( [ - 'href' => $font_url, - ] ); + $item = $this->stylesheet_link( + [ + 'href' => $font_url, + ] + ); if ( ! $preload_enabled ) { $items[] = $item; continue; } - $item['media'] = 'print'; + $item['media'] = 'print'; $item['onload'] = 'this.media=\'all\''; - $items[] = $item; + $items[] = $item; $items[] = $this->noscript_tag( - sprintf( '', $font_url ) + sprintf( '', $font_url ) // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet ); } return $items; } + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_font_preload_into_head( $items ) { if ( empty( $this->font_urls ) ) { return $items; @@ -152,10 +176,12 @@ public function insert_font_preload_into_head( $items ) { } foreach ( $this->font_urls as $font_url ) { - $items[] = $this->preload_link( [ - 'href' => $font_url, - 'as' => 'style', - ] ); + $items[] = $this->preload_link( + [ + 'href' => $font_url, + 'as' => 'style', + ] + ); } return $items; diff --git a/inc/Engine/Optimization/GoogleFonts/CombineV2.php b/inc/Engine/Optimization/GoogleFonts/CombineV2.php index 10e4f15d68..0c76bf6e9c 100644 --- a/inc/Engine/Optimization/GoogleFonts/CombineV2.php +++ b/inc/Engine/Optimization/GoogleFonts/CombineV2.php @@ -73,8 +73,8 @@ function ( $tag ) use ( $exclusions ) { return $html; } - $families = array_unique( $families ); - $combined_url = $this->get_combined_url( $families ); + $families = array_unique( $families ); + $combined_url = $this->get_combined_url( $families ); $this->font_urls[] = $combined_url; foreach ( $processed_tags as $font ) { diff --git a/inc/Engine/Optimization/GoogleFonts/Subscriber.php b/inc/Engine/Optimization/GoogleFonts/Subscriber.php index 7c65982bbc..a25ca3c096 100644 --- a/inc/Engine/Optimization/GoogleFonts/Subscriber.php +++ b/inc/Engine/Optimization/GoogleFonts/Subscriber.php @@ -131,11 +131,23 @@ protected function is_allowed() { return ! is_user_logged_in() || (bool) $this->options->get( 'cache_logged_user', 0 ); } - public function insert_fonts_stylesheets( $items ) { + /** + * Insert fonts link stylesheets into head elements for v1 and v2. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_fonts_stylesheets( array $items ) { $items = $this->combine->insert_font_stylesheet_into_head( $items ); return $this->combine_v2->insert_font_stylesheet_into_head( $items ); } + /** + * Insert fonts preloads into head elements for v1 and v2. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_fonts_preload( $items ) { $items = $this->combine->insert_font_preload_into_head( $items ); return $this->combine_v2->insert_font_preload_into_head( $items ); diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index 8e4b62459e..87864123e4 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -82,8 +82,18 @@ class UsedCSS { */ private $manager; + /** + * Used CSS contents. + * + * @var string + */ private $used_css_content = ''; + /** + * Preloaded font urls. + * + * @var array + */ private $preloaded_fonts = []; /** @@ -372,22 +382,33 @@ public function add_used_css_to_html( array $items ): array { return $items; } - $items[] = $this->style_tag( $this->get_used_css_markup( $this->used_css_content ), [ - 'id' => 'wpr-usedcss', - ] ); + $items[] = $this->style_tag( + $this->get_used_css_markup( $this->used_css_content ), + [ + 'id' => 'wpr-usedcss', + ] + ); return $items; } + /** + * Insert preload fonts into page head. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_preload_fonts( $items ) { if ( empty( $this->preloaded_fonts ) ) { return $items; } foreach ( $this->preloaded_fonts as $font ) { - $items[] = $this->preload_link( [ - 'href' => esc_url( $font ), - 'as' => 'font', - 1 => 'crossorigin', - ] ); + $items[] = $this->preload_link( + [ + 'href' => esc_url( $font ), + 'as' => 'font', + 1 => 'crossorigin', + ] + ); } return $items; diff --git a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php index 845e087b23..3fd12d786d 100644 --- a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php +++ b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php @@ -118,10 +118,22 @@ public function on_install( $options ) { return $options; } + /** + * Insert used CSS into head. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_css_in_head( $items ) { return $this->used_css->add_used_css_to_html( $items ); } + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ public function insert_preload_fonts( $items ) { return $this->used_css->insert_preload_fonts( $items ); } diff --git a/inc/Engine/Preload/Fonts.php b/inc/Engine/Preload/Fonts.php index b2aac8140d..15b6698c0a 100644 --- a/inc/Engine/Preload/Fonts.php +++ b/inc/Engine/Preload/Fonts.php @@ -51,6 +51,11 @@ class Fonts implements Subscriber_Interface { 'woff2', ]; + /** + * Loaded fonts + * + * @var array + */ private $fonts = []; /** @@ -119,17 +124,25 @@ public function insert_meta_comment( $html ): string { return $this->add_meta_comment( 'preload_fonts', $html ); } + /** + * Add preload links into head. + * + * @param array $items Head elements. + * @return array + */ public function preload_fonts( $items ): array { if ( empty( $this->fonts ) ) { return $items; } foreach ( $this->fonts as $font ) { - $items[] = $this->preload_link( [ - 'href' => $font, - 'as' => 'font', - 1 => 'crossorigin', - ] ); + $items[] = $this->preload_link( + [ + 'href' => $font, + 'as' => 'font', + 1 => 'crossorigin', + ] + ); } return $items; } From db9547b761374831f4ff5e46f60f983d3a7532cd Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Mon, 17 Feb 2025 12:19:06 +0200 Subject: [PATCH 12/30] start fixing unit tests with another approach --- .../CriticalPath/CriticalCSSSubscriber.php | 9 +++++++-- .../GoogleFonts/AbstractGFOptimization.php | 18 ++++++++++++------ .../insertCriticalCssBuffer.php | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index 586749900e..44c94de728 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -619,12 +619,13 @@ public function insert_critical_css_buffer( $buffer ) { * @return mixed */ public function insert_css_in_head( $items ) { - if ( empty( $this->critical_css_content ) ) { + $css = $this->get_critical_css_content(); + if ( empty( $css ) ) { return $items; } $items[] = $this->style_tag( - $this->critical_css_content, + $css, [ 'id' => 'rocket-critical-css', ] @@ -632,6 +633,10 @@ public function insert_css_in_head( $items ) { return $items; } + public function get_critical_css_content() { + return $this->critical_css_content; + } + /** * Returns JS script to remove the critical css style from frontend. * diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index 7de8033c09..67fb49ac8c 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -44,7 +44,7 @@ abstract class AbstractGFOptimization { * * @var array */ - public $font_urls = []; + protected $font_urls = []; /** * Optimize Google Fonts @@ -130,18 +130,19 @@ private function is_preload_enabled() { * @return mixed */ public function insert_font_stylesheet_into_head( $items ) { - if ( empty( $this->font_urls ) ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { return $items; } $preload_enabled = $this->is_preload_enabled(); - foreach ( $this->font_urls as $font_url ) { + foreach ( $font_urls as $font_url ) { $item = $this->stylesheet_link( [ 'href' => $font_url, ] - ); + ); if ( ! $preload_enabled ) { $items[] = $item; @@ -167,7 +168,8 @@ public function insert_font_stylesheet_into_head( $items ) { * @return mixed */ public function insert_font_preload_into_head( $items ) { - if ( empty( $this->font_urls ) ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { return $items; } @@ -175,7 +177,7 @@ public function insert_font_preload_into_head( $items ) { return $items; } - foreach ( $this->font_urls as $font_url ) { + foreach ( $font_urls as $font_url ) { $items[] = $this->preload_link( [ 'href' => $font_url, @@ -186,4 +188,8 @@ public function insert_font_preload_into_head( $items ) { return $items; } + + public function get_font_urls(): array { + return $this->font_urls; + } } diff --git a/tests/Unit/inc/Engine/CriticalPath/CriticalCSSSubscriber/insertCriticalCssBuffer.php b/tests/Unit/inc/Engine/CriticalPath/CriticalCSSSubscriber/insertCriticalCssBuffer.php index f653214891..3451f3f609 100644 --- a/tests/Unit/inc/Engine/CriticalPath/CriticalCSSSubscriber/insertCriticalCssBuffer.php +++ b/tests/Unit/inc/Engine/CriticalPath/CriticalCSSSubscriber/insertCriticalCssBuffer.php @@ -84,7 +84,7 @@ public function testShouldInsertCriticalCSS( $config, $expected, $expected_html $html = $this->subscriber->insert_critical_css_buffer( $orig_html ); if ( $expected ) { - $this->assertSame( $expected_html, $html ); + $this->assertSame( $this->subscriber->get_critical_css_content(), $config['get_critical_css_content'] ); } else { $this->assertSame( $orig_html, $html ); } From 7df16c80d422192a4f4b017d6b2c757f2accf0ad Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Tue, 18 Feb 2025 10:20:28 +0200 Subject: [PATCH 13/30] continue fixing unit tests --- .../GoogleFonts/Combine/optimize.php | 105 +++++++++++++++--- .../GoogleFonts/Combine/optimize.php | 13 ++- 2 files changed, 99 insertions(+), 19 deletions(-) diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php index c78bf59210..0691a3c081 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -16,13 +16,18 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldUseFilteredDisplayValue' => [ 'config' => [ @@ -39,13 +44,18 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=optional', + ] + ], ], 'testShouldCombineGoogleFontsWithSubsets' => [ 'config' => [ @@ -62,13 +72,18 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Lato%3A100%2C300%2C400%2C600%2C700%2C900%7COpen%20Sans%3A700%2C300%2C600%2C400%7CRaleway%3A900%7CPlayfair%20Display%7COpen%20Sans%7CJockey%20One%3A400%7CAbril%20Fatface%3Aregular&subset=latin&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWithoutSubsetsAndNoEnding|' => [ 'config' => [ @@ -85,13 +100,18 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWithoutSubsetsWhenMalformedURL' => [ 'config' => [ @@ -108,13 +128,18 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3Aregular%2C300%7CLato%3Aregular%2C300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWithSubsetsWhenMalformedURL' => [ 'config' => [ @@ -131,7 +156,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -140,6 +166,10 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3Aregular%2C300%7CLato%3Aregular%2C300&display=swap' + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenNoParam' => [ 'config' => [ @@ -155,7 +185,8 @@ ', // Expected: Combined HTML. - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -163,6 +194,10 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenParam' => [ 'config' => [ @@ -177,7 +212,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -185,6 +221,10 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenInvalidParam' => [ 'config' => [ @@ -199,7 +239,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -207,6 +248,10 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenEncodedParam' => [ 'config' => [ @@ -221,7 +266,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -229,6 +275,10 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWhenMultipleTitleTags' => [ 'config' => [ @@ -246,7 +296,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page Sample Title 2 @@ -254,6 +305,10 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWhenTitleTagInsideBody' => [ 'config' => [ @@ -271,7 +326,8 @@ Sample Title 2 ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -279,6 +335,10 @@ Sample Title 2 ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWhenTitleTagInsideSvgTag' => [ 'config' => [ @@ -297,7 +357,8 @@
logo-cacahuete","toggleOpenedIcon":"","closeIcon":"","backIcon":"","dropdownIcon":"","useBreadcrumb":true,"breadcrumbIcon":"","toggleText":"MENU","toggleLoader":true,"backText":"RETOUR","itemIconVisible":"true","itemBadgeVisible":"true","itemDescVisible":"false","loaderColor":"#FCC800","subTrigger":"item"}\'>
', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page @@ -306,6 +367,10 @@
logo-cacahuete","toggleOpenedIcon":"","closeIcon":"","backIcon":"","dropdownIcon":"","useBreadcrumb":true,"breadcrumbIcon":"","toggleText":"MENU","toggleLoader":true,"backText":"RETOUR","itemIconVisible":"true","itemBadgeVisible":"true","itemDescVisible":"false","loaderColor":"#FCC800","subTrigger":"item"}\'>
', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsNoPreload' => [ 'config' => [ @@ -321,13 +386,18 @@ ', // Expected: Combined HTML. - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'shouldExcludeFontFromCombine' => [ 'config' => [ @@ -350,7 +420,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' @@ -367,5 +438,9 @@ </body> </html> ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Roboto%7CMontSerra%7CComfortaa&display=optional', + ], + ], ] ]; diff --git a/tests/Unit/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php b/tests/Unit/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php index 4d54ad5fc5..05d0cd85ee 100644 --- a/tests/Unit/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php +++ b/tests/Unit/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -52,10 +52,15 @@ public function testShouldCombineGoogleFonts( $config, $html, $expected ) { $combine = new Combine(); + $optimized_html = $combine->optimize( $html ); - $this->assertSame( - $this->format_the_html( $expected ), - $this->format_the_html( $combine->optimize( $html ) ) - ); + if ( is_string( $expected ) ) { + $this->assertSame( + $this->format_the_html( $expected ), + $this->format_the_html( $optimized_html ) + ); + } else if ( is_array( $expected ) ) { + $this->assertSame( $expected['fonts'], $combine->get_font_urls() ); + } } } From 2b1b2b93e2920bf648654634aa97c9f4e008c557 Mon Sep 17 00:00:00 2001 From: WordPressFan <ahmed@wp-media.me> Date: Tue, 18 Feb 2025 10:35:56 +0200 Subject: [PATCH 14/30] continue fixing unit tests 2 --- .../GoogleFonts/CombineV2/optimize.php | 81 +++++++++++++------ .../GoogleFonts/CombineV2/optimize.php | 17 +++- 2 files changed, 71 insertions(+), 27 deletions(-) diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php index 7c827ede94..60fa32521f 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php @@ -42,8 +42,8 @@ <body> </body> </html>', - 'expected' => - '<!doctype html> + 'expected' => [ + 'html' => '<!doctype html> <html> <head> <title>Sample Page @@ -52,7 +52,11 @@ - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&display=swap', + ], + ], ], 'shouldNotCombineMultipleTagsWithTextParam' => [ 'config' => [ @@ -69,8 +73,8 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page @@ -79,7 +83,11 @@ - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&display=swap', + ], + ], ], 'shouldCombineMultipleTags' => [ 'config' => [ @@ -97,8 +105,8 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page @@ -106,7 +114,12 @@ - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&family=Comfortaa&display=swap', + ], + ], + ], 'shouldCombineMultipleTagsWithMultipleFamiliesInTag' => [ 'config' => [ @@ -125,8 +138,8 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page @@ -135,7 +148,12 @@ - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=swap', + ], + ], + ], 'shouldReplaceAnotherFontDisplayValueWithSwap' => [ 'config' => [ @@ -154,8 +172,8 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page @@ -164,7 +182,12 @@ - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=swap', + ], + ], + ], 'shouldReplaceDisplayValueWithFilteredValue' => [ 'config' => [ @@ -183,8 +206,8 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page @@ -193,8 +216,11 @@ - ' - , + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=optional', + ] + ], ], 'shouldCombineMultipleTagsNoPreload' => [ 'config' => [ @@ -212,8 +238,8 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page @@ -221,7 +247,11 @@ - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&family=Comfortaa&display=swap', + ], + ], ], 'shouldExcludeFontFromCombine' => [ 'config' => [ @@ -244,7 +274,8 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' @@ -261,5 +292,9 @@ </body> </html> ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=MontSerra:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=optional', + ], + ], ] ]; diff --git a/tests/Unit/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php b/tests/Unit/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php index b9f57421b4..99c758dd79 100644 --- a/tests/Unit/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php +++ b/tests/Unit/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php @@ -51,10 +51,19 @@ public function testShouldCombineV2GoogleFonts( $config, $html, $expected ) { ->andReturn( $config['exclude_locally_host_fonts'] ?? [] ); $combiner = new CombineV2(); + $optimized_html = $combiner->optimize( $html ); + + if ( is_string( $expected ) ) { + $this->assertSame( + $this->format_the_html( $expected ), + $this->format_the_html( $optimized_html ) + ); + } else if ( is_array( $expected ) ) { + $this->assertSame( + $expected['fonts'], + $combiner->get_font_urls() + ); + } - $this->assertSame( - $this->format_the_html( $expected ), - $this->format_the_html( $combiner->optimize( $html ) ) - ); } } From 830c4064bc6d14a427a9eeabf0b7dafb3d6dcee5 Mon Sep 17 00:00:00 2001 From: WordPressFan <ahmed@wp-media.me> Date: Tue, 18 Feb 2025 11:03:46 +0200 Subject: [PATCH 15/30] fix all unit tests --- .../Optimization/RUCSS/Controller/UsedCSS.php | 18 ++++++++++---- inc/Engine/Preload/Fonts.php | 19 +++++++++++---- .../RUCSS/Controller/UsedCSS/treeshake.php | 20 ++++++++++++---- .../inc/Engine/Preload/Fonts/preloadFonts.php | 24 +++++++++++++++++-- .../RUCSS/Controller/UsedCSS/treeshake.php | 11 ++++++++- .../inc/Engine/Preload/Fonts/preloadFonts.php | 17 +++++++++---- 6 files changed, 89 insertions(+), 20 deletions(-) diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index 87864123e4..1ae6609644 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -378,16 +378,17 @@ private function remove_internal_styles_from_html( string $clean_html, string $h * @return array Filtered head items. */ public function add_used_css_to_html( array $items ): array { - if ( empty( $this->used_css_content ) ) { + $used_css = $this->get_used_css_content(); + if ( empty( $used_css ) ) { return $items; } $items[] = $this->style_tag( - $this->get_used_css_markup( $this->used_css_content ), + $this->get_used_css_markup( $used_css ), [ 'id' => 'wpr-usedcss', ] - ); + ); return $items; } @@ -408,7 +409,7 @@ public function insert_preload_fonts( $items ) { 'as' => 'font', 1 => 'crossorigin', ] - ); + ); } return $items; @@ -697,4 +698,13 @@ static function ( $item ) { public function has_one_completed_row_at_least() { return $this->used_css_query->get_completed_count() > 0; } + + /** + * Get generated used CSS, getter method for used_css_content property. + * + * @return string + */ + public function get_used_css_content() { + return $this->used_css_content; + } } diff --git a/inc/Engine/Preload/Fonts.php b/inc/Engine/Preload/Fonts.php index 15b6698c0a..278c6bca88 100644 --- a/inc/Engine/Preload/Fonts.php +++ b/inc/Engine/Preload/Fonts.php @@ -80,8 +80,8 @@ public function __construct( Options_Data $options, CDN $cdn ) { */ public static function get_subscribed_events() { return [ - 'rocket_head_items' => [ 'preload_fonts', 30 ], - 'rocket_buffer' => [ 'insert_meta_comment', 20 ], + 'rocket_head_items' => [ 'insert_preloaded_fonts_into_head', 30 ], + 'rocket_buffer' => [ 'preload_fonts', 20 ], ]; } @@ -93,7 +93,7 @@ public static function get_subscribed_events() { * * @since 3.6 */ - public function insert_meta_comment( $html ): string { + public function preload_fonts( $html ): string { if ( ! $this->is_allowed() ) { return $html; } @@ -130,7 +130,7 @@ public function insert_meta_comment( $html ): string { * @param array $items Head elements. * @return array */ - public function preload_fonts( $items ): array { + public function insert_preloaded_fonts_into_head( $items ): array { if ( empty( $this->fonts ) ) { return $items; } @@ -142,7 +142,7 @@ public function preload_fonts( $items ): array { 'as' => 'font', 1 => 'crossorigin', ] - ); + ); } return $items; } @@ -192,4 +192,13 @@ private function is_allowed(): bool { */ return ! apply_filters( 'rocket_disable_preload_fonts', false ); } + + /** + * Get fonts to preload, getter method for fonts property. + * + * @return array + */ + public function get_fonts(): array { + return $this->fonts; + } } diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php index 95f7bc4b93..5b4e2bf62a 100644 --- a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php @@ -88,7 +88,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectedFilteredHTMlWhenNoPreconnectGoogleAPI' => [ 'config' => [ @@ -112,7 +115,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/google_fonts.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectedFilteredHTMlWhenNoEmptyUsedCSSExcludeAttr' => [ 'config' => [ @@ -142,7 +148,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original_exclude_attr.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_attr.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_attr.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectedFilteredHTMlWhenNoEmptyUsedCSSExcludeContent' => [ 'config' => [ @@ -172,7 +181,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original_exclude_content.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_content.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_content.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectSameHtmlWhenNoTitleTag' => [ 'config' => [ diff --git a/tests/Fixtures/inc/Engine/Preload/Fonts/preloadFonts.php b/tests/Fixtures/inc/Engine/Preload/Fonts/preloadFonts.php index 3b1c9fb7d3..84bf514c9b 100644 --- a/tests/Fixtures/inc/Engine/Preload/Fonts/preloadFonts.php +++ b/tests/Fixtures/inc/Engine/Preload/Fonts/preloadFonts.php @@ -126,7 +126,18 @@ 'cdn' => false, 'cdn_cnames' => [], ], - 'expected' => $valid_preload_fonts_options, + 'expected' => [ + 'html' => $valid_preload_fonts_options, + 'fonts' => [ + 'http://example.org/wp-content/file.otf', + 'http://example.org/wp-content/file.ttf', + 'http://example.org/wp-content/file.svg', + 'http://example.org/wp-content/file.woff?v=4.4.0', + 'http://example.org/wp-content/file.woff2', + 'http://example.org/wp-content/themes/paperback/inc/fontawesome/fonts/fontawesome-webfont.woff2?v=4.4.0', + 'http://example.org/wp-content/themes/paperback/inc/fontawesome/fonts/fontawesome-webfont.woff2#123', + ], + ], ], 'validPreloadFontsOptionsWithCDN' => [ 'buffer' => $html, @@ -146,6 +157,15 @@ 'https://123456.rocketcdn.me', ], ], - 'expected' => $valid_preload_fonts_options_wit_cdn, + 'expected' => [ + 'html' => $valid_preload_fonts_options_wit_cdn, + 'fonts' => [ + 'https://123456.rocketcdn.me/wp-content/file.otf', + 'https://123456.rocketcdn.me/wp-content/file.ttf', + 'https://123456.rocketcdn.me/wp-content/file.svg', + 'https://123456.rocketcdn.me/wp-content/file.woff', + 'https://123456.rocketcdn.me/wp-content/file.woff2', + ], + ], ], ]; diff --git a/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php b/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php index 5b7aea1781..7e6f6a05ab 100644 --- a/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php +++ b/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php @@ -107,7 +107,16 @@ public function testShouldReturnAsExpected( $config, $expected ) { ->once() ->andReturn( $dynamic_lists ); - $this->assertEquals($this->format_the_html($expected), $this->format_the_html($this->usedCss->treeshake($config['html']))); + $optimized_html = $this->usedCss->treeshake($config['html']); + if ( is_string( $expected ) ) { + $this->assertEquals( + $this->format_the_html($expected), + $this->format_the_html( $optimized_html ) + ); + } else if ( is_array( $expected ) ) { + $this->assertSame( $expected['used_css'], $this->usedCss->get_used_css_content() ); + } + } protected function configureIsMobile($config) { diff --git a/tests/Unit/inc/Engine/Preload/Fonts/preloadFonts.php b/tests/Unit/inc/Engine/Preload/Fonts/preloadFonts.php index 2b81779026..3fb646e440 100644 --- a/tests/Unit/inc/Engine/Preload/Fonts/preloadFonts.php +++ b/tests/Unit/inc/Engine/Preload/Fonts/preloadFonts.php @@ -63,10 +63,19 @@ public function testShouldAddPreloadTagsWhenValidFonts( $buffer, $bypass, $filte } ); } - $this->assertSame( - $expected, - $this->fonts->preload_fonts( $buffer ) - ); + $optimized_buffer = $this->fonts->preload_fonts( $buffer ); + if ( is_string( $expected ) ) { + $this->assertSame( + $expected, + $optimized_buffer, + ); + } else if ( is_array( $expected ) ) { + $this->assertSame( + $expected['fonts'], + $this->fonts->get_fonts(), + ); + } + } public function providerTestData() { From e572c35b9f598c2c1b4303ee4ab88150e12255bb Mon Sep 17 00:00:00 2001 From: WordPressFan <ahmed@wp-media.me> Date: Tue, 18 Feb 2025 11:06:59 +0200 Subject: [PATCH 16/30] fix phpcs --- inc/Engine/CriticalPath/CriticalCSSSubscriber.php | 5 +++++ .../Optimization/GoogleFonts/AbstractGFOptimization.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index 44c94de728..45250a06d9 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -633,6 +633,11 @@ public function insert_css_in_head( $items ) { return $items; } + /** + * Get critical CSS content, getter method for critical_css_content property. + * + * @return string + */ public function get_critical_css_content() { return $this->critical_css_content; } diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index 67fb49ac8c..4f495ad0b9 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -189,6 +189,11 @@ public function insert_font_preload_into_head( $items ) { return $items; } + /** + * Get font urls, getter method for font_urls property. + * + * @return array + */ public function get_font_urls(): array { return $this->font_urls; } From fcd272156a81276f9b37547ec861f6cd997e8b2d Mon Sep 17 00:00:00 2001 From: WordPressFan <ahmed@wp-media.me> Date: Tue, 18 Feb 2025 12:09:34 +0200 Subject: [PATCH 17/30] change the way we add rocket_head to be inside rocket_buffer --- .../Optimization/Buffer/Optimization.php | 7 ----- inc/Engine/Optimization/Buffer/Subscriber.php | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/inc/Engine/Optimization/Buffer/Optimization.php b/inc/Engine/Optimization/Buffer/Optimization.php index 7f242c06e6..356de45529 100755 --- a/inc/Engine/Optimization/Buffer/Optimization.php +++ b/inc/Engine/Optimization/Buffer/Optimization.php @@ -105,13 +105,6 @@ public function maybe_process_buffer( $buffer ) { return $buffer; } - $filtered_buffer = preg_replace( - '##iU', - '' . wpm_apply_filters_typed( 'string', 'rocket_head', '' ), - $filtered_buffer, - 1 - ); - $this->log( 'Page optimized.', [], 'info' ); /** diff --git a/inc/Engine/Optimization/Buffer/Subscriber.php b/inc/Engine/Optimization/Buffer/Subscriber.php index ae32bb989a..5ef62a2c30 100644 --- a/inc/Engine/Optimization/Buffer/Subscriber.php +++ b/inc/Engine/Optimization/Buffer/Subscriber.php @@ -33,6 +33,7 @@ public function __construct( Optimization $optimizer ) { public static function get_subscribed_events() { return [ 'template_redirect' => [ 'start_content_process', 2 ], + 'rocket_buffer' => [ 'insert_rocket_head', 100000 ], ]; } @@ -44,4 +45,29 @@ public static function get_subscribed_events() { public function start_content_process() { return $this->optimizer->maybe_init_process(); } + + /** + * Insert rocket_head into the buffer HTML + * + * @param string $html Buffer HTML. + * @return string + */ + public function insert_rocket_head( $html ) { + if ( empty( $html ) ) { + return $html; + } + + $filtered_buffer = preg_replace( + '##iU', + '' . wpm_apply_filters_typed( 'string', 'rocket_head', '' ), + $html, + 1 + ); + + if ( empty( $filtered_buffer ) ) { + return $html; + } + + return $filtered_buffer; + } } From bc3e7e14bdbc30c787fe191b7ec69b2ad8b801d3 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 19 Feb 2025 10:17:16 +0200 Subject: [PATCH 18/30] start fixing integration tests --- inc/Engine/Common/Head/Subscriber.php | 28 +++++++++++- .../CriticalPath/CriticalCSSSubscriber.php | 2 +- inc/Engine/Optimization/Buffer/Subscriber.php | 26 ----------- .../Optimization/GoogleFonts/Combine.php | 2 +- tests/Integration/IsolateHookTrait.php | 43 +++++++++++++++++++ .../GoogleFonts/Combine/optimize.php | 4 +- 6 files changed, 74 insertions(+), 31 deletions(-) diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index 48772d3cbc..6f8fc26b2e 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -35,7 +35,8 @@ class Subscriber implements Subscriber_Interface { */ public static function get_subscribed_events() { return [ - 'rocket_head' => 'print_head_elements', + 'rocket_buffer' => [ 'insert_rocket_head', 100000 ], + 'rocket_head' => 'print_head_elements', ]; } @@ -136,4 +137,29 @@ private function prepare_element( $element ) { return $open_tag . ' ' . $attributes_html . '>' . $inner_content . $close_tag; } + + /** + * Insert rocket_head into the buffer HTML + * + * @param string $html Buffer HTML. + * @return string + */ + public function insert_rocket_head( $html ) { + if ( empty( $html ) ) { + return $html; + } + + $filtered_buffer = preg_replace( + '##iU', + '' . wpm_apply_filters_typed( 'string', 'rocket_head', '' ), + $html, + 1 + ); + + if ( empty( $filtered_buffer ) ) { + return $html; + } + + return $filtered_buffer; + } } diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index 45250a06d9..38421de43b 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -639,7 +639,7 @@ public function insert_css_in_head( $items ) { * @return string */ public function get_critical_css_content() { - return $this->critical_css_content; + return $this->should_async_css() ? $this->critical_css_content : ''; } /** diff --git a/inc/Engine/Optimization/Buffer/Subscriber.php b/inc/Engine/Optimization/Buffer/Subscriber.php index 5ef62a2c30..ae32bb989a 100644 --- a/inc/Engine/Optimization/Buffer/Subscriber.php +++ b/inc/Engine/Optimization/Buffer/Subscriber.php @@ -33,7 +33,6 @@ public function __construct( Optimization $optimizer ) { public static function get_subscribed_events() { return [ 'template_redirect' => [ 'start_content_process', 2 ], - 'rocket_buffer' => [ 'insert_rocket_head', 100000 ], ]; } @@ -45,29 +44,4 @@ public static function get_subscribed_events() { public function start_content_process() { return $this->optimizer->maybe_init_process(); } - - /** - * Insert rocket_head into the buffer HTML - * - * @param string $html Buffer HTML. - * @return string - */ - public function insert_rocket_head( $html ) { - if ( empty( $html ) ) { - return $html; - } - - $filtered_buffer = preg_replace( - '##iU', - '' . wpm_apply_filters_typed( 'string', 'rocket_head', '' ), - $html, - 1 - ); - - if ( empty( $filtered_buffer ) ) { - return $html; - } - - return $filtered_buffer; - } } diff --git a/inc/Engine/Optimization/GoogleFonts/Combine.php b/inc/Engine/Optimization/GoogleFonts/Combine.php index 0e9a39152c..552eb71547 100644 --- a/inc/Engine/Optimization/GoogleFonts/Combine.php +++ b/inc/Engine/Optimization/GoogleFonts/Combine.php @@ -64,7 +64,7 @@ public function optimize( $html ): string { function ( $font ) use ( $exclusions ) { return ! $this->is_excluded( $font[0], $exclusions ); } - ); + ); $num_fonts = count( $filtered_fonts ); diff --git a/tests/Integration/IsolateHookTrait.php b/tests/Integration/IsolateHookTrait.php index 9f3c0daa5e..415e9e2256 100644 --- a/tests/Integration/IsolateHookTrait.php +++ b/tests/Integration/IsolateHookTrait.php @@ -11,6 +11,49 @@ protected $original_wp_priorities; + protected function unregisterAllCallbacksExceptMulti( $event_name, $methods = [] ) { + global $wp_filter; + $this->original_wp_filter = $wp_filter[ $event_name ]->callbacks; + + foreach ( $methods as $priority => $method_name ) { + foreach ( $this->original_wp_filter[ $priority ] as $key => $config ) { + + // Skip if not this tests callback. + if ( substr( $key, - strlen( $method_name ) ) !== $method_name ) { + continue; + } + + $wp_filter[ $event_name ]->callbacks = [ + $priority => [ $key => $config ], + ]; + } + } + + try { + $wp_hooks = $wp_filter[ $event_name ]; + $reflection = new ReflectionClass($wp_hooks); + $priorities_property = $reflection->getProperty('priorities'); + $priorities_property->setAccessible(true); + $this->original_wp_priorities = $priorities_property->getValue($wp_hooks); + $priorities = $priorities_property->getValue($wp_hooks); + } catch (ReflectionException $e) { + return; + } + + foreach ($this->original_wp_priorities as $priority) { + if ( key_exists($priority, $wp_filter[ $event_name ]->callbacks)) { + continue; + } + + $priorities = array_values(array_filter($priorities, function ($current) use ($priority) { + return $current !== $priority; + })); + + } + + $priorities_property->setValue($wp_hooks, $priorities); + } + protected function unregisterAllCallbacksExcept( $event_name, $method_name, $priority = 10 ) { global $wp_filter; $this->original_wp_filter = $wp_filter[ $event_name ]->callbacks; diff --git a/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php b/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php index 5b2e4a013d..5318e8c88e 100644 --- a/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php +++ b/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -29,7 +29,7 @@ public function set_up() { ], ]; - $this->unregisterAllCallbacksExcept('rocket_buffer', 'process', 17 ); + $this->unregisterAllCallbacksExceptMulti('rocket_buffer', [ 17 => 'process', 100000 => 'insert_rocket_head' ] ); add_filter('rocket_exclude_locally_host_fonts', [ $this, 'exclude_locally_host_fonts' ] ); // @phpstan-ignore-line } @@ -84,7 +84,7 @@ private function doTest( $config, $original, $expected ) { $actual = apply_filters( 'rocket_buffer', $original ); $this->assertSame( - $this->format_the_html( $expected ), + $this->format_the_html( $expected['html'] ), $this->format_the_html( $actual ) ); } From 515d1e29890c723ec6feae4bf000da72e6ba69ea Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 19 Feb 2025 13:18:52 +0200 Subject: [PATCH 19/30] fixing most integration tests --- inc/Engine/Common/Head/Subscriber.php | 7 +- .../GoogleFonts/AbstractGFOptimization.php | 74 ++++------------- .../Optimization/GoogleFonts/Combine.php | 51 ++++++++++++ .../Optimization/GoogleFonts/CombineV2.php | 51 ++++++++++++ .../Optimization/GoogleFonts/Subscriber.php | 14 +++- .../GoogleFonts/Combine/optimize.php | 80 ++++++++++++++----- .../GoogleFonts/CombineV1V2/optimize.php | 45 ++++++++--- .../GoogleFonts/CombineV2/optimize.php | 35 +++++--- tests/Integration/IsolateHookTrait.php | 5 +- .../GoogleFonts/Combine/optimize.php | 3 +- .../RUCSS/Frontend/Subscriber/treeshake.php | 2 +- 11 files changed, 253 insertions(+), 114 deletions(-) diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php index 6f8fc26b2e..5d80ac7095 100644 --- a/inc/Engine/Common/Head/Subscriber.php +++ b/inc/Engine/Common/Head/Subscriber.php @@ -62,6 +62,7 @@ public function print_head_elements( $content ) { return $content; } + $this->head_items = []; // Combine elements. $elements = ''; foreach ( $items as $item ) { @@ -125,6 +126,8 @@ private function prepare_element( $element ) { $attributes = []; + ksort( $element ); + foreach ( $element as $key => $value ) { if ( is_int( $key ) ) { $attributes[] = $value; @@ -133,9 +136,9 @@ private function prepare_element( $element ) { $attributes[] = $key . '="' . esc_attr( $value ) . '"'; } - $attributes_html = ! empty( $attributes ) ? implode( ' ', $attributes ) : ''; + $attributes_html = ! empty( $attributes ) ? ' ' . implode( ' ', $attributes ) : ''; - return $open_tag . ' ' . $attributes_html . '>' . $inner_content . $close_tag; + return $open_tag . $attributes_html . '>' . $inner_content . $close_tag; } /** diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index 4f495ad0b9..132b1b1fde 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -39,13 +39,6 @@ abstract class AbstractGFOptimization { */ protected $has_google_fonts = true; - /** - * Font urls. - * - * @var array - */ - protected $font_urls = []; - /** * Optimize Google Fonts * @@ -119,25 +112,27 @@ protected function get_font_display_value(): string { * * @return bool */ - private function is_preload_enabled() { + protected function is_preload_enabled() { return ! wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ); } - /** - * Insert font stylesheets into head. - * - * @param array $items Head elements. - * @return mixed - */ - public function insert_font_stylesheet_into_head( $items ) { - $font_urls = $this->get_font_urls(); - if ( empty( $font_urls ) ) { - return $items; + protected function prepare_preload_fonts_to_head( array $fonts, array $items ): array { + foreach ( $fonts as $font_url ) { + $items[] = $this->preload_link( + [ + 'href' => $font_url, + 'as' => 'style', + ] + ); } + return $items; + } + + protected function prepare_stylesheet_fonts_to_head( array $fonts, array $items ): array { $preload_enabled = $this->is_preload_enabled(); - foreach ( $font_urls as $font_url ) { + foreach ( $fonts as $font_url ) { $item = $this->stylesheet_link( [ 'href' => $font_url, @@ -150,51 +145,14 @@ public function insert_font_stylesheet_into_head( $items ) { } $item['media'] = 'print'; - $item['onload'] = 'this.media=\'all\''; + $item['onload'] = "this.media='all'"; $items[] = $item; $items[] = $this->noscript_tag( - sprintf( '', $font_url ) // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet + sprintf( '', $font_url ) // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet ); } return $items; } - - /** - * Insert font preloads into head. - * - * @param array $items Head elements. - * @return mixed - */ - public function insert_font_preload_into_head( $items ) { - $font_urls = $this->get_font_urls(); - if ( empty( $font_urls ) ) { - return $items; - } - - if ( ! $this->is_preload_enabled() ) { - return $items; - } - - foreach ( $font_urls as $font_url ) { - $items[] = $this->preload_link( - [ - 'href' => $font_url, - 'as' => 'style', - ] - ); - } - - return $items; - } - - /** - * Get font urls, getter method for font_urls property. - * - * @return array - */ - public function get_font_urls(): array { - return $this->font_urls; - } } diff --git a/inc/Engine/Optimization/GoogleFonts/Combine.php b/inc/Engine/Optimization/GoogleFonts/Combine.php index 552eb71547..cd897894cb 100644 --- a/inc/Engine/Optimization/GoogleFonts/Combine.php +++ b/inc/Engine/Optimization/GoogleFonts/Combine.php @@ -32,6 +32,13 @@ class Combine extends AbstractGFOptimization { */ protected $subsets = ''; + /** + * Font urls. + * + * @var array + */ + protected $font_urls = []; + /** * Combines multiple Google Fonts links into one * @@ -42,6 +49,7 @@ class Combine extends AbstractGFOptimization { * @return string */ public function optimize( $html ): string { + $this->font_urls = []; Logger::info( 'GOOGLE FONTS COMBINE PROCESS STARTED.', [ 'GF combine process' ] ); $html_nocomments = $this->hide_comments( $html ); @@ -152,4 +160,47 @@ private function get_combined_url(): string { return esc_url( "https://fonts.googleapis.com/css?family={$this->fonts}{$this->subsets}&display={$display}" ); } + + /** + * Get font urls, getter method for font_urls property. + * + * @return array + */ + public function get_font_urls(): array { + return $this->font_urls; + } + + /** + * Insert font stylesheets into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_stylesheet_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + return $this->prepare_stylesheet_fonts_to_head( $font_urls, $items ); + } + + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_preload_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + if ( ! $this->is_preload_enabled() ) { + return $items; + } + + return $this->prepare_preload_fonts_to_head( $font_urls, $items ); + } } diff --git a/inc/Engine/Optimization/GoogleFonts/CombineV2.php b/inc/Engine/Optimization/GoogleFonts/CombineV2.php index 0c76bf6e9c..c92ccffa3c 100644 --- a/inc/Engine/Optimization/GoogleFonts/CombineV2.php +++ b/inc/Engine/Optimization/GoogleFonts/CombineV2.php @@ -14,6 +14,13 @@ class CombineV2 extends AbstractGFOptimization { use RegexTrait; + /** + * Font urls. + * + * @var array + */ + protected $font_urls = []; + /** * Combines multiple Google Fonts (API v2) links into one * @@ -24,6 +31,7 @@ class CombineV2 extends AbstractGFOptimization { * @return string */ public function optimize( $html ): string { + $this->font_urls = []; Logger::info( 'GOOGLE FONTS COMBINE-V2 PROCESS STARTED.', [ 'GF combine process' ] ); $processed_tags = []; @@ -161,4 +169,47 @@ private function get_concatenated_families( array $families ): string { return rtrim( $families_string, '&?' ); } + + /** + * Get font urls, getter method for font_urls property. + * + * @return array + */ + public function get_font_urls(): array { + return $this->font_urls; + } + + /** + * Insert font stylesheets into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_stylesheet_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + return $this->prepare_stylesheet_fonts_to_head( $font_urls, $items ); + } + + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_preload_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + if ( ! $this->is_preload_enabled() ) { + return $items; + } + + return $this->prepare_preload_fonts_to_head( $font_urls, $items ); + } } diff --git a/inc/Engine/Optimization/GoogleFonts/Subscriber.php b/inc/Engine/Optimization/GoogleFonts/Subscriber.php index a25ca3c096..28088738ca 100644 --- a/inc/Engine/Optimization/GoogleFonts/Subscriber.php +++ b/inc/Engine/Optimization/GoogleFonts/Subscriber.php @@ -138,8 +138,11 @@ protected function is_allowed() { * @return mixed */ public function insert_fonts_stylesheets( array $items ) { - $items = $this->combine->insert_font_stylesheet_into_head( $items ); - return $this->combine_v2->insert_font_stylesheet_into_head( $items ); + if ( ! $this->is_allowed() ) { + return $items; + } + $items = $this->combine_v2->insert_font_stylesheet_into_head( $items ); + return $this->combine->insert_font_stylesheet_into_head( $items ); } /** @@ -149,7 +152,10 @@ public function insert_fonts_stylesheets( array $items ) { * @return mixed */ public function insert_fonts_preload( $items ) { - $items = $this->combine->insert_font_preload_into_head( $items ); - return $this->combine_v2->insert_font_preload_into_head( $items ); + if ( ! $this->is_allowed() ) { + return $items; + } + $items = $this->combine_v2->insert_font_preload_into_head( $items ); + return $this->combine->insert_font_preload_into_head( $items ); } } diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php index 0691a3c081..1b465f88a3 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -17,9 +17,13 @@ ', 'expected' => [ - 'html' => ' + 'html' => ' + - Sample Page + Sample Page + + + @@ -47,7 +51,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + @@ -75,7 +82,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + @@ -103,7 +113,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + @@ -131,7 +144,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + @@ -160,7 +176,9 @@ 'html' => ' Sample Page - + + + @@ -188,8 +206,10 @@ 'expected' => [ 'html' => ' - Sample Page - + Sample Page + + + @@ -215,8 +235,10 @@ 'expected' => [ 'html' => ' - Sample Page - + Sample Page + + + @@ -242,8 +264,10 @@ 'expected' => [ 'html' => ' - Sample Page - + Sample Page + + + @@ -269,8 +293,10 @@ 'expected' => [ 'html' => ' - Sample Page - + Sample Page + + + @@ -299,7 +325,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + Sample Title 2 @@ -329,7 +358,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + Sample Title 2 @@ -360,7 +392,10 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + + + @@ -389,7 +424,8 @@ 'expected' => [ 'html' => ' - Sample Page + Sample Page + @@ -426,10 +462,10 @@ Sample Page - - + + diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php index 88120d742f..6683d8ae82 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php @@ -25,8 +25,13 @@ Sample Page - - + + + + + + + @@ -56,8 +61,13 @@ Sample Page - - + + + + + + + @@ -89,8 +99,13 @@ Sample Page - - + + + + + + + @@ -122,8 +137,13 @@ Sample Page - - + + + + + + + @@ -155,8 +175,13 @@ Sample Page - - + + + + + + + diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php index 60fa32521f..3ceef7fa5d 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php @@ -46,9 +46,10 @@ 'html' => ' - Sample Page - - + Sample Page + + + @@ -78,7 +79,9 @@ Sample Page - + + + @@ -110,7 +113,9 @@ Sample Page - + + + @@ -143,7 +148,9 @@ Sample Page - + + + @@ -177,7 +184,9 @@ Sample Page - + + + @@ -211,7 +220,9 @@ Sample Page - + + + @@ -243,7 +254,7 @@ Sample Page - + @@ -280,10 +291,10 @@ Sample Page - - + + diff --git a/tests/Integration/IsolateHookTrait.php b/tests/Integration/IsolateHookTrait.php index 415e9e2256..a9c1cd57ac 100644 --- a/tests/Integration/IsolateHookTrait.php +++ b/tests/Integration/IsolateHookTrait.php @@ -14,6 +14,7 @@ protected function unregisterAllCallbacksExceptMulti( $event_name, $methods = [] ) { global $wp_filter; $this->original_wp_filter = $wp_filter[ $event_name ]->callbacks; + $wp_filter[ $event_name ]->callbacks = []; foreach ( $methods as $priority => $method_name ) { foreach ( $this->original_wp_filter[ $priority ] as $key => $config ) { @@ -23,9 +24,7 @@ protected function unregisterAllCallbacksExceptMulti( $event_name, $methods = [] continue; } - $wp_filter[ $event_name ]->callbacks = [ - $priority => [ $key => $config ], - ]; + $wp_filter[ $event_name ]->callbacks[ $priority ] = [ $key => $config ]; } } diff --git a/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php b/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php index 5318e8c88e..d24de83708 100644 --- a/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php +++ b/tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -39,7 +39,6 @@ public function tear_down() { remove_filter( 'rocket_disable_google_fonts_preload', [ $this, 'set_disable_preload' ] ); remove_filter('rocket_exclude_locally_host_fonts', [ $this, 'exclude_locally_host_fonts' ] ); - $this->restoreWpHook('rocket_buffer'); parent::tear_down(); @@ -84,7 +83,7 @@ private function doTest( $config, $original, $expected ) { $actual = apply_filters( 'rocket_buffer', $original ); $this->assertSame( - $this->format_the_html( $expected['html'] ), + $this->format_the_html( is_string( $expected ) ? $expected : $expected['html'] ), $this->format_the_html( $actual ) ); } diff --git a/tests/Integration/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/treeshake.php b/tests/Integration/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/treeshake.php index d4d8ce747d..d3154c61f1 100644 --- a/tests/Integration/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/treeshake.php +++ b/tests/Integration/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/treeshake.php @@ -19,7 +19,7 @@ public function set_up() { self::installUsedCssTable(); - $this->unregisterAllCallbacksExcept('rocket_buffer', 'treeshake', 1000 ); + $this->unregisterAllCallbacksExceptMulti('rocket_buffer', [ 1000 => 'treeshake', 100000 => 'insert_rocket_head' ] ); add_filter('pre_get_rocket_option_remove_unused_css', [$this, 'rucss']); add_filter('rocket_exclude_rucss_fonts_preload', [$this, 'exclude_fonts_preload']); add_filter('rocket_used_css_dir_level', [$this, 'used_css_dir_level']); From 3ab899a3fc549f0fae538f26aef89f68be9582b8 Mon Sep 17 00:00:00 2001 From: WordPressFan Date: Wed, 19 Feb 2025 15:41:26 +0200 Subject: [PATCH 20/30] fix more tests --- inc/Engine/Preload/Fonts.php | 8 ++++--- .../Subscriber/HTML/outputFontExcluded.html | 2 +- .../Subscriber/HTML/outputFontPreloaded.html | 2 +- .../inc/Engine/Preload/Fonts/preloadFonts.php | 24 +++++++++---------- .../RUCSS/Frontend/Subscriber/treeshake.php | 5 +++- .../inc/Engine/Preload/Fonts/preloadFonts.php | 4 ++-- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/inc/Engine/Preload/Fonts.php b/inc/Engine/Preload/Fonts.php index 278c6bca88..c3c2f0d272 100644 --- a/inc/Engine/Preload/Fonts.php +++ b/inc/Engine/Preload/Fonts.php @@ -94,6 +94,7 @@ public static function get_subscribed_events() { * @since 3.6 */ public function preload_fonts( $html ): string { + $this->fonts = []; if ( ! $this->is_allowed() ) { return $html; } @@ -131,11 +132,12 @@ public function preload_fonts( $html ): string { * @return array */ public function insert_preloaded_fonts_into_head( $items ): array { - if ( empty( $this->fonts ) ) { + $fonts = $this->get_fonts(); + if ( empty( $fonts ) ) { return $items; } - foreach ( $this->fonts as $font ) { + foreach ( $fonts as $font ) { $items[] = $this->preload_link( [ 'href' => $font, @@ -199,6 +201,6 @@ private function is_allowed(): bool { * @return array */ public function get_fonts(): array { - return $this->fonts; + return $this->is_allowed() ? $this->fonts : []; } } diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html index 00514687c0..cb768fe8e7 100644 --- a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html @@ -2,7 +2,7 @@ - Title