Completed
Push — master ( 442fb0...806e3d )
by frank
03:33
created

autoptimizeExtra.php ➔ autoptimize_extra_options_page()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 69
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 40
nc 16
nop 0
dl 0
loc 69
rs 6.9081
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
    /* async JS */
38
    if ( !empty($autoptimize_extra_options['autoptimize_extra_text_field_3']) && !is_plugin_active('autoptimize/autoptimize.php') ) {
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
        add_filter( 'wp_resource_hints', 'autoptimize_extra_gfonts_remove_dnsprefetch', 10, 2 );        
45
        if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "2" ) {
46
            add_filter('autoptimize_filter_css_removables','autoptimize_extra_remove_gfonts',10,1);
47
        } else {
48
            add_filter('autoptimize_html_after_minify','autoptimize_extra_gfonts',10,1);
49
            add_filter('autoptimize_extra_filter_tobepreconn','autoptimize_extra_preconnectgooglefonts',10,1);
50
        }
51
    }
52
    
53
    /* preconnect */
54
    if ( !empty($autoptimize_extra_options['autoptimize_extra_text_field_2']) || has_filter('autoptimize_extra_filter_tobepreconn') ) {
55
        add_filter( 'wp_resource_hints', 'autoptimize_extra_preconnect', 10, 2 );
56
    }
