-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Co-authored-by: Rémy Perona <remperona@gmail.com> Co-authored-by: Opeyemi Ibrahim <opeyemi.khadri@gmail.com> Co-authored-by: Michael Lee <michaelleemichaellee408@gmail.com>
- Loading branch information
1 parent
c3c6cc3
commit 061f8b6
Showing
18 changed files
with
579 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
<?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 | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?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 ], | ||
]; | ||
} | ||
|
||
/** | ||
* 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 ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
tests/Fixtures/inc/Engine/Media/Fonts/Context/Context/isAllowed.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
], | ||
]; |
33 changes: 33 additions & 0 deletions
33
tests/Fixtures/inc/Engine/Media/Fonts/Frontend/Controller/HTML/expected_v1.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
41 changes: 41 additions & 0 deletions
41
tests/Fixtures/inc/Engine/Media/Fonts/Frontend/Controller/HTML/expected_v1_v2.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
/** | ||
* Template Name: Google Font V1 and V2 Template | ||
*/ ?> | ||
|
||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Google Font V1 and V2 Template</title> | ||
<link rel="stylesheet" href="http://example.org/wp-content/cache/fonts/1/6/2/4/f2c2b9858423d0688793189f6e6cb.css" data-wpr-hosted-gf-parameters="family=Roboto|Open+Sans"/> <!-- V1 Fonts --> | ||
<link rel="stylesheet" href="http://example.org/wp-content/cache/fonts/1/8/d/4/e42f26da0305c49cd3264956d8329.css" data-wpr-hosted-gf-parameters="family=Lato:wght@400;700&family=Montserrat:wght@400;700&display=swap"/> <!-- V2 Fonts --> | ||
<style> | ||
.v1-font-roboto { | ||
font-family: 'Roboto', sans-serif; | ||
} | ||
.v1-font-open-sans { | ||
font-family: 'Open Sans', sans-serif; | ||
} | ||
.v2-font-lato { | ||
font-family: 'Lato', sans-serif; | ||
} | ||
.v2-font-montserrat { | ||
font-family: 'Montserrat', sans-serif; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="wrap"> | ||
<div id="primary" class="content-area"> | ||
<main id="main" class="site-main"> | ||
<h1 class="v1-font-roboto">Hello World</h1> | ||
<p class="v1-font-open-sans">Welcome to the world</p> | ||
<h2 class="v2-font-lato">This is a subtitle</h2> | ||
<p class="v2-font-montserrat">Enjoy your stay</p> | ||
</main><!-- #main --> | ||
</div><!-- #primary --> | ||
</div><!-- .wrap --> | ||
</body> | ||
</html> |
33 changes: 33 additions & 0 deletions
33
tests/Fixtures/inc/Engine/Media/Fonts/Frontend/Controller/HTML/expected_v2.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
/** | ||
* Template Name: Google Font V2 Template | ||
*/ ?> | ||
|
||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Google Font V2 Template</title> | ||
<link rel="stylesheet" href="http://example.org/wp-content/cache/fonts/1/a/b/2/8ffb4f83584e9add1be594dd90dfd.css" data-wpr-hosted-gf-parameters="family=Roboto:wght@400;700&display=swap"/> | ||
<link rel="stylesheet" href="http://example.org/wp-content/cache/fonts/1/b/4/d/9ffca0114d3acb6ab0b068feaf933.css" data-wpr-hosted-gf-parameters="family=Lato:wght@400;700&display=swap"/> | ||
<style> | ||
.roboto-font { | ||
font-family: 'Roboto', sans-serif; | ||
} | ||
.lato-font { | ||
font-family: 'Lato', 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="lato-font">Welcome to the world</p> | ||
</main><!-- #main --> | ||
</div><!-- #primary --> | ||
</div><!-- .wrap --> | ||
</body> | ||
</html> |
Oops, something went wrong.