-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Font Library #5285
Font Library #5285
Changes from all commits
9a00814
6f9aefc
d78d99b
1d74144
42eeb48
9e06a93
b323b67
715eea9
e54426a
1078767
699f45b
a6dca33
9ba9187
5084180
46a1e9f
7e666e6
e6cce43
673c042
72bbec5
1d8de84
d769cc5
c4a31d2
57f05a1
8933cb8
9aeb0ba
1725825
d4bce59
89e888f
ab70608
739edeb
534264e
c2d38d6
2a715cd
6bf7be3
bbb09e9
654dd1d
635d870
8714206
2e08b53
8c5ddec
ae15e18
04fe719
839ff70
5116443
d89e201
e4b2a85
8e3e711
947e2cb
88ec9b7
3e63080
e218ec8
02d6767
641e9f3
5178b1e
4612703
f69e6e5
17c9fd3
3021090
db11c1f
31af894
21e3d33
9aa43bf
f38bb59
b005321
2b29de4
aaf3741
d6534cc
3b01b46
f16ead0
30369c6
e1f0b58
aec6c93
b34fe52
e948c1b
0926426
11b26db
feb1199
a776cee
909da30
fd706d1
7081941
b49da9a
2d369aa
86dab9e
b167d7f
1c23f09
4f7fd91
14ca3bd
8d9f496
1243b31
c5c6ec4
f398761
d85e545
07d01ff
ec52113
3967726
a19ac36
05d3ff7
963d226
e28134f
b2a96fc
640159e
d44da25
603ee9e
7382406
d9ffea9
9edfb39
c4de43f
9deeb4a
6c9e856
89cd000
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
/** | ||
* Font Collection class. | ||
* | ||
* This file contains the Font Collection class definition. | ||
* | ||
* @package WordPress | ||
* @subpackage Fonts | ||
* @since 6.4.0 | ||
*/ | ||
|
||
/** | ||
* Font Collection class. | ||
* | ||
* @since 6.4.0 | ||
*/ | ||
class WP_Font_Collection { | ||
|
||
/** | ||
* Font collection configuration. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @var array | ||
*/ | ||
private $config = array(); | ||
|
||
/** | ||
* WP_Font_Collection constructor. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @param array $config Font collection config options. | ||
* See {@see wp_register_font_collection()} for the supported fields. | ||
* @throws Exception If the required parameters are missing. | ||
*/ | ||
public function __construct( $config ) { | ||
if ( empty( $config ) || ! is_array( $config ) ) { | ||
throw new Exception( 'Font Collection config options is required as a non-empty array.' ); | ||
} | ||
|
||
if ( empty( $config['id'] ) || ! is_string( $config['id'] ) ) { | ||
throw new Exception( 'Font Collection config ID is required as a non-empty string.' ); | ||
} | ||
|
||
if ( empty( $config['name'] ) || ! is_string( $config['name'] ) ) { | ||
throw new Exception( 'Font Collection config name is required as a non-empty string.' ); | ||
} | ||
|
||
if ( empty( $config['src'] ) || ! is_string( $config['src'] ) ) { | ||
throw new Exception( 'Font Collection config "src" option is required as a non-empty string.' ); | ||
} | ||
|
||
$this->config = $config; | ||
} | ||
|
||
/** | ||
* Gets the font collection config. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @return array An array containing the font collection config. | ||
*/ | ||
public function get_config() { | ||
return $this->config; | ||
} | ||
|
||
/** | ||
* Gets the font collection data. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @return array|WP_Error An array containing the list of font families in theme.json format on success, | ||
* else an instance of WP_Error on failure. | ||
*/ | ||
public function get_data() { | ||
// If the src is a URL, fetch the data from the URL. | ||
if ( str_contains( $this->config['src'], 'http' ) && str_contains( $this->config['src'], '://' ) ) { | ||
if ( ! wp_http_validate_url( $this->config['src'] ) ) { | ||
return new WP_Error( 'font_collection_read_error', __( 'Invalid URL for font collection data.' ) ); | ||
} | ||
|
||
$response = wp_remote_get( $this->config['src'] ); | ||
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { | ||
return new WP_Error( 'font_collection_read_error', __( 'Error fetching the font collection data from a URL.' ) ); | ||
} | ||
|
||
$data = json_decode( wp_remote_retrieve_body( $response ), true ); | ||
if ( empty( $data ) ) { | ||
return new WP_Error( 'font_collection_read_error', __( 'Error decoding the font collection data from the REST response JSON.' ) ); | ||
} | ||
// If the src is a file path, read the data from the file. | ||
} else { | ||
if ( ! file_exists( $this->config['src'] ) ) { | ||
return new WP_Error( 'font_collection_read_error', __( 'Font collection data JSON file does not exist.' ) ); | ||
} | ||
$data = wp_json_file_decode( $this->config['src'], array( 'associative' => true ) ); | ||
if ( empty( $data ) ) { | ||
return new WP_Error( 'font_collection_read_error', __( 'Error reading the font collection data JSON file contents.' ) ); | ||
} | ||
} | ||
|
||
$collection_data = $this->get_config(); | ||
$collection_data['data'] = $data; | ||
unset( $collection_data['src'] ); | ||
|
||
return $collection_data; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
/** | ||
* Font Family Utils class. | ||
* | ||
* This file contains utils for Font Family class. | ||
* | ||
* @package WordPress | ||
* @subpackage Fonts | ||
* @since 6.4.0 | ||
*/ | ||
|
||
/** | ||
* A class of utilities for working with the Font Library. | ||
* | ||
* @since 6.4.0 | ||
*/ | ||
class WP_Font_Family_Utils { | ||
|
||
/** | ||
* Generates a filename for a font face asset. | ||
* | ||
* Creates a filename for a font face asset using font family, style, weight and | ||
* extension information. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @param string $font_slug The font slug to use in the filename. | ||
* @param array $font_face The font face array containing 'fontFamily', 'fontStyle', and | ||
* 'fontWeight' attributes. | ||
* @param string $url The URL of the font face asset, used to derive the file extension. | ||
* @param string $suffix Optional. The suffix added to the resulting filename. Default empty string. | ||
* @return string The generated filename for the font face asset. | ||
*/ | ||
public static function get_filename_from_font_face( $font_slug, $font_face, $url, $suffix = '' ) { | ||
$extension = pathinfo( $url, PATHINFO_EXTENSION ); | ||
$filename = "{$font_slug}_{$font_face['fontStyle']}_{$font_face['fontWeight']}"; | ||
if ( '' !== $suffix ) { | ||
$filename .= "_{$suffix}"; | ||
} | ||
|
||
return sanitize_file_name( "{$filename}.{$extension}" ); | ||
} | ||
|
||
/** | ||
* Merges two fonts and their font faces. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @param array $font1 The first font to merge. | ||
* @param array $font2 The second font to merge. | ||
* @return array|WP_Error The merged font or WP_Error if the fonts have different slugs. | ||
*/ | ||
public static function merge_fonts_data( $font1, $font2 ) { | ||
if ( $font1['slug'] !== $font2['slug'] ) { | ||
return new WP_Error( | ||
'fonts_must_have_same_slug', | ||
__( 'Fonts must have the same slug to be merged.' ) | ||
); | ||
} | ||
|
||
$font_faces_1 = isset( $font1['fontFace'] ) ? $font1['fontFace'] : array(); | ||
$font_faces_2 = isset( $font2['fontFace'] ) ? $font2['fontFace'] : array(); | ||
$merged_font_faces = array_merge( $font_faces_1, $font_faces_2 ); | ||
|
||
$serialized_faces = array_map( 'serialize', $merged_font_faces ); | ||
$unique_serialized_faces = array_unique( $serialized_faces ); | ||
$unique_faces = array_map( 'unserialize', $unique_serialized_faces ); | ||
Comment on lines
+65
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seralization can be expensive compute wise. Was json_decode considered? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, this looks like a very JS-esque kinda way to make an array unique. Nested foreach loops or something would be more performant. Or if fonts are actual class instances instead of arrays, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is JSON data, just serializing like this is incorrect since it doesn't follow JSON semantics regarding key order. We have Is this function called in a hot-path? I.e. does it happen on most page loads? Or is this something called during the ingestion(?) of a font, i.e. once. If it is in a hot-path I agree this should be done more performantly. If this only happens during the initial download, then I think serializing is fine, that's how we validate uniqueness in the REST API, see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is called only when a new font is installed and NOT on every page load. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see no references to https://github.com/WordPress/gutenberg/tree/trunk/lib/compat/wordpress-6.5/fonts Some "merging" happens here but the code has evolved significantly. |
||
|
||
$merged_font = array_merge( $font1, $font2 ); | ||
$merged_font['fontFace'] = array_values( $unique_faces ); | ||
|
||
return $merged_font; | ||
} | ||
|
||
/** | ||
* Returns whether the given file has a font MIME type. | ||
* | ||
* @since 6.4.0 | ||
* | ||
* @param string $filepath The file to check. | ||
* @return bool True if the file has a font MIME type, false otherwise. | ||
*/ | ||
public static function has_font_mime_type( $filepath ) { | ||
$allowed_mime_types = WP_Font_Library::get_font_mime_types(); | ||
$filetype = wp_check_filetype( $filepath, $allowed_mime_types ); | ||
|
||
return in_array( $filetype['type'], $allowed_mime_types, true ); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how do a unregister a font collection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not currently possible but that work is already started: WordPress/gutenberg#54701
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is now covered by
https://github.com/WordPress/gutenberg/blob/066f8777b113ca8a71c79deb052d1deb23fe9860/lib/compat/wordpress-6.5/fonts/fonts.php#L147-L149