PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.9.2
Jetpack – WP Security, Backup, Speed, & Growth v14.9.2
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 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / google-fonts / current / class-jetpack-google-font-face.php
jetpack / modules / google-fonts / current Last commit date
class-jetpack-google-font-face.php 1 year ago load-google-fonts.php 1 year ago
class-jetpack-google-font-face.php
258 lines
1 <?php
2 /**
3 * Jetpack_Google_Font_Face class
4 *
5 * @package automattic/jetpack
6 */
7
8 /**
9 * Jetpack Google Font Face disables Font Face hooks in Core that prints **ALL** font faces.
10 * Instead, it collects fonts that are used in global styles or block-level settings and
11 * print those fonts in use.
12 *
13 * @phan-constructor-used-for-side-effects
14 */
15 class Jetpack_Google_Font_Face {
16 /**
17 * The fonts that are used in global styles or block-level settings.
18 *
19 * @var array
20 */
21 private $fonts_in_use = array();
22
23 /**
24 * The constructor.
25 */
26 public function __construct() {
27 // Turns off hooks to print fonts
28 add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
29 add_action( 'current_screen', array( $this, 'current_screen' ), 10 );
30
31 // Collect and print fonts in use
32 if ( wp_is_block_theme() ) {
33 add_action( 'wp_head', array( $this, 'print_font_faces' ), 50 );
34 } else {
35 // In classic themes wp_head runs before the blocks are processed to collect the block fonts.
36 add_action( 'wp_footer', array( $this, 'print_font_faces' ), 50 );
37 }
38 add_filter( 'pre_render_block', array( $this, 'collect_block_fonts' ), 10, 2 );
39 }
40
41 /**
42 * Turn off hooks to print fonts on frontend
43 */
44 public function wp_loaded() {
45 remove_action( 'wp_head', 'wp_print_fonts', 50 );
46 remove_action( 'wp_head', 'wp_print_font_faces', 50 );
47 }
48
49 /**
50 * Turn off hooks to print fonts on wp-admin, except for GB editor pages.
51 */
52 public function current_screen() {
53 remove_action( 'admin_print_styles', 'wp_print_fonts', 50 );
54
55 if ( ! $this->is_block_editor() ) {
56 remove_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
57 }
58 }
59
60 /**
61 * Print fonts that are used in global styles or block-level settings.
62 */
63 public function print_font_faces() {
64 $fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
65 $font_slug_aliases = $this->get_font_slug_aliases();
66 $fonts_to_print = array();
67
68 $this->collect_global_styles_fonts();
69 $fonts_in_use = array_values( array_unique( $this->fonts_in_use, SORT_STRING ) );
70 $fonts_in_use = array_map(
71 function ( $font_slug ) use ( $font_slug_aliases ) {
72 return $font_slug_aliases[ $font_slug ] ?? $font_slug;
73 },
74 $this->fonts_in_use
75 );
76
77 foreach ( $fonts as $font_faces ) {
78 $font_family = $font_faces[0]['font-family'] ?? '';
79 if ( in_array( $this->format_font( $font_family ), $fonts_in_use, true ) ) {
80 $fonts_to_print[] = $font_faces;
81 }
82 }
83
84 if ( ! empty( $fonts_to_print ) ) {
85 wp_print_font_faces( $fonts_to_print );
86 }
87 }
88
89 /**
90 * Collect fonts used for global styles settings.
91 */
92 public function collect_global_styles_fonts() {
93 $global_styles = wp_get_global_styles();
94
95 $global_styles_font_slug = $this->get_font_slug_from_setting( $global_styles );
96 if ( $global_styles_font_slug ) {
97 $this->add_font( $global_styles_font_slug );
98 }
99
100 if ( isset( $global_styles['blocks'] ) ) {
101 foreach ( $global_styles['blocks'] as $setting ) {
102 $font_slug = $this->get_font_slug_from_setting( $setting );
103
104 if ( $font_slug ) {
105 $this->add_font( $font_slug );
106 }
107 }
108 }
109
110 if ( isset( $global_styles['elements'] ) ) {
111 foreach ( $global_styles['elements'] as $setting ) {
112 $font_slug = $this->get_font_slug_from_setting( $setting );
113
114 if ( $font_slug ) {
115 $this->add_font( $font_slug );
116 }
117 }
118 }
119 }
120
121 /**
122 * Collect fonts used for block-level settings.
123 *
124 * @filter pre_render_block
125 *
126 * @param string|null $content The pre-rendered content. Default null.
127 * @param array $parsed_block The block being rendered.
128 */
129 public function collect_block_fonts( $content, $parsed_block ) {
130 if ( ! is_admin() && isset( $parsed_block['attrs']['fontFamily'] ) ) {
131 $block_font_family = $parsed_block['attrs']['fontFamily'];
132 $this->add_font( $block_font_family );
133 }
134
135 return $content;
136 }
137
138 /**
139 * Add the specify font to the fonts_in_use list.
140 *
141 * @param string $font_slug The font slug.
142 */
143 public function add_font( $font_slug ) {
144 if ( is_string( $font_slug ) ) {
145 $this->fonts_in_use[] = $this->format_font( $font_slug );
146 }
147 }
148
149 /**
150 * Format the given font slug.
151 *
152 * @example "ABeeZee" formats to "abeezee"
153 * @example "ADLaM Display" formats to "adlam-display"
154 * @param string $font_slug The font slug.
155 * @return string The formatted font slug.
156 */
157 public function format_font( $font_slug ) {
158 return _wp_to_kebab_case( strtolower( $font_slug ) );
159 }
160
161 /**
162 * Get the font slug aliases that maps the font slug to the font family if they are different.
163 *
164 * The font definition may define an alias slug name, so we have to add the map from the slug name to the font family.
165 * See https://github.com/WordPress/twentytwentyfour/blob/df92472089ede6fae5924c124a93c843b84e8cbd/theme.json#L215.
166 */
167 public function get_font_slug_aliases() {
168 $font_slug_aliases = array();
169
170 $theme_json = WP_Theme_JSON_Resolver::get_theme_data();
171 $raw_data = $theme_json->get_data();
172 if ( ! empty( $raw_data['settings']['typography']['fontFamilies'] ) ) {
173 foreach ( $raw_data['settings']['typography']['fontFamilies'] as $font ) {
174 if ( ! isset( $font['fontFamily'] ) ) {
175 continue;
176 }
177 $font_family_name = $this->format_font( $this->get_font_family_name( $font ) );
178 $font_slug = $font['slug'] ?? '';
179 if ( $font_slug && $font_slug !== $font_family_name && ! array_key_exists( $font_slug, $font_slug_aliases ) ) {
180 $font_slug_aliases[ $font_slug ] = $font_family_name;
181 }
182 }
183 }
184
185 return $font_slug_aliases;
186 }
187
188 /**
189 * Get the font family name from a font.
190 *
191 * @param array $font The font definition object.
192 */
193 public static function get_font_family_name( $font ) {
194 $font_family = $font['fontFamily'];
195 if ( str_contains( $font_family, ',' ) ) {
196 $font_family = explode( ',', $font_family )[0];
197 }
198
199 return trim( $font_family, "\"'" );
200 }
201
202 /**
203 * Get the font family slug from a settings array.
204 *
205 * @param array $setting The settings object.
206 *
207 * @return string|null
208 */
209 public function get_font_slug_from_setting( $setting ) {
210 if ( ! isset( $setting['typography']['fontFamily'] ) ) {
211 return null;
212 }
213
214 $font_family = $setting['typography']['fontFamily'];
215
216 // The font family may be a reference to a path to the value stored at that location,
217 // e.g.: { "ref": "styles.elements.heading.typography.fontFamily" }.
218 // Ignore it as we also get the value stored at that location from the setting.
219 if ( ! is_string( $font_family ) ) {
220 return null;
221 }
222
223 // Full string: var(--wp--preset--font-family--slug).
224 // We do not care about the origin of the font, only its slug.
225 preg_match( '/font-family--(?P<slug>.+)\)$/', $font_family, $matches );
226
227 if ( isset( $matches['slug'] ) ) {
228 return $matches['slug'];
229 }
230
231 // Full string: var:preset|font-family|slug
232 // We do not care about the origin of the font, only its slug.
233 preg_match( '/font-family\|(?P<slug>.+)$/', $font_family, $matches );
234
235 if ( isset( $matches['slug'] ) ) {
236 return $matches['slug'];
237 }
238
239 return $font_family;
240 }
241
242 /**
243 * Check if the current screen is the block editor.
244 *
245 * @return bool
246 */
247 public function is_block_editor() {
248 if ( function_exists( 'get_current_screen' ) ) {
249 $current_screen = get_current_screen();
250 if ( ! empty( $current_screen ) && method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
251 return true;
252 }
253 }
254
255 return false;
256 }
257 }
258