57
}
58
59
// disable emoji's functions
60
function autoptimize_extra_disable_emojis() {
61
    // all actions related to emojis
62
    remove_action( 'admin_print_styles', 'print_emoji_styles' );
63
    remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
64
    remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
65
    remove_action( 'wp_print_styles', 'print_emoji_styles' );
66
    remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
67
    remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
68
    remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
69
70
    // filter to remove TinyMCE emojis
71
    add_filter( 'tiny_mce_plugins', 'autoptimize_extra_disable_emojis_tinymce' );
72
73
    // and remove dns-prefetch for emoji
74
    add_filter( 'wp_resource_hints', 'autoptimize_extra_emojis_remove_dns_prefetch', 10, 2 );
75
}
76
77
function autoptimize_extra_disable_emojis_tinymce( $plugins ) {
78
    if ( is_array( $plugins ) ) {
79
        return array_diff( $plugins, array( 'wpemoji' ) );
80
    } else {
81
        return array();
82
    }
83
}
84
85
function autoptimize_extra_emojis_remove_dns_prefetch( $urls, $relation_type ) {
86
    $_emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/' );
87
88
    return autoptimize_extra_remove_dns_prefetch( $urls, $relation_type, $_emoji_svg_url );
89
}
90
91
// remove query string function
92
function autoptimize_extra_remove_qs( $src ) {
93
    if ( strpos($src, '?ver=') ) {
94
            $src = remove_query_arg( 'ver', $src );
95
    }
96
    return $src;
97
}
98
99
// async function
100
function autoptimize_extra_async_js($in) {
101
    $autoptimize_extra_options = autoptimize_extra_get_options();
102
    
103
    // get exclusions
104
    $AO_JSexclArrayIn = array();
105 View Code Duplication
    if (!empty($in)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
        $AO_JSexclArrayIn = array_fill_keys(array_filter(array_map('trim',explode(",",$in))),"");
107
    }
108
    
109
    // get asyncs
110
    $_fromSetting = $autoptimize_extra_options['autoptimize_extra_text_field_3'];
111
    $AO_asynced_JS = array_fill_keys(array_filter(array_map('trim',explode(",",$_fromSetting))),"");
112
    $AO_async_flag = apply_filters('autoptimize_filter_extra_async',"async");
113
    foreach ($AO_asynced_JS as $JSkey => $JSvalue) {
114
        $AO_asynced_JS[$JSkey] = $AO_async_flag;
115
    }
116
    
117
    // merge exclusions & asyncs in one array and return to AO API
118
    $AO_excl_w_async = array_merge( $AO_JSexclArrayIn, $AO_asynced_JS );
119
    return $AO_excl_w_async;
120
}
121
122
// preconnect function
123
function autoptimize_extra_preconnect($hints, $relation_type) {
124
    $autoptimize_extra_options = autoptimize_extra_get_options();
125
    
126
    // get setting and store in array
127
    $_to_be_preconnected = array_filter(array_map('trim',explode(",",$autoptimize_extra_options['autoptimize_extra_text_field_2'])));
128
    $_to_be_preconnected = apply_filters( 'autoptimize_extra_filter_tobepreconn', $_to_be_preconnected );
129
130
    // walk array, extract domain and add to new array with crossorigin attribute
131
    foreach ($_to_be_preconnected as $_preconn_single) {
132
        $_preconn_parsed = parse_url($_preconn_single);
133
        
134
        if ( is_array($_preconn_parsed) && empty($_preconn_parsed['scheme']) ) {
135
            $_preconn_domain = "//".$_preconn_parsed['host'];
136
        } else if ( is_array($_preconn_parsed) ) {
137
            $_preconn_domain = $_preconn_parsed['scheme']."://".$_preconn_parsed['host'];
138
        }
139
        
140
        if ( !empty($_preconn_domain) ) {
141
            $_preconn_hint = array('href' => $_preconn_domain);
142
            // fonts don't get preconnected unless crossorigin flag is set, non-fonts don't get preconnected if origin flag is set
143
            // so hardcode fonts.gstatic.com to come with crossorigin and have filter to add other domains if needed
144
            $_preconn_crossorigin = apply_filters( 'autoptimize_extra_filter_preconn_crossorigin', array('https://fonts.gstatic.com') );
145
            if ( in_array( $_preconn_domain, $_preconn_crossorigin ) ) {
146
                $_preconn_hint['crossorigin'] = 'anonymous';
147
            }
148
            $_new_hints[] = $_preconn_hint;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$_new_hints was never initialized. Although not strictly required by PHP, it is generally a good practice to add $_new_hints = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
149
        }
150
    }
151
152
    // merge in wordpress' preconnect hints
153
    if ( 'preconnect' === $relation_type && !empty($_new_hints) ) {
154
        $hints = array_merge($hints, $_new_hints);      
155
    }
156
    
157
    return $hints;
158
}
159
160
// google font functions
161
function autoptimize_extra_gfonts_remove_dnsprefetch ( $urls, $relation_type ) {
162
    $_gfonts_url = "fonts.googleapis.com";
163
    
164
    return autoptimize_extra_remove_dns_prefetch( $urls, $relation_type, $_gfonts_url );
165
}
166
167
function autoptimize_extra_remove_gfonts($in) { 
168
    // simply remove google fonts
169
    return $in.", fonts.googleapis.com"; 
170
}
171
172
function autoptimize_extra_gfonts($in) {
173
    $autoptimize_extra_options = autoptimize_extra_get_options();
174
    
175
    // extract fonts, partly based on wp rocket's extraction code
176
    $_without_comments = preg_replace( '/<!--(.*)-->/Uis', '', $in );
177
    preg_match_all( '#<link(?:\s+(?:(?!href\s*=\s*)[^>])+)?(?:\s+href\s*=\s*([\'"])((?:https?:)?\/\/fonts\.googleapis\.com\/css(?:(?!\1).)+)\1)(?:\s+[^>]*)?>#iU', $_without_comments, $matches );
178
179
    $i = 0;
180
    $fontsCollection = array();
181
    if ( ! $matches[2] ) {
182
        return $in;
183
    }
184
    
185
    // store them in $fonts array
186
    foreach ( $matches[2] as $font ) {
187
        if ( ! preg_match( '/rel=["\']dns-prefetch["\']/', $matches[0][ $i ] ) ) {
188
            // Get fonts name.
189
            $font = str_replace( array( '%7C', '%7c' ) , '|', $font );
190
            $font = explode( 'family=', $font );
191
            $font = ( isset( $font[1] ) ) ? explode( '&', $font[1] ) : array();
192
            // Add font to $fonts[$i] but make sure not to pollute with an empty family
193
            $_thisfont = array_values( array_filter( explode( '|', reset( $font ) ) ) );
194
            if ( !empty($_thisfont) ) {
195
                $fontsCollection[$i]["fonts"] = $_thisfont;
196
                // And add subset if any
197
                $subset = ( is_array( $font ) ) ? end( $font ) : '';
198
                if ( false !== strpos( $subset, 'subset=' ) ) {
199
                    $subset = explode( 'subset=', $subset );
200
                    $fontsCollection[$i]["subsets"] = explode( ',', $subset[1] );
201
                }
202
            }
203
            // And remove Google Fonts.
204
            $in = str_replace( $matches[0][ $i ], '', $in );
205
        }
206
        $i++;
207
    }
208
209
    $_fontsOut="";
210
    if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "3" ) {
211
        // aggregate & link
212
        $_fontsString="";
213
        $_subsetString="";
214
        foreach ($fontsCollection as $font) {
215
            $_fontsString .= '|'.trim( implode( '|' , $font["fonts"] ), '|' );
216
            if ( !empty( $font["subsets"] ) ) {
217
                $_subsetString .= implode( ',', $font["subsets"] ); 
218
            }
219
        }
220
                    
221
        if (!empty($_subsetString)) {
222
            $_fontsString = $_fontsString."#038;subset=".$_subsetString;
223
        }
224
225
        $_fontsString = str_replace( '|', '%7C', ltrim($_fontsString,'|') );
226
        
227
        if ( ! empty( $_fontsString ) ) {
228
            $_fontsOut = '<link rel="stylesheet" id="ao_optimized_gfonts" href="https://fonts.googleapis.com/css?family=' . $_fontsString . '" />';
229
        }
230
    } else if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "4" ) {
231
        // aggregate & load async (webfont.js impl.)
232
        $_fontsArray = array();
233
        foreach ($fontsCollection as $_fonts) {
234
            if ( !empty( $_fonts["subsets"] ) ) {
235
                $_subset = implode(",",$_fonts["subsets"]);
236
                foreach ($_fonts["fonts"] as $key => $_one_font) {
237
                    $_one_font = $_one_font.":".$_subset;
238
                    $_fonts["fonts"][$key] = $_one_font;
239
                } 
240
            }
241
            $_fontsArray = array_merge($_fontsArray, $_fonts["fonts"]);
242
        }
243
        
244
        $_fontsOut = '<script data-cfasync="false" type="text/javascript">WebFontConfig={google:{families:[\'';
245
        foreach ($_fontsArray as $_font) {
246
            $_fontsOut .= $_font."','";
247
        }
248
        $_fontsOut = trim(trim($_fontsOut,"'"),",");
249
        $_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>';
250
    }
