PluginProbe
Elementor Website Builder – more than just a page builder / 3.27.0-dev2
Elementor Website Builder – more than just a page builder v3.27.0-dev2
4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 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 All 457 releases
elementor / core / files / fonts / google-font.php

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

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