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 #7062 Fonts filesystem #7083

Merged
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
308d5f5
:chore: Add filesystem #7062
Khadreal Oct 31, 2024
cedbd31
:chore: Fixed font saving issue in local directory
Khadreal Oct 31, 2024
dc911c6
:chore: Add service provider, fix rewrite issue with font filepath, a…
Khadreal Nov 1, 2024
e74f03d
Modify cache font path
Khadreal Nov 1, 2024
9f5690d
Add initial test
Khadreal Nov 1, 2024
d65847c
Add google font providers, subscribers
Khadreal Nov 4, 2024
0f09562
Refactor font saving process, delete unused class and methods #7062
Khadreal Nov 4, 2024
670ab89
:broom: cleanup code, fix lint errors
Khadreal Nov 4, 2024
d6f493e
add version of font as part of the file directory
Khadreal Nov 4, 2024
18a0513
Add download for google font version 1
Khadreal Nov 4, 2024
bf73446
Removed filter from external class, pr reviews
Khadreal Nov 6, 2024
f252e6f
create an abstract class for filesystem
Khadreal Nov 6, 2024
d52d732
Fix lint, change file path
Khadreal Nov 6, 2024
c36857f
Change hash url value
Khadreal Nov 8, 2024
83ff00a
Merge feature branch and fixed conflict
Khadreal Nov 11, 2024
71d1299
add logger for fonts process
Khadreal Nov 11, 2024
665fdc5
Add test for write_css method
Khadreal Nov 12, 2024
94603f4
Fixed test error for lower php version
Khadreal Nov 13, 2024
3ae1412
Fixed test
Khadreal Nov 13, 2024
57e211d
fix conflict
Khadreal Nov 14, 2024
ac35c24
fix lint error
Khadreal Nov 14, 2024
d862d23
Review modifications
Khadreal Nov 14, 2024
0c9004c
Changed method name
Khadreal Nov 14, 2024
f5fded4
Remove unused method
Khadreal Nov 14, 2024
670847b
rename method in abstract class
Khadreal Nov 14, 2024
8147c3a
Add download to the fontend process
Khadreal Nov 14, 2024
b55ea83
fix linter
Khadreal Nov 14, 2024
60be49e
:sparkles: Review modifications
Khadreal Nov 15, 2024
fa775cb
fixed test error
Khadreal Nov 15, 2024
80688cb
Update test, modify serviceprovider for media fonts
Khadreal Nov 15, 2024
db12b1d
Remove spacing
Khadreal Nov 15, 2024
fa21618
Fixed font path
Khadreal Nov 15, 2024
a86be50
Remove version from font path and update test
Khadreal Nov 15, 2024
6c97b7a
Fixed filepath and test issue
Khadreal Nov 15, 2024
7148673
fixed test
Khadreal Nov 15, 2024
3980356
add hash_to_path to abstract class
remyperona Nov 15, 2024
f31abb8
move filesystem class
remyperona Nov 15, 2024
ddc37de
remove file
remyperona Nov 15, 2024
99fc327
code improvements
remyperona Nov 15, 2024
7a1b41b
remove typehint
remyperona Nov 15, 2024
c985d7a
update instantiation
remyperona Nov 15, 2024
2a90b02
remove method moved to parent
remyperona Nov 15, 2024
b911c8c
update tests
remyperona Nov 15, 2024
a404fd2
update fixture
remyperona Nov 15, 2024
84c29d3
Merge branch 'feature/host-google-fonts' into sub-task/3.18-backend-f…
remyperona Nov 15, 2024
fe13945
preserve resource hints if error during replace
remyperona Nov 15, 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
217 changes: 217 additions & 0 deletions inc/Engine/Media/Fonts/Controller/Filesystem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?php

declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts\Controller;

