PluginProbe
Elementor Website Builder – more than just a page builder / 3.27.4
Elementor Website Builder – more than just a page builder v3.27.4
4.3.0-beta3 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 All 452 releases
elementor / core / files / fonts / google-font.php

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

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