Rename font assets when theme is saved and/or exported (#712)

* Rename font asset files when theme is saved or exported

* add and update tests

* test

* use sub-directories for each font family
This commit is contained in:
Matias Benedetto 2024-09-05 10:22:01 -03:00 committed by GitHub
parent 6973cf8690
commit 4911a06cfb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 419 additions and 320 deletions

634
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -84,6 +84,34 @@ class CBT_Theme_Fonts {
return $user_settings['typography']['fontFamilies']['custom'] ?? null;
}
/**
* Make a pretty filename from a font face.
*
* The filename is based on the font family name, weight, style, unicode range and the source index.
* Example:
* $font_face = [ 'fontFamily' => 'Open Sans', 'fontWeight' => '400', 'fontStyle' => 'normal' ]
* $src = 'https://example.com/assets/fonts/open-sans-regular.ttf'
* $src_index = 0
* Returns: 'open-sans-400-normal.ttf'
*
* @param array $font_face
* @param string $src
* @param int $src_index
* @return string
*/
public static function make_filename_from_fontface( $font_face, $src, $src_index = 0 ) {
$font_extension = pathinfo( $src, PATHINFO_EXTENSION );
$font_filename = sanitize_title( $font_face['fontFamily'] )
. ( isset( $font_face['fontWeight'] ) ? '-' . sanitize_title( $font_face['fontWeight'] ) : '' )
. ( isset( $font_face['fontStyle'] ) ? '-' . sanitize_title( $font_face['fontStyle'] ) : '' )
. ( isset( $font_face['unicodeRange'] ) ? '-' . sanitize_title( $font_face['unicodeRange'] ) : '' )
. ( 0 !== $src_index ? '-' . $src_index : '' )
. '.'
. $font_extension;
return $font_filename;
}
public static function copy_activated_fonts_to_theme() {
$font_families_to_copy = self::get_user_activated_fonts();
@ -92,34 +120,40 @@ class CBT_Theme_Fonts {
}
$theme_json = CBT_Theme_JSON_Resolver::get_theme_file_contents();
$theme_font_asset_location = get_stylesheet_directory() . '/assets/fonts/';
require_once ABSPATH . 'wp-admin/includes/file.php';
if ( ! file_exists( $theme_font_asset_location ) ) {
mkdir( $theme_font_asset_location, 0777, true );
}
$theme_font_asset_location = path_join( get_stylesheet_directory(), 'assets/fonts/' );
// Create the font asset directory if it does not exist.
wp_mkdir_p( $theme_font_asset_location );
foreach ( $font_families_to_copy as &$font_family ) {
if ( ! isset( $font_family['fontFace'] ) ) {
continue;
}
$font_family_dir_name = sanitize_title( $font_family['name'] );
$font_family_dir_path = path_join( $theme_font_asset_location, $font_family_dir_name );
// Crete a font family specific directory if it does not exist.
wp_mkdir_p( $font_family_dir_path );
foreach ( $font_family['fontFace'] as &$font_face ) {
// src can be a string or an array
// if it is a string, cast it to an array
$font_face['src'] = (array) $font_face['src'];
foreach ( $font_face['src'] as $font_src_index => &$font_src ) {
$font_filename = basename( $font_src );
$font_dir = wp_get_font_dir();
$font_filename = basename( $font_src );
$font_pretty_filename = self::make_filename_from_fontface( $font_face, $font_src, $font_src_index );
$font_face_path = path_join( $font_family_dir_path, $font_pretty_filename );
$font_dir = wp_get_font_dir();
if ( str_contains( $font_src, $font_dir['url'] ) ) {
// If the file is hosted on this server then copy it to the theme
copy( $font_dir['path'] . '/' . $font_filename, $theme_font_asset_location . '/' . $font_filename );
copy( path_join( $font_dir['path'], $font_filename ), $font_face_path );
} else {
// otherwise download it from wherever it is hosted
$tmp_file = download_url( $font_src );
copy( $tmp_file, $theme_font_asset_location . $font_filename );
copy( $tmp_file, $font_face_path );
unlink( $tmp_file );
}
$font_face['src'][ $font_src_index ] = 'file:./assets/fonts/' . $font_filename;
$font_face_family_path = path_join( $font_family_dir_name, $font_pretty_filename );
$font_face['src'][ $font_src_index ] = path_join( 'file:./assets/fonts/', $font_face_family_path );
}
}
}

View file

@ -47,19 +47,27 @@ class CBT_Theme_Zip {
}
$font_slugs_to_remove[] = $font_family['slug'];
foreach ( $font_family['fontFace'] as &$font_face ) {
$font_filename = basename( $font_face['src'] );
$font_dir = wp_get_font_dir();
$font_face_path = path_join( $theme_font_asset_location, $font_filename );
if ( str_contains( $font_face['src'], $font_dir['url'] ) ) {
$zip->addFileToTheme( path_join( $font_dir['path'], $font_filename ), $font_face_path );
} else {
// otherwise download it from wherever it is hosted
$tmp_file = download_url( $font_face['src'] );
$zip->addFileToTheme( $tmp_file, $font_face_path );
unlink( $tmp_file );
}
$font_filename = basename( $font_face['src'] );
$font_dir = wp_get_font_dir();
$font_face['src'] = (array) $font_face['src'];
foreach ( $font_face['src'] as $font_src_index => &$font_src ) {
$font_filename = basename( $font_src );
$font_pretty_filename = CBT_Theme_Fonts::make_filename_from_fontface( $font_face, $font_src, $font_src_index );
$font_family_dir_name = sanitize_title( $font_family['name'] );
$font_family_dir_path = path_join( $theme_font_asset_location, $font_family_dir_name );
$font_face_path = path_join( $font_family_dir_path, $font_pretty_filename );
$font_face['src'] = 'file:./assets/fonts/' . $font_filename;
$font_dir = wp_get_font_dir();
if ( str_contains( $font_src, $font_dir['url'] ) ) {
$zip->addFileToTheme( path_join( $font_dir['path'], $font_filename ), $font_face_path );
} else {
// otherwise download it from wherever it is hosted
$tmp_file = download_url( $font_face['src'] );
$zip->addFileToTheme( $tmp_file, $font_face_path );
unlink( $tmp_file );
}
$font_face['src'][ $font_src_index ] = 'file:./assets/fonts/' . path_join( $font_family_dir_name, $font_pretty_filename );
}
}
}

View file

@ -51,8 +51,8 @@ class Test_Create_Block_Theme_Fonts extends WP_UnitTestCase {
$this->assertEquals( 'open-sans', $theme_data_after['typography']['fontFamilies']['theme'][1]['slug'] );
// Ensure that the URL was changed to a local file and that it was copied to where it should be
$this->assertEquals( 'file:./assets/fonts/open-sans-normal-400.ttf', $theme_data_after['typography']['fontFamilies']['theme'][1]['fontFace'][0]['src'][0] );
$this->assertTrue( file_exists( get_stylesheet_directory() . '/assets/fonts/open-sans-normal-400.ttf' ) );
$this->assertEquals( 'file:./assets/fonts/open-sans/open-sans-400-normal.ttf', $theme_data_after['typography']['fontFamilies']['theme'][1]['fontFace'][0]['src'][0] );
$this->assertTrue( file_exists( get_stylesheet_directory() . '/assets/fonts/open-sans/open-sans-400-normal.ttf' ) );
$this->uninstall_theme( $test_theme_slug );
@ -486,5 +486,18 @@ class Test_Create_Block_Theme_Fonts extends WP_UnitTestCase {
CBT_Theme_JSON_Resolver::write_user_settings( $settings );
}
public function test_make_filename_from_fontface() {
$font_face = array(
'fontFamily' => 'Open Sans',
'fontWeight' => '400',
'fontStyle' => 'normal',
'unicodeRange' => 'U+0000-00FF',
);
$src = 'https://example.com/assets/fonts/open-sans-regular.ttf';
$src_index = 0;
$expected = 'open-sans-400-normal-u0000-00ff.ttf';
$actual = CBT_Theme_Fonts::make_filename_from_fontface( $font_face, $src, $src_index );
$this->assertEquals( $expected, $actual );
}
}