251
 
252
    // inject in HTML
253
    $out = substr_replace($in, $_fontsOut."<link", strpos($in, "<link"), strlen("<link"));
254
    return $out;
255
}
256
257
function autoptimize_extra_preconnectgooglefonts($in) {
258
    $autoptimize_extra_options = autoptimize_extra_get_options();
259
260
    // preconnect to fonts.gstatic.com speed up download of static font-files
261
    $in[] = "https://fonts.gstatic.com";
262
    if ( $autoptimize_extra_options['autoptimize_extra_radio_field_4'] == "4" ) {
263
        // and more preconnects for webfont.js
264
        $in[] = "https://ajax.googleapis.com";
265
        $in[] = "https://fonts.googleapis.com";
266
    }
267
    return $in;
268
}
269
270
function autoptimize_extra_remove_dns_prefetch( $urls, $relation_type, $_remove_url ) {
271
        if ( 'dns-prefetch' == $relation_type ) {
272
        $_count=0;
273
        foreach ($urls as $_url) {
274
            if ( strpos($_url, $_remove_url) !== false ) {
275
                unset($urls[$_count]);
276
            }
277
            $_count++;
278
        }
279
    }
280
281
    return $urls;
282
}
283
284
/* admin page functions */
285
function autoptimize_extra_admin() { 
286
    add_submenu_page( null, 'autoptimize_extra', 'autoptimize_extra', 'manage_options', 'autoptimize_extra', 'autoptimize_extra_options_page' );
287
    register_setting( 'autoptimize_extra_settings', 'autoptimize_extra_settings' );
288
}
289
290
function add_autoptimize_extra_tab($in) {
291
    $in=array_merge($in,array('autoptimize_extra' => __('Extra','autoptimize')));
292
    return $in;
293
}
294
295
function autoptimize_extra_options_page() { 
296
    $autoptimize_extra_options = autoptimize_extra_get_options();
297
    $_googlef = $autoptimize_extra_options['autoptimize_extra_radio_field_4'];
298
    ?>
299
    <style>
300
        #ao_settings_form {background: white;border: 1px solid #ccc;padding: 1px 15px;margin: 15px 10px 10px 0;}
301
        #ao_settings_form .form-table th {font-weight: 100;}
302
        #autoptimize_extra_descr{font-size: 120%;}
303
    </style>
304
    <div class="wrap">
305
    <h1><?php _e('Autoptimize Settings','autoptimize'); ?></h1>
306
    <?php echo autoptimizeConfig::ao_admin_tabs(); ?>
307
    <form id='ao_settings_form' action='options.php' method='post'>
308
        <?php settings_fields('autoptimize_extra_settings'); ?>
309
        <h2><?php _e('Extra Auto-Optimizations','autoptimize'); ?></h2>
310
        <span id='autoptimize_extra_descr'><?php _e('The following settings can improve your site\'s performance even more.','autoptimize'); ?></span>
311
        <table class="form-table">
312
            <tr>
313
                <th scope="row"><?php _e('Remove emojis','autoptimize'); ?></th>
314
                <td>
315
                    <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>
316
                </td>
317
            </tr>
318
            <tr>
319
                <th scope="row"><?php _e('Remove query strings from static resources','autoptimize'); ?></th>
320
                <td>
321
                    <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>
322
                </td>
323
            </tr>
324
            <tr>
325
                <th scope="row"><?php _e('Google Fonts','autoptimize'); ?></th>
326
                <td>
327
                    <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/>
328
                    <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/>
329
                    <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/>
330
                    <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/>
331
                </td>
332
            </tr>
333
            <tr>
334
                <th scope="row"><?php _e('Preconnect to 3rd party domains <em>(advanced users)</em>','autoptimize'); ?></th>
335
                <td>
336
                    <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>
337
                </td>
338
            </tr>
339
            <tr>
340
                <th scope="row"><?php _e('Async Javascript-files <em>(advanced users)</em>','autoptimize'); ?></th>
341
                <td>
342
                    <?php if ( is_plugin_active('async-javascript/async-javascript.php') ) {
343
                        _e('You have "Async JavaScript" installed, ','autoptimize');
344
                        $asj_config_url="options-general.php?page=async-javascript";
345
                        echo sprintf('<a href="'.$asj_config_url.'">%s</a>', __('configuration of async javascript is best done there.'));
346
                    } else { ?>
347
                        <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']; ?>'>
348
                        <br />
349
                        <?php 
350
                        _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');
351
                        echo "<strong>";
352
                        _e('Configuration of async javascript is easier and more flexible using the "Async Javascript"-plugin. ','autoptimize');
353
                        echo "</strong>";
354
                        $asj_install_url= network_admin_url()."plugin-install.php?s=async+javascript&tab=search&type=term";
355
                        echo sprintf('<a href="'.$asj_install_url.'">%s</a>', __('Click here to install it.'));
356
                    } ?>
357
                </td>
358
            </tr>
359
        </table>
360
        <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php _e('Save Changes','autoptimize') ?>" /></p>
361
    </form>
362
    <?php
363
}
364