Completed
Push — master ( 1330c6...fc6b8c )
by frank
02:26
created

autoptimizeExtra.php ➔ autoptimize_extra_init()   C

Complexity

Conditions 12
Paths 96

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 21
nc 96
nop 0
dl 0
loc 39
rs 5.1612
c 0
b 0
f 0

How to fix   Complexity   

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