PluginProbe
Autoptimize / 2.3.4
Autoptimize v2.3.4
2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 All 107 releases
autoptimize / classlesses / autoptimizeExtra.php

autoptimizeExtra.php in Autoptimize 2.3.4, at classlesses/autoptimizeExtra.php

387 lines 19.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4 // initialize
5 if ( is_admin() ) {
6 add_action( 'admin_menu', 'autoptimize_extra_admin' );
7 add_filter( 'autoptimize_filter_settingsscreen_tabs','add_autoptimize_extra_tab' );
8 } else {
9 autoptimize_extra_init();
10 }
11
12 // get option
13 function autoptimize_extra_get_options() {
14 $_default_val = array("autoptimize_extra_checkbox_field_1"=>"0","autoptimize_extra_checkbox_field_0"=>"0","autoptimize_extra_radio_field_4"=>"1","autoptimize_extra_text_field_2"=>"","autoptimize_extra_text_field_3"=>"");
15 $_option_val = get_option( 'autoptimize_extra_settings' );
16 if (empty($_option_val)) {
17 $_option_val = $_default_val;
18 }
19 return $_option_val;
20 }
21
22 // frontend init
23 function autoptimize_extra_init() {
24 $autoptimize_extra_options = autoptimize_extra_get_options();
25
26 /* disable emojis */
27 if ( !empty($autoptimize_extra_options['autoptimize_extra_checkbox_field_1']) ) {
28 autoptimize_extra_disable_emojis();
29 }
30
31 /* remove version from query string */
32 if ( !empty($autoptimize_extra_options['autoptimize_extra_checkbox_field_0']) ) {
33 add_filter( 'script_loader_src', 'autoptimize_extra_remove_qs', 15, 1 );
34 add_filter( 'style_loader_src', 'autoptimize_extra_remove_qs', 15, 1 );
35 }
36
37 /*
38 * async JS
39 *
40 * is_plugin_active is not available in frontend by default
41 * cfr. https://codex.wordpress.org/Function_Reference/is_plugin_active
42 * so we need to source in wp-admin/includes/plugin.php
43 */
44 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
45 $_asyncJSactive = false;
46 if ( function_exists('is_plugin_active') && is_plugin_active('async-javascript/async-javascript.php') ) {
47 $_asyncJSactive = true;
48 }
49 if ( !empty($autoptimize_extra_options['autoptimize_extra_text_field_3']) && $_asyncJSactive === false ) {
50 add_filter('autoptimize_filter_js_exclude','autoptimize_extra_async_js',10,1);
51 }
52
53 /* optimize google fonts */
54 if ( !empty( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] ) && ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] != "1" ) ) {
55 add_filter( 'wp_resource_hints', 'autoptimize_extra_gfonts_remove_dnsprefetch', 10, 2 );
56 if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "2" ) {
57 add_filter('autoptimize_filter_css_removables','autoptimize_extra_remove_gfonts',10,1);
58 } else {
59 add_filter('autoptimize_html_after_minify','autoptimize_extra_gfonts',10,1);
60 add_filter('autoptimize_extra_filter_tobepreconn','autoptimize_extra_preconnectgooglefonts',10,1);
61 }
62 }
63
64 /* preconnect */
65 if ( !empty($autoptimize_extra_options['autoptimize_extra_text_field_2']) || has_filter('autoptimize_extra_filter_tobepreconn') ) {
66 add_filter( 'wp_resource_hints', 'autoptimize_extra_preconnect', 10, 2 );
67 }
68 }
69
70 // disable emoji's functions
71 function autoptimize_extra_disable_emojis() {
72 // all actions related to emojis
73 remove_action( 'admin_print_styles', 'print_emoji_styles' );
74 remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
75 remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
76 remove_action( 'wp_print_styles', 'print_emoji_styles' );
77 remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
78 remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
79 remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
80
81 // filter to remove TinyMCE emojis
82 add_filter( 'tiny_mce_plugins', 'autoptimize_extra_disable_emojis_tinymce' );
83
84 // and remove dns-prefetch for emoji
85 add_filter( 'wp_resource_hints', 'autoptimize_extra_emojis_remove_dns_prefetch', 10, 2 );
86 }
87
88 function autoptimize_extra_disable_emojis_tinymce( $plugins ) {
89 if ( is_array( $plugins ) ) {
90 return array_diff( $plugins, array( 'wpemoji' ) );
91 } else {
92 return array();
93 }
94 }
95
96 function autoptimize_extra_emojis_remove_dns_prefetch( $urls, $relation_type ) {
97 $_emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/' );
98
99 return autoptimize_extra_remove_dns_prefetch( $urls, $relation_type, $_emoji_svg_url );
100 }
101
102 // remove query string function
103 function autoptimize_extra_remove_qs( $src ) {
104 if ( strpos($src, '?ver=') ) {
105 $src = remove_query_arg( 'ver', $src );
106 }
107 return $src;
108 }
109
110 // async function
111 function autoptimize_extra_async_js($in) {
112 $autoptimize_extra_options = autoptimize_extra_get_options();
113
114 // get exclusions
115 $AO_JSexclArrayIn = array();
116 if (!empty($in)) {
117 $AO_JSexclArrayIn = array_fill_keys(array_filter(array_map('trim',explode(",",$in))),"");
118 }
119
120 // get asyncs
121 $_fromSetting = $autoptimize_extra_options['autoptimize_extra_text_field_3'];
122 $AO_asynced_JS = array_fill_keys(array_filter(array_map('trim',explode(",",$_fromSetting))),"");
123 $AO_async_flag = apply_filters('autoptimize_filter_extra_async',"async");
124 foreach ($AO_asynced_JS as $JSkey => $JSvalue) {
125 $AO_asynced_JS[$JSkey] = $AO_async_flag;
126 }
127
128 // merge exclusions & asyncs in one array and return to AO API
129 $AO_excl_w_async = array_merge( $AO_JSexclArrayIn, $AO_asynced_JS );
130 return $AO_excl_w_async;
131 }
132
133 // preconnect function
134 function autoptimize_extra_preconnect($hints, $relation_type) {
135 $autoptimize_extra_options = autoptimize_extra_get_options();
136
137 // get setting and store in array
138 $_to_be_preconnected = array_filter(array_map('trim',explode(",",$autoptimize_extra_options['autoptimize_extra_text_field_2'])));
139 $_to_be_preconnected = apply_filters( 'autoptimize_extra_filter_tobepreconn', $_to_be_preconnected );
140
141 // walk array, extract domain and add to new array with crossorigin attribute
142 foreach ($_to_be_preconnected as $_preconn_single) {
143 $_preconn_parsed = parse_url($_preconn_single);
144
145 if ( is_array($_preconn_parsed) && empty($_preconn_parsed['scheme']) ) {
146 $_preconn_domain = "//".$_preconn_parsed['host'];
147 } else if ( is_array($_preconn_parsed) ) {
148 $_preconn_domain = $_preconn_parsed['scheme']."://".$_preconn_parsed['host'];
149 }
150
151 if ( !empty($_preconn_domain) ) {
152 $_preconn_hint = array('href' => $_preconn_domain);
153 // fonts don't get preconnected unless crossorigin flag is set, non-fonts don't get preconnected if origin flag is set
154 // so hardcode fonts.gstatic.com to come with crossorigin and have filter to add other domains if needed
155 $_preconn_crossorigin = apply_filters( 'autoptimize_extra_filter_preconn_crossorigin', array('https://fonts.gstatic.com') );
156 if ( in_array( $_preconn_domain, $_preconn_crossorigin ) ) {
157 $_preconn_hint['crossorigin'] = 'anonymous';
158 }
159 $_new_hints[] = $_preconn_hint;
160 }
161 }
162
163 // merge in wordpress' preconnect hints
164 if ( 'preconnect' === $relation_type && !empty($_new_hints) ) {
165 $hints = array_merge($hints, $_new_hints);
166 }
167
168 return $hints;
169 }
170
171 // google font functions
172 function autoptimize_extra_gfonts_remove_dnsprefetch ( $urls, $relation_type ) {
173 $_gfonts_url = "fonts.googleapis.com";
174
175 return autoptimize_extra_remove_dns_prefetch( $urls, $relation_type, $_gfonts_url );
176 }
177
178 function autoptimize_extra_remove_gfonts($in) {
179 // simply remove google fonts
180 return $in.", fonts.googleapis.com";
181 }
182
183 function autoptimize_extra_gfonts($in) {
184 $autoptimize_extra_options = autoptimize_extra_get_options();
185
186 // extract fonts, partly based on wp rocket's extraction code
187 $_without_comments = preg_replace( '/<!--(.*)-->/Uis', '', $in );
188 preg_match_all( '#<link(?:\s+(?:(?!href\s*=\s*)[^>])+)?(?:\s+href\s*=\s*([\'"])((?:https?:)?\/\/fonts\.googleapis\.com\/css(?:(?!\1).)+)\1)(?:\s+[^>]*)?>#iU', $_without_comments, $matches );
189
190 $i = 0;
191 $fontsCollection = array();
192 if ( ! $matches[2] ) {
193 return $in;
194 }
195
196 // store them in $fonts array
197 foreach ( $matches[2] as $font ) {
198 if ( ! preg_match( '/rel=["\']dns-prefetch["\']/', $matches[0][ $i ] ) ) {
199 // Get fonts name.
200 $font = str_replace( array( '%7C', '%7c' ) , '|', $font );
201 $font = explode( 'family=', $font );
202 $font = ( isset( $font[1] ) ) ? explode( '&', $font[1] ) : array();
203 // Add font to $fonts[$i] but make sure not to pollute with an empty family
204 $_thisfont = array_values( array_filter( explode( '|', reset( $font ) ) ) );
205 if ( !empty($_thisfont) ) {
206 $fontsCollection[$i]["fonts"] = $_thisfont;
207 // And add subset if any
208 $subset = ( is_array( $font ) ) ? end( $font ) : '';
209 if ( false !== strpos( $subset, 'subset=' ) ) {
210 $subset = explode( 'subset=', $subset );
211 $fontsCollection[$i]["subsets"] = explode( ',', $subset[1] );
212 }
213 }
214 // And remove Google Fonts.
215 $in = str_replace( $matches[0][ $i ], '', $in );
216 }
217 $i++;
218 }
219
220 $_fontsOut="";
221 if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "3" ) {
222 // aggregate & link
223 $_fontsString="";
224 $_subsetString="";
225 foreach ($fontsCollection as $font) {
226 $_fontsString .= '|'.trim( implode( '|' , $font["fonts"] ), '|' );
227 if ( !empty( $font["subsets"] ) ) {
228 $_subsetString .= implode( ',', $font["subsets"] );
229 }
230 }
231
232 if (!empty($_subsetString)) {
233 $_fontsString = $_fontsString."#038;subset=".$_subsetString;
234 }
235
236 $_fontsString = str_replace( '|', '%7C', ltrim($_fontsString,'|') );
237
238 if ( ! empty( $_fontsString ) ) {
239 $_fontsOut = '<link rel="stylesheet" id="ao_optimized_gfonts" href="https://fonts.googleapis.com/css?family=' . $_fontsString . '" />';
240 }
241 } else if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "4" ) {
242 // aggregate & load async (webfont.js impl.)
243 $_fontsArray = array();
244 foreach ($fontsCollection as $_fonts) {
245 if ( !empty( $_fonts["subsets"] ) ) {
246 $_subset = implode(",",$_fonts["subsets"]);
247 foreach ($_fonts["fonts"] as $key => $_one_font) {
248 $_one_font = $_one_font.":".$_subset;
249 $_fonts["fonts"][$key] = $_one_font;
250 }
251 }
252 $_fontsArray = array_merge($_fontsArray, $_fonts["fonts"]);
253 }
254
255 $_fontsOut = '<script data-cfasync="false" type="text/javascript">WebFontConfig={google:{families:[\'';
256 foreach ($_fontsArray as $_font) {
257 $_fontsOut .= $_font."','";
258 }
259 $_fontsOut = trim(trim($_fontsOut,"'"),",");
260 $_fontsOut .= '] },classes:false, events:false, timeout:1500};(function() {var wf = document.createElement(\'script\');wf.src=\'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js\';wf.type=\'text/javascript\';wf.defer=\'true\';var s=document.getElementsByTagName(\'script\')[0];s.parentNode.insertBefore(wf, s);})();</script>';
261 }
262
263 // inject in HTML
264 $out = substr_replace($in, $_fontsOut."<link", strpos($in, "<link"), strlen("<link"));
265 return $out;
266 }
267
268 function autoptimize_extra_preconnectgooglefonts($in) {
269 $autoptimize_extra_options = autoptimize_extra_get_options();
270
271 // preconnect to fonts.gstatic.com speed up download of static font-files
272 $in[] = "https://fonts.gstatic.com";
273 if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "4" ) {
274 // and more preconnects for webfont.js
275 $in[] = "https://ajax.googleapis.com";
276 $in[] = "https://fonts.googleapis.com";
277 }
278 return $in;
279 }
280
281 function autoptimize_extra_remove_dns_prefetch( $urls, $relation_type, $_remove_url ) {
282 if ( 'dns-prefetch' == $relation_type ) {
283 $_count=0;
284 foreach ($urls as $_url) {
285 if ( strpos($_url, $_remove_url) !== false ) {
286 unset($urls[$_count]);
287 }
288 $_count++;
289 }
290 }
291
292 return $urls;
293 }
294
295 /* admin page functions */
296 function autoptimize_extra_admin() {
297 add_submenu_page( null, 'autoptimize_extra', 'autoptimize_extra', 'manage_options', 'autoptimize_extra', 'autoptimize_extra_options_page' );
298 register_setting( 'autoptimize_extra_settings', 'autoptimize_extra_settings' );
299 }
300
301 function add_autoptimize_extra_tab($in) {
302 $in=array_merge($in,array('autoptimize_extra' => __('Extra','autoptimize')));
303 return $in;
304 }
305
306 function autoptimize_extra_options_page() {
307 $autoptimize_extra_options = autoptimize_extra_get_options();
308 $_googlef = $autoptimize_extra_options['autoptimize_extra_radio_field_4'];
309 ?>
310 <style>
311 #ao_settings_form {background: white;border: 1px solid #ccc;padding: 1px 15px;margin: 15px 10px 10px 0;}
312 #ao_settings_form .form-table th {font-weight: 100;}
313 #autoptimize_extra_descr{font-size: 120%;}
314 </style>
315 <div class="wrap">
316 <h1><?php _e('Autoptimize Settings','autoptimize'); ?></h1>
317 <?php echo autoptimizeConfig::ao_admin_tabs(); ?>
318 <form id='ao_settings_form' action='options.php' method='post'>
319 <?php settings_fields('autoptimize_extra_settings'); ?>
320 <h2><?php _e('Extra Auto-Optimizations','autoptimize'); ?></h2>
321 <span id='autoptimize_extra_descr'><?php _e('The following settings can improve your site\'s performance even more.','autoptimize'); ?></span>
322 <table class="form-table">
323 <tr>
324 <th scope="row"><?php _e('Remove emojis','autoptimize'); ?></th>
325 <td>
326 <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_1]' <?php if (!empty($autoptimize_extra_options['autoptimize_extra_checkbox_field_1']) && 1 == $autoptimize_extra_options['autoptimize_extra_checkbox_field_1']) echo 'checked="checked"'; ?> value='1'><?php _e('Removes WordPress\' core emojis\' inline CSS, inline JavaScript, and an otherwise un-autoptimized JavaScript file.','autoptimize'); ?></label>
327 </td>
328 </tr>
329 <tr>
330 <th scope="row"><?php _e('Remove query strings from static resources','autoptimize'); ?></th>
331 <td>
332 <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_0]' <?php if (!empty( $autoptimize_extra_options['autoptimize_extra_checkbox_field_0']) && 1 == $autoptimize_extra_options['autoptimize_extra_checkbox_field_0']) echo 'checked="checked"'; ?> value='1'><?php _e('Removing query strings (or more specificaly the <code>ver</code> parameter) will not improve load time, but might improve performance scores.','autoptimize'); ?></label>
333 </td>
334 </tr>
335 <tr>
336 <th scope="row"><?php _e('Google Fonts','autoptimize'); ?></th>
337 <td>
338 <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="1" <?php if (!in_array($_googlef,array(2,3,4))) {echo "checked"; } ?> ><?php _e('Leave as is','autoptimize'); ?><br/>
339 <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="2" <?php checked(2, $_googlef, true); ?> ><?php _e('Remove Google Fonts','autoptimize'); ?><br/>
340 <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="3" <?php checked(3, $_googlef, true); ?> ><?php _e('Combine and link in head','autoptimize'); ?><br/>
341 <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="4" <?php checked(4, $_googlef, true); ?> ><?php _e('Combine and load fonts asynchronously with <a href="https://github.com/typekit/webfontloader#readme" target="_blank">webfont.js</a>','autoptimize'); ?><br/>
342 </td>
343 </tr>
344 <tr>
345 <th scope="row"><?php _e('Preconnect to 3rd party domains <em>(advanced users)</em>','autoptimize'); ?></th>
346 <td>
347 <label><input type='text' style='width:80%' name='autoptimize_extra_settings[autoptimize_extra_text_field_2]' value='<?php echo $autoptimize_extra_options['autoptimize_extra_text_field_2']; ?>'><br /><?php _e('Add 3rd party domains you want the browser to <a href="https://www.keycdn.com/support/preconnect/#primary" target="_blank">preconnect</a> to, separated by comma\'s. Make sure to include the correct protocol (HTTP or HTTPS).','autoptimize'); ?></label>
348 </td>
349 </tr>
350 <tr>
351 <th scope="row"><?php _e('Async Javascript-files <em>(advanced users)</em>','autoptimize'); ?></th>
352 <td>
353 <?php if ( function_exists('is_plugin_active') && is_plugin_active('async-javascript/async-javascript.php') ) {
354 _e('You have "Async JavaScript" installed,','autoptimize');
355 $asj_config_url="options-general.php?page=async-javascript";
356 echo sprintf(' <a href="'.$asj_config_url.'">%s</a>', __('configuration of async javascript is best done there.','autoptimize'));
357 } else { ?>
358 <input type='text' style='width:80%' name='autoptimize_extra_settings[autoptimize_extra_text_field_3]' value='<?php echo $autoptimize_extra_options['autoptimize_extra_text_field_3']; ?>'>
359 <br />
360 <?php
361 _e('Comma-separated list of local or 3rd party JS-files that should loaded with the <code>async</code> flag. JS-files from your own site will be automatically excluded if added here. ','autoptimize');
362 echo sprintf( __('Configuration of async javascript is easier and more flexible using the %s plugin.','autoptimize'), '"<a href="https://wordpress.org/plugins/async-javascript" target="_blank">Async Javascript</a>"');
363 $asj_install_url= network_admin_url()."plugin-install.php?s=async+javascript&tab=search&type=term";
364 echo sprintf(' <a href="'.$asj_install_url.'">%s</a>', __('Click here to install and activate it.','autoptimize'));
365 } ?>
366 </td>
367 </tr>
368 <tr>
369 <th scope="row"><?php _e('Optimize YouTube videos','autoptimize'); ?></th>
370 <td>
371 <?php if ( function_exists('is_plugin_active') && is_plugin_active('wp-youtube-lyte/wp-youtube-lyte.php') ) {
372 _e('Great, you have WP YouTube Lyte installed.','autoptimize');
373 $lyte_config_url="options-general.php?page=lyte_settings_page";
374 echo sprintf(' <a href="'.$lyte_config_url.'">%s</a>', __('Click here to configure it.','autoptimize'));
375 } else {
376 echo sprintf( __('%s allows you to “lazy load” your videos, by inserting responsive “Lite YouTube Embeds". ','autoptimize'),'<a href="https://wordpress.org/plugins/wp-youtube-lyte" target="_blank">WP YouTube Lyte</a>');
377 $lyte_install_url= network_admin_url()."plugin-install.php?s=lyte&tab=search&type=term";
378 echo sprintf(' <a href="'.$lyte_install_url.'">%s</a>', __('Click here to install and activate it.','autoptimize'));
379 } ?>
380 </td>
381 </tr>
382 </table>
383 <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php _e('Save Changes','autoptimize') ?>" /></p>
384 </form>
385 <?php
386 }
387