PluginProbe
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant / 1.0.2
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant v1.0.2
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.2, at easyfonts.php

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