PluginProbe
GutSlider – All in One Slider and Carousel Blocks for Gutenberg / trunk
GutSlider – All in One Slider and Carousel Blocks for Gutenberg vtrunk
3.1.0 3.0.0 2.13.2 2.13.1 2.13.0 trunk 1.0.0 2.1.0 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.2.1 2.2.2 2.3.0 2.4.0 2.5.1 2.5.3 2.5.4 2.5.5 2.6.1 All 56 releases
slider-blocks / includes / Assets / LoadFonts.php

LoadFonts.php in GutSlider – All in One Slider and Carousel Blocks for Gutenberg trunk, at includes/Assets/LoadFonts.php

224 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 declare( strict_types=1 );
3
4 namespace GutSlider\Assets;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 /**
11 * Handles loading of Google Fonts used in slider blocks.
12 *
13 * Collects font family attributes from rendered blocks and enqueues
14 * the corresponding Google Fonts stylesheets.
15 *
16 * @package GutSlider\Assets
17 * @since 3.0.0
18 */
19 final class LoadFonts {
20
21 /**
22 * System fonts that do not need to be loaded from Google Fonts.
23 *
24 * @since 3.0.0
25 * @var array<int, string>
26 */
27 private const SYSTEM_FONTS = array(
28 // Posts saved before the picker stored an empty value for "inherit".
29 'Default',
30 'Arial',
31 'Tahoma',
32 'Verdana',
33 'Helvetica',
34 'Times New Roman',
35 'Trebuchet MS',
36 'Georgia',
37 );
38
39 /**
40 * Collected font families from rendered blocks.
41 *
42 * @since 3.0.0
43 * @var array<int, string>
44 */
45 private static array $all_fonts = array();
46
47 /**
48 * Constructor.
49 *
50 * Registers WordPress hooks for font loading.
51 *
52 * @since 3.0.0
53 */
54 public function __construct() {
55 add_action( 'wp_enqueue_scripts', array( $this, 'fonts_loader' ), 10 );
56 add_action( 'admin_enqueue_scripts', array( $this, 'fonts_loader' ), 10 );
57 add_action( 'enqueue_block_assets', array( $this, 'enqueue_editor_fonts' ) );
58 add_action( 'gutsliders_render_block', array( $this, 'font_generator' ) );
59 }
60
61 /**
62 * Enqueue the fonts used by the post open in the block editor.
63 *
64 * Hooked to `enqueue_block_assets` because WordPress mirrors that hook into
65 * the editor canvas iframe, which is where apiVersion 3 blocks render.
66 * `admin_enqueue_scripts` only reaches the document around the canvas, so
67 * the preview would resolve `font-family` against a font that document has
68 * but the iframe never loaded.
69 *
70 * @since 3.0.0
71 *
72 * @return void
73 */
74 public function enqueue_editor_fonts(): void {
75 if ( ! is_admin() || ! function_exists( 'get_current_screen' ) ) {
76 return;
77 }
78
79 $screen = get_current_screen();
80
81 if ( null === $screen || ! $screen->is_block_editor() ) {
82 return;
83 }
84
85 $post = get_post();
86
87 if ( ! $post instanceof \WP_Post || ! has_blocks( $post->post_content ) ) {
88 return;
89 }
90
91 $this->collect_fonts( parse_blocks( $post->post_content ) );
92 $this->fonts_loader();
93 }
94
95 /**
96 * Walk a parsed block tree and record every font family it uses.
97 *
98 * The front end collects fonts from `render_block`, which fires for nested
99 * blocks too. A parsed tree has to be walked explicitly.
100 *
101 * @since 3.0.0
102 *
103 * @param array<int, array<string, mixed>> $blocks Parsed blocks.
104 * @return void
105 */
106 private function collect_fonts( array $blocks ): void {
107 foreach ( $blocks as $block ) {
108 if ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) {
109 $this->collect_block_fonts( $block['attrs'] );
110 }
111
112 if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
113 $this->collect_fonts( $block['innerBlocks'] );
114 }
115 }
116 }
117
118 /**
119 * Record the font families named in a single block's attributes.
120 *
121 * @since 3.0.0
122 *
123 * @param array<string, mixed> $attributes Block attributes.
124 * @return void
125 */
126 private function collect_block_fonts( array $attributes ): void {
127 foreach ( $attributes as $key => $value ) {
128 if ( ! empty( $value )
129 && is_string( $value )
130 && strpos( $key, 'gutsliders_' ) === 0
131 && strpos( $key, 'FontFamily' ) !== false
132 ) {
133 self::$all_fonts[] = sanitize_text_field( $value );
134 }
135 }
136 }
137
138 /**
139 * Extract font families from a rendered block's attributes.
140 *
141 * Scans block attributes for font family values and triggers
142 * the font loader to enqueue any new fonts found.
143 *
144 * @since 3.0.0
145 *
146 * @param array<string, mixed> $block The block data array.
147 * @return void
148 */
149 public function font_generator( array $block ): void {
150 if ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) {
151 $this->collect_block_fonts( $block['attrs'] );
152 $this->fonts_loader();
153 }
154 }
155
156 /**
157 * Enqueue Google Fonts stylesheets for collected font families.
158 *
159 * Filters out system fonts and duplicates, then registers and
160 * enqueues individual Google Fonts CSS files.
161 *
162 * @since 3.0.0
163 *
164 * @return void
165 */
166 public function fonts_loader(): void {
167 if ( ! $this->is_google_fonts_enabled() ) {
168 return;
169 }
170
171 if ( ! is_array( self::$all_fonts ) || count( self::$all_fonts ) === 0 ) {
172 return;
173 }
174
175 $fonts = array_filter( array_unique( self::$all_fonts ) );
176
177 if ( empty( $fonts ) ) {
178 return;
179 }
180
181 $gfonts_attr = ':100,200,300,400,500,600,700,800,900';
182
183 foreach ( $fonts as $font ) {
184 if ( in_array( $font, self::SYSTEM_FONTS, true ) || empty( $font ) ) {
185 continue;
186 }
187
188 $font_family = str_replace( ' ', '+', trim( $font ) ) . $gfonts_attr;
189 $query_args = array( 'family' => $font_family );
190 $font_handle = 'gutsliders-font-' . sanitize_title( $font );
191
192 wp_register_style(
193 $font_handle,
194 add_query_arg( $query_args, '//fonts.googleapis.com/css' ),
195 array(),
196 GUTSLIDER_VERSION,
197 'all'
198 );
199
200 wp_enqueue_style( $font_handle );
201 }
202 }
203
204 /**
205 * Whether Google Fonts requests are allowed.
206 *
207 * Site owners can turn this off from the GutSlider settings screen
208 * when the theme already loads the fonts or hosts them locally.
209 *
210 * @since 3.0.0
211 *
212 * @return bool True when Google Fonts may be enqueued.
213 */
214 private function is_google_fonts_enabled(): bool {
215 $settings = get_option( 'gutslider_settings', array() );
216
217 if ( is_array( $settings ) && array_key_exists( 'google_fonts', $settings ) ) {
218 return (bool) $settings['google_fonts'];
219 }
220
221 return true;
222 }
223 }
224