PluginProbe
Elementor Website Builder – more than just a page builder / 3.31.4
Elementor Website Builder – more than just a page builder v3.31.4
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 3.31.4, at core/files/fonts/google-font.php

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