PluginProbe
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant / 1.3
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant v1.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 / inc / options.php

options.php in EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant 1.3, at inc/options.php

324 lines 16.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'WPINC' ) ) {
3 die;
4 }
5
6 class EasyFonts_Options {
7
8 public function __construct() {
9 add_action( 'admin_menu', [ $this, 'add_options_page' ] );
10 add_action( 'admin_init', [ $this, 'register_settings' ] );
11 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_speed_check_assets' ] );
12 }
13
14 public function add_options_page() {
15 add_options_page(
16 __( 'Easy Fonts Options', 'easyfonts' ),
17 __( 'Easy Fonts', 'easyfonts' ),
18 'manage_options',
19 'easyfonts',
20 [ $this, 'options_page_html' ]
21 );
22 }
23
24 public function register_settings() {
25 register_setting( 'easyfonts', 'easyfonts_options' );
26
27 add_settings_section( 'easyfonts_main', __( 'Easy Fonts Settings', 'easyfonts' ), null, 'easyfonts' );
28
29 add_settings_field( 'host_link', __( 'Process Google fonts Stylesheet', 'easyfonts' ), [ $this, 'checkbox_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'host_link', 'desc' => __( 'Download Google Fonts from <code>&lt;link&gt;</code> and host them locally.', 'easyfonts' ) ] );
30 add_settings_field( 'host_import', __( 'Process @import inline style', 'easyfonts' ), [ $this, 'checkbox_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'host_import', 'desc' => __( 'Process <code>@import</code> rules from inline <code>&lt;style&gt;</code> tags.', 'easyfonts' ) ] );
31 add_settings_field( 'process_fontface', __( 'Process @font-face statement', 'easyfonts' ), [ $this, 'checkbox_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'process_fontface', 'desc' => __( 'Process <code>@font-face</code> from inline <code>&lt;style&gt;</code> tags.', 'easyfonts' ) ] );
32 add_settings_field( 'remove_hints', __( 'Remove Resource Hints', 'easyfonts' ), [ $this, 'checkbox_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'remove_hints', 'desc' => __( 'Remove resource hints like <code>preconnect</code>, <code>prefetch</code>.', 'easyfonts' ) ] );
33 add_settings_field( 'remove_scripts', __( 'Remove webfont.js fonts', 'easyfonts' ), [ $this, 'checkbox_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'remove_scripts', 'desc' => __( 'Remove Google Fonts loading from <code>webfont.js</code> inline scripts.', 'easyfonts' ) ] );
34 add_settings_field( 'combine_fonts', __( 'Combine Font Stylesheets', 'easyfonts' ), [ $this, 'checkbox_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'combine_fonts', 'desc' => __( 'Merge all locally hosted font CSS files into a single file and remove duplicates.', 'easyfonts' ) ] );
35 add_settings_field( 'font_display', __( 'Font Display', 'easyfonts' ), [ $this, 'select_field' ], 'easyfonts', 'easyfonts_main', [ 'label_for' => 'font_display', 'desc' => __( 'Set <code>font-display</code> on all <code>@font-face</code> declarations for better loading control.', 'easyfonts' ) ] );
36 }
37
38 public function checkbox_field( $args ) {
39 $options = get_option( 'easyfonts_options', [] );
40 $id = $args['label_for'];
41 $checked = ! empty( $options[ $id ] ) ? 'checked' : '';
42 echo '<div class="checkbox-wrapper-2"><label for="easyfonts_options[' . esc_attr( $id ) . ']"><input class="sc-gJwTLC ikxBAC" type="checkbox" id="easyfonts_options[' . esc_attr( $id ) . ']" name="easyfonts_options[' . esc_attr( $id ) . ']" value="1" ' . $checked . '><span class="slider"></span></label></div>';
43 if ( ! empty( $args['desc'] ) ) {
44 echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>';
45 }
46 }
47
48 public function select_field( $args ) {
49 $options = get_option( 'easyfonts_options', [] );
50 $id = $args['label_for'];
51 $current = ! empty( $options[ $id ] ) ? $options[ $id ] : 'none';
52 $choices = [
53 'none' => __( 'Disabled', 'easyfonts' ),
54 'auto' => 'auto',
55 'block' => 'block',
56 'swap' => 'swap',
57 'fallback' => 'fallback',
58 'optional' => 'optional',
59 ];
60 echo '<select name="easyfonts_options[' . esc_attr( $id ) . ']" id="easyfonts_options[' . esc_attr( $id ) . ']" class="easyfonts-select">';
61 foreach ( $choices as $val => $label ) {
62 $selected = selected( $current, $val, false );
63 echo '<option value="' . esc_attr( $val ) . '" ' . $selected . '>' . esc_html( $label ) . '</option>';
64 }
65 echo '</select>';
66 if ( ! empty( $args['desc'] ) ) {
67 echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>';
68 }
69 }
70
71 public function options_page_html() {
72 if ( ! current_user_can( 'manage_options' ) ) {
73 return;
74 }
75
76 $this->handle_actions();
77
78 $options = get_option( 'easyfonts_options', [] );
79 ?><div class="easymain">
80 <div class="easyfontwrap">
81 <div class="heading"><h1><?php esc_html_e( 'Easy Fonts Options', 'easyfonts' ); ?></h1></div>
82 <p class="confirm"><?php printf( __( 'This plugin is free, fast, and extremely lightweight (only 30KB). If you find it useful, <a href="%s" target="_blank">Support Us with 5⭐ Rating</a>', 'easyfonts' ), 'https://wordpress.org/support/plugin/easyfonts/reviews/#new-post' ); ?></p>
83 <form method="post" action="options.php">
84 <?php
85 settings_fields( 'easyfonts' );
86 do_settings_sections( 'easyfonts' );
87 submit_button( __( 'Save Changes', 'easyfonts' ), 'primary', 'submit', true, array( 'id' => 'easyfonts_submit' ) );
88 ?>
89 </form>
90 <form method="post">
91 <?php wp_nonce_field( 'easyfonts_actions', 'easyfonts_nonce' ); ?>
92 <button type="submit" name="easyfonts_clear_cache" class="button remove"><?php esc_html_e( 'Remove All stored Fonts', 'easyfonts' ); ?></button>
93 <?php if ( ! empty( $options['host_link'] ) || ! empty( $options['host_import'] ) || ! empty( $options['process_fontface'] ) ) : ?>
94 <button type="submit" name="easyfonts_preload" class="button preload"><?php esc_html_e( 'Preload Fonts', 'easyfonts' ); ?></button>
95 <?php endif; ?>
96 </form>
97 <?php
98 if ( ! empty( $options['host_link'] ) || ! empty( $options['host_import'] ) || ! empty( $options['combine_fonts'] ) ) {
99 $this->list_styles();
100 }
101 ?>
102 </div><div class="easy">
103 <div id="speed-results">
104 <h1>Is Your Hosting Slowing You Down?</h1><p>
105 Your hosting plays a key role in website speed and user experience. Analyze your server’s performance now, and explore better solutions if needed.
106 </p>
107 </div>
108 <button id="check-speed-btn" class="button button-primary">Run Speed Test</button></div></div>
109 <?php
110 }
111
112 private function handle_actions() {
113 if ( empty( $_POST['easyfonts_nonce'] ) || ! wp_verify_nonce( $_POST['easyfonts_nonce'], 'easyfonts_actions' ) ) {
114 return;
115 }
116
117 if ( isset( $_POST['easyfonts_clear_cache'] ) ) {
118 $this->clear_font_cache();
119 }
120
121 if ( isset( $_POST['easyfonts_preload'] ) ) {
122 $this->preload_fonts();
123 }
124 }
125
126 private function clear_font_cache() {
127 $dir = EASYFONTS_UPLOAD_DIR;
128 if ( is_dir( $dir ) ) {
129 $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST );
130 foreach ( $files as $fileinfo ) {
131 $todo = ( $fileinfo->isDir() ? 'rmdir' : 'unlink' );
132 $todo( $fileinfo->getRealPath() );
133 }
134 rmdir( $dir );
135 }
136 add_settings_error( 'easyfonts_messages', 'easyfonts_message', __( 'The fonts have been removed.', 'easyfonts' ), 'success' );
137 }
138
139 private function preload_fonts() {
140 $current_user = wp_get_current_user();
141 if ( ! user_can( $current_user, 'manage_options' ) ) {
142 return;
143 }
144 $tokens = $current_user->get_session_tokens();
145 $options = [
146 'cookies' => $tokens,
147 'headers' => [
148 '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',
149 ],
150 ];
151 $home_url = home_url( '?easyfonts_preload=1' );
152 $response = wp_remote_get( $home_url, $options );
153 if ( is_wp_error( $response ) ) {
154 add_settings_error( 'easyfonts_messages', 'easyfonts_message', __( 'Preload failed: ', 'easyfonts' ) . $response->get_error_message(), 'error' );
155 } else {
156 add_settings_error( 'easyfonts_messages', 'easyfonts_message', __( 'The fonts have been preloaded.', 'easyfonts' ), 'success' );
157 }
158 }
159
160
161
162 private function list_styles() {
163 $options = get_option( 'easyfonts_options', [] );
164 $combine_enabled = ! empty( $options['combine_fonts'] );
165 $css_files = [];
166 $style_data = [];
167
168 if ( ! is_dir( EASYFONTS_UPLOAD_DIR ) ) {
169 echo '<p>' . esc_html__( 'Fonts styles are not found. Preload the font first or visit the homepage.', 'easyfonts' ) . '</p>';
170 return;
171 }
172 $dir = new DirectoryIterator( EASYFONTS_UPLOAD_DIR );
173 foreach ( $dir as $file ) {
174 if ( ! $file->isFile() || $file->getExtension() !== 'css' ) {
175 continue;
176 }
177 $fname = $file->getFilename();
178 // When combine is enabled, only show combined file
179 if ( $combine_enabled && strpos( $fname, '_combined.css' ) === false ) {
180 continue;
181 }
182 // When combine is disabled, skip combined files
183 if ( ! $combine_enabled && strpos( $fname, '_combined.css' ) !== false ) {
184 continue;
185 }
186 $css_files[] = $fname;
187 }
188 if ( empty( $css_files ) ) {
189 echo '<p>' . esc_html__( 'Fonts styles are not found. Preload the font first or visit the homepage.', 'easyfonts' ) . '</p>';
190 return;
191 }
192 foreach ( $css_files as $file_name ) {
193 if ( strpos( $file_name, '..' ) !== false ) {
194 continue;
195 }
196 $file_path = EASYFONTS_UPLOAD_DIR . '/' . $file_name;
197 if ( ! is_readable( $file_path ) ) {
198 continue;
199 }
200 $file_content = file_get_contents( $file_path );
201 $font_family = [];
202 $variant_italic = [];
203 $variant_normal = [];
204 preg_match_all( '/@font-face\s*{[^}]+}/', $file_content, $matches );
205 if ( empty( $matches[0] ) ) {
206 continue;
207 }
208 foreach ( $matches[0] as $font_face ) {
209 if ( preg_match( '/font-family:\s*[\'"]?([^;\'"]+)[\'"]?;/', $font_face, $family_match ) ) {
210 $font_family[] = trim( $family_match[1] );
211 }
212 if ( preg_match( '/font-style:\s*([^;]+);/', $font_face, $style_match ) ) {
213 $style = trim( $style_match[1] );
214 if ( preg_match( '/font-weight:\s*([^;]+);/', $font_face, $weight_match ) ) {
215 $weight = trim( $weight_match[1] );
216 if ( $style === 'italic' ) {
217 $variant_italic[] = $weight;
218 } elseif ( $style === 'normal' ) {
219 $variant_normal[] = $weight;
220 }
221 }
222 }
223 }
224 $font_family = array_unique( $font_family );
225 $variant_italic = array_unique( $variant_italic );
226 $variant_normal = array_unique( $variant_normal );
227 $style_data[] = [
228 'file_url' => esc_url( EASYFONTS_UPLOAD_URL . '/' . $file_name ),
229 'font_families' => esc_html( implode( ', ', $font_family ) ),
230 'variant' => esc_html( 'italic: ' . implode( ', ', $variant_italic ) . ' | normal: ' . implode( ', ', $variant_normal ) ),
231 ];
232 }
233 if ( empty( $style_data ) ) {
234 return;
235 }
236 echo '<table class="styled-table"><thead><tr><th>' . esc_html__( 'Hosted Fonts CSS URL', 'easyfonts' ) . '</th><th>' . esc_html__( 'Font Families', 'easyfonts' ) . '</th><th>' . esc_html__( 'Variants', 'easyfonts' ) . '</th></tr></thead><tbody>';
237 foreach ( $style_data as $style ) {
238 echo '<tr><td><a href="' . $style['file_url'] . '" target="_blank" rel="noopener">' . $style['file_url'] . '</a></td><td>' . $style['font_families'] . '</td><td>' . $style['variant'] . '</td></tr>';
239 }
240 echo '</tbody></table>';
241 }
242 public function enqueue_speed_check_assets( $hook ) {
243 if ( 'settings_page_easyfonts' !== $hook ) {
244 return;
245 }
246
247 wp_enqueue_script( 'jquery' ); // Ensure jQuery.
248
249 // Localize PHP values into JS safely
250 wp_localize_script( 'jquery', 'speedCheckData', array(
251 'apiKey' => 'AIzaSyA3CHybGfa0lOaXRwjc42lJDxAZsG3Rwos',
252 'pageUrl' => home_url(),
253 'phpVersion' => phpversion(),
254 'affiliateLink' => 'https://unified.cloudways.com/signup?id=662383&coupon=EASYWPSTUFF',
255 ) );
256
257 $script = <<<JS
258 jQuery(document).ready(function($) {
259 $('#check-speed-btn').click(function() {
260 var btn = $(this);
261 btn.text('🔍 Checking Site Speed…').prop('disabled', true);
262 var apiKey = speedCheckData.apiKey;
263 var pageUrl = speedCheckData.pageUrl;
264 var phpVersion = speedCheckData.phpVersion;
265 var affiliateLink = speedCheckData.affiliateLink;
266
267 var mobileApiUrl = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' + encodeURIComponent(pageUrl) + '&strategy=mobile&key=' + apiKey;
268 var desktopApiUrl = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' + encodeURIComponent(pageUrl) + '&strategy=desktop&key=' + apiKey;
269
270 $('#speed-results').html('<div class="lds-hourglass"></div><p class="checking-speed">⏳Fetching Performance Data…... Please wait.</p>');
271
272 $.when(
273 $.get(mobileApiUrl),
274 $.get(desktopApiUrl)
275 ).done(function(mobileResponse, desktopResponse) {
276 var mobileScore = Math.round(mobileResponse[0].lighthouseResult.categories.performance.score * 100);
277 var desktopScore = Math.round(desktopResponse[0].lighthouseResult.categories.performance.score * 100);
278 var mobileSpeed = (mobileResponse[0].lighthouseResult.audits['speed-index'].numericValue / 1000).toFixed(2);
279 var desktopSpeed = (desktopResponse[0].lighthouseResult.audits['speed-index'].numericValue / 1000).toFixed(2);
280
281 var resultHtml = '<div class="result-item mobile-score"><strong>📱 Mobile Score:</strong> <span class="score">' + mobileScore + '</span></div>';
282 resultHtml += '<div class="result-item desktop-score"><strong>💻 Desktop Score:</strong> <span class="score">' + desktopScore + '</span></div>';
283 resultHtml += '<div class="result-item mobile-speed"><strong>📱 Mobile Speed:</strong> <span class="speed">' + mobileSpeed + ' sec</span></div>';
284 resultHtml += '<div class="result-item desktop-speed"><strong>💻 Desktop Speed:</strong> <span class="speed">' + desktopSpeed + ' sec</span></div>';
285 resultHtml += '<div class="result-item php-version"><strong>🐘 PHP Version:</strong> ' + phpVersion + '</div>';
286
287 var shouldRecommend = false;
288
289 if (mobileScore < 50 || desktopScore < 50) {
290 shouldRecommend = true;
291 resultHtml += '<div class="warning"><span style="color:red;">⚠️ Low PageSpeed score detected!</span></div>';
292 }
293
294 if (mobileSpeed > 3 || desktopSpeed > 2) {
295 shouldRecommend = true;
296 resultHtml += '<div class="warning"><span style="color:red;">⚠️ Your server is slow!</span></div>';
297 }
298
299 if (parseFloat(phpVersion) < 7.4) {
300 shouldRecommend = true;
301 resultHtml += '<div class="warning"><span style="color:red;">⚠️ Your PHP version is outdated!</span></div>';
302 }
303
304 if (shouldRecommend) {
305 resultHtml += '<div class="recommendation"> <a class="downeasy" href="' + affiliateLink + '" target="_blank">Switch to Faster Hosting</a></div>';
306 } else {
307 resultHtml += '<div class="optimized"><span style="color: #9dffa7;font-size: 20px;">�
308 Your server is well-optimized!</span></div>';
309 }
310
311 $('#speed-results').html(resultHtml);
312 $('#check-speed-btn').hide();
313 }).fail(function() {
314 $('#speed-results').html('<p style="color:red;">⚠️ Error fetching speed test results.</p>');
315 });
316 });
317 });
318 JS;
319
320 wp_add_inline_script( 'jquery', $script );
321 }
322 }
323
324 new EasyFonts_Options();