PluginProbe
Autoptimize / 2.3.1
Autoptimize v2.3.1
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.1, at classlesses/autoptimizeExtra.php

321 lines 15.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 ($autoptimize_extra_options['autoptimize_extra_checkbox_field_1']) {
28 autoptimize_extra_disable_emojis();
29 }
30
31 /* remove version from query string */
32 if ($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 /* async JS */
38 if (!empty($autoptimize_extra_options['autoptimize_extra_text_field_3'])) {
39 add_filter('autoptimize_filter_js_exclude','autoptimize_extra_async_js',10,1);
40 }
41
42 /* optimize google fonts */
43 if ( !empty( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] ) && ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] != "1" ) ) {
44 if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "2" ) {
45 add_filter('autoptimize_filter_css_removables','autoptimize_extra_remove_gfonts',10,1);
46 } else {
47 add_filter('autoptimize_html_after_minify','autoptimize_extra_gfonts',10,1);
48 add_filter('autoptimize_extra_filter_tobepreconn','autoptimize_extra_preconnectgooglefonts',10,1);
49 }
50 }
51
52 /* preconnect */
53 if ( !empty($autoptimize_extra_options['autoptimize_extra_text_field_2']) || has_filter('autoptimize_extra_filter_tobepreconn') ) {
54 add_filter( 'wp_resource_hints', 'autoptimize_extra_preconnect', 10, 2 );
55 }
56 }
57
58 // disable emoji's functions
59 function autoptimize_extra_disable_emojis() {
60 // all actions related to emojis
61 remove_action( 'admin_print_styles', 'print_emoji_styles' );
62 remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
63 remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
64 remove_action( 'wp_print_styles', 'print_emoji_styles' );
65 remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
66 remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
67 remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
68
69 // filter to remove TinyMCE emojis
70 add_filter( 'tiny_mce_plugins', 'autoptimize_extra_disable_emojis_tinymce' );
71 }
72
73 function autoptimize_extra_disable_emojis_tinymce( $plugins ) {
74 if ( is_array( $plugins ) ) {
75 return array_diff( $plugins, array( 'wpemoji' ) );
76 } else {
77 return array();
78 }
79 }
80
81 // remove query string function
82 function autoptimize_extra_remove_qs( $src ) {
83 if ( strpos($src, '?ver=') ) {
84 $src = remove_query_arg( 'ver', $src );
85 }
86 return $src;
87 }
88
89 // async function
90 function autoptimize_extra_async_js($in) {
91 $autoptimize_extra_options = autoptimize_extra_get_options();
92
93 // get exclusions
94 $AO_JSexclArrayIn = array();
95 if (!empty($in)) {
96 $AO_JSexclArrayIn = array_fill_keys(array_filter(array_map('trim',explode(",",$in))),"");
97 }
98
99 // get asyncs
100 $_fromSetting = $autoptimize_extra_options['autoptimize_extra_text_field_3'];
101 $AO_asynced_JS = array_fill_keys(array_filter(array_map('trim',explode(",",$_fromSetting))),"");
102 foreach ($AO_asynced_JS as $JSkey => $JSvalue) {
103 $AO_asynced_JS[$JSkey] = "async";
104 }
105
106 // merge exclusions & asyncs in one array and return to AO API
107 $AO_excl_w_async = array_merge( $AO_JSexclArrayIn, $AO_asynced_JS );
108 return $AO_excl_w_async;
109 }
110
111 // preconnect function
112 function autoptimize_extra_preconnect($hints, $relation_type) {
113 $autoptimize_extra_options = autoptimize_extra_get_options();
114
115 // get setting and store in array
116 $_to_be_preconnected = array_filter(array_map('trim',explode(",",$autoptimize_extra_options['autoptimize_extra_text_field_2'])));
117 $_to_be_preconnected = apply_filters( 'autoptimize_extra_filter_tobepreconn', $_to_be_preconnected );
118
119 // walk array, extract domain and add to new array with crossorigin attribute
120 foreach ($_to_be_preconnected as $_preconn_single) {
121 $_preconn_parsed = parse_url($_preconn_single);
122
123 if ( is_array($_preconn_parsed) && empty($_preconn_parsed['scheme']) ) {
124 $_preconn_domain = "//".$_preconn_parsed['host'];
125 } else if ( is_array($_preconn_parsed) ) {
126 $_preconn_domain = $_preconn_parsed['scheme']."://".$_preconn_parsed['host'];
127 }
128
129 if ( !empty($_preconn_domain) ) {
130 $_preconn_hint = array('href' => $_preconn_domain);
131 // fonts don't get preconnected unless crossorigin flag is set, non-fonts don't get preconnected if origin flag is set
132 // so hardcode fonts.gstatic.com to come with crossorigin and have filter to add other domains if needed
133 $_preconn_crossorigin = apply_filters( 'autoptimize_extra_filter_preconn_crossorigin', array('https://fonts.gstatic.com') );
134 if ( in_array( $_preconn_domain, $_preconn_crossorigin ) ) {
135 $_preconn_hint['crossorigin'] = 'anonymous';
136 }
137 $_new_hints[] = $_preconn_hint;
138 }
139 }
140
141 // merge in wordpress' preconnect hints
142 if ( 'preconnect' === $relation_type && !empty($_new_hints) ) {
143 $hints = array_merge($hints, $_new_hints);
144 }
145
146 return $hints;
147 }
148
149 // google font functions
150 function autoptimize_extra_remove_gfonts($in) {
151 // simply remove google fonts
152 return $in.", fonts.googleapis.com";
153 }
154
155 function autoptimize_extra_gfonts($in) {
156 $autoptimize_extra_options = autoptimize_extra_get_options();
157
158 // extract fonts, partly based on wp rocket's extraction code
159 $_without_comments = preg_replace( '/<!--(.*)-->/Uis', '', $in );
160 preg_match_all( '#<link(?:\s+(?:(?!href\s*=\s*)[^>])+)?(?:\s+href\s*=\s*([\'"])((?:https?:)?\/\/fonts\.googleapis\.com\/css(?:(?!\1).)+)\1)(?:\s+[^>]*)?>#iU', $_without_comments, $matches );
161
162 $i = 0;
163 $fontsCollection = array();
164 if ( ! $matches[2] ) {
165 return $in;
166 }
167
168 // store them in $fonts array
169 foreach ( $matches[2] as $font ) {
170 if ( ! preg_match( '/rel=["\']dns-prefetch["\']/', $matches[0][ $i ] ) ) {
171 // Get fonts name.
172 $font = str_replace( array( '%7C', '%7c' ) , '|', $font );
173 $font = explode( 'family=', $font );
174 $font = ( isset( $font[1] ) ) ? explode( '&', $font[1] ) : array();
175 // Add font to $fonts[$i] but make sure not to pollute with an empty family
176 $_thisfont = array_values( array_filter( explode( '|', reset( $font ) ) ) );
177 if ( !empty($_thisfont) ) {
178 $fontsCollection[$i]["fonts"] = $_thisfont;
179 // And add subset if any
180 $subset = ( is_array( $font ) ) ? end( $font ) : '';
181 if ( false !== strpos( $subset, 'subset=' ) ) {
182 $subset = explode( 'subset=', $subset );
183 $fontsCollection[$i]["subsets"] = explode( ',', $subset[1] );
184 }
185 }
186 // And remove Google Fonts.
187 $in = str_replace( $matches[0][ $i ], '', $in );
188 }
189 $i++;
190 }
191
192 $_fontsOut="";
193 if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "3" ) {
194 // aggregate & link
195 $_fontsString="";
196 $_subsetString="";
197 foreach ($fontsCollection as $font) {
198 $_fontsString .= '|'.trim( implode( '|' , $font["fonts"] ), '|' );
199 if ( !empty( $font["subsets"] ) ) {
200 $_subsetString .= implode( ',', $font["subsets"] );
201 }
202 }
203
204 if (!empty($_subsetString)) {
205 $_fontsString = $_fontsString."#038;subset=".$_subsetString;
206 }
207
208 $_fontsString = str_replace( '|', '%7C', ltrim($_fontsString,'|') );
209
210 if ( ! empty( $_fontsString ) ) {
211 $_fontsOut = '<link rel="stylesheet" id="ao_optimized_gfonts" href="https://fonts.googleapis.com/css?family=' . $_fontsString . '" />';
212 }
213 } else if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "4" ) {
214 // aggregate & load async (webfont.js impl.)
215 $_fontsArray = array();
216 foreach ($fontsCollection as $_fonts) {
217 if ( !empty( $_fonts["subsets"] ) ) {
218 $_subset = implode(",",$_fonts["subsets"]);
219 foreach ($_fonts["fonts"] as $key => $_one_font) {
220 $_one_font = $_one_font.":".$_subset;
221 $_fonts["fonts"][$key] = $_one_font;
222 }
223 }
224 $_fontsArray = array_merge($_fontsArray, $_fonts["fonts"]);
225 }
226
227 $_fontsOut = '<script data-cfasync="false" type="text/javascript">WebFontConfig={google:{families:[\'';
228 foreach ($_fontsArray as $_font) {
229 $_fontsOut .= $_font."','";
230 }
231 $_fontsOut = trim(trim($_fontsOut,"'"),",");
232 $_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.async=\'true\';var s=document.getElementsByTagName(\'script\')[0];s.parentNode.insertBefore(wf, s);})();</script>';
233 }
234
235 // inject in HTML
236 $out = substr_replace($in, $_fontsOut."<link", strpos($in, "<link"), strlen("<link"));
237 return $out;
238 }
239
240 function autoptimize_extra_preconnectgooglefonts($in) {
241 $autoptimize_extra_options = autoptimize_extra_get_options();
242
243 // preconnect to fonts.gstatic.com speed up download of static font-files
244 $in[] = "https://fonts.gstatic.com";
245 if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "4" ) {
246 // and more preconnects for webfont.js
247 $in[] = "https://ajax.googleapis.com/";
248 $in[] = "https://fonts.googleapis.com";
249 }
250 return $in;
251 }
252
253 /* admin page functions */
254 function autoptimize_extra_admin() {
255 add_submenu_page( null, 'autoptimize_extra', 'autoptimize_extra', 'manage_options', 'autoptimize_extra', 'autoptimize_extra_options_page' );
256 register_setting( 'autoptimize_extra_settings', 'autoptimize_extra_settings' );
257 }
258
259 function add_autoptimize_extra_tab($in) {
260 $in=array_merge($in,array('autoptimize_extra' => __('Extra','autoptimize')));
261 return $in;
262 }
263
264 function autoptimize_extra_options_page() {
265 $autoptimize_extra_options = autoptimize_extra_get_options();
266 $_googlef = $autoptimize_extra_options['autoptimize_extra_radio_field_4'];
267 ?>
268 <style>
269 #ao_settings_form {background: white;border: 1px solid #ccc;padding: 1px 15px;margin: 15px 10px 10px 0;}
270 #ao_settings_form .form-table th {font-weight: 100;}
271 #autoptimize_extra_descr{font-size: 120%;}
272 </style>
273 <div class="wrap">
274 <h1><?php _e('Autoptimize Settings','autoptimize'); ?></h1>
275 <?php echo autoptimizeConfig::ao_admin_tabs(); ?>
276 <form id='ao_settings_form' action='options.php' method='post'>
277 <?php settings_fields('autoptimize_extra_settings'); ?>
278 <h2><?php _e('Extra Auto-Optimizations','autoptimize'); ?></h2>
279 <span id='autoptimize_extra_descr'><?php _e('The following settings can improve your site\'s performance even more.','autoptimize'); ?></span>
280 <table class="form-table">
281 <tr>
282 <th scope="row"><?php _e('Remove emojis','autoptimize'); ?></th>
283 <td>
284 <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_1]' <?php checked( $autoptimize_extra_options['autoptimize_extra_checkbox_field_1'], 1 ); ?> value='1'><?php _e('Removes WordPress\' core emojis\' inline CSS, inline JavaScript, and an otherwise un-autoptimized JavaScript file.','autoptimize'); ?></label>
285 </td>
286 </tr>
287 <tr>
288 <th scope="row"><?php _e('Remove query strings from static resources','autoptimize'); ?></th>
289 <td>
290 <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_0]' <?php checked( $autoptimize_extra_options['autoptimize_extra_checkbox_field_0'], 1 ); ?> 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>
291 </td>
292 </tr>
293 <tr>
294 <th scope="row"><?php _e('Google Fonts','autoptimize'); ?></th>
295 <td>
296 <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/>
297 <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/>
298 <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/>
299 <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/>
300 </td>
301 </tr>
302 <tr>
303 <th scope="row"><?php _e('Preconnect to 3rd party domains <em>(advanced users)</em>','autoptimize'); ?></th>
304 <td>
305 <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>
306 </td>
307 </tr>
308 <tr>
309 <th scope="row"><?php _e('Async Javascript-files <em>(advanced users)</em>','autoptimize'); ?></th>
310 <td>
311 <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']; ?>'>
312 <br />
313 <?php _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'); ?>
314 </td>
315 </tr>
316 </table>
317 <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes" /></p>
318 </form>
319 <?php
320 }
321