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

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