PluginProbe
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant / 1.0.3
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant v1.0.3
2.0.4 2.0.3 2.0.2 2.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2 1.3 2.0.0
easyfonts / easyfonts.php

easyfonts.php in EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant 1.0.3, at easyfonts.php

296 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: EasyFonts
4 Plugin URI:
5 Description: Automatically Host existing google fonts locally on your server
6 Version: 1.0.3
7 Author: Uzair
8 Author URI: https://easywpstuff.com
9 License: GPL2
10 */
11
12 // If this file is called directly, abort.
13 if (!defined("WPINC")){
14 die;
15 }
16
17 require_once dirname(__FILE__) . '/lib/simple_html_dom.php';
18
19 include_once dirname(__FILE__) . '/inc/options.php';
20
21 include_once dirname(__FILE__) . '/inc/notices.php';
22
23
24 function easyfont_process_content_link_tag($content) {
25 $html = hgfl_str_get_html($content, false, true, 'UTF-8', false, PHP_EOL, ' ');
26 // Check if the 'easyfonts' directory exists and is writable
27 $easyfonts_dir = wp_upload_dir() ['basedir'] . '/easyfonts';
28 if (!wp_mkdir_p($easyfonts_dir)) {
29 return $content;
30 }
31 // Find all <link> tags with a rel attribute of 'stylesheet' and a href attribute that points to a Google Fonts stylesheet
32 foreach ($html->find('link[rel=stylesheet][href*=fonts.googleapis.com]') as $link) {
33 $url = $link->href;
34 if(strpos($url,'//') === 0){
35 $url = 'https:'.$url;
36 }
37 // Generate a local filename for the stylesheet
38 $filename = hash('sha256', $url, false);
39 $filename = substr($filename, 0, 10) . '.css';
40 if (!file_exists($easyfonts_dir . '/' . $filename)) {
41 $response = wp_remote_get($url, array('user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',));
42 if (is_wp_error($response)) {
43 add_settings_error('easyfont_process_content_link_tag', 'http_error', $response->get_error_message(), 'error');
44 return $content;
45 }
46 $css = wp_remote_retrieve_body($response);
47 if (!preg_match_all('/@font-face\s*\{([^}]+)\}/', $css, $matches)) continue;
48
49 if (preg_match_all('/@font-face\s*\{([^}]+)\}/', $css, $matches)) {
50 foreach ($matches[1] as $match) {
51 if (preg_match_all('/src\s*:\s*([^;]+);/', $match, $srcs)) {
52 foreach ($srcs[1] as $src) {
53 if (preg_match('/url\(([^)]+)\)/', $src, $url_match)) {
54 $font_url = trim($url_match[1], "'\"");
55 $font_filename = hash('sha256', $font_url, false);
56 $font_filename = substr($font_filename, 0, 10) . '.' . pathinfo($font_url, PATHINFO_EXTENSION);
57 if (!file_exists($easyfonts_dir . '/' . $font_filename)) {
58 $font_response = wp_remote_get($font_url, array('user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',));
59 if (is_wp_error($font_response)) {
60 add_settings_error('easyfont_process_content_link_tag', 'http_error', $font_response->get_error_message(), 'error');
61 continue;
62 }
63 $font_data = wp_remote_retrieve_body($font_response);
64 // Save the font file to the 'wp-content/uploads/easyfonts' directory
65 file_put_contents($easyfonts_dir . '/' . $font_filename, $font_data);
66 }
67 // Replace the src property with a local reference to the downloaded font file
68 if (is_ssl()) {
69 $base_url = set_url_scheme(wp_upload_dir()['baseurl'], 'https');
70 } else {
71 $base_url = wp_upload_dir()['baseurl'];
72 }
73 $css = str_replace($src, "url('" . $base_url . "/easyfonts/" . $font_filename . "')", $css);
74 }
75 }
76 }
77 }
78 }
79 // Save the modified stylesheet to the 'wp-content/uploads/easyfonts' directory
80 file_put_contents($easyfonts_dir . '/' . $filename, $css);
81 }
82 // Replace the href attribute with a local reference to the downloaded stylesheet
83 $link->href = wp_upload_dir() ['baseurl'] . '/easyfonts/' . $filename;
84 }
85 // Return the modified content
86 return $html->save();
87 }
88
89 function easyfont_process_content_import($content) {
90
91 $html = hgfl_str_get_html($content, false, true, 'UTF-8', false, PHP_EOL, ' ');
92 // Check if the 'easyfonts' directory exists and is writable
93 $easyfonts_dir = wp_upload_dir() ['basedir'] . '/easyfonts';
94 if (!wp_mkdir_p($easyfonts_dir)) {
95 return $content;
96 }
97 // Find all <style> tags with @import statements that import a Google Fonts stylesheet
98 foreach ($html->find('style') as $style) {
99 if (preg_match_all('/@import\s+(url\()?\s*([^\);]+)\s*(\))?/', $style->innertext, $matches)) {
100 foreach ($matches[2] as $match) {
101 if (strpos($match, 'fonts.googleapis.com') !== false) {
102 $url = trim($match, "'\"");
103 if (strpos($url, '//') === 0) {
104 $url = 'https:' . $url;
105 }
106 $filename = hash('sha256', $url, false);
107 $filename = substr($filename, 0, 10) . '.css';
108 // Check if the stylesheet file already exists
109 if (!file_exists($easyfonts_dir . '/' . $filename)) {
110 $response = wp_remote_get($url, array('user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',));
111 if (is_wp_error($response)) {
112 add_settings_error('easyfont_process_content_import', 'http_error', $response->get_error_message(), 'error');
113 return $content;
114 }
115 $css = wp_remote_retrieve_body($response);
116 if (preg_match_all('/@font-face\s*\{([^}]+)\}/', $css, $matches)) {
117 foreach ($matches[1] as $match) {
118 if (preg_match_all('/src\s*:\s*([^;]+);/', $match, $srcs)) {
119 foreach ($srcs[1] as $src) {
120 if (preg_match('/url\(([^)]+)\)/', $src, $url_match)) {
121 $font_url = trim($url_match[1], "'\"");
122 $font_filename = hash('sha256', $font_url, false);
123 $font_filename = substr($font_filename, 0, 10) . '.' . pathinfo($font_url, PATHINFO_EXTENSION);
124 // Check if the font file already exists
125 if (!file_exists($easyfonts_dir . '/' . $font_filename)) {
126
127 $font_response = wp_remote_get($font_url, array('user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',));
128 if (is_wp_error($font_response)) {
129 add_settings_error('easyfont_process_content_import', 'http_error', $font_response->get_error_message(), 'error');
130 continue;
131 }
132 $font_data = wp_remote_retrieve_body($font_response);
133 $file = fopen($easyfonts_dir . '/' . $font_filename, 'w');
134 fwrite($file, $font_data);
135 fclose($file);
136 }
137 if (is_ssl()) {
138 $base_url = set_url_scheme(wp_upload_dir()['baseurl'], 'https');
139 } else {
140 $base_url = wp_upload_dir()['baseurl'];
141 }
142 $css = str_replace($src, "url('" . $base_url . "/easyfonts/" . $font_filename . "')", $css);
143 }
144 }
145 }
146 }
147 }
148 // Save the modified stylesheet to the 'wp-content/uploads/easyfonts' directory
149 file_put_contents($easyfonts_dir . '/' . $filename, $css);
150 }
151 // Replace the @import statement with a local reference to the downloaded stylesheet
152 $style->innertext = str_replace($match, "" . wp_upload_dir() ['baseurl'] . '/easyfonts/' . $filename . "", $style->innertext);
153 }
154 }
155 }
156 }
157 // Return the modified content
158 return $html->save();
159 }
160 function easyfonts_remove_resource_hints($html) {
161 // Load the HTML into the Simple HTML DOM library
162 $dom = hgfl_str_get_html($html, false, true, 'UTF-8', false, PHP_EOL, ' ');
163
164 // Find all <link> elements with the preload, preconnect, or prefetch attributes
165 $links = $dom->find('link[rel=preload],link[rel=preconnect],link[rel=dns-prefetch]');
166
167 // Loop through the <link> elements
168 foreach($links as $link) {
169 // Check if the <link> element has a href attribute with the fonts.googleapis.com or fonts.gstatic.com domain
170 if (preg_match('/(https:\/\/|\/\/)(fonts\.googleapis\.com|fonts\.gstatic\.com)/', $link->href)) {
171 // Remove the <link> element
172 $link->outertext = '';
173 }
174 }
175
176 // Find all <style> elements
177 $styles = $dom->find('style');
178
179 // Loop through the <style> elements
180 foreach($styles as $style) {
181 // Remove comments that contain the fonts.googleapis.com or fonts.gstatic.com domain
182 if (strpos($style->innertext, 'fonts.googleapis.com') !== false || strpos($style->innertext, 'fonts.gstatic.com') !== false) {
183 $style->innertext = preg_replace('#/\*(?:[^*]*(?:\*(?!/))*)*\*/#','',$style->innertext);
184 }
185 }
186 // Return the modified HTML
187 return $dom->save();
188 }
189
190
191 function easyfont_remove_font_scripts($html) {
192 // Load the HTML string into a Simple HTML DOM object
193 $dom = hgfl_str_get_html($html, false, true, 'UTF-8', false, PHP_EOL, ' ');
194
195 // Find all `script` elements
196 $scripts = $dom->find('script');
197 foreach($scripts as $script) {
198 // Check if the `script` element contains the `WebFontConfig` or `webfont.js` strings
199 if(strpos($script->innertext, 'WebFontConfig') !== false || strpos($script->innertext, 'webfont.js') !== false) {
200 // Remove the `script` element
201 $script->outertext = '';
202 }
203 }
204
205 // Return the modified HTML as a string
206 return $dom->save();
207 }
208
209 function easyfont_download_gstatic_fonts($content) {
210 // Create the "easyfonts" directory if it doesn't exist
211 $easyfonts_dir = wp_upload_dir()['basedir'] . '/easyfonts';
212 if (!wp_mkdir_p($easyfonts_dir)) {
213 return $content;
214 }
215 $content = preg_replace('/(url\s?\(["\']?)\/\/(fonts\.gstatic\.com[^"\']+)/', '$1https://$2', $content);
216 $html = hgfl_str_get_html($content, false, true, 'UTF-8', false, PHP_EOL, ' ');
217 foreach ($html->find('style') as $style) {
218 if (preg_match_all('/url\(([^)]+)\)/', $style->innertext, $matches)) {
219 foreach ($matches[1] as $match) {
220 $url = trim($match, "'\"");
221 if(strpos($url,'//') === 0){
222 $url = 'https:'.$url;
223 }
224 if (strpos($url, 'fonts.gstatic.com') !== false) {
225 $path_parts = pathinfo($url);
226 $extension = isset($path_parts['extension'])?$path_parts['extension']:'';
227 if (empty($extension)) {
228 if(strpos($url,'/l/font') !== false){
229 $extension = 'svg';
230 }else{
231 $extension = 'woff2';
232 }
233 }
234 $filename = hash('sha256', $url, false);
235 $filename = substr($filename, 0, 10) . '.' . $extension;
236 // Check if the font file already exists
237 if (!file_exists($easyfonts_dir . '/' . $filename)) {
238 $response = wp_remote_get($url, array('user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',));
239 if (is_wp_error($response)) {
240 add_settings_error('download_gstatic_fonts', 'http_error', $response->get_error_message(), 'error');
241 return $content;
242 }
243 $font_data = wp_remote_retrieve_body($response);
244 $file = fopen($easyfonts_dir . '/' . $filename, 'w');
245 fwrite($file, $font_data);
246 fclose($file);
247 }
248 $local_url = wp_upload_dir()['baseurl'] . '/easyfonts/' . $filename;
249 $content = str_replace($url, $local_url, $content);
250 }
251 }
252 }
253 }
254 return $content;
255 }
256
257
258 function easy_fonts_run_template_redirect() {
259
260 if (get_option('easyfonts_host_google_fonts_locally_link', false)) {
261 ob_start( 'easyfont_process_content_link_tag',0, PHP_OUTPUT_HANDLER_REMOVABLE );
262 }
263 if (get_option('easyfonts_host_google_fonts_locally_import', false)) {
264 ob_start( 'easyfont_process_content_import',0, PHP_OUTPUT_HANDLER_REMOVABLE );
265 }
266
267 if (get_option('easyfonts_remove_inline_css_fontface', false)) {
268 ob_start( 'easyfont_download_gstatic_fonts',0, PHP_OUTPUT_HANDLER_REMOVABLE );
269 }
270
271 if (get_option('easyfonts_remove_resource_hints', false)) {
272 ob_start( 'easyfonts_remove_resource_hints',0, PHP_OUTPUT_HANDLER_REMOVABLE );
273 }
274
275 if (get_option('easyfonts_remove_inline_script_font', false)) {
276 ob_start( 'easyfont_remove_font_scripts',0, PHP_OUTPUT_HANDLER_REMOVABLE );
277 }
278 //ob_start( 'download_gstatic_fonts',0, PHP_OUTPUT_HANDLER_REMOVABLE );
279
280
281 }
282 add_action( 'template_redirect', 'easy_fonts_run_template_redirect', 999 );
283
284 function easyfonts_enqueue_options_styles() {
285 if ( 'settings_page_easyfonts' == get_current_screen()->id ) {
286 wp_enqueue_style( 'easyfonts-options-styles', plugin_dir_url( __FILE__ ) . 'assets/style.css', array(), '1.0.0' );
287 }
288 }
289 add_action( 'admin_enqueue_scripts', 'easyfonts_enqueue_options_styles' );
290
291 function easyfonts_settings_link($links) {
292 $settings_link = '<a href="options-general.php?page=easyfonts">Settings</a>';
293 array_push($links, $settings_link);
294 return $links;
295 }
296 add_filter("plugin_action_links_easyfonts/easyfonts.php", "easyfonts_settings_link");