PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | modules/google-fonts/current/load-google-fonts.php +300 -0 16.2-beta → 16.3-beta View file →
@@ -1,0 +1,300 @@
1 +<?php
2 +/**
3 + * Load the google fonts by the new Font Library. See pNEWy-hhx-p2.
4 + *
5 + * @package automattic/jetpack
6 + */
7 +
8 +if ( ! defined( 'ABSPATH' ) ) {
9 + exit( 0 );
10 +}
11 +
12 +if ( ! class_exists( 'Jetpack_Google_Font_Face' ) ) {
13 + /**
14 + * Load Jetpack Google Font Face
15 + */
16 + require_once __DIR__ . '/class-jetpack-google-font-face.php';
17 +}
18 +
19 +/**
20 + * Gets the Google Fonts data
21 + *
22 + * @return array|null The collection data of the Google Fonts.
23 + */
24 +function jetpack_get_google_fonts_data() {
25 + /**
26 + * Filters the Google Fonts data before the default retrieval process.
27 + *
28 + * This filter allows short-circuiting the default Google Fonts data retrieval process.
29 + * Returning a non-null value from this filter will bypass the default retrieval
30 + * and return the filtered value instead.
31 + *
32 + * @module google-fonts
33 + *
34 + * @since 13.7
35 + *
36 + * @param null|array $pre The pre-filtered Google Fonts data, default null.
37 + */
38 + $pre = apply_filters( 'pre_jetpack_get_google_fonts_data', null );
39 + if ( null !== $pre ) {
40 + return $pre;
41 + }
42 +
43 + $default_google_fonts_api_url = 'https://fonts.gstatic.com';
44 + $jetpack_google_fonts_collection_url = 'https://s0.wp.com/i/font-collections/jetpack-google-fonts.json';
45 + $cache_key = 'jetpack_google_fonts_' . md5( $jetpack_google_fonts_collection_url );
46 + $data = get_transient( $cache_key );
47 + if ( $data === false ) {
48 + $response = wp_remote_get( $jetpack_google_fonts_collection_url );
49 + if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
50 + return null;
51 + }
52 +
53 + $data = json_decode( wp_remote_retrieve_body( $response ), true );
54 + if ( $data === null ) {
55 + return null;
56 + }
57 +
58 + set_transient( $cache_key, $data, DAY_IN_SECONDS );
59 + }
60 +
61 + // Replace the google fonts api url if the custom one is provided.
62 + $custom_google_fonts_api_url = \esc_url(
63 + /**
64 + * Filters the Google Fonts API URL.
65 + *
66 + * @module google-fonts
67 + *
68 + * @since 12.8
69 + *
70 + * @param string $url The Google Fonts API URL.
71 + */
72 + apply_filters( 'jetpack_google_fonts_api_url', $default_google_fonts_api_url )
73 + );
74 + if ( $custom_google_fonts_api_url !== $default_google_fonts_api_url ) {
75 + foreach ( $data['fontFamilies'] as &$font_family ) {
76 + foreach ( $font_family['fontFace'] as &$font_face ) {
77 + $font_face['src'] = str_replace(
78 + $default_google_fonts_api_url,
79 + $custom_google_fonts_api_url,
80 + $font_face['src']
81 + );
82 + }
83 + }
84 + }
85 +
86 + if ( is_array( $data ) && is_array( $data['fontFamilies'] ) ) {
87 + return $data;
88 + }
89 +}
90 +
91 +/**
92 + * Gets the map of the available Google Fonts
93 + *
94 + * @param array $google_fonts_data The collection data of the Google Fonts.
95 + * @return array The map of the the available Google Fonts.
96 + */
97 +function jetpack_get_available_google_fonts_map( $google_fonts_data ) {
98 + $jetpack_google_fonts_list = array_map(
99 + function ( $font_family ) {
100 + return $font_family['name'];
101 + },
102 + $google_fonts_data['fontFamilies']
103 + );
104 +
105 + /**
106 + * Curated list of Google Fonts.
107 + *
108 + * @module google-fonts
109 + *
110 + * @since 10.8
111 + *
112 + * @param array $fonts_to_register Array of Google Font names to register.
113 + */
114 + $google_font_list = apply_filters( 'jetpack_google_fonts_list', $jetpack_google_fonts_list );
115 + $available_google_fonts_map = array();
116 +
117 + foreach ( $google_font_list as $google_font ) {
118 + $available_google_fonts_map[ $google_font ] = true;
119 + }
120 +
121 + return $available_google_fonts_map;
122 +}
123 +
124 +/**
125 + * Whether the request URL is a REST route.
126 + *
127 + * Theme JSON can resolve before REST_REQUEST is defined, and the Accept header also matches front-end requests.
128 + *
129 + * @since 16.3
130 + *
131 + * @return bool
132 + */
133 +function jetpack_google_fonts_is_rest_url() {
134 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only used to classify the request.
135 + if ( isset( $_GET['rest_route'] ) ) {
136 + return true;
137 + }
138 + $path = (string) wp_parse_url( isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '', PHP_URL_PATH ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Parsed for path comparison only.
139 + return str_contains( $path, '/' . rest_get_url_prefix() . '/' );
140 +}
141 +
142 +/**
143 + * Whether catalogue faces are needed in theme JSON for an editor or API request.
144 + *
145 + * @since 16.3
146 + *
147 + * @return bool
148 + */
149 +function jetpack_google_fonts_load_font_faces() {
150 + $load_font_faces = is_admin()
151 + || ( defined( 'REST_REQUEST' ) && REST_REQUEST )
152 + || jetpack_google_fonts_is_rest_url()
153 + || ( defined( 'WP_CLI' ) && WP_CLI );
154 +
155 + /**
156 + * Filters whether catalogue font faces are loaded into theme JSON.
157 + *
158 + * When true, the catalogue's files reach theme JSON and the native font printer prints all of them.
159 + *
160 + * @module google-fonts
161 + *
162 + * @since 16.3
163 + *
164 + * @param bool $load_font_faces Whether to load catalogue font faces. Default true for editor, API and CLI requests.
165 + */
166 + return (bool) apply_filters( 'jetpack_google_fonts_load_font_faces', $load_font_faces );
167 +}
168 +
169 +/**
170 + * Register google fonts to the theme json data
171 + *
172 + * @param WP_Theme_JSON_Data $theme_json The theme json data of core.
173 + * @return WP_Theme_JSON_Data The theme json data with registered google fonts.
174 + */
175 +function jetpack_register_google_fonts_to_theme_json( $theme_json ) {
176 + $google_fonts_data = jetpack_get_google_fonts_data();
177 + if ( ! $google_fonts_data ) {
178 + return $theme_json;
179 + }
180 +
181 + $available_google_fonts_map = jetpack_get_available_google_fonts_map( $google_fonts_data );
182 + $google_fonts_families = array_values(
183 + array_filter(
184 + $google_fonts_data['fontFamilies'],
185 + function ( $google_fonts_family ) use ( $available_google_fonts_map ) {
186 + $name = $google_fonts_family['name'];
187 + return $available_google_fonts_map[ $name ] ?? false;
188 + }
189 + )
190 + );
191 +
192 + $raw_data = $theme_json->get_data();
193 + $origin = 'default';
194 + if ( empty( $raw_data['settings']['typography']['fontFamilies'][ $origin ] ) ) {
195 + $raw_data['settings']['typography']['fontFamilies'][ $origin ] = array();
196 + }
197 +
198 + $load_font_faces = jetpack_google_fonts_load_font_faces();
199 + foreach ( $google_fonts_families as $font_family ) {
200 + if ( ! $load_font_faces ) {
201 + unset( $font_family['fontFace'] );
202 + }
203 + $raw_data['settings']['typography']['fontFamilies'][ $origin ][] = $font_family;
204 + }
205 +
206 + $theme_json_class = get_class( $theme_json );
207 + return new $theme_json_class( $raw_data, $origin );
208 +}
209 +
210 +add_filter( 'wp_theme_json_data_default', 'jetpack_register_google_fonts_to_theme_json' );
211 +
212 +/**
213 + * Filter out the deprecated font families that are from the jetpack-google-fonts provider.
214 + *
215 + * @param array[] $font_families The font families.
216 + * @return array[] The filtered font families.
217 + */
218 +function jetpack_google_fonts_filter_out_deprecated_font_data( $font_families ) {
219 + return array_values(
220 + array_filter(
221 + $font_families,
222 + function ( $font_family ) {
223 + $has_deprecated_google_fonts_data = false;
224 +
225 + if ( isset( $font_family['fontFace'] ) ) {
226 + foreach ( $font_family['fontFace'] as $font_face ) {
227 + $provider = $font_face['provider'] ?? '';
228 + if ( $provider === 'jetpack-google-fonts' ) {
229 + $has_deprecated_google_fonts_data = true;
230 + break;
231 + }
232 + }
233 + }
234 +
235 + return ! $has_deprecated_google_fonts_data;
236 + }
237 + )
238 + );
239 +}
240 +
241 +/**
242 + * Unregister the deprecated jetpack-google-fonts provider from theme json data that were stored
243 + * before we moved to the Font Library.
244 + *
245 + * @param WP_Theme_JSON_Data $theme_json The theme json data.
246 + * @return WP_Theme_JSON_Data The filtered theme json data.
247 + */
248 +function jetpack_unregister_deprecated_google_fonts_from_theme_json_data( $theme_json ) {
249 + $raw_data = $theme_json->get_data();
250 + $origin = 'theme';
251 + if ( empty( $raw_data['settings']['typography']['fontFamilies'][ $origin ] ) ) {
252 + return $theme_json;
253 + }
254 +
255 + // Filter out the font definitions that are from the jetpack-google-fonts provider.
256 + $raw_data['settings']['typography']['fontFamilies'][ $origin ] = jetpack_google_fonts_filter_out_deprecated_font_data(
257 + $raw_data['settings']['typography']['fontFamilies'][ $origin ]
258 + );
259 +
260 + $theme_json_class = get_class( $theme_json );
261 + return new $theme_json_class( $raw_data, 'custom' );
262 +}
263 +
264 +add_filter( 'wp_theme_json_data_theme', 'jetpack_unregister_deprecated_google_fonts_from_theme_json_data' );
265 +add_filter( 'wp_theme_json_data_user', 'jetpack_unregister_deprecated_google_fonts_from_theme_json_data' );
266 +
267 +/**
268 + * Clean up the Google Fonts data if either google fonts module is disabled or Jetpack is disabled.
269 + */
270 +function jetpack_unregister_google_fonts() {
271 + $post_id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id();
272 +
273 + // Get user config
274 + $user_config = WP_Theme_JSON_Resolver::get_user_data();
275 + $user_config_raw_data = $user_config->get_raw_data();
276 + $user_config_raw_data['isGlobalStylesUserThemeJSON'] = true;
277 +
278 + // Prepare data for saving
279 + if ( ! empty( $user_config_raw_data['settings']['typography']['fontFamilies']['default'] ) ) {
280 + $user_config_raw_data['settings']['typography']['fontFamilies']['default'] = array();
281 + }
282 +
283 + if ( ! empty( $user_config_raw_data['settings']['typography']['fontFamilies']['theme'] ) ) {
284 + $user_config_raw_data['settings']['typography']['fontFamilies']['theme'] = jetpack_google_fonts_filter_out_deprecated_font_data(
285 + $user_config_raw_data['settings']['typography']['fontFamilies']['theme'] // @phan-suppress-current-line PhanTypeInvalidDimOffset, PhanTypeMismatchArgument
286 + );
287 + }
288 +
289 + // Prepare changes
290 + $changes = new stdClass();
291 + $changes->ID = $post_id;
292 + $changes->post_content = wp_json_encode( $user_config_raw_data, JSON_UNESCAPED_SLASHES );
293 +
294 + // Update user config
295 + wp_update_post( wp_slash( (array) $changes ), true );
296 +}
297 +add_action( 'jetpack_deactivate_module_google-fonts', 'jetpack_unregister_google_fonts' );
298 +
299 +// Print legacy catalogue faces separately from native theme and user fonts.
300 +new Jetpack_Google_Font_Face();