PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.0-dev2
Elementor Website Builder – more than just a page builder v4.0.0-dev2
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / core / files / fonts / google-font.php

google-font.php in Elementor Website Builder – more than just a page builder 4.0.0-dev2, at core/files/fonts/google-font.php

283 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Files\Fonts;
3
4 use Elementor\Plugin;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly.
8 }
9
10 class Google_Font {
11
12 const FOLDER_BASE = 'elementor/google-fonts';
13
14 const FOLDER_CSS = 'css';
15
16 const FOLDER_FONTS = 'fonts';
17
18 const AVAILABLE_FOLDERS = [
19 self::FOLDER_CSS,
20 self::FOLDER_FONTS,
21 ];
22
23 const UA_STRING = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36';
24
25 const TYPE_DEFAULT = 'default';
26
27 const TYPE_EARLYACCESS = 'earlyaccess';
28
29 private static array $folders = [];
30
31 public static function enqueue( string $font_name, string $font_type = self::TYPE_DEFAULT, $force_enqueue_from_cdn = false ): bool {
32 if ( static::enqueue_style( $font_name ) ) {
33 return true;
34 }
35
36 $is_local_gf_enabled = (bool) get_option( 'elementor_local_google_fonts', '0' );
37 if ( ! $is_local_gf_enabled ) {
38 $force_enqueue_from_cdn = true;
39 }
40
41 if ( $force_enqueue_from_cdn || ! static::fetch_font_data( $font_name, $font_type ) ) {
42 static::enqueue_from_cdn( $font_name, $font_type );
43 return false;
44 }
45
46 return static::enqueue_style( $font_name );
47 }
48
49 private static function sanitize_font_name( string $font_name ): string {
50 return sanitize_key( $font_name );
51 }
52
53 private static function enqueue_style( string $font_name ): bool {
54 $sanitize_font_name = static::sanitize_font_name( $font_name );
55
56 $font_data = static::get_font_data( $sanitize_font_name );
57
58 if ( empty( $font_data['url'] ) ) {
59 return false;
60 }
61
62 wp_enqueue_style(
63 'elementor-gf-local-' . $sanitize_font_name,
64 $font_data['url'],
65 [],
66 $font_data['version']
67 );
68
69 return true;
70 }
71
72 private static function get_font_data( string $font_name ) {
73 $local_google_fonts = static::get_local_google_fonts();
74
75 return $local_google_fonts[ $font_name ] ?? null;
76 }
77
78 private static function get_local_google_fonts(): array {
79 return (array) get_option( '_elementor_local_google_fonts', [] );
80 }
81
82 private static function set_local_google_fonts( string $font_name, array $font_data ): void {
83 $local_google_fonts = static::get_local_google_fonts();
84
85 $local_google_fonts[ $font_name ] = $font_data;
86
87 update_option( '_elementor_local_google_fonts', $local_google_fonts );
88 }
89
90 private static function fetch_font_data( string $font_name, string $font_type ): bool {
91 $sanitize_font_name = static::sanitize_font_name( $font_name );
92
93 $fonts_folder = static::get_folder( static::FOLDER_FONTS );
94 $css_folder = static::get_folder( static::FOLDER_CSS );
95
96 if ( empty( $fonts_folder ) || empty( $css_folder ) ) {
97 return false;
98 }
99
100 $css_content = static::get_css_content( $font_name, $font_type );
101
102 if ( empty( $css_content ) ) {
103 return false;
104 }
105
106 $font_data = [
107 'url' => $css_folder['url'] . $sanitize_font_name . '.css',
108 'version' => time(),
109 ];
110
111 $css_folder_path = $css_folder['path'] . $sanitize_font_name . '.css';
112
113 $is_font_file_saved = file_put_contents( $css_folder_path, $css_content );
114
115 if ( ! $is_font_file_saved ) {
116 return false;
117 }
118
119 static::set_local_google_fonts( $sanitize_font_name, $font_data );
120
121 return true;
122 }
123
124 private static function get_folder( string $folder ): array {
125 $folders = static::get_folders();
126
127 return $folders[ $folder ] ?? [];
128 }
129
130 private static function get_folders(): array {
131 static::init_folders();
132
133 return static::$folders;
134 }
135
136 private static function init_folders(): void {
137 if ( ! empty( static::$folders ) ) {
138 return;
139 }
140
141 static::$folders = [];
142
143 $upload_dir = wp_upload_dir();
144
145 foreach ( static::AVAILABLE_FOLDERS as $folder ) {
146 $folder_path = $upload_dir['basedir'] . '/' . static::FOLDER_BASE . '/' . $folder;
147 $folder_url = $upload_dir['baseurl'] . '/' . static::FOLDER_BASE . '/' . $folder;
148
149 if ( ! file_exists( $folder_path ) ) {
150 wp_mkdir_p( $folder_path );
151 }
152
153 static::$folders[ $folder ] = [
154 'path' => trailingslashit( $folder_path ),
155 'url' => trailingslashit( $folder_url ),
156 ];
157 }
158 }
159
160 private static function get_css_content( string $font_name, $font_type ): string {
161 $css_content = static::get_raw_css_content( $font_name, $font_type );
162
163 if ( empty( $css_content ) ) {
164 return '';
165 }
166
167 return static::download_fonts( $font_name, $css_content );
168 }
169
170 private static function get_raw_css_content( string $font_name, string $font_type ): string {
171 $font_url = static::get_google_fonts_remote_url( $font_name, $font_type );
172
173 $css_content_response = wp_remote_get( $font_url, [
174 'headers' => [
175 'User-Agent' => static::UA_STRING,
176 ],
177 ] );
178
179 if ( is_wp_error( $css_content_response ) || 200 !== (int) wp_remote_retrieve_response_code( $css_content_response ) ) {
180 return '';
181 }
182
183 return wp_remote_retrieve_body( $css_content_response );
184 }
185
186 private static function get_google_fonts_remote_url( string $font, string $font_type ): string {
187 if ( self::TYPE_EARLYACCESS === $font_type ) {
188 return static::get_earlyaccess_google_fonts_url( $font );
189 }
190
191 return Plugin::$instance->frontend->get_stable_google_fonts_url( [ $font ] );
192 }
193
194 private static function get_earlyaccess_google_fonts_url( string $font ): string {
195 return sprintf( 'https://fonts.googleapis.com/earlyaccess/%s.css', strtolower( str_replace( ' ', '', $font ) ) );
196 }
197
198 private static function download_fonts( string $font_name, string $css_content ): string {
199 preg_match_all( '/url\(([^)]+)\)/', $css_content, $font_urls );
200
201 if ( ! function_exists( 'download_url' ) ) {
202 require_once ABSPATH . 'wp-admin/includes/file.php';
203 }
204
205 if ( ! empty( $font_urls[1] ) ) {
206 $font_urls = $font_urls[1];
207
208 $fonts_folder = static::get_folder( static::FOLDER_FONTS );
209 $sanitize_font_name = static::sanitize_font_name( $font_name );
210
211 foreach ( $font_urls as $current_font_url ) {
212 $original_font_url = trim( $current_font_url, '\'"' );
213
214 $cleaned_url = set_url_scheme( $original_font_url, 'https' );
215 $cleaned_url = strtok( $cleaned_url, '?#' );
216
217 $font_ext = pathinfo( $cleaned_url, PATHINFO_EXTENSION );
218
219 $tmp_font_file = download_url( $cleaned_url );
220 if ( is_wp_error( $tmp_font_file ) ) {
221 return '';
222 }
223
224 $unique_font_id = static::get_unique_font_id( $cleaned_url );
225
226 $current_font_basename = sprintf(
227 '%s-%s.%s',
228 $sanitize_font_name,
229 strtolower( sanitize_file_name( $unique_font_id ) ),
230 $font_ext
231 );
232
233 $dest_file = $fonts_folder['path'] . $current_font_basename;
234 $dest_file_url = $fonts_folder['url'] . $current_font_basename;
235
236 // Use copy and unlink because rename breaks streams.
237 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
238 $is_font_file_saved = @copy( $tmp_font_file, $dest_file );
239 @unlink( $tmp_font_file );
240
241 if ( ! $is_font_file_saved ) {
242 return '';
243 }
244
245 $css_content = str_replace( $original_font_url, $dest_file_url, $css_content );
246 }
247 }
248
249 return $css_content;
250 }
251
252 private static function get_unique_font_id( $font_url ): string {
253 return substr( sha1( $font_url ), 0, 8 );
254 }
255
256 private static function enqueue_from_cdn( string $font_name, string $font_type ): void {
257 $font_url = static::get_google_fonts_remote_url( $font_name, $font_type );
258
259 $sanitize_font_name = static::sanitize_font_name( $font_name );
260
261 wp_enqueue_style(
262 'elementor-gf-' . $sanitize_font_name,
263 $font_url,
264 [],
265 null
266 );
267 }
268
269 public static function clear_cache() {
270 $folders = static::get_folders();
271
272 foreach ( $folders as $folder ) {
273 $path = $folder['path'] . '*';
274
275 foreach ( glob( $path ) as $file_path ) {
276 unlink( $file_path );
277 }
278 }
279
280 delete_option( '_elementor_local_google_fonts' );
281 }
282 }
283