Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #7104: Duplicated tag added to page #7105

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
be9e3b9
Base structure
Miraeld Nov 6, 2024
b33302c
Google font version management
Miraeld Nov 6, 2024
5687237
Change of structure + fixes linters
Miraeld Nov 6, 2024
5fac384
Change use of `home_url` to WPR constant
Miraeld Nov 6, 2024
968eefd
Change use of `home_url` to WPR constant
Miraeld Nov 6, 2024
359f175
Changes the build of the factory
Miraeld Nov 7, 2024
6f044c0
Add unit tests
Miraeld Nov 7, 2024
4882bbf
Fix ServiceProvider
Miraeld Nov 7, 2024
833baaf
Works up to combining URL
Miraeld Nov 8, 2024
98d8fdc
Apply linter
Miraeld Nov 8, 2024
0f2c05b
First working prototype
Miraeld Nov 8, 2024
32fa787
WIP: Integration test
Miraeld Nov 8, 2024
ebbbaf2
revert visibility
remyperona Nov 8, 2024
5160b3d
update context checking
remyperona Nov 8, 2024
e2d59b2
add strict declare
remyperona Nov 8, 2024
02a4c23
rewrite fonts URL
remyperona Nov 8, 2024
03845d4
update instantiation
remyperona Nov 8, 2024
84480aa
update URL
remyperona Nov 8, 2024
44f0891
update tests
remyperona Nov 8, 2024
e4934af
remove group
remyperona Nov 8, 2024
7e7c721
Merge branch 'feature/host-google-fonts' into feature/7063-google-fon…
remyperona Nov 8, 2024
29b218c
update name
remyperona Nov 8, 2024
8ed9d56
update config
remyperona Nov 8, 2024
1322df3
update test
remyperona Nov 8, 2024
32930b5
update instantiation
remyperona Nov 8, 2024
46e6a8b
remove file
remyperona Nov 8, 2024
04dcaed
Change the position of google font combined url process
Khadreal Nov 11, 2024
489c049
Fixed linter error
Khadreal Nov 11, 2024
81eaa9c
update test
Khadreal Nov 11, 2024
cab4e86
refactor duplicate code
remyperona Nov 12, 2024
810538b
Updated namespace
jeawhanlee Nov 13, 2024
dcee3f0
Closes #7104: Remove preload tag if host_fonts_locally is enabled
Miraeld Nov 13, 2024
a663210
Add tests
Miraeld Nov 13, 2024
6890cfd
filter preload of google fonts
remyperona Nov 13, 2024
9cf8452
disable google fonts preload when host fonts locally
remyperona Nov 13, 2024
37fa596
update tests
remyperona Nov 13, 2024
22e9f61
fix code styling
remyperona Nov 13, 2024
85b6385
update tests
remyperona Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions inc/Engine/Media/Fonts/Context/Context.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts\Context;

use WP_Rocket\Engine\Common\Context\AbstractContext;

class Context extends AbstractContext {
/**
* Checks if the feature is allowed.
*
* @param array $data Optional. Data to check against.
*
* @return bool
*/
public function is_allowed( array $data = [] ): bool {
$is_allowed = $this->run_common_checks(
[
'do_not_optimize' => false,
'bypass' => false,
'option' => 'host_fonts_locally',
]
);

return $is_allowed;
}
}
128 changes: 128 additions & 0 deletions inc/Engine/Media/Fonts/Frontend/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts\Frontend;

use WP_Rocket\Engine\Media\Fonts\Context\Context;
use WP_Rocket\Engine\Optimization\RegexTrait;
use WP_Rocket\Logger\Logger;