class Filesystem {
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
/**
* WP Filesystem instance
*
* @var WP_Filesystem_Direct
*/
private $filesystem;

Check failure on line 13 in inc/Engine/Media/Fonts/Controller/Filesystem.php

View workflow job for this annotation

GitHub Actions / WPRocket lint with PHP Stan. PHP 8.2 on ubuntu-latest.

Property WP_Rocket\Engine\Media\Fonts\Controller\Filesystem::$filesystem has unknown class WP_Rocket\Engine\Media\Fonts\Controller\WP_Filesystem_Direct as its type.

/**
* Path to the fonts storage
*
* @var string
*/
private $path;

/**
* Version of the fonts.
*
* @var int
*/
private $version;

/**
* Instantiate the class
*
* @param string $base_path Base path to the fonts storage.
* @param WP_Filesystem_Direct $filesystem WP Filesystem instance.
*/
public function __construct( $base_path, $filesystem = null ) {

Check failure on line 35 in inc/Engine/Media/Fonts/Controller/Filesystem.php

View workflow job for this annotation

GitHub Actions / WPRocket lint with PHP Stan. PHP 8.2 on ubuntu-latest.

Parameter $filesystem of method WP_Rocket\Engine\Media\Fonts\Controller\Filesystem::__construct() has invalid type WP_Rocket\Engine\Media\Fonts\Controller\WP_Filesystem_Direct.
$this->filesystem = is_null( $filesystem ) ? rocket_direct_filesystem() : $filesystem;
$this->path = $base_path . get_current_blog_id() . '/';
}

/**
* Hash the url
*
* @param string $url Url of the page to hash.
*
* @return string
*/
private function hash_url( string $url ): string {
return md5( $url );
}

/**
* Write font css to path
*
* @param string $font_url The font url to save locally.
* @param string $provider The url of the page.
*
* @return bool
*/
public function write_font_css( string $font_url, string $provider ): bool {
global $wp;
$url = untrailingslashit( home_url( add_query_arg( [], $wp->request ) ) );

$font_provider_path = $this->get_font_provider_path( $provider );
$hash_url = $this->hash_url( $url );
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
$file = $this->get_fonts_full_path( $font_provider_path, $hash_url );
$css_file_name = $file . $hash_url . '.css';
$relative_path = $this->get_fonts_relative_path( $font_provider_path, $hash_url );

if ( ! rocket_mkdir_p( dirname( $file ) ) ) {
return false;
}

$css_content = $this->download_font( html_entity_decode( $font_url ) );

if ( ! $css_content ) {
return false;
}

preg_match_all( '/url\((https:\/\/[^)]+)\)/', $css_content, $matches );
$font_urls = $matches[1];
$local_css = $css_content;

foreach ( $font_urls as $font_url ) {
$parsed_url = wp_parse_url( $font_url );
$path_parts = explode( '/', trim( $parsed_url['path'], '/' ) );
$local_path = $file . implode( '/', $path_parts );
$local_dir = dirname( $local_path );

rocket_mkdir_p( $local_dir );

if ( ! file_exists( $local_path ) ) {
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
$font_content = $this->download_font( $font_url );

if ( ! $font_content ) {
continue;
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
}

$this->filesystem->put_contents( $local_path, $font_content, rocket_get_filesystem_perms( 'file' ) );

Check failure on line 98 in inc/Engine/Media/Fonts/Controller/Filesystem.php

View workflow job for this annotation

GitHub Actions / WPRocket lint with PHP Stan. PHP 8.2 on ubuntu-latest.

Call to method put_contents() on an unknown class WP_Rocket\Engine\Media\Fonts\Controller\WP_Filesystem_Direct.
}

$local_url = content_url( $relative_path . implode( '/', $path_parts ) );
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
$local_css = str_replace( $font_url, $local_url, $local_css );
}

return $this->filesystem->put_contents( $css_file_name, $local_css, rocket_get_filesystem_perms( 'file' ) );

Check failure on line 105 in inc/Engine/Media/Fonts/Controller/Filesystem.php

View workflow job for this annotation

GitHub Actions / WPRocket lint with PHP Stan. PHP 8.2 on ubuntu-latest.

Call to method put_contents() on an unknown class WP_Rocket\Engine\Media\Fonts\Controller\WP_Filesystem_Direct.
}

/**
* Download font from external url
*
* @param string $url Url of the file to download.
*
* @return bool|string
*/
private function download_font( string $url ): bool|string {
$content = wp_remote_retrieve_body(
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
wp_remote_get(
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
$url,
[
'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'httpversion' => '2.0',
]
)
);

if ( ! $content ) {
return false;
}

return $content;
}

/**
* Get the fonts path for the css file.
*
* @param string $provider Font provider.
* @param string $hash_url Url of the page.
*
* @return string Path for the font file.
*/
private function get_fonts_full_path( string $provider, string $hash_url ): string {
$font_provider_path = $this->get_font_provider_path( $provider );

return $this->path . $font_provider_path . $hash_url . '/' . $this->get_version() . '/';
}


/**
* Get the fonts relative paths
*
* @param string $font_provider_path Font provider path.
* @param string $hash_url Url of the page.
*
* @return string
*/
private function get_fonts_relative_path( string $font_provider_path, string $hash_url, ): string {
$full_path = $this->path . $font_provider_path;
$relative_path = str_replace( WP_CONTENT_DIR, '', $full_path );

return $relative_path . $hash_url . '/' . $this->get_version() . '/';
}

/**
* Get the fonts provider path
*
* @param string $provider The font provider.
*
* @return string
*/
private function get_font_provider_path( string $provider ): string {
$provider = str_replace( '_', '-', $provider );

return $provider . '/';
}

/**
* Deletes the locally stored fonts for the corresponding url
*
* @since 3.11.4
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
*
* @param string $url The url of the page to be deleted.
*
* @return bool
*/
public function delete_font_css( string $url ): bool {
$dir = $this->get_fonts_full_path( $this->get_font_provider_path( $url ), $url );

return $this->filesystem->delete( $dir, true, 'd' );

Check failure on line 188 in inc/Engine/Media/Fonts/Controller/Filesystem.php

View workflow job for this annotation

GitHub Actions / WPRocket lint with PHP Stan. PHP 8.2 on ubuntu-latest.

Call to method delete() on an unknown class WP_Rocket\Engine\Media\Fonts\Controller\WP_Filesystem_Direct.
}

/**
* Deletes all the font CSS files
*/
public function delete_all_font_css() {
// TODO:create method to recursively delete all locally stored fonts.
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Set the version of the fonts
*
* @param int $version The version of the font.
*
* @return void
*/
public function set_version( int $version ): void {
$this->version = $version;
}

/**
* Get the font version
*
* @return int
*/
public function get_version(): int {
return $this->version;
}
}
58 changes: 58 additions & 0 deletions inc/Engine/Media/Fonts/Controller/Fonts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts\Controller;

use WP_Rocket\Admin\Options_Data;
use WP_Rocket\Engine\Optimization\RegexTrait;

class Fonts {
use RegexTrait;

/**
* Filesystem instance.
*
* @var Filesystem
*/
private $filesystem;

/**
* Instance of options handler.
*
* @var Options_Data
*/
private $options;

/**
* Instantiate the class.
*
* @param Filesystem $filesystem Filesystem Instance.
* @param Options_Data $options Options instance.
*/
public function __construct(
Filesystem $filesystem,
Options_Data $options
) {
$this->filesystem = $filesystem;
$this->options = $options;
}

/**
* Start the process of downloading font locally
*
* @param string $font_url URL of the font to be saved locally.
* @param string $provider Provider of the font.
* @param integer $version Version.
*
* @return void
*/
public function process( string $font_url, string $provider, int $version ): void {
jeawhanlee marked this conversation as resolved.
Show resolved Hide resolved
if ( ! $this->options->get( 'host_google_fonts' ) ) {
return;
}

$this->filesystem->set_version( $version );

$this->filesystem->write_font_css( $font_url, $provider );
}
}
51 changes: 51 additions & 0 deletions inc/Engine/Media/Fonts/Frontend/Subscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts\Frontend;

use WP_Rocket\Engine\Media\Fonts\Controller\Fonts;
use WP_Rocket\Event_Management\Subscriber_Interface;

class Subscriber implements Subscriber_Interface {
/**
* Fonts instance
*
* @var Fonts
*/
private $fonts;

/**
* Instantiate the class
*
* @param Fonts $fonts Fonts instance.
*/
public function __construct( Fonts $fonts ) {
$this->fonts = $fonts;
}

/**
* Return an array of events that this subscriber wants to listen to.
*
* @since 3.18
*
* @return array
*/
public static function get_subscribed_events() {
return [
'rocket_host_google_fonts' => [ 'process', 15, 3 ],
];
}

/**
* Save Fonts locally
*
* @param string $font_url The url of the font.
* @param string $provider The font provider.
* @param integer $version The version of the font.
*
* @return void
*/
public function process( string $font_url, string $provider, int $version ): void {
$this->fonts->process( $font_url, $provider, $version );
}
}
54 changes: 54 additions & 0 deletions inc/Engine/Media/Fonts/ServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace WP_Rocket\Engine\Media\Fonts;

use WP_Rocket\Dependencies\League\Container\ServiceProvider\AbstractServiceProvider;
use WP_Rocket\Engine\Media\Fonts\Frontend\Subscriber as FrontendSubscriber;
use WP_Rocket\Engine\Media\Fonts\Controller\Fonts as FontsController;
use WP_Rocket\Engine\Media\Fonts\Controller\Filesystem;

/**
* Service provider for the WP Rocket Font Optimization
*/
class ServiceProvider extends AbstractServiceProvider {
/**
* Array of services provided by this service provider
*
* @var array
*/
protected $provides = [
'fonts_frontend_subscriber',
'fonts_filesystem',
];

/**
* Check if the service provider provides a specific service.
*
* @param string $id The id of the service.
*
* @return bool
*/
public function provides( string $id ): bool {
return in_array( $id, $this->provides, true );
}

/**
* Registers the option array in the container
*
* @return void
*/
public function register(): void {
$this->getContainer()->add( 'fonts_filesystem', Filesystem::class )
->addArgument( rocket_get_constant( 'WP_ROCKET_FONT_CSS_PATH' ) )
->addArgument( rocket_direct_filesystem() );

$this->getContainer()->add( 'fonts_controller', FontsController::class )
->addArgument( $this->getContainer()->get( 'fonts_filesystem' ) )
->addArgument( $this->getContainer()->get( 'options' ) );

$this->getContainer()->addShared( 'fonts_frontend_subscriber', FrontendSubscriber::class )
->addArgument( $this->getContainer()->get( 'fonts_controller' ) );
}
}
Loading
Loading