init
This commit is contained in:
+252
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack_Google_Font_Face class
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* Jetpack Google Font Face disables Font Face hooks in Core that prints **ALL** font faces.
|
||||
* Instead, it collects fonts that are used in global styles or block-level settings and
|
||||
* print those fonts in use.
|
||||
*/
|
||||
class Jetpack_Google_Font_Face {
|
||||
/**
|
||||
* The fonts that are used in global styles or block-level settings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $fonts_in_use = array();
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Turns off hooks to print fonts
|
||||
add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
|
||||
add_action( 'current_screen', array( $this, 'current_screen' ), 10 );
|
||||
|
||||
// Collect and print fonts in use
|
||||
if ( wp_is_block_theme() ) {
|
||||
add_action( 'wp_head', array( $this, 'print_font_faces' ), 50 );
|
||||
} else {
|
||||
// In classic themes wp_head runs before the blocks are processed to collect the block fonts.
|
||||
add_action( 'wp_footer', array( $this, 'print_font_faces' ), 50 );
|
||||
}
|
||||
add_filter( 'pre_render_block', array( $this, 'collect_block_fonts' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off hooks to print fonts on frontend
|
||||
*/
|
||||
public function wp_loaded() {
|
||||
remove_action( 'wp_head', 'wp_print_fonts', 50 );
|
||||
remove_action( 'wp_head', 'wp_print_font_faces', 50 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off hooks to print fonts on wp-admin, except for GB editor pages.
|
||||
*/
|
||||
public function current_screen() {
|
||||
remove_action( 'admin_print_styles', 'wp_print_fonts', 50 );
|
||||
|
||||
if ( ! $this->is_block_editor() ) {
|
||||
remove_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print fonts that are used in global styles or block-level settings.
|
||||
*/
|
||||
public function print_font_faces() {
|
||||
$fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
|
||||
$font_slug_aliases = $this->get_font_slug_aliases();
|
||||
$fonts_to_print = array();
|
||||
|
||||
$this->collect_global_styles_fonts();
|
||||
$fonts_in_use = array_values( array_unique( $this->fonts_in_use, SORT_STRING ) );
|
||||
$fonts_in_use = array_map(
|
||||
function ( $font_slug ) use ( $font_slug_aliases ) {
|
||||
return $font_slug_aliases[ $font_slug ] ?? $font_slug;
|
||||
},
|
||||
$this->fonts_in_use
|
||||
);
|
||||
|
||||
foreach ( $fonts as $font_faces ) {
|
||||
$font_family = $font_faces[0]['font-family'] ?? '';
|
||||
if ( in_array( $this->format_font( $font_family ), $fonts_in_use, true ) ) {
|
||||
$fonts_to_print[] = $font_faces;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $fonts_to_print ) ) {
|
||||
wp_print_font_faces( $fonts_to_print );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect fonts used for global styles settings.
|
||||
*/
|
||||
public function collect_global_styles_fonts() {
|
||||
$global_styles = wp_get_global_styles();
|
||||
|
||||
$global_styles_font_slug = $this->get_font_slug_from_setting( $global_styles );
|
||||
if ( $global_styles_font_slug ) {
|
||||
$this->add_font( $global_styles_font_slug );
|
||||
}
|
||||
|
||||
if ( isset( $global_styles['blocks'] ) ) {
|
||||
foreach ( $global_styles['blocks'] as $setting ) {
|
||||
$font_slug = $this->get_font_slug_from_setting( $setting );
|
||||
|
||||
if ( $font_slug ) {
|
||||
$this->add_font( $font_slug );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $global_styles['elements'] ) ) {
|
||||
foreach ( $global_styles['elements'] as $setting ) {
|
||||
$font_slug = $this->get_font_slug_from_setting( $setting );
|
||||
|
||||
if ( $font_slug ) {
|
||||
$this->add_font( $font_slug );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect fonts used for block-level settings.
|
||||
*
|
||||
* @filter pre_render_block
|
||||
*
|
||||
* @param string|null $content The pre-rendered content. Default null.
|
||||
* @param array $parsed_block The block being rendered.
|
||||
*/
|
||||
public function collect_block_fonts( $content, $parsed_block ) {
|
||||
if ( ! is_admin() && isset( $parsed_block['attrs']['fontFamily'] ) ) {
|
||||
$block_font_family = $parsed_block['attrs']['fontFamily'];
|
||||
$this->add_font( $block_font_family );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specify font to the fonts_in_use list.
|
||||
*
|
||||
* @param string $font_slug The font slug.
|
||||
*/
|
||||
public function add_font( $font_slug ) {
|
||||
if ( is_string( $font_slug ) ) {
|
||||
$this->fonts_in_use[] = $this->format_font( $font_slug );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given font slug.
|
||||
*
|
||||
* @example "ABeeZee" formats to "abeezee"
|
||||
* @example "ADLaM Display" formats to "adlam-display"
|
||||
* @param string $font_slug The font slug.
|
||||
* @return string The formatted font slug.
|
||||
*/
|
||||
public function format_font( $font_slug ) {
|
||||
return _wp_to_kebab_case( strtolower( $font_slug ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font slug aliases that maps the font slug to the font family if they are different.
|
||||
*
|
||||
* The font definition may define an alias slug name, so we have to add the map from the slug name to the font family.
|
||||
* See https://github.com/WordPress/twentytwentyfour/blob/df92472089ede6fae5924c124a93c843b84e8cbd/theme.json#L215.
|
||||
*/
|
||||
public function get_font_slug_aliases() {
|
||||
$font_slug_aliases = array();
|
||||
|
||||
$theme_json = WP_Theme_JSON_Resolver::get_theme_data();
|
||||
$raw_data = $theme_json->get_data();
|
||||
if ( ! empty( $raw_data['settings']['typography']['fontFamilies'] ) ) {
|
||||
foreach ( $raw_data['settings']['typography']['fontFamilies'] as $font ) {
|
||||
$font_family_name = $this->format_font( $this->get_font_family_name( $font ) );
|
||||
$font_slug = $font['slug'] ?? '';
|
||||
if ( $font_slug && $font_slug !== $font_family_name && ! array_key_exists( $font_slug, $font_slug_aliases ) ) {
|
||||
$font_slug_aliases[ $font_slug ] = $font_family_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $font_slug_aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font family name from a font.
|
||||
*
|
||||
* @param array $font The font definition object.
|
||||
*/
|
||||
public static function get_font_family_name( $font ) {
|
||||
$font_family = $font['fontFamily'];
|
||||
if ( str_contains( $font_family, ',' ) ) {
|
||||
$font_family = explode( ',', $font_family )[0];
|
||||
}
|
||||
|
||||
return trim( $font_family, "\"'" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font family slug from a settings array.
|
||||
*
|
||||
* @param array $setting The settings object.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_font_slug_from_setting( $setting ) {
|
||||
if ( ! isset( $setting['typography']['fontFamily'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$font_family = $setting['typography']['fontFamily'];
|
||||
|
||||
// The font family may be a reference to a path to the value stored at that location,
|
||||
// e.g.: { "ref": "styles.elements.heading.typography.fontFamily" }.
|
||||
// Ignore it as we also get the value stored at that location from the setting.
|
||||
if ( ! is_string( $font_family ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Full string: var(--wp--preset--font-family--slug).
|
||||
// We do not care about the origin of the font, only its slug.
|
||||
preg_match( '/font-family--(?P<slug>.+)\)$/', $font_family, $matches );
|
||||
|
||||
if ( isset( $matches['slug'] ) ) {
|
||||
return $matches['slug'];
|
||||
}
|
||||
|
||||
// Full string: var:preset|font-family|slug
|
||||
// We do not care about the origin of the font, only its slug.
|
||||
preg_match( '/font-family\|(?P<slug>.+)$/', $font_family, $matches );
|
||||
|
||||
if ( isset( $matches['slug'] ) ) {
|
||||
return $matches['slug'];
|
||||
}
|
||||
|
||||
return $font_family;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current screen is the block editor.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_block_editor() {
|
||||
if ( function_exists( 'get_current_screen' ) ) {
|
||||
$current_screen = get_current_screen();
|
||||
if ( ! empty( $current_screen ) && method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/**
|
||||
* Load the google fonts by the new Font Library. See pNEWy-hhx-p2.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'Jetpack_Google_Font_Face' ) ) {
|
||||
/**
|
||||
* Load Jetpack Google Font Face
|
||||
*/
|
||||
require_once __DIR__ . '/class-jetpack-google-font-face.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Google Fonts data
|
||||
*
|
||||
* @return object[] The collection data of the Google Fonts.
|
||||
*/
|
||||
function jetpack_get_google_fonts_data() {
|
||||
/**
|
||||
* Filters the Google Fonts data before the default retrieval process.
|
||||
*
|
||||
* This filter allows short-circuiting the default Google Fonts data retrieval process.
|
||||
* Returning a non-null value from this filter will bypass the default retrieval
|
||||
* and return the filtered value instead.
|
||||
*
|
||||
* @module google-fonts
|
||||
*
|
||||
* @since 13.7
|
||||
*
|
||||
* @param null|array $pre The pre-filtered Google Fonts data, default null.
|
||||
*/
|
||||
$pre = apply_filters( 'pre_jetpack_get_google_fonts_data', null );
|
||||
if ( null !== $pre ) {
|
||||
return $pre;
|
||||
}
|
||||
|
||||
$default_google_fonts_api_url = 'https://fonts.gstatic.com';
|
||||
$jetpack_google_fonts_collection_url = 'https://s0.wp.com/i/font-collections/jetpack-google-fonts.json';
|
||||
$cache_key = 'jetpack_google_fonts_' . md5( $jetpack_google_fonts_collection_url );
|
||||
$data = get_transient( $cache_key );
|
||||
if ( $data === false ) {
|
||||
$response = wp_remote_get( $jetpack_google_fonts_collection_url );
|
||||
if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
if ( $data === null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
set_transient( $cache_key, $data, DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
// Replace the google fonts api url if the custom one is provided.
|
||||
$custom_google_fonts_api_url = \esc_url(
|
||||
/**
|
||||
* Filters the Google Fonts API URL.
|
||||
*
|
||||
* @module google-fonts
|
||||
*
|
||||
* @since 12.8
|
||||
*
|
||||
* @param string $url The Google Fonts API URL.
|
||||
*/
|
||||
apply_filters( 'jetpack_google_fonts_api_url', $default_google_fonts_api_url )
|
||||
);
|
||||
if ( $custom_google_fonts_api_url !== $default_google_fonts_api_url ) {
|
||||
foreach ( $data['fontFamilies'] as &$font_family ) {
|
||||
foreach ( $font_family['fontFace'] as &$font_face ) {
|
||||
$font_face['src'] = str_replace(
|
||||
$default_google_fonts_api_url,
|
||||
$custom_google_fonts_api_url,
|
||||
$font_face['src']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_array( $data ) && is_array( $data['fontFamilies'] ) ) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map of the available Google Fonts
|
||||
*
|
||||
* @param object[] $google_fonts_data The collection data of the Google Fonts.
|
||||
* @return object[] The map of the the available Google Fonts.
|
||||
*/
|
||||
function jetpack_get_available_google_fonts_map( $google_fonts_data ) {
|
||||
$jetpack_google_fonts_list = array_map(
|
||||
function ( $font_family ) {
|
||||
return $font_family['name'];
|
||||
},
|
||||
$google_fonts_data['fontFamilies']
|
||||
);
|
||||
|
||||
/**
|
||||
* Curated list of Google Fonts.
|
||||
*
|
||||
* @module google-fonts
|
||||
*
|
||||
* @since 10.8
|
||||
*
|
||||
* @param array $fonts_to_register Array of Google Font names to register.
|
||||
*/
|
||||
$google_font_list = apply_filters( 'jetpack_google_fonts_list', $jetpack_google_fonts_list );
|
||||
$available_google_fonts_map = array();
|
||||
|
||||
foreach ( $google_font_list as $google_font ) {
|
||||
$available_google_fonts_map[ $google_font ] = true;
|
||||
}
|
||||
|
||||
return $available_google_fonts_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register google fonts to the theme json data
|
||||
*
|
||||
* @param WP_Theme_JSON_Data $theme_json The theme json data of core.
|
||||
* @return WP_Theme_JSON_Data The theme json data with registered google fonts.
|
||||
*/
|
||||
function jetpack_register_google_fonts_to_theme_json( $theme_json ) {
|
||||
$google_fonts_data = jetpack_get_google_fonts_data();
|
||||
if ( ! $google_fonts_data ) {
|
||||
return $theme_json;
|
||||
}
|
||||
|
||||
$available_google_fonts_map = jetpack_get_available_google_fonts_map( $google_fonts_data );
|
||||
$google_fonts_families = array_values(
|
||||
array_filter(
|
||||
$google_fonts_data['fontFamilies'],
|
||||
function ( $google_fonts_family ) use ( $available_google_fonts_map ) {
|
||||
$name = $google_fonts_family['name'];
|
||||
return $available_google_fonts_map[ $name ] ?? false;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$raw_data = $theme_json->get_data();
|
||||
$origin = 'default';
|
||||
if ( empty( $raw_data['settings']['typography']['fontFamilies'][ $origin ] ) ) {
|
||||
$raw_data['settings']['typography']['fontFamilies'][ $origin ] = array();
|
||||
}
|
||||
|
||||
foreach ( $google_fonts_families as $font_family ) {
|
||||
$raw_data['settings']['typography']['fontFamilies'][ $origin ][] = $font_family;
|
||||
}
|
||||
|
||||
$theme_json_class = get_class( $theme_json );
|
||||
return new $theme_json_class( $raw_data, $origin );
|
||||
}
|
||||
|
||||
add_filter( 'wp_theme_json_data_default', 'jetpack_register_google_fonts_to_theme_json' );
|
||||
|
||||
/**
|
||||
* Filter out the deprecated font families that are from the jetpack-google-fonts provider.
|
||||
*
|
||||
* @param object[] $font_families The font families.
|
||||
* @return object[] The filtered font families.
|
||||
*/
|
||||
function jetpack_google_fonts_filter_out_deprecated_font_data( $font_families ) {
|
||||
return array_values(
|
||||
array_filter(
|
||||
$font_families,
|
||||
function ( $font_family ) {
|
||||
$has_deprecated_google_fonts_data = false;
|
||||
|
||||
if ( isset( $font_family['fontFace'] ) ) {
|
||||
foreach ( $font_family['fontFace'] as $font_face ) {
|
||||
$provider = $font_face['provider'] ?? '';
|
||||
if ( $provider === 'jetpack-google-fonts' ) {
|
||||
$has_deprecated_google_fonts_data = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ! $has_deprecated_google_fonts_data;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the deprecated jetpack-google-fonts provider from theme json data that were stored
|
||||
* before we moved to the Font Library.
|
||||
*
|
||||
* @param WP_Theme_JSON_Data $theme_json The theme json data.
|
||||
* @return WP_Theme_JSON_Data The filtered theme json data.
|
||||
*/
|
||||
function jetpack_unregister_deprecated_google_fonts_from_theme_json_data( $theme_json ) {
|
||||
$raw_data = $theme_json->get_data();
|
||||
$origin = 'theme';
|
||||
if ( empty( $raw_data['settings']['typography']['fontFamilies'][ $origin ] ) ) {
|
||||
return $theme_json;
|
||||
}
|
||||
|
||||
// Filter out the font definitions that are from the jetpack-google-fonts provider.
|
||||
$raw_data['settings']['typography']['fontFamilies'][ $origin ] = jetpack_google_fonts_filter_out_deprecated_font_data(
|
||||
$raw_data['settings']['typography']['fontFamilies'][ $origin ]
|
||||
);
|
||||
|
||||
$theme_json_class = get_class( $theme_json );
|
||||
return new $theme_json_class( $raw_data, 'custom' );
|
||||
}
|
||||
|
||||
add_filter( 'wp_theme_json_data_theme', 'jetpack_unregister_deprecated_google_fonts_from_theme_json_data' );
|
||||
add_filter( 'wp_theme_json_data_user', 'jetpack_unregister_deprecated_google_fonts_from_theme_json_data' );
|
||||
|
||||
/**
|
||||
* Clean up the Google Fonts data if either google fonts module is disabled or Jetpack is disabled.
|
||||
*/
|
||||
function jetpack_unregister_google_fonts() {
|
||||
$post_id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id();
|
||||
|
||||
// Get user config
|
||||
$user_config = WP_Theme_JSON_Resolver::get_user_data();
|
||||
$user_config_raw_data = $user_config->get_raw_data();
|
||||
$user_config_raw_data['isGlobalStylesUserThemeJSON'] = true;
|
||||
|
||||
// Prepare data for saving
|
||||
if ( ! empty( $user_config_raw_data['settings']['typography']['fontFamilies']['default'] ) ) {
|
||||
$user_config_raw_data['settings']['typography']['fontFamilies']['default'] = array();
|
||||
}
|
||||
|
||||
if ( ! empty( $user_config_raw_data['settings']['typography']['fontFamilies']['theme'] ) ) {
|
||||
$user_config_raw_data['settings']['typography']['fontFamilies']['theme'] = jetpack_google_fonts_filter_out_deprecated_font_data(
|
||||
$user_config_raw_data['settings']['typography']['fontFamilies']['theme'] // @phan-suppress-current-line PhanTypeInvalidDimOffset, PhanTypeMismatchArgument
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare changes
|
||||
$changes = new stdClass();
|
||||
$changes->ID = $post_id;
|
||||
$changes->post_content = wp_json_encode( $user_config_raw_data );
|
||||
|
||||
// Update user config
|
||||
wp_update_post( wp_slash( (array) $changes ), true );
|
||||
}
|
||||
add_action( 'jetpack_deactivate_module_google-fonts', 'jetpack_unregister_google_fonts' );
|
||||
|
||||
// Initialize Jetpack Google Font Face to avoid printing **ALL** google fonts provided by this module.
|
||||
// See p1700040028362329-slack-C4GAQ900P and p7DVsv-jib-p2
|
||||
new Jetpack_Google_Font_Face();
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Load the google fonts based on the current WordPress version.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* The modules is loaded during the late_initialization action and it also hooks to the `after_setup_theme`.
|
||||
* See projects/plugins/jetpack/class.jetpack.php.
|
||||
*/
|
||||
add_action(
|
||||
'after_setup_theme',
|
||||
function () {
|
||||
if (
|
||||
/**
|
||||
* Filters whether to skip loading the Jetpack Google Fonts module.
|
||||
*
|
||||
* This filter allows skipping the loading of the Jetpack Google Fonts module
|
||||
* based on specific conditions or requirements. By default, the module will
|
||||
* load normally. If the filter returns true, the module will be skipped.
|
||||
*
|
||||
* @module google-fonts
|
||||
*
|
||||
* @since 13.4
|
||||
*
|
||||
* @param bool $skip Whether to skip loading the Jetpack Google Fonts module. Default false.
|
||||
*/
|
||||
apply_filters( 'jetpack_google_fonts_skip_load', false )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/current/load-google-fonts.php';
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user