class Controller {
use RegexTrait;

/**
* Context instance.
*
* @var Context
*/
private $context;

/**
* Base url.
*
* @var string
*/
private $base_url;

/**
* Constructor.
*
* @param Context $context Context instance.
*/
public function __construct( Context $context ) {
$this->context = $context;
$this->base_url = rocket_get_constant( 'WP_ROCKET_CACHE_ROOT_URL', '' ) . 'fonts/' . get_current_blog_id() . '/';
}

/**
* Rewrites the Google Fonts paths to local ones.
*
* @param string $html HTML content.
* @return string
*/
public function rewrite_fonts( string $html ): string {
if ( ! $this->context->is_allowed() ) {
return $html;
}

$html_nocomments = $this->hide_comments( $html );

$v1_fonts = $this->find( '<link(?:\s+(?:(?!href\s*=\s*)[^>])+)?(?:\s+href\s*=\s*([\'"])(?<url>(?:https?:)?\/\/fonts\.googleapis\.com\/css[^\d](?:(?!\1).)+)\1)(?:\s+[^>]*)?>', $html_nocomments );
$v2_fonts = $this->find( '<link(?:\s+(?:(?!href\s*=\s*)[^>])+)?(?:\s+href\s*=\s*([\'"])(?<url>(?:https?:)?\/\/fonts\.googleapis\.com\/css2(?:(?!\1).)+)\1)(?:\s+[^>]*)?>', $html_nocomments );

if ( ! $v1_fonts && ! $v2_fonts ) {
Logger::debug( 'No Google Fonts found.', [ 'Host Fonts Locally' ] );
return $html;
}

foreach ( $v1_fonts as $font ) {
$html = $this->replace_font( $font, $html );
}

foreach ( $v2_fonts as $font ) {
$html = $this->replace_font( $font, $html );
}

return $html;
}

/**
* Replaces the Google Fonts URL with the local one.
*
* @param array $font Font data.
* @param string $html HTML content.
*
* @return string
*/
private function replace_font( $font, $html ): string {
$hash = md5( $font['url'] );
$local = $this->get_optimized_markup( $hash, $font['url'] );

return str_replace( $font[0], $local, $html );
}

/**
* Returns the optimized markup for Google Fonts
*
* @since 3.18
*
* @param string $hash Font Url has.
* @param string $original_url Fonts Url.
*
* @return string
*/
protected function get_optimized_markup( string $hash, string $original_url ): string {
$levels = 3;
$base = substr( $hash, 0, $levels );
$remain = substr( $hash, $levels );

$path_array = str_split( $base );
$path_array[] = $remain;

$path = implode( '/', $path_array );
$url = $this->base_url . $path . '.css';

$gf_parameters = wp_parse_url( $original_url, PHP_URL_QUERY );

return sprintf(
'<link rel="stylesheet" href="%1$s" data-wpr-hosted-gf-parameters="%2$s"/>', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
$url,
$gf_parameters
);
}

/**
* Disables the preload of Google Fonts.
*
* @param bool $disable Whether to disable the preload of Google Fonts.
*
* @return bool
*/
public function disable_google_fonts_preload( $disable ): bool {
if ( ! $this->context->is_allowed() ) {
return $disable;
}

return true;
}
}
57 changes: 57 additions & 0 deletions inc/Engine/Media/Fonts/Frontend/Subscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts\Frontend;

use WP_Rocket\Event_Management\Subscriber_Interface;

class Subscriber implements Subscriber_Interface {
/**
* Frontend Controller instance.
*
* @var Controller
*/
private $frontend_controller;

/**
* Constructor.
*
* @param Controller $frontend_controller Frontend Controller instance.
*/
public function __construct( Controller $frontend_controller ) {
$this->frontend_controller = $frontend_controller;
}

/**
* Returns an array of events that this subscriber wants to listen to.
*
* @return array
*/
public static function get_subscribed_events(): array {
return [
'rocket_buffer' => [ 'rewrite_fonts', 18 ],
'rocket_disable_google_fonts_preload' => 'disable_google_fonts_preload',
];
}

/**
* Rewrites the Google Fonts paths to local ones.
*
* @param string $html HTML content.
* @return string
*/
public function rewrite_fonts( string $html ): string {
return $this->frontend_controller->rewrite_fonts( $html );
}

/**
* Disables the preload of Google Fonts.
*
* @param bool $disable Whether to disable the preload of Google Fonts.
*
* @return bool
*/
public function disable_google_fonts_preload( $disable ): bool {
return $this->frontend_controller->disable_google_fonts_preload( $disable );
}
}
19 changes: 19 additions & 0 deletions inc/Engine/Media/Fonts/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
use WP_Rocket\Dependencies\League\Container\ServiceProvider\AbstractServiceProvider;
use WP_Rocket\Engine\Media\Fonts\Admin\Settings;
use WP_Rocket\Engine\Media\Fonts\Admin\Subscriber as AdminSubscriber;
use WP_Rocket\Engine\Media\Fonts\Context\Context;
use WP_Rocket\Engine\Media\Fonts\Frontend\Controller as FrontendController;
use WP_Rocket\Engine\Media\Fonts\Frontend\Subscriber as FrontendSubscriber;

class ServiceProvider extends AbstractServiceProvider {
/**
Expand All @@ -20,6 +23,9 @@ class ServiceProvider extends AbstractServiceProvider {
protected $provides = [
'media_fonts_settings',
'media_fonts_admin_subscriber',
'media_fonts_context',
'media_fonts_frontend_controller',
'media_fonts_frontend_subscriber',
];

/**
Expand All @@ -42,5 +48,18 @@ public function register(): void {
$this->getContainer()->add( 'media_fonts_settings', Settings::class );
$this->getContainer()->addShared( 'media_fonts_admin_subscriber', AdminSubscriber::class )
->addArgument( 'media_fonts_settings' );

$this->getContainer()->add( 'media_fonts_context', Context::class )
->addArgument( $this->getContainer()->get( 'options' ) );
$this->getContainer()->add( 'media_fonts_frontend_controller', FrontendController::class )
->addArguments(
[
$this->getContainer()->get( 'media_fonts_context' ),
]
);
$this->getContainer()->add( 'media_fonts_frontend_subscriber', FrontendSubscriber::class )
->addArgument(
$this->getContainer()->get( 'media_fonts_frontend_controller' )
);
}
}
14 changes: 14 additions & 0 deletions inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@ protected function get_font_display_value(): string {
* @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(
'<link rel="stylesheet" href="%1$s" />', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
$url
);
}

return sprintf(
'<link rel="preload" data-rocket-preload as="style" href="%1$s" /><link rel="stylesheet" href="%1$s" media="print" onload="this.media=\'all\'" /><noscript><link rel="stylesheet" href="%1$s" /></noscript>', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
$url
Expand Down
2 changes: 1 addition & 1 deletion inc/Engine/Optimization/GoogleFonts/Subscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function __construct( AbstractGFOptimization $combine, AbstractGFOptimiza
public static function get_subscribed_events() {
return [
'wp_resource_hints' => [ 'preconnect', 10, 2 ],
'rocket_buffer' => [ 'process', 1001 ],
'rocket_buffer' => [ 'process', 17 ],
];
}

Expand Down
1 change: 1 addition & 0 deletions inc/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ private function init_common_subscribers() {
'performance_hints_admin_subscriber',
'lrc_frontend_subscriber',
'taxonomy_subscriber',
'media_fonts_frontend_subscriber',
'media_fonts_admin_subscriber',
];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

return [
'testShouldReturnFalseWhenBypass' => [
'config' => [
'bypass' => true,
'do_not_optimize' => false,
'option' => true,
],
'expected' => false,
],
'testShouldReturnFalseWhenDoNotOptimize' => [
'config' => [
'bypass' => false,
'do_not_optimize' => true,
'option' => true,
],
'expected' => false,
],
'testShouldReturnFalseWhenOptionDisabled' => [
'config' => [
'bypass' => false,
'do_not_optimize' => true,
'option' => false,
],
'expected' => false,
],
'testShouldReturnTrueWhenOptionEnabled' => [
'config' => [
'bypass' => false,
'do_not_optimize' => false,
'option' => true,
],
'expected' => true,
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Template Name: Google Font V1 Template
*/ ?>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Google Font V1 Template</title>
<link rel="stylesheet" href="http://example.org/wp-content/cache/fonts/1/e/b/c/173c0fc97eef86a6e51ada56c5a9a.css" data-wpr-hosted-gf-parameters="family=Roboto"/>
<link rel="stylesheet" href="http://example.org/wp-content/cache/fonts/1/5/9/5/cb6ccb56826a802ed411cef875f0e.css" data-wpr-hosted-gf-parameters="family=Open+Sans"/>
<style>
.roboto-font {
font-family: 'Roboto', sans-serif;
}
.open-sans-font {
font-family: 'Open Sans', sans-serif;
}
</style>
</head>
<body>
<div class="wrap">
<div id="primary" class="content-area">
<main id="main" class="site-main">
<h1 class="roboto-font">Hello World</h1>
<p class="open-sans-font">Welcome to the world</p>
</main><!-- #main -->
</div><!-- #primary -->
</div><!-- .wrap -->
</body>
</html>
Loading
Loading