Plugin Directory

Changeset 1081305


Ignore:
Timestamp:
02/03/2015 02:42:19 AM (11 years ago)
Author:
NodeCode
Message:

version 1.4.0

Location:
wp-minify-fix
Files:
4 edited
13 copied

Legend:

Unmodified
Added
Removed
  • wp-minify-fix/tags/1.4.0/options-generic.php

    r889074 r1081305  
    11<script type="text/javascript">
    22function confirm_reset() {
    3   var answer = confirm("<?php _e('All of options will return to default settings. Are you sure you want to reset all settings?'); ?>");
    4   if(answer)
    5     return true;
    6   else
    7     return false;
     3    var answer = confirm("<?php _e('All of options will return to default settings. Are you sure you want to reset all settings?'); ?>");
     4    if(answer)
     5        return true;
     6    else
     7        return false;
    88}
    99
    1010jQuery(document).ready(function($){
    11   $("#wpm_options_toggle_advanced").click(function(e){
    12     e.preventDefault();
    13     state = $(this).attr("state");
    14     if(state == "visible"){
    15       $(".wpm_advanced").slideUp();
    16       $("#wpm_options_reset").fadeOut();
    17       $(this).attr("state", "hidden");
    18       $(this).attr("value", "<?php echo __('Show Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
    19       $.ajax({
    20         type    : "POST",
    21         url     : "admin-ajax.php",
    22         data    : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "hide_advanced" },
    23         success : function(resp){
    24           // do nothing visually
    25         },
    26         error   : function(resp){
    27           alert("Error:" + resp);
    28         }
    29       });
    30     }
    31     else{
    32       $(".wpm_advanced").slideDown();
    33       $("#wpm_options_reset").fadeIn();
    34       $(this).attr("state", "visible");
    35       $(this).attr("value", "<?php echo __('Hide Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
    36       $.ajax({
    37         type    : "POST",
    38         url     : "admin-ajax.php",
    39         data    : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "show_advanced" },
    40         success : function(resp){
    41           // do nothing visually
    42         },
    43         error   : function(resp){
    44           alert("Error:" + resp);
    45         }
    46       });
    47     }
    48   });
    49   $('#cache_external_checkbox').click(function(e) {
    50     state = $(this).attr("state");
    51     if (state == "on") {
    52       $(".wpm_include").slideDown();
    53       $(this).attr("state", "off");
    54     } else {
    55       $(".wpm_include").slideUp();
    56       $(this).attr("state", "on");
    57     }
    58   });
     11    $("#wpm_options_toggle_advanced").click(function(e){
     12        e.preventDefault();
     13        state = $(this).attr("state");
     14        if(state == "visible"){
     15            $(".wpm_advanced").slideUp();
     16            $("#wpm_options_reset").fadeOut();
     17            $(this).attr("state", "hidden");
     18            $(this).attr("value", "<?php echo __('Show Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
     19            $.ajax({
     20                type        : "POST",
     21                url         : "admin-ajax.php",
     22                data        : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "hide_advanced" },
     23                success : function(resp){
     24                    // do nothing visually
     25                },
     26                error       : function(resp){
     27                    alert("Error:" + resp);
     28                }
     29            });
     30        }
     31        else{
     32            $(".wpm_advanced").slideDown();
     33            $("#wpm_options_reset").fadeIn();
     34            $(this).attr("state", "visible");
     35            $(this).attr("value", "<?php echo __('Hide Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
     36            $.ajax({
     37                type        : "POST",
     38                url         : "admin-ajax.php",
     39                data        : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "show_advanced" },
     40                success : function(resp){
     41                    // do nothing visually
     42                },
     43                error       : function(resp){
     44                    alert("Error:" + resp);
     45                }
     46            });
     47        }
     48    });
     49    $('#cache_external_checkbox').click(function(e) {
     50        state = $(this).attr("state");
     51        if (state == "on") {
     52            $(".wpm_include").slideDown();
     53            $(this).attr("state", "off");
     54        } else {
     55            $(".wpm_include").slideUp();
     56            $(this).attr("state", "on");
     57        }
     58    });
    5959});
    6060</script>
    6161<form method="post"><fieldset>
    6262<?php
    63     // take care of advanced options
    64     if ($wpm_options['show_advanced']) {
    65       $advanced_style = '';
    66       $advanced_toggle_text = __('Hide Advanced Options', $this->name);
    67       $advanced_toggle_state = 'visible';
    68     }
    69     else {
    70       $advanced_style = 'style="display:none"';
    71       $advanced_toggle_text = __('Show Advanced Options', $this->name);
    72       $advanced_toggle_state = 'hidden';
    73     }
    74    
    75     if ($wpm_options['cache_external']) {
    76       $include_style = 'style="display:none"';
    77       $include_toggle_state = 'on';
    78     } else {
    79       $include_style = '';
    80       $include_toggle_state = 'off';
    81     }
    82 
    83     printf('
    84       <h2>%s</h2>
    85       <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="on" type="radio" '.checked(true, $wpm_options['show_link'], false).'/></label></p>
    86       <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="off" type="radio" '.checked(false, $wpm_options['show_link'], false).'/></label></p>
    87       ',
    88       __('Support this plugin!', $this->name),
    89       __('Display "Page optimized by WP Minify" link in the footer', $this->name),
    90       __('Do not display "Page optimized by WP Minify" link.', $this->name)
    91     );
    92 
    93     printf('
    94       <h2>%s</h2>
    95       <p><label>%s &nbsp; <input name="wpm_options_update[enable_js]" type="checkbox" '.checked(true, $wpm_options['enable_js'], false).'/></label></p>
    96       <p><label>%s &nbsp; <input name="wpm_options_update[enable_css]" type="checkbox" '.checked(true, $wpm_options['enable_css'], false).'/></label></p>
    97       <p><label>%s &nbsp; <input name="wpm_options_update[enable_html]" type="checkbox" '.checked(true, $wpm_options['enable_html'], false).'/></label></p>
    98       ',
    99       __('General Configuration', $this->name),
    100       __('Enable JavaScript Minification', $this->name),
    101       __('Enable CSS Minification', $this->name),
    102       __('Enable HTML Minification', $this->name)
    103     );
    104    
    105     printf('
    106       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    107       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[debug_nominify]" type="checkbox" '.checked(true, $wpm_options['debug_nominify'], false).'/></label></p>
    108       <p class="wpm_advanced" '.$advanced_style.'><label><a href="http://omninoggin.com/wordpress-posts/troubleshooting-wp-minify-with-firephp/">%s</a> &nbsp; <input name="wpm_options_update[debug_firephp]" type="checkbox" '.checked(true, $wpm_options['debug_firephp'], false).'/></label></p>
    109       ',
    110       __('Debugging', $this->name),
    111       __('Combine files but do not minify', $this->name),
    112       __('Show minify errors through FirePHP', $this->name)
    113     );
    114    
    115     printf('
    116       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    117       <p><label>%s<br/><textarea name="wpm_options_update[js_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_exclude'])).'</textarea></label></p>
    118       <p><label>%s<br/><textarea name="wpm_options_update[css_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_exclude'])).'</textarea></label></p>
    119       <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><textarea name="wpm_options_update[uri_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['uri_exclude'])).'</textarea></label></p>
    120       ',
    121       __('Local Files Minification', $this->name),
    122       __('JavaScript files to exclude from minify (line delimited).', $this->name),
    123       __('CSS files to exclude from minify (line delimited).', $this->name),
    124       __('URIs on which WP-Minify-Fix parsing will be disabled (line delimited)', $this->name)
    125     );
    126 
    127     printf('
    128       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    129       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[cache_external]" id="cache_external_checkbox" state="'.$include_toggle_state.'" type="checkbox" '.checked(true, $wpm_options['cache_external'], false).'/> &nbsp; (%s)</label></p>
    130       <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[js_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_include'])).'</textarea></label></p>
    131       <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[css_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_include'])).'</textarea></label></p>
    132       ',
    133       __('Non-Local Files Minification', $this->name),
    134       __('Enable minification on external files', $this->name),
    135       __('Not recommended unless you want to exclude a bunch of external .js/.css files', $this->name),
    136       __('External JavaScript files to include into minify.', $this->name),
    137       __('Only useful if "Minification on external files" is unchecked', $this->name),
    138       __('more info', $this->name),
    139       __('External CSS files to include into minify.', $this->name),
    140       __('Only useful if "Minification on external files" is unchecked', $this->name),
    141       __('more info', $this->name)
    142     );
    143 
    144     printf('
    145       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    146       <p class="wpm_advanced" '.$advanced_style.'><label>%s<input name="wpm_options_update[cache_interval]" type="text" size="4" value="'.attribute_escape($wpm_options['cache_interval']).'"/>%s <span class="submit"><input type="submit" name="wpm_options_clear_cache_submit" value="%s"/></span></p></label>
    147       ',
    148       __('Caching', $this->name),
    149       __('Cache expires after every', $this->name),
    150       __('seconds', $this->name),
    151       __('Manually Clear Cache', $this->name)
    152     );
    153 
    154     printf('
    155       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    156       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[pretty_url]" type="checkbox" '.checked(true, $wpm_options['pretty_url'], false).'/> &nbsp; (%s)</label></p>
    157       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_in_footer]" type="checkbox" '.checked(true, $wpm_options['js_in_footer'], false).'/> &nbsp; (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#manual_placement">%s</a>)</label></p>
    158       ',
    159       __('Tweaking/Tuning', $this->name),
    160       __('Use "pretty" URL"', $this->name),
    161       __('i.e. use "wp-minify-fix/cache/1234abcd.js" instead of "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js"', $this->name),
    162       __('Place Minified JavaScript in footer', $this->name),
    163       __('Not recommended', $this->name),
    164       __('more info', $this->name)
    165     );
    166 
    167     printf('
    168       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[force_https]" type="checkbox" '.checked(true, $wpm_options['force_https'], false).'/></label></p>
    169       ',
    170       __('Force all JavaScript/CSS calls to be HTTPS on HTTPS pages', $this->name)
    171     );
    172 
    173     printf('
    174       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[auto_base]" type="checkbox" '.checked(true, $wpm_options['auto_base'], false).'/></label></p>
    175       <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><input name="wpm_options_update[extra_minify_options]" type="text" size="100" value="'.attribute_escape($wpm_options['extra_minify_options']).'"/><br/><em>%s</em></label></p>
    176       ',
    177       __('Automatically set your Minify base per siteurl setting (recommended)', $this->name),
    178       __('Extra arguments to pass to minify engine. This value will get append to calls to URL "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js".', $this->name),
    179       __('e.g. You can specify this value to be b=somepath to specify the base path for all files passed into Minify.', $this->name)
    180     );
    181 
    182     if ( function_exists( 'wp_nonce_field' ) && wp_nonce_field( $this->name ) ) {
    183       printf('
    184         <p class="submit">
    185           <input type="submit" name="wpm_options_update_submit" value="%s &#187;" />
    186           <input type="submit" name="wpm_options_reset_submit" id="wpm_options_reset" value="%s &#187;" onclick="return confirm_reset()" '.$advanced_style.'/>
    187           <input type="button" id="wpm_options_toggle_advanced" state="'.$advanced_toggle_state.'" value="'.$advanced_toggle_text.' &#187;"/>
    188         </p>
    189         ',
    190         __('Update Options', $this->name),
    191         __('Reset ALL Options', $this->name)
    192       );
    193     }
     63        // take care of advanced options
     64        if ($wpm_options['show_advanced']) {
     65            $advanced_style = '';
     66            $advanced_toggle_text = __('Hide Advanced Options', $this->name);
     67            $advanced_toggle_state = 'visible';
     68        }
     69        else {
     70            $advanced_style = 'style="display:none"';
     71            $advanced_toggle_text = __('Show Advanced Options', $this->name);
     72            $advanced_toggle_state = 'hidden';
     73        }
     74       
     75        if ($wpm_options['cache_external']) {
     76            $include_style = 'style="display:none"';
     77            $include_toggle_state = 'on';
     78        } else {
     79            $include_style = '';
     80            $include_toggle_state = 'off';
     81        }
     82
     83        printf('
     84            <h2>%s</h2>
     85            <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="on" type="radio" '.checked(true, $wpm_options['show_link'], false).'/></label></p>
     86            <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="off" type="radio" '.checked(false, $wpm_options['show_link'], false).'/></label></p>
     87            ',
     88            __('Support this plugin!', $this->name),
     89            __('Display "Page optimized by WP Minify" link in the footer', $this->name),
     90            __('Do not display "Page optimized by WP Minify" link.', $this->name)
     91        );
     92
     93        printf('
     94            <h2>%s</h2>
     95            <p><label>%s &nbsp; <input name="wpm_options_update[enable_js]" type="checkbox" '.checked(true, $wpm_options['enable_js'], false).'/></label></p>
     96            <p><label>%s &nbsp; <input name="wpm_options_update[enable_css]" type="checkbox" '.checked(true, $wpm_options['enable_css'], false).'/></label></p>
     97            <p><label>%s &nbsp; <input name="wpm_options_update[enable_html]" type="checkbox" '.checked(true, $wpm_options['enable_html'], false).'/></label></p>
     98            ',
     99            __('General Configuration', $this->name),
     100            __('Enable JavaScript Minification', $this->name),
     101            __('Enable CSS Minification', $this->name),
     102            __('Enable HTML Minification', $this->name)
     103        );
     104       
     105        printf('
     106            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     107            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[debug_nominify]" type="checkbox" '.checked(true, $wpm_options['debug_nominify'], false).'/></label></p>
     108            <p class="wpm_advanced" '.$advanced_style.'><label><a href="http://omninoggin.com/wordpress-posts/troubleshooting-wp-minify-with-firephp/">%s</a> &nbsp; <input name="wpm_options_update[debug_firephp]" type="checkbox" '.checked(true, $wpm_options['debug_firephp'], false).'/></label></p>
     109            ',
     110            __('Debugging', $this->name),
     111            __('Combine files but do not minify', $this->name),
     112            __('Show minify errors through FirePHP', $this->name)
     113        );
     114       
     115        printf('
     116            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     117            <p><label>%s<br/><textarea name="wpm_options_update[js_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_exclude'])).'</textarea></label></p>
     118            <p><label>%s<br/><textarea name="wpm_options_update[css_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_exclude'])).'</textarea></label></p>
     119            <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><textarea name="wpm_options_update[uri_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['uri_exclude'])).'</textarea></label></p>
     120            ',
     121            __('Local Files Minification', $this->name),
     122            __('JavaScript files to exclude from minify (line delimited).', $this->name),
     123            __('CSS files to exclude from minify (line delimited).', $this->name),
     124            __('URIs on which WP-Minify-Fix parsing will be disabled (line delimited)', $this->name)
     125        );
     126
     127        printf('
     128            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     129            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[cache_external]" id="cache_external_checkbox" state="'.$include_toggle_state.'" type="checkbox" '.checked(true, $wpm_options['cache_external'], false).'/> &nbsp; (%s)</label></p>
     130            <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[js_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_include'])).'</textarea></label></p>
     131            <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[css_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_include'])).'</textarea></label></p>
     132            ',
     133            __('Non-Local Files Minification', $this->name),
     134            __('Enable minification on external files', $this->name),
     135            __('Not recommended unless you want to exclude a bunch of external .js/.css files', $this->name),
     136            __('External JavaScript files to include into minify.', $this->name),
     137            __('Only useful if "Minification on external files" is unchecked', $this->name),
     138            __('more info', $this->name),
     139            __('External CSS files to include into minify.', $this->name),
     140            __('Only useful if "Minification on external files" is unchecked', $this->name),
     141            __('more info', $this->name)
     142        );
     143
     144        printf('
     145            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     146            <p class="wpm_advanced" '.$advanced_style.'><label>%s<input name="wpm_options_update[cache_interval]" type="text" size="4" value="'.attribute_escape($wpm_options['cache_interval']).'"/>%s <span class="submit"><input type="submit" name="wpm_options_clear_cache_submit" value="%s"/></span></p></label>
     147            ',
     148            __('Caching', $this->name),
     149            __('Cache expires after every', $this->name),
     150            __('seconds', $this->name),
     151            __('Manually Clear Cache', $this->name)
     152        );
     153       
     154        printf('
     155            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     156            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_placement]" value="header-footer" type="radio" '.checked('header-footer', $wpm_options['js_placement'], false).'/></label></p>
     157            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_placement]" value="header" type="radio" '.checked('header', $wpm_options['js_placement'], false).'/></label></p>
     158            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_placement]" value="footer" type="radio" '.checked('footer', $wpm_options['js_placement'], false).'/></label></p>
     159            ',
     160            __('JavaScript Placement', $this->name),
     161            __('In the header, and if necessary also in the footer (recommended)', $this->name),
     162            __('Everything in the header', $this->name),
     163            __('Everything in the footer', $this->name)
     164        );
     165
     166        printf('
     167            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     168            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[pretty_url]" type="checkbox" '.checked(true, $wpm_options['pretty_url'], false).'/> &nbsp; (%s)</label></p>',
     169            __('Tweaking/Tuning', $this->name),
     170            __('Use "pretty" URL"', $this->name),
     171            __('i.e. use "wp-minify-fix/cache/1234abcd.js" instead of "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js"', $this->name)
     172        );
     173       
     174        printf('
     175            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_async]" type="checkbox" '.checked(true, $wpm_options['js_async'], false).'/> &nbsp; (%s, <a href="http://css-tricks.com/async-attribute-scripts-bottom/" target="_blank">%s</a>)</label></p>
     176            ',
     177            __('Add the HTML5 async tag', $this->name),
     178            __('Only for the header', $this->name),
     179            __('more info', $this->name)
     180        );
     181
     182        printf('
     183            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[force_https]" type="checkbox" '.checked(true, $wpm_options['force_https'], false).'/></label></p>
     184            ',
     185            __('Force all JavaScript/CSS calls to be HTTPS on HTTPS pages', $this->name)
     186        );
     187
     188        printf('
     189            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[auto_base]" type="checkbox" '.checked(true, $wpm_options['auto_base'], false).'/></label></p>
     190            <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><input name="wpm_options_update[extra_minify_options]" type="text" size="100" value="'.attribute_escape($wpm_options['extra_minify_options']).'"/><br/><em>%s</em></label></p>
     191            ',
     192            __('Automatically set your Minify base per siteurl setting (recommended)', $this->name),
     193            __('Extra arguments to pass to minify engine. This value will get append to calls to URL "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js".', $this->name),
     194            __('e.g. You can specify this value to be b=somepath to specify the base path for all files passed into Minify.', $this->name)
     195        );
     196
     197        if ( function_exists( 'wp_nonce_field' ) && wp_nonce_field( $this->name ) ) {
     198            printf('
     199                <p class="submit">
     200                    <input type="submit" name="wpm_options_update_submit" value="%s &#187;" />
     201                    <input type="submit" name="wpm_options_reset_submit" id="wpm_options_reset" value="%s &#187;" onclick="return confirm_reset()" '.$advanced_style.'/>
     202                    <input type="button" id="wpm_options_toggle_advanced" state="'.$advanced_toggle_state.'" value="'.$advanced_toggle_text.' &#187;"/>
     203                </p>
     204                ',
     205                __('Update Options', $this->name),
     206                __('Reset ALL Options', $this->name)
     207            );
     208        }
    194209?>
    195210</fieldset></form>
  • wp-minify-fix/tags/1.4.0/readme.txt

    r892852 r1081305  
    33Contributors: NodeCode, madeinthayaland
    44Requires at least: 2.7
    5 Tested up to: 3.8.1
    6 Stable Tag: 1.3.4
     5Tested up to: 4.1
     6Stable Tag: 1.4.0
    77
    88[Fixed] This plugin uses the Minify engine to combine and compress JS and CSS files
     
    1010
    1111== Description ==
    12 This plugin is a fork of [WP Minify](http://wordpress.org/plugins/wp-minify/) to fix bugs, because it has not been updated since 2012-6-4.
     12This plugin is a fork of [WP Minify](http://wordpress.org/plugins/wp-minify/) to fix bugs and add features, because it has not been updated since 2012-6-4.
    1313
    1414This plugin integrates the [Minify engine](http://code.google.com/p/minify/)
     
    1818= What has been fixed? =
    1919
    20 * Minify engine 2.1.7 updated
    21 * cache interval option fixed
    22 * move CSS-@imports to the top of the output
    23 * bottom CSS- and JavaScript output fixed
    24 * support for script-tags without `type="text/javascript"`
    25 * detection of protocol-relative URLs as external file (e.g. Google AdSense)
     20* Minify engine updated to version 2.1.7
     21* Cache interval option has been fixed
     22* Move CSS-@imports to the top of the output
     23* Bottom CSS- and JavaScript output fixed
     24* Support for script tags without `type="text/javascript"`
     25* Detection of protocol-relative URLs as external file (e.g. Google AdSense)
     26* New option for the HTML5 async attribute
     27* A separate JavaScript file in the footer is now possible
    2628
    2729= How Does it Work? =
     
    4749
    4850== Changelog ==
     51= 1.4.0 =
     52* Added option for the HTML5 async attribute
     53* Added option for a separate JavaScript file in the footer
     54* Tabs are used instead of spaces in the PHP code
     55* Bugfixes
     56* Small changes
     57
    4958= 1.3.4 =
    50 * support for script-tags without `type="text/javascript"`
    51 * detection of protocol-relative URLs as external file (e.g. Google AdSense)
     59* Support for script-tags without `type="text/javascript"`
     60* Detection of protocol-relative URLs as external file (e.g. Google AdSense)
    5261
    5362= 1.3.3 =
    54 * bottom CSS- and JavaScript output fixed
     63* Bottom CSS- and JavaScript output fixed
    5564
    5665= 1.3.2 =
    57 * move CSS-@imports to the top of the output
     66* Move CSS-@imports to the top of the output
    5867
    5968= 1.3.1 =
     
    6271= 1.3.0 =
    6372* WP Minify Fix released
    64 * cache interval fixed
     73* Cache interval fixed
    6574
    6675= 1.2.0 =
  • wp-minify-fix/tags/1.4.0/wp-minify.php

    r892852 r1081305  
    44Plugin URI: http://wordpress.org/plugins/wp-minify-fixed/
    55Description: [Fixed] This plugin uses the Minify engine to combine and compress JS and CSS files to improve page load time.
    6 Version: 1.3.4
     6Version: 1.4.0
    77Author: NodeCode
    88Author URI: http://nodecode.de
     
    2020This program is distributed in the hope that it will be useful,
    2121but WITHOUT ANY WARRANTY; without even the implied warranty of
    22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    2323GNU General Public License for more details.
    2424
    2525You should have received a copy of the GNU General Public License
    26 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     26along with this program.    If not, see <http://www.gnu.org/licenses/>.
    2727*/
    2828
    2929class WPMinify {
    3030
    31   var $author_homepage = 'http://nodecode.de/';
    32   var $homepage = 'http://wordpress.org/plugins/wp-minify-fixed/';
    33   var $name = 'wp_minify';
    34   var $name_dashed = 'wp-minify-fix';
    35   var $name_proper = 'WP Minify Fix';
    36   var $required_wp_version = '2.7';
    37   var $version = '1.3.4';
    38 
    39   var $c = null;
    40   var $debug = false;
    41   var $cache_location = 'wp-content/plugins/wp-minify-fix/cache/';
    42   var $url_len_limit = 2000;
    43   var $minify_limit = 50;
    44   var $buffer_started = false;
    45   var $default_exclude = array();
    46 
    47   function WPMinify() {
    48     // initialize common functions
    49     $this->c = new WPMinifyCommon($this);
    50 
    51     // load translation
    52     $this->c->load_text_domain();
    53 
    54     // register admin scripts
    55     add_action('admin_init', array($this->c, 'a_register_scripts'));
    56     add_action('admin_init', array($this->c, 'a_register_styles'));
    57 
    58     // check wp version
    59     add_action('admin_head', array($this->c, 'a_check_version'));
    60 
    61     // load admin menu
    62     add_action('admin_menu', array($this, 'a_menu'));
    63 
    64     // register ajax handler
    65     add_action('wp_ajax_wpm', array($this, 'a_ajax_handler'));
    66 
    67     // No need to minify admin stuff
    68     if (!is_admin() && !is_feed() && !defined('XMLRPC_REQUEST')) {
    69       // Don't minify if if user passes wp-minify-off=1 in GET parameter
    70       if (!(isset($_GET['wp-minify-off']) && $_GET['wp-minify-off'])) {
    71         add_action('init', array($this, 'pre_content'), 99999);
    72         add_action('wp_footer', array($this, 'post_content'), 99999);
    73       }
    74       // advertise hook
    75       add_action('wp_footer', array($this, 'advertise'));
    76     }
    77   }
    78 
    79   // admin functions
    80 
    81   function a_default_options() {
    82     return array(
    83       'cache_external' => false,
    84       'cache_interval' => 3600,
    85       'css_exclude' => array(),
    86       'css_include' => array(),
    87       'debug_nominify' => false,
    88       'debug_firephp' => false,
    89       'enable_css' => true,
    90       'enable_js' => true,
    91       'enable_html' => true,
    92       'auto_base' => true,
    93       'extra_minify_options' => '',
    94       'js_exclude' => array(),
    95       'js_include' => array(),
    96       'js_in_footer' => false,
    97       'force_https' => false,
    98       'pretty_url' => false,
    99       'show_link' => false,
    100       'show_advanced' => false,
    101       'uri_exclude' => array(),
    102       'version' => $this->version,
    103       'deprecated' => array(
    104         'wp_path', 'debug', 'debug_noprettyurl'
    105       )
    106     );
    107   }
    108 
    109   function a_update_options() {
    110     // new options
    111     $wpm_new_options = stripslashes_deep($_POST['wpm_options_update']);
    112 
    113     // current options
    114     $wpm_current_options = get_option($this->name);
    115 
    116     // convert "on" to true and "off" to false for checkbox fields
    117     // and set defaults for fields that are left blank
    118     if (isset($wpm_new_options['show_link']) && $wpm_new_options['show_link'] == "on")
    119       $wpm_new_options['show_link'] = true;
    120     else
    121       $wpm_new_options['show_link'] = false;
    122 
    123     if (isset($wpm_new_options['enable_js']))
    124       $wpm_new_options['enable_js'] = true;
    125     else
    126       $wpm_new_options['enable_js'] = false;
    127 
    128     if (isset($wpm_new_options['enable_css']))
    129       $wpm_new_options['enable_css'] = true;
    130     else
    131       $wpm_new_options['enable_css'] = false;
    132 
    133     if (isset($wpm_new_options['enable_html']))
    134       $wpm_new_options['enable_html'] = true;
    135     else
    136       $wpm_new_options['enable_html'] = false;
    137 
    138     if (isset($wpm_new_options['auto_base']))
    139       $wpm_new_options['auto_base'] = true;
    140     else
    141       $wpm_new_options['auto_base'] = false;
    142 
    143     if (isset($wpm_new_options['cache_external']))
    144       $wpm_new_options['cache_external'] = true;
    145     else
    146       $wpm_new_options['cache_external'] = false;
    147 
    148     if (isset($wpm_new_options['js_in_footer']))
    149       $wpm_new_options['js_in_footer'] = true;
    150     else
    151       $wpm_new_options['js_in_footer'] = false;
    152 
    153     if (isset($wpm_new_options['pretty_url']))
    154       $wpm_new_options['pretty_url'] = true;
    155     else
    156       $wpm_new_options['pretty_url'] = false;
    157 
    158     if (isset($wpm_new_options['debug_nominify']))
    159       $wpm_new_options['debug_nominify'] = true;
    160     else
    161       $wpm_new_options['debug_nominify'] = false;
    162 
    163     if (isset($wpm_new_options['debug_firephp']))
    164       $wpm_new_options['debug_firephp'] = true;
    165     else
    166       $wpm_new_options['debug_firephp'] = false;
    167 
    168     $this->a_set_minify_config($wpm_new_options['debug_nominify'], $wpm_new_options['debug_firephp']);
    169 
    170     if ( isset($wpm_new_options['force_https']) )
    171       $wpm_new_options['force_https'] = true;
    172     else
    173       $wpm_new_options['force_https'] = false;
    174 
    175     if (strlen(trim($wpm_new_options['js_include'])) > 0)
    176       $wpm_new_options['js_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_include'])));
    177     else
    178       $wpm_new_options['js_include'] = array();
    179 
    180     if (strlen(trim($wpm_new_options['js_exclude'])) > 0)
    181       $wpm_new_options['js_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_exclude'])));
    182     else
    183       $wpm_new_options['js_exclude'] = array();
    184 
    185     if (strlen(trim($wpm_new_options['css_include'])) > 0)
    186       $wpm_new_options['css_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_include'])));
    187     else
    188       $wpm_new_options['css_include'] = array();
    189 
    190     if (strlen(trim($wpm_new_options['css_exclude'])) > 0)
    191       $wpm_new_options['css_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_exclude'])));
    192     else
    193       $wpm_new_options['css_exclude'] = array();
    194 
    195     if ( strlen(trim($wpm_new_options['uri_exclude'])) > 0 )
    196       $wpm_new_options['uri_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['uri_exclude'])));
    197     else
    198       $wpm_new_options['uri_exclude'] = array();
    199 
    200     // Update options
    201     foreach ($wpm_new_options as $key => $value) {
    202       $wpm_current_options[$key] = $value;
    203     }
    204 
    205     update_option($this->name, $wpm_current_options);
    206   }
    207 
    208   function a_set_advanced_options($val) {
    209     $wpm_options = get_option($this->name);
    210     $wpm_options['show_advanced'] = $val;
    211     update_option($this->name, $wpm_options);
    212   }
    213 
    214   function a_ajax_handler() {
    215     check_ajax_referer($this->name);
    216     if (isset($_POST['wpm_action'])) {
    217       if (strtolower($_POST['wpm_action']) == 'show_advanced') {
    218         $this->a_set_advanced_options(true);
    219       }
    220       elseif (strtolower($_POST['wpm_action']) == 'hide_advanced') {
    221         $this->a_set_advanced_options(false);
    222       }
    223       else {
    224         echo 'Invalid wpm_action.';
    225       }
    226     }
    227     exit();
    228   }
    229 
    230   function a_request_handler() {
    231     if (isset($_POST['wpm_options_update_submit'])) {
    232       check_admin_referer($this->name);
    233       $this->a_update_options();
    234       add_action('admin_notices', array($this->c, 'a_notify_updated'));
    235     }
    236     elseif (isset($_POST['wpm_options_clear_cache_submit'])) {
    237       // if user wants to regenerate nonce
    238       check_admin_referer($this->name);
    239       $this->c->a_clear_cache();
    240       add_action('admin_notices', array($this->c, 'a_notify_cache_cleared'));
    241     }
    242     elseif (isset($_POST['wpm_options_upgrade_submit'])) {
    243       // if user wants to upgrade options (for new options on version upgrades)
    244       check_admin_referer($this->name);
    245       $this->c->a_upgrade_options();
    246       add_action('admin_notices', array($this->c, 'a_notify_upgraded'));
    247     }
    248     elseif (isset($_POST['wpm_options_reset_submit'])) {
    249       // if user wants to reset all options
    250       check_admin_referer($this->name);
    251       $this->c->a_reset_options();
    252       add_action('admin_notices', array($this->c, 'a_notify_reset'));
    253     }
    254 
    255     // only check these on plugin settings page
    256     $this->c->a_check_dir_writable($this->c->get_plugin_dir().'cache/', array($this, 'a_notify_cache_not_writable'));
    257     $this->c->a_check_orphan_options(array($this, 'a_notify_orphan_options'));
    258     if ($this->c->a_check_dir_writable($this->c->get_plugin_dir().'min/config.php', array($this, 'a_notify_config_not_writable'))) {
    259       $this->a_check_minify_config();
    260     }
    261   }
    262 
    263   function a_check_minify_config() {
    264     $fname = $this->c->get_plugin_dir().'min/config.php';
    265     $fhandle = fopen($fname,'r');
    266     $content = fread($fhandle,filesize($fname));
    267 
    268     $config_modified = false;
    269    
    270     preg_match('/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s', $content, $matches);
    271     $cache_path_code = $matches[1];
    272     if (!preg_match('/\$min_cachePath.*?/', $cache_path_code)) {
    273       $content = preg_replace(
    274         '/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s',
    275         "//###WPM-CACHE-PATH-BEFORE###\n".'$min_cachePath = \''.$this->c->get_plugin_dir()."cache/';\n//###WPM-CACHE-PATH-AFTER###",
    276         $content);
    277       $config_modified = true;
    278     }
    279 
    280     preg_match('/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s', $content, $matches);
    281     $cache_age_code = $matches[1];
    282     if (!preg_match('/\$min_serveOptions\[\'maxAge\'].*?/', $cache_age_code)) {
    283       $content = preg_replace(
    284         '/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s',
    285         "//###WPM-CACHE-AGE-BEFORE###\n".'$min_serveOptions[\'maxAge\'] = 2592000;'."\n//###WPM-CACHE-AGE-AFTER###",
    286         $content);
    287       $config_modified = true;
    288     }
    289 
    290     if ($config_modified) {
    291       $this->a_notify_modified_minify_config();
    292     }
    293    
    294     $fhandle = fopen($fname,"w");
    295     fwrite($fhandle,$content);
    296     fclose($fhandle);
    297   }
    298 
    299   function a_set_minify_config($nominify = false, $firephp = false) {
    300     if ($nominify) {
    301       $nominify = 'true';
    302     } else {
    303       $nominify = 'false';
    304     }
    305     if ($firephp) {
    306       $firephp = 'true';
    307     } else {
    308       $firephp = 'false';
    309     }
    310     $fname = $this->c->get_plugin_dir().'min/config.php';
    311     $fhandle = fopen($fname,'r');
    312     $content = fread($fhandle,filesize($fname));
    313 
    314     $content = preg_replace(
    315       '/\/\/###WPM-DEBUG-FLAG-BEFORE###(.*)\/\/###WPM-DEBUG-FLAG-AFTER###/s',
    316       "//###WPM-DEBUG-FLAG-BEFORE###\n".'$min_allowDebugFlag = '.$nominify.";\n//###WPM-DEBUG-FLAG-AFTER###",
    317       $content);
    318 
    319     $content = preg_replace(
    320       '/\/\/###WPM-ERROR-LOGGER-BEFORE###(.*)\/\/###WPM-ERROR-LOGGER-AFTER###/s',
    321       "//###WPM-ERROR-LOGGER-BEFORE###\n".'$min_errorLogger = '.$firephp.";\n//###WPM-ERROR-LOGGER-AFTER###",
    322       $content);
    323 
    324     $fhandle = fopen($fname,"w");
    325     fwrite($fhandle,$content);
    326     fclose($fhandle);
    327   }
    328 
    329   function a_notify_cache_not_writable() {
    330     $this->c->a_notify(
    331       sprintf('%s: %s',
    332         __('Cache directory is not writable. Please grant your server write permissions to the directory', $this->name),
    333         $this->c->get_plugin_dir().'cache/'),
    334       true);
    335   }
    336 
    337   function a_notify_config_not_writable() {
    338     $this->c->a_notify(
    339       sprintf('%s: %s',
    340         __('Minify Engine config.php is not writable. Please grant your server write permissions to file', $this->name),
    341         $this->c->get_plugin_dir().'min/config.php'));
    342   }
    343 
    344   function a_notify_orphan_options() {
    345     $this->c->a_notify(
    346       sprintf('%s',
    347         __('Some option settings are missing (possibly from plugin upgrade).', $this->name)));
    348   }
    349 
    350   function a_notify_modified_minify_config() {
    351     $this->c->a_notify(__('Minify Engine config.php was configured automatically.', $this->name));
    352   }
    353 
    354   function a_menu() {
    355     $options_page = add_options_page($this->name_proper, $this->name_proper, 'manage_options', 'wp-minify-fix', array($this, 'a_page'));
    356     add_action('admin_head-'.$options_page, array($this, 'a_request_handler'));
    357     add_action('admin_print_scripts-'.$options_page, array($this->c, 'a_enqueue_scripts'));
    358     add_action('admin_print_styles-'.$options_page, array($this->c, 'a_enqueue_styles'));
    359   }
    360 
    361   function a_page() {
    362     $wpm_options = get_option($this->name);
    363     printf('
    364       <div class="wrap omni_admin_content">
    365         <h2>%s</h2>
    366         <div>
    367           <a href="'.preg_replace('/&wpm-page=[^&]*/', '', $_SERVER['REQUEST_URI']).'">%s</a>&nbsp;|&nbsp;
    368           <a href="'.$this->homepage.'">%s</a>
    369         </div>',
    370       __('WP Minify Options', $this->name),
    371       __('General Configuration', $this->name),
    372       __('Documentation', $this->name)
    373     );
    374     printf('<div class="omni_admin_main">');
    375     if (isset($_GET['wpm-page'])) {
    376       if ($_GET['wpm-page'] || !$_GET['wpm-page']) {
    377         require_once('options-generic.php');
    378       }
    379     }
    380     else {
    381       require_once('options-generic.php');
    382     }
    383     printf('</div>'); // omni_admin_main
    384     require_once('options-sidebar.php');
    385     printf('</div>'); // wrap
    386 
    387   } // admin_page()
    388 
    389   // other functions
    390 
    391   function fetch_and_cache($url, $cache_file) {
    392     $ch = curl_init();
    393     $timeout = 5; // set to zero for no timeout
    394     curl_setopt ($ch, CURLOPT_URL, $url);
    395     curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    396     curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    397     curl_setopt ($ch, CURLOPT_USERAGENT, 'WP-Minify Fix');
    398     $content = curl_exec($ch);
    399     curl_close($ch);
    400     if ($content) {
    401       if (is_array($content)) {
    402         $content = implode($content);
    403       }
    404 
    405       // save cache file
    406       $fh = fopen($cache_file, 'w');
    407       if ($fh) {
    408         fwrite($fh, $content);
    409         fclose($fh);
    410       }
    411       else {
    412         // cannot open for write.  no error b/c something else is probably writing to the file.
    413       }
    414 
    415       return $content;
    416     }
    417     else {
    418       printf(
    419         '%s: '.$url.'. %s<br/>',
    420         __('Error: Could not fetch and cache URL'),
    421         __('You might need to exclude this file in WP Minify options.')
    422       );
    423       return '';
    424     }
    425   }
    426 
    427   function refetch_cache_if_expired($url, $cache_file) {
    428     $wpm_options = get_option($this->name);
    429     $cache_file_mtime = filemtime($cache_file);
    430     if ((time() - $cache_file_mtime) > $wpm_options['cache_interval']) {
    431       $this->fetch_and_cache($url, $cache_file);
    432     }
    433   }
    434 
    435   function tiny_filename($str) {
    436     $f = __FILE__;
    437     // no fancy shortening for Windows
    438     return ('/' === $f[0]) ? strtr(base64_encode(md5($str, true)), '+/=', '-_(') : md5($str);
    439   }
    440 
    441   function array_trim($arr, $charlist=null) {
    442     foreach ($arr as $key => $value) {
    443       if (is_array($value)) $result[$key] = array_trim($value, $charlist);
    444       else $result[$key] = trim($value, $charlist);
    445     }
    446     return $result;
    447   }
    448 
    449   function check_and_split_url($url, $latest_modified = 0) {
    450     $url_chunk = explode('?f=', $url);
    451     $base_url = array_shift($url_chunk);
    452     $files = explode(',', array_shift($url_chunk));
    453     $num_files = sizeof($files);
    454 
    455     if ($this->url_needs_splitting($url, $files)) {
    456       $first_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, 0, $num_files/2)), $latest_modified);
    457       $second_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, $num_files/2)), $latest_modified);
    458       return $first_half + $second_half;
    459     }
    460     else {
    461       $wpm_options = get_option($this->name);
    462 
    463       // append &debug if we need to
    464       if ($wpm_options['debug_nominify']) {
    465         $debug_string = '&amp;debug=true';
    466       } else {
    467         $debug_string = '';
    468       }
    469 
    470       // append base directory if needed
    471       $base = $this->get_base();
    472       if ($base != '') {
    473         $base_string = '&amp;b='.$base;
    474       } else {
    475         $base_string = '';
    476       }
    477 
    478       // get rid of any base directory specification in extra options
    479       $extra_minify_options = preg_replace('/(&|&amp;|\b)b=[^&]*/', '', trim($wpm_options['extra_minify_options']));
    480       if (trim($extra_minify_options) != '') {
    481         $extra_string = '&amp;'.$extra_minify_options;
    482       } else {
    483         $extra_string = '';
    484       }
    485 
    486       // append last modified time
    487       $latest_modified_string = '&amp;m='.$latest_modified;
    488 
    489       return array($base_url . '?f=' . implode(',', $files) . $debug_string . $base_string . $extra_string . $latest_modified_string);
    490     }
    491   }
    492 
    493   function fetch_content($url, $type = '') {
    494     $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
    495     $content = '';
    496     if (file_exists($cache_file)) {
    497       // check cache expiration
    498       $this->refetch_cache_if_expired($url, $cache_file);
    499 
    500       $fh = fopen($cache_file, 'r');
    501       if ($fh && filesize($cache_file) > 0) {
    502         $content = fread($fh, filesize($cache_file));
    503         fclose($fh);
    504       }
    505       else {
    506         // cannot open cache file so fetch it
    507         $content = $this->fetch_and_cache($url, $cache_file);
    508       }
    509     }
    510     else {
    511       // no cache file.  fetch from internet and save to local cache
    512       $content = $this->fetch_and_cache($url, $cache_file);
    513     }
    514     return $content;
    515   }
    516 
    517   function local_version($url) {
    518     $site_url = trailingslashit(get_option('siteurl'));
    519     $url = str_replace($site_url, '', $url); // relative paths only for local urls
    520     //$url = preg_replace('/^\//', '', $url); // strip front / if any
    521     $url = preg_replace('/\?.*/i', '', $url); // throws away parameters, if any
    522     return $url;
    523   }
    524 
    525   function is_external($url, $localize=true) {
    526     if ($localize) {
    527       $url = $this->local_version($url);
    528     }
    529 
    530     if (substr($url, 0, 4) != 'http' && substr($url, 0, 2) != '//'
    531       && (substr($url, -3, 3) == '.js' || substr($url, -4, 4) == '.css')) {
    532       return false;
    533     } else {
    534       return true;
    535     }
    536   }
    537 
    538   function get_js_location($src) {
    539     if ($this->debug)
    540       echo 'Script URL:'.$src."<br/>\n";
    541 
    542     $script_path = $this->local_version($src);
    543     if ($this->is_external($script_path, false)) {
    544       // fetch scripts if necessary
    545       $this->fetch_content($src, '.js');
    546       $location = $this->cache_location . md5($src) . '.js';
    547       if ($this->debug)
    548         echo 'External script detected, cached as:'. md5($src) . "<br/>\n";
    549     } else {
    550       // if script is local to server
    551       $location = $script_path;
    552       if ($this->debug)
    553         echo 'Local script detected:'.$script_path."<br/>\n";
    554     }
    555 
    556     return $location;
    557   }
    558 
    559   function get_css_location($src) {
    560     if ($this->debug)
    561       echo 'Style URL:'.$src."<br/>\n";
    562 
    563     $css_path = $this->local_version($src);
    564     if ($this->is_external($css_path, false)) {
    565       // fetch scripts if necessary
    566       $this->fetch_content($src, '.css');
    567       $location = $this->cache_location . md5($src) . '.css';
    568       if ($this->debug)
    569         echo 'External css detected, cached as:'. md5($src) . "<br/>\n";
    570     } else {
    571       $location = $css_path;
    572       // if css is local to server
    573       if ($this->debug)
    574         echo 'Local css detected:'.$css_path."<br/>\n";
    575     }
    576 
    577     return $location;
    578   }
    579 
    580   function url_needs_splitting($url, $locations) {
    581     if ($url > $this->url_len_limit || count($locations) > $this->minify_limit) {
    582       return true;
    583     } else {
    584       return false;
    585     }
    586   }
    587 
    588   function build_minify_urls($locations, $type) {
    589     $wpm_options = get_option($this->name);
    590     $minify_url = $this->c->get_plugin_url().'min/?f=';
    591     if ($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on") {
    592       $minify_url = preg_replace('/^http:\/\//', 'https://', $minify_url);
    593     }
    594     $minify_url .= implode(',', $locations);
    595     $latest_modified = $this->get_latest_modified_time($locations);
    596     $minify_urls = $this->check_and_split_url($minify_url, $latest_modified);
    597 
    598     if ($wpm_options['pretty_url']) {
    599       return $this->get_cached_minify_urls($minify_urls, $type);
    600     } else {
    601       return $minify_urls;
    602     }
    603   }
    604  
    605   function get_cached_minify_urls($urls, $type) {
    606     $wpm_options = get_option($this->name);
    607     $cached_urls = array();
    608     foreach ($urls as $url) {
    609       $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
    610       if (file_exists($cache_file)) {
    611         // check cache expiration
    612         $this->refetch_cache_if_expired($url, $cache_file);
    613  
    614         $fh = fopen($cache_file, 'r');
    615         if ($fh && filesize($cache_file) > 0) {
    616           $content = fread($fh, filesize($cache_file));
    617           fclose($fh);
    618         } else {
    619           // cannot open cache file so fetch it
    620           $this->fetch_and_cache($url, $cache_file);
    621         }
    622       } else {
    623         // no cache file. fetch it
    624         $this->fetch_and_cache($url, $cache_file);
    625       }
    626       $cache_url = $this->c->get_plugin_url().'cache/'.md5($url).$type.'?m='.filemtime($cache_file);
    627       $cached_urls[] = $cache_url;
    628     }
    629     return $cached_urls;
    630   }
    631 
    632   function get_base_from_minify_args() {
    633     $wpm_options = get_option($this->name);
    634     if (!empty($wpm_options['extra_minify_options'])) {
    635       if (preg_match('/\bb=([^&]*?)(&|$)/', trim($wpm_options['extra_minify_options']), $matches)) {
    636         return rtrim(trim($matches[1]), '\\/');
    637       }
    638     }
    639     return '';
    640   }
    641 
    642   function get_base_from_siteurl() {
    643     $site_url = trailingslashit(get_option('siteurl'));
    644     return rtrim(preg_replace('/^https?:\/\/.*?\//', '', $site_url), '\\/');
    645   }
    646 
    647   function get_base() {
    648     $base_from_min_args = $this->get_base_from_minify_args();
    649     if ($base_from_min_args != '') {
    650       return $base_from_min_args;
    651     }
    652 
    653     $wpm_options = get_option($this->name);
    654     if ($wpm_options['auto_base']) {
    655       return $this->get_base_from_siteurl();
    656     } else {
    657       return '';
    658     }
    659   }
    660 
    661   function get_latest_modified_time($locations = array()) {
    662     $latest_modified = 0;
    663     if (!empty($locations)) {
    664       $base_path = trailingslashit($_SERVER['DOCUMENT_ROOT']);
    665       $base_path .= trailingslashit($this->get_base());
    666 
    667       foreach ($locations as $location) {
    668         $path = $base_path.$location;
    669         $mtime = filemtime($path);
    670         if ($latest_modified < $mtime) {
    671           $latest_modified = $mtime;
    672         }
    673       }
    674     }
    675     return $latest_modified;
    676   }
    677 
    678   function extract_css($content) {
    679     $wpm_options = get_option($this->name);
    680     $css_locations = array();
    681 
    682     preg_match_all('/<link([^>]*?)>/i', $content, $link_tags_match);
    683 
    684     foreach ($link_tags_match[0] as $link_tag) {
    685       if (strpos(strtolower($link_tag), 'stylesheet')) {
    686         // check CSS media type
    687         if (!strpos(strtolower($link_tag), 'media=')
    688           || preg_match('/media=["\'](?:["\']|[^"\']*?(all|screen)[^"\']*?["\'])/', $link_tag)
    689         ) {
    690           preg_match('/href=[\'"]([^\'"]+)/', $link_tag, $href_match);
    691           if ($href_match[1]) {
    692             // include it if it is in the include list
    693             $include = false;
    694             $inclusions = $wpm_options['css_include'];
    695             foreach ($inclusions as $include_pat) {
    696               $include_pat = trim($include_pat);
    697               if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
    698                 $include = true;
    699                 break;
    700               }
    701             }
    702 
    703             if (!$include) {
    704               // support external files?
    705               if (!$wpm_options['cache_external'] && $this->is_external($href_match[1])) {
    706                 continue; // skip if we don't cache externals and this file is external
    707               }
    708 
    709               // do not include anything in excluded list
    710               $skip = false;
    711               $exclusions = array_merge($this->default_exclude, $wpm_options['css_exclude']);
    712               foreach ($exclusions as $exclude_pat) {
    713                 $exclude_pat = trim($exclude_pat);
    714                 if (strlen($exclude_pat) > 0 && strpos($href_match[1], $exclude_pat) !== false) {
    715                   $skip = true;
    716                   break;
    717                 }
    718               }
    719               if ($skip) continue;
    720             }
    721 
    722             $content = str_replace($link_tag . '</link>', '', $content);
    723             $content = str_replace($link_tag, '', $content);
    724             $css_locations[] = $this->get_css_location($href_match[1]);
    725           }
    726         }
    727       }
    728     }
    729 
    730     $css_locations = array_unique($css_locations);
    731 
    732     return array($content, $css_locations);
    733   }
    734 
    735   function inject_css($content, $css_locations) {
    736     if (count($css_locations) > 0) {
    737       $wpm_options = get_option($this->name);
    738       // build minify URLS
    739       $css_tags = '';
    740       $minify_urls = $this->build_minify_urls($css_locations, '.css');
    741 
    742       foreach ($minify_urls as $minify_url) {
    743         $minify_url = apply_filters('wp_minify_css_url', $minify_url); // Allow plugins to modify final minify URL
    744         $css_tags .= "<link rel='stylesheet' href='$minify_url' type='text/css' media='screen' />";
    745       }
    746 
    747       $matches = preg_match('/<!-- WP-Minify CSS -->/', $content);
    748 
    749       if ($matches) {
    750         $content = preg_replace('/<!-- WP-Minify CSS -->/', "$css_tags", $content, 1); // limit 1 replacement
    751       } else {
    752         // HTML5 has <header> tags so account for those in regex
    753         $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$css_tags", $content, 1); // limit 1 replacement
    754       }
    755     }
    756     return $content;
    757   }
    758 
    759   function extract_conditionals($content) {
    760     preg_match_all('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', $content, $conditionals_match);
    761     $content = preg_replace('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', '###WPM-CSS-CONDITIONAL###', $content);
    762 
    763     $conditionals = array();
    764     foreach ($conditionals_match[0] as $conditional) {
    765       $conditionals[] = $conditional;
    766     }
    767 
    768     return array($content, $conditionals);
    769   }
    770 
    771   function inject_conditionals($content, $conditionals) {
    772     while (count($conditionals) > 0 && strpos($content, '###WPM-CSS-CONDITIONAL###')) {
    773       $conditional = array_shift($conditionals);
    774       $content = preg_replace('/###WPM-CSS-CONDITIONAL###/', $conditional, $content, 1);
    775     }
    776 
    777     return $content;
    778   }
    779 
    780   function extract_js($content) {
    781     $wpm_options = get_option($this->name);
    782     $js_locations = array();
    783 
    784     preg_match_all('/<script([^>]*?)><\/script>/i', $content, $script_tags_match);
    785 
    786     foreach ($script_tags_match[0] as $script_tag) {
    787       preg_match('/src=[\'"]([^\'"]+)/', $script_tag, $src_match);
    788       if ($src_match[1]) {
    789         // include it if it is in the include list
    790         $include = false;
    791         $inclusions = $wpm_options['js_include'];
    792         foreach ($inclusions as $include_pat) {
    793           $include_pat = trim($include_pat);
    794           if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
    795             $include = true;
    796             break;
    797           }
    798         }
    799 
    800         if (!$include) {
    801           // support external files?
    802           if (!$wpm_options['cache_external'] && $this->is_external($src_match[1])) {
    803             continue; // skip if we don't cache externals and this file is external
    804           }
    805 
    806           // do not include anything in excluded list
    807           $skip = false;
    808           $exclusions = array_merge($this->default_exclude, $wpm_options['js_exclude']);
    809           foreach ($exclusions as $exclude_pat) {
    810             $exclude_pat = trim($exclude_pat);
    811             if (strlen($exclude_pat) > 0 && strpos($src_match[1], $exclude_pat) !== false) {
    812               $skip = true;
    813               break;
    814             }
    815           }
    816           if ($skip) continue;
    817         }
    818 
    819         $content = str_replace($script_tag, '', $content);
    820         $js_locations[] = $this->get_js_location($src_match[1]);
    821       }
    822     }
    823 
    824     $js_locations = array_unique($js_locations);
    825 
    826     return array($content, $js_locations);
    827   }
    828 
    829   function inject_js($content, $js_locations) {
    830     if (count($js_locations) > 0) {
    831       // build minify URLS
    832       $js_tags = '';
    833       $minify_urls = $this->build_minify_urls($js_locations, '.js');
    834 
    835       foreach ($minify_urls as $minify_url) {
    836         $minify_url = apply_filters('wp_minify_js_url', $minify_url); // Allow plugins to modify final minify URL
    837         $js_tags .= "<script type='text/javascript' src='$minify_url'></script>";
    838       }
    839 
    840       $matches = preg_match('/<!-- WP-Minify JS -->/', $content);
    841 
    842       if ($matches) {
    843         $content = preg_replace('/<!-- WP-Minify JS -->/', "$js_tags", $content, 1); // limit 1 replacement
    844       } else {
    845         $wpm_options = get_option($this->name);
    846         if ($wpm_options['js_in_footer']) {
    847           $content = preg_replace('/<\/body>/', "$js_tags\n</body>", $content, 1); // limit 1 replacement
    848         } else {
    849           // HTML5 has <header> tags so account for those in regex
    850           $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$js_tags", $content, 1); // limit 1 replacement
    851         }
    852       }
    853     }
    854     return $content;
    855   }
    856 
    857   function pre_content() {
    858     $wpm_options = get_option($this->name);
    859     if ($wpm_options['uri_exclude'] && count($wpm_options['uri_exclude'])) {
    860       foreach ($wpm_options['uri_exclude'] as $exclude_pat) {
    861         $exclude_pat = trim($exclude_pat);
    862         if (strlen($exclude_pat) > 0 && strpos($_SERVER['REQUEST_URI'], $exclude_pat) !== false) {
    863           return;
    864         }
    865       }
    866     }
    867 
    868     ob_start(array($this, 'modify_buffer'));
    869 
    870     // variable for sanity checking
    871     $this->buffer_started = true;
    872   }
    873 
    874   function modify_buffer($buffer) {
    875     $wpm_options = get_option($this->name);
    876 
    877     // if we do not want to force http to https then we need to exclude https
    878     if (!($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on")) {
    879       $this->default_exclude[] = 'https://';
    880     }
    881 
    882     // minify JS
    883     if ($wpm_options['enable_js']) {
    884       list($buffer, $js_locations) = $this->extract_js($buffer);
    885       $buffer= $this->inject_js($buffer, $js_locations);
    886     }
    887 
    888     // minify CSS (make sure to exclude CSS conditionals)
    889     if ($wpm_options['enable_css']) {
    890       list($buffer, $conditionals) = $this->extract_conditionals($buffer);
    891       list($buffer, $css_locations) = $this->extract_css($buffer);
    892       $buffer = $this->inject_css($buffer, $css_locations);
    893       $buffer = $this->inject_conditionals($buffer, $conditionals);
    894     }
    895 
    896     // get rid of empty lines
    897     $buffer = preg_replace('/\s*(\r?\n)(\r?\n)*/', '$1', $buffer);
    898 
    899     // minify HTML
    900     if ($wpm_options['enable_html']) {
    901       if (!class_exists('Minify_HTML')) {
    902         require_once('min/lib/Minify/HTML.php');
    903       }
    904       $buffer = Minify_HTML::minify($buffer);
    905     }
    906 
    907     $buffer = apply_filters('wp_minify_content', $buffer); // allow plugins to modify buffer
    908 
    909     return $buffer;
    910   }
    911 
    912   function post_content() {
    913     // sanity checking
    914     if ($this->buffer_started) {
    915       ob_end_flush();
    916     }
    917   }
    918 
    919   function advertise() {
    920     $wpm_options = get_option($this->name);
    921     if ($wpm_options['show_link']) {
    922       printf("<p align='center'><small>Page optimized by <a href='$this->homepage' title='$this->name_proper WordPress Plugin' style='text-decoration:none;'>$this->name_proper</a> <a href='$this->author_homepage' title='WordPress Plugin' style='text-decoration:none;'>WordPress Plugin</a></small></p>");
    923     }
    924   }
     31    var $author_homepage = 'http://nodecode.de/';
     32    var $homepage = 'http://wordpress.org/plugins/wp-minify-fixed/';
     33    var $name = 'wp_minify';
     34    var $name_dashed = 'wp-minify-fix';
     35    var $name_proper = 'WP Minify Fix';
     36    var $required_wp_version = '2.7';
     37    var $version = '1.4.0';
     38
     39    var $c = null;
     40    var $debug = false;
     41    var $cache_location = 'wp-content/plugins/wp-minify-fix/cache/';
     42    var $url_len_limit = 2000;
     43    var $minify_limit = 50;
     44    var $buffer_started = false;
     45    var $default_exclude = array();
     46   
     47    var $footer_scripts_string = 'abc';
     48
     49    function WPMinify() {
     50        // initialize common functions
     51        $this->c = new WPMinifyCommon($this);
     52
     53        // load translation
     54        $this->c->load_text_domain();
     55
     56        // register admin scripts
     57        add_action('admin_init', array($this->c, 'a_register_scripts'));
     58        add_action('admin_init', array($this->c, 'a_register_styles'));
     59
     60        // check wp version
     61        add_action('admin_head', array($this->c, 'a_check_version'));
     62
     63        // load admin menu
     64        add_action('admin_menu', array($this, 'a_menu'));
     65
     66        // register ajax handler
     67        add_action('wp_ajax_wpm', array($this, 'a_ajax_handler'));
     68
     69        // No need to minify admin stuff
     70        if (!is_admin() && !defined('XMLRPC_REQUEST')) {
     71            // Don't minify if if user passes wp-minify-off=1 in GET parameter
     72            if (!(isset($_GET['wp-minify-off']) && $_GET['wp-minify-off'])) {
     73                // footer scripts hook
     74                add_action('wp_footer', array($this, 'footer_placeholder'), 1);
     75               
     76                add_action('init', array($this, 'pre_content'), 99999);
     77                add_action('wp_footer', array($this, 'post_content'), 99999);
     78            }
     79            // advertise hook
     80            add_action('wp_footer', array($this, 'advertise'));
     81        }
     82    }
     83
     84    // admin functions
     85
     86    function a_default_options() {
     87        return array(
     88            'cache_external' => false,
     89            'cache_interval' => 3600,
     90            'css_exclude' => array(),
     91            'css_include' => array(),
     92            'debug_nominify' => false,
     93            'debug_firephp' => false,
     94            'enable_css' => true,
     95            'enable_js' => true,
     96            'enable_html' => true,
     97            'auto_base' => true,
     98            'extra_minify_options' => '',
     99            'js_exclude' => array(),
     100            'js_include' => array(),
     101            'js_placement' => 'header-footer', // header-footer, header or footer
     102            'js_async' => false, // Header only, see http://css-tricks.com/async-attribute-scripts-bottom/
     103            'force_https' => false,
     104            'pretty_url' => false,
     105            'show_link' => false,
     106            'show_advanced' => false,
     107            'uri_exclude' => array(),
     108            'version' => $this->version,
     109            'deprecated' => array(
     110                'wp_path', 'debug', 'debug_noprettyurl', 'js_in_footer'
     111            )
     112        );
     113    }
     114
     115    function a_update_options() {
     116        // new options
     117        $wpm_new_options = stripslashes_deep($_POST['wpm_options_update']);
     118
     119        // current options
     120        $wpm_current_options = get_option($this->name);
     121
     122        // convert "on" to true and "off" to false for checkbox fields
     123        // and set defaults for fields that are left blank
     124        if (isset($wpm_new_options['show_link']) && $wpm_new_options['show_link'] == "on")
     125            $wpm_new_options['show_link'] = true;
     126        else
     127            $wpm_new_options['show_link'] = false;
     128
     129        if (isset($wpm_new_options['enable_js']))
     130            $wpm_new_options['enable_js'] = true;
     131        else
     132            $wpm_new_options['enable_js'] = false;
     133
     134        if (isset($wpm_new_options['enable_css']))
     135            $wpm_new_options['enable_css'] = true;
     136        else
     137            $wpm_new_options['enable_css'] = false;
     138
     139        if (isset($wpm_new_options['enable_html']))
     140            $wpm_new_options['enable_html'] = true;
     141        else
     142            $wpm_new_options['enable_html'] = false;
     143
     144        if (isset($wpm_new_options['auto_base']))
     145            $wpm_new_options['auto_base'] = true;
     146        else
     147            $wpm_new_options['auto_base'] = false;
     148
     149        if (isset($wpm_new_options['cache_external']))
     150            $wpm_new_options['cache_external'] = true;
     151        else
     152            $wpm_new_options['cache_external'] = false;
     153
     154        if (isset($wpm_new_options['js_in_footer']))
     155            $wpm_new_options['js_in_footer'] = true;
     156        else
     157            $wpm_new_options['js_in_footer'] = false;
     158
     159        if (isset($wpm_new_options['pretty_url']))
     160            $wpm_new_options['pretty_url'] = true;
     161        else
     162            $wpm_new_options['pretty_url'] = false;
     163
     164        if (isset($wpm_new_options['debug_nominify']))
     165            $wpm_new_options['debug_nominify'] = true;
     166        else
     167            $wpm_new_options['debug_nominify'] = false;
     168
     169        if (isset($wpm_new_options['debug_firephp']))
     170            $wpm_new_options['debug_firephp'] = true;
     171        else
     172            $wpm_new_options['debug_firephp'] = false;
     173
     174        $this->a_set_minify_config($wpm_new_options['debug_nominify'], $wpm_new_options['debug_firephp']);
     175       
     176        if ( isset($wpm_new_options['js_async']) )
     177            $wpm_new_options['js_async'] = true;
     178        else
     179            $wpm_new_options['js_async'] = false;
     180
     181        if ( isset($wpm_new_options['force_https']) )
     182            $wpm_new_options['force_https'] = true;
     183        else
     184            $wpm_new_options['force_https'] = false;
     185
     186        if (strlen(trim($wpm_new_options['js_include'])) > 0)
     187            $wpm_new_options['js_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_include'])));
     188        else
     189            $wpm_new_options['js_include'] = array();
     190
     191        if (strlen(trim($wpm_new_options['js_exclude'])) > 0)
     192            $wpm_new_options['js_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_exclude'])));
     193        else
     194            $wpm_new_options['js_exclude'] = array();
     195
     196        if (strlen(trim($wpm_new_options['css_include'])) > 0)
     197            $wpm_new_options['css_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_include'])));
     198        else
     199            $wpm_new_options['css_include'] = array();
     200
     201        if (strlen(trim($wpm_new_options['css_exclude'])) > 0)
     202            $wpm_new_options['css_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_exclude'])));
     203        else
     204            $wpm_new_options['css_exclude'] = array();
     205
     206        if ( strlen(trim($wpm_new_options['uri_exclude'])) > 0 )
     207            $wpm_new_options['uri_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['uri_exclude'])));
     208        else
     209            $wpm_new_options['uri_exclude'] = array();
     210
     211        // Update options
     212        foreach ($wpm_new_options as $key => $value) {
     213            $wpm_current_options[$key] = $value;
     214        }
     215
     216        update_option($this->name, $wpm_current_options);
     217    }
     218
     219    function a_set_advanced_options($val) {
     220        $wpm_options = get_option($this->name);
     221        $wpm_options['show_advanced'] = $val;
     222        update_option($this->name, $wpm_options);
     223    }
     224
     225    function a_ajax_handler() {
     226        check_ajax_referer($this->name);
     227        if (isset($_POST['wpm_action'])) {
     228            if (strtolower($_POST['wpm_action']) == 'show_advanced') {
     229                $this->a_set_advanced_options(true);
     230            }
     231            elseif (strtolower($_POST['wpm_action']) == 'hide_advanced') {
     232                $this->a_set_advanced_options(false);
     233            }
     234            else {
     235                echo 'Invalid wpm_action.';
     236            }
     237        }
     238        exit();
     239    }
     240
     241    function a_request_handler() {
     242        if (isset($_POST['wpm_options_update_submit'])) {
     243            check_admin_referer($this->name);
     244            $this->a_update_options();
     245            add_action('admin_notices', array($this->c, 'a_notify_updated'));
     246        }
     247        elseif (isset($_POST['wpm_options_clear_cache_submit'])) {
     248            // if user wants to regenerate nonce
     249            check_admin_referer($this->name);
     250            $this->c->a_clear_cache();
     251            add_action('admin_notices', array($this->c, 'a_notify_cache_cleared'));
     252        }
     253        elseif (isset($_POST['wpm_options_upgrade_submit'])) {
     254            // if user wants to upgrade options (for new options on version upgrades)
     255            check_admin_referer($this->name);
     256            $this->c->a_upgrade_options();
     257            add_action('admin_notices', array($this->c, 'a_notify_upgraded'));
     258        }
     259        elseif (isset($_POST['wpm_options_reset_submit'])) {
     260            // if user wants to reset all options
     261            check_admin_referer($this->name);
     262            $this->c->a_reset_options();
     263            add_action('admin_notices', array($this->c, 'a_notify_reset'));
     264        }
     265
     266        // only check these on plugin settings page
     267        $this->c->a_check_dir_writable($this->c->get_plugin_dir().'cache/', array($this, 'a_notify_cache_not_writable'));
     268        $this->c->a_check_orphan_options(array($this, 'a_notify_orphan_options'));
     269        if ($this->c->a_check_dir_writable($this->c->get_plugin_dir().'min/config.php', array($this, 'a_notify_config_not_writable'))) {
     270            $this->a_check_minify_config();
     271        }
     272    }
     273
     274    function a_check_minify_config() {
     275        $fname = $this->c->get_plugin_dir().'min/config.php';
     276        $fhandle = fopen($fname,'r');
     277        $content = fread($fhandle,filesize($fname));
     278
     279        $config_modified = false;
     280       
     281        preg_match('/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s', $content, $matches);
     282        $cache_path_code = $matches[1];
     283        if (!preg_match('/\$min_cachePath.*?/', $cache_path_code)) {
     284            $content = preg_replace(
     285                '/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s',
     286                "//###WPM-CACHE-PATH-BEFORE###\n".'$min_cachePath = \''.$this->c->get_plugin_dir()."cache/';\n//###WPM-CACHE-PATH-AFTER###",
     287                $content);
     288            $config_modified = true;
     289        }
     290
     291        preg_match('/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s', $content, $matches);
     292        $cache_age_code = $matches[1];
     293        if (!preg_match('/\$min_serveOptions\[\'maxAge\'].*?/', $cache_age_code)) {
     294            $content = preg_replace(
     295                '/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s',
     296                "//###WPM-CACHE-AGE-BEFORE###\n".'$min_serveOptions[\'maxAge\'] = 2592000;'."\n//###WPM-CACHE-AGE-AFTER###",
     297                $content);
     298            $config_modified = true;
     299        }
     300
     301        if ($config_modified) {
     302            $this->a_notify_modified_minify_config();
     303        }
     304       
     305        $fhandle = fopen($fname,"w");
     306        fwrite($fhandle,$content);
     307        fclose($fhandle);
     308    }
     309
     310    function a_set_minify_config($nominify = false, $firephp = false) {
     311        if ($nominify) {
     312            $nominify = 'true';
     313        } else {
     314            $nominify = 'false';
     315        }
     316        if ($firephp) {
     317            $firephp = 'true';
     318        } else {
     319            $firephp = 'false';
     320        }
     321        $fname = $this->c->get_plugin_dir().'min/config.php';
     322        $fhandle = fopen($fname,'r');
     323        $content = fread($fhandle,filesize($fname));
     324
     325        $content = preg_replace(
     326            '/\/\/###WPM-DEBUG-FLAG-BEFORE###(.*)\/\/###WPM-DEBUG-FLAG-AFTER###/s',
     327            "//###WPM-DEBUG-FLAG-BEFORE###\n".'$min_allowDebugFlag = '.$nominify.";\n//###WPM-DEBUG-FLAG-AFTER###",
     328            $content);
     329
     330        $content = preg_replace(
     331            '/\/\/###WPM-ERROR-LOGGER-BEFORE###(.*)\/\/###WPM-ERROR-LOGGER-AFTER###/s',
     332            "//###WPM-ERROR-LOGGER-BEFORE###\n".'$min_errorLogger = '.$firephp.";\n//###WPM-ERROR-LOGGER-AFTER###",
     333            $content);
     334
     335        $fhandle = fopen($fname,"w");
     336        fwrite($fhandle,$content);
     337        fclose($fhandle);
     338    }
     339
     340    function a_notify_cache_not_writable() {
     341        $this->c->a_notify(
     342            sprintf('%s: %s',
     343                __('Cache directory is not writable. Please grant your server write permissions to the directory', $this->name),
     344                $this->c->get_plugin_dir().'cache/'),
     345            true);
     346    }
     347
     348    function a_notify_config_not_writable() {
     349        $this->c->a_notify(
     350            sprintf('%s: %s',
     351                __('Minify Engine config.php is not writable. Please grant your server write permissions to file', $this->name),
     352                $this->c->get_plugin_dir().'min/config.php'));
     353    }
     354
     355    function a_notify_orphan_options() {
     356        $this->c->a_notify(
     357            sprintf('%s',
     358                __('Some option settings are missing (possibly from plugin upgrade).', $this->name)));
     359    }
     360
     361    function a_notify_modified_minify_config() {
     362        $this->c->a_notify(__('Minify Engine config.php was configured automatically.', $this->name));
     363    }
     364
     365    function a_menu() {
     366        $options_page = add_options_page($this->name_proper, $this->name_proper, 'manage_options', 'wp-minify-fix', array($this, 'a_page'));
     367        add_action('admin_head-'.$options_page, array($this, 'a_request_handler'));
     368        add_action('admin_print_scripts-'.$options_page, array($this->c, 'a_enqueue_scripts'));
     369        add_action('admin_print_styles-'.$options_page, array($this->c, 'a_enqueue_styles'));
     370    }
     371
     372    function a_page() {
     373        $wpm_options = get_option($this->name);
     374        printf('
     375            <div class="wrap omni_admin_content">
     376                <h2>%s</h2>
     377                <div>
     378                    <a href="'.preg_replace('/&wpm-page=[^&]*/', '', $_SERVER['REQUEST_URI']).'">%s</a>&nbsp;|&nbsp;
     379                    <a href="'.$this->homepage.'">%s</a>
     380                </div>',
     381            __('WP Minify Options', $this->name),
     382            __('General Configuration', $this->name),
     383            __('Documentation', $this->name)
     384        );
     385        printf('<div class="omni_admin_main">');
     386        if (isset($_GET['wpm-page'])) {
     387            if ($_GET['wpm-page'] || !$_GET['wpm-page']) {
     388                require_once('options-generic.php');
     389            }
     390        }
     391        else {
     392            require_once('options-generic.php');
     393        }
     394        printf('</div>'); // omni_admin_main
     395        require_once('options-sidebar.php');
     396        printf('</div>'); // wrap
     397
     398    } // admin_page()
     399
     400    // other functions
     401
     402    function fetch_and_cache($url, $cache_file) {
     403        $ch = curl_init();
     404        $timeout = 5; // set to zero for no timeout
     405        curl_setopt ($ch, CURLOPT_URL, $url);
     406        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
     407        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
     408        curl_setopt ($ch, CURLOPT_USERAGENT, 'WP-Minify Fix');
     409        $content = curl_exec($ch);
     410        curl_close($ch);
     411        if ($content) {
     412            if (is_array($content)) {
     413                $content = implode($content);
     414            }
     415
     416            // save cache file
     417            $fh = fopen($cache_file, 'w');
     418            if ($fh) {
     419                fwrite($fh, $content);
     420                fclose($fh);
     421            }
     422            else {
     423                // cannot open for write.    no error b/c something else is probably writing to the file.
     424            }
     425
     426            return $content;
     427        }
     428        else {
     429            printf(
     430                '%s: '.$url.'. %s<br/>',
     431                __('Error: Could not fetch and cache URL'),
     432                __('You might need to exclude this file in WP Minify options.')
     433            );
     434            return '';
     435        }
     436    }
     437
     438    function refetch_cache_if_expired($url, $cache_file) {
     439        $wpm_options = get_option($this->name);
     440        $cache_file_mtime = filemtime($cache_file);
     441        if ((time() - $cache_file_mtime) > $wpm_options['cache_interval']) {
     442            $this->fetch_and_cache($url, $cache_file);
     443        }
     444    }
     445
     446    function tiny_filename($str) {
     447        $f = __FILE__;
     448        // no fancy shortening for Windows
     449        return ('/' === $f[0]) ? strtr(base64_encode(md5($str, true)), '+/=', '-_(') : md5($str);
     450    }
     451
     452    function array_trim($arr, $charlist=null) {
     453        foreach ($arr as $key => $value) {
     454            if (is_array($value)) $result[$key] = array_trim($value, $charlist);
     455            else $result[$key] = trim($value, $charlist);
     456        }
     457        return $result;
     458    }
     459
     460    function check_and_split_url($url, $latest_modified = 0) {
     461        $url_chunk = explode('?f=', $url);
     462        $base_url = array_shift($url_chunk);
     463        $files = explode(',', array_shift($url_chunk));
     464        $num_files = sizeof($files);
     465
     466        if ($this->url_needs_splitting($url, $files)) {
     467            $first_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, 0, $num_files/2)), $latest_modified);
     468            $second_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, $num_files/2)), $latest_modified);
     469            return $first_half + $second_half;
     470        }
     471        else {
     472            $wpm_options = get_option($this->name);
     473
     474            // append &debug if we need to
     475            if ($wpm_options['debug_nominify']) {
     476                $debug_string = '&amp;debug=true';
     477            } else {
     478                $debug_string = '';
     479            }
     480
     481            // append base directory if needed
     482            $base = $this->get_base();
     483            if ($base != '') {
     484                $base_string = '&amp;b='.$base;
     485            } else {
     486                $base_string = '';
     487            }
     488
     489            // get rid of any base directory specification in extra options
     490            $extra_minify_options = preg_replace('/(&|&amp;|\b)b=[^&]*/', '', trim($wpm_options['extra_minify_options']));
     491            if (trim($extra_minify_options) != '') {
     492                $extra_string = '&amp;'.$extra_minify_options;
     493            } else {
     494                $extra_string = '';
     495            }
     496
     497            // append last modified time
     498            $latest_modified_string = '&amp;m='.$latest_modified;
     499
     500            return array($base_url . '?f=' . implode(',', $files) . $debug_string . $base_string . $extra_string . $latest_modified_string);
     501        }
     502    }
     503
     504    function fetch_content($url, $type = '') {
     505        $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
     506        $content = '';
     507        if (file_exists($cache_file)) {
     508            // check cache expiration
     509            $this->refetch_cache_if_expired($url, $cache_file);
     510
     511            $fh = fopen($cache_file, 'r');
     512            if ($fh && filesize($cache_file) > 0) {
     513                $content = fread($fh, filesize($cache_file));
     514                fclose($fh);
     515            }
     516            else {
     517                // cannot open cache file so fetch it
     518                $content = $this->fetch_and_cache($url, $cache_file);
     519            }
     520        }
     521        else {
     522            // no cache file.    fetch from internet and save to local cache
     523            $content = $this->fetch_and_cache($url, $cache_file);
     524        }
     525        return $content;
     526    }
     527
     528    function local_version($url) {
     529        $site_url = trailingslashit(get_option('siteurl'));
     530        $url = str_replace($site_url, '', $url); // relative paths only for local urls
     531        //$url = preg_replace('/^\//', '', $url); // strip front / if any
     532        $url = preg_replace('/\?.*/i', '', $url); // throws away parameters, if any
     533        return $url;
     534    }
     535
     536    function is_external($url, $localize=true) {
     537        if ($localize) {
     538            $url = $this->local_version($url);
     539        }
     540
     541        if (substr($url, 0, 4) != 'http' && substr($url, 0, 2) != '//'
     542            && (substr($url, -3, 3) == '.js' || substr($url, -4, 4) == '.css')) {
     543            return false;
     544        } else {
     545            return true;
     546        }
     547    }
     548
     549    function get_js_location($src) {
     550        if ($this->debug)
     551            echo 'Script URL:'.$src."<br/>\n";
     552
     553        $script_path = $this->local_version($src);
     554        if ($this->is_external($script_path, false)) {
     555            // fetch scripts if necessary
     556            $this->fetch_content($src, '.js');
     557            $location = $this->cache_location . md5($src) . '.js';
     558            if ($this->debug)
     559                echo 'External script detected, cached as:'. md5($src) . "<br/>\n";
     560        } else {
     561            // if script is local to server
     562            $location = $script_path;
     563            if ($this->debug)
     564                echo 'Local script detected:'.$script_path."<br/>\n";
     565        }
     566
     567        return $location;
     568    }
     569
     570    function get_css_location($src) {
     571        if ($this->debug)
     572            echo 'Style URL:'.$src."<br/>\n";
     573
     574        $css_path = $this->local_version($src);
     575        if ($this->is_external($css_path, false)) {
     576            // fetch scripts if necessary
     577            $this->fetch_content($src, '.css');
     578            $location = $this->cache_location . md5($src) . '.css';
     579            if ($this->debug)
     580                echo 'External css detected, cached as:'. md5($src) . "<br/>\n";
     581        } else {
     582            $location = $css_path;
     583            // if css is local to server
     584            if ($this->debug)
     585                echo 'Local css detected:'.$css_path."<br/>\n";
     586        }
     587
     588        return $location;
     589    }
     590
     591    function url_needs_splitting($url, $locations) {
     592        if ($url > $this->url_len_limit || count($locations) > $this->minify_limit) {
     593            return true;
     594        } else {
     595            return false;
     596        }
     597    }
     598
     599    function build_minify_urls($locations, $type) {
     600        $wpm_options = get_option($this->name);
     601        $minify_url = $this->c->get_plugin_url().'min/?f=';
     602        if ($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on") {
     603            $minify_url = preg_replace('/^http:\/\//', 'https://', $minify_url);
     604        }
     605        $minify_url .= implode(',', $locations);
     606        $latest_modified = $this->get_latest_modified_time($locations);
     607        $minify_urls = $this->check_and_split_url($minify_url, $latest_modified);
     608
     609        if ($wpm_options['pretty_url']) {
     610            return $this->get_cached_minify_urls($minify_urls, $type);
     611        } else {
     612            return $minify_urls;
     613        }
     614    }
     615   
     616    function get_cached_minify_urls($urls, $type) {
     617        $wpm_options = get_option($this->name);
     618        $cached_urls = array();
     619        foreach ($urls as $url) {
     620            $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
     621            if (file_exists($cache_file)) {
     622                // check cache expiration
     623                $this->refetch_cache_if_expired($url, $cache_file);
     624   
     625                $fh = fopen($cache_file, 'r');
     626                if ($fh && filesize($cache_file) > 0) {
     627                    $content = fread($fh, filesize($cache_file));
     628                    fclose($fh);
     629                } else {
     630                    // cannot open cache file so fetch it
     631                    $this->fetch_and_cache($url, $cache_file);
     632                }
     633            } else {
     634                // no cache file. fetch it
     635                $this->fetch_and_cache($url, $cache_file);
     636            }
     637            $cache_url = $this->c->get_plugin_url().'cache/'.md5($url).$type.'?m='.filemtime($cache_file);
     638            $cached_urls[] = $cache_url;
     639        }
     640        return $cached_urls;
     641    }
     642
     643    function get_base_from_minify_args() {
     644        $wpm_options = get_option($this->name);
     645        if (!empty($wpm_options['extra_minify_options'])) {
     646            if (preg_match('/\bb=([^&]*?)(&|$)/', trim($wpm_options['extra_minify_options']), $matches)) {
     647                return rtrim(trim($matches[1]), '\\/');
     648            }
     649        }
     650        return '';
     651    }
     652
     653    function get_base_from_siteurl() {
     654        $site_url = trailingslashit(get_option('siteurl'));
     655        return rtrim(preg_replace('/^https?:\/\/.*?\//', '', $site_url), '\\/');
     656    }
     657
     658    function get_base() {
     659        $base_from_min_args = $this->get_base_from_minify_args();
     660        if ($base_from_min_args != '') {
     661            return $base_from_min_args;
     662        }
     663
     664        $wpm_options = get_option($this->name);
     665        if ($wpm_options['auto_base']) {
     666            return $this->get_base_from_siteurl();
     667        } else {
     668            return '';
     669        }
     670    }
     671
     672    function get_latest_modified_time($locations = array()) {
     673        $latest_modified = 0;
     674        if (!empty($locations)) {
     675            $base_path = trailingslashit($_SERVER['DOCUMENT_ROOT']);
     676            $base_path .= trailingslashit($this->get_base());
     677
     678            foreach ($locations as $location) {
     679                $path = $base_path.$location;
     680                $mtime = filemtime($path);
     681                if ($latest_modified < $mtime) {
     682                    $latest_modified = $mtime;
     683                }
     684            }
     685        }
     686        return $latest_modified;
     687    }
     688
     689    function extract_css($content) {
     690        $wpm_options = get_option($this->name);
     691        $css_locations = array();
     692
     693        preg_match_all('/<link([^>]*?)>/i', $content, $link_tags_match);
     694
     695        foreach ($link_tags_match[0] as $link_tag) {
     696            if (strpos(strtolower($link_tag), 'stylesheet')) {
     697                // check CSS media type
     698                if (!strpos(strtolower($link_tag), 'media=')
     699                    || preg_match('/media=["\'](?:["\']|[^"\']*?(all|screen)[^"\']*?["\'])/', $link_tag)
     700                ) {
     701                    preg_match('/href=[\'"]([^\'"]+)/', $link_tag, $href_match);
     702                    if ($href_match[1]) {
     703                        // include it if it is in the include list
     704                        $include = false;
     705                        $inclusions = $wpm_options['css_include'];
     706                        foreach ($inclusions as $include_pat) {
     707                            $include_pat = trim($include_pat);
     708                            if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
     709                                $include = true;
     710                                break;
     711                            }
     712                        }
     713
     714                        if (!$include) {
     715                            // support external files?
     716                            if (!$wpm_options['cache_external'] && $this->is_external($href_match[1])) {
     717                                continue; // skip if we don't cache externals and this file is external
     718                            }
     719
     720                            // do not include anything in excluded list
     721                            $skip = false;
     722                            $exclusions = array_merge($this->default_exclude, $wpm_options['css_exclude']);
     723                            foreach ($exclusions as $exclude_pat) {
     724                                $exclude_pat = trim($exclude_pat);
     725                                if (strlen($exclude_pat) > 0 && strpos($href_match[1], $exclude_pat) !== false) {
     726                                    $skip = true;
     727                                    break;
     728                                }
     729                            }
     730                            if ($skip) continue;
     731                        }
     732
     733                        $content = str_replace($link_tag . '</link>', '', $content);
     734                        $content = str_replace($link_tag, '', $content);
     735                        $css_locations[] = $this->get_css_location($href_match[1]);
     736                    }
     737                }
     738            }
     739        }
     740
     741        $css_locations = array_unique($css_locations);
     742
     743        return array($content, $css_locations);
     744    }
     745
     746    function inject_css($content, $css_locations) {
     747        if (count($css_locations) > 0) {
     748            $wpm_options = get_option($this->name);
     749            // build minify URLS
     750            $css_tags = '';
     751            $minify_urls = $this->build_minify_urls($css_locations, '.css');
     752
     753            foreach ($minify_urls as $minify_url) {
     754                $minify_url = apply_filters('wp_minify_css_url', $minify_url); // Allow plugins to modify final minify URL
     755                $css_tags .= "<link rel='stylesheet' href='$minify_url' type='text/css' media='screen' />";
     756            }
     757
     758            $matches = preg_match('/<!-- WP-Minify CSS -->/', $content);
     759
     760            if ($matches) {
     761                $content = preg_replace('/<!-- WP-Minify CSS -->/', "$css_tags", $content, 1); // limit 1 replacement
     762            } else {
     763                // HTML5 has <header> tags so account for those in regex
     764                $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$css_tags", $content, 1); // limit 1 replacement
     765            }
     766        }
     767        return $content;
     768    }
     769
     770    function extract_conditionals($content) {
     771        preg_match_all('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', $content, $conditionals_match);
     772        $content = preg_replace('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', '###WPM-CSS-CONDITIONAL###', $content);
     773
     774        $conditionals = array();
     775        foreach ($conditionals_match[0] as $conditional) {
     776            $conditionals[] = $conditional;
     777        }
     778
     779        return array($content, $conditionals);
     780    }
     781
     782    function inject_conditionals($content, $conditionals) {
     783        while (count($conditionals) > 0 && strpos($content, '###WPM-CSS-CONDITIONAL###')) {
     784            $conditional = array_shift($conditionals);
     785            $content = preg_replace('/###WPM-CSS-CONDITIONAL###/', $conditional, $content, 1);
     786        }
     787
     788        return $content;
     789    }
     790
     791    function extract_js($content) {
     792        $wpm_options = get_option($this->name);
     793        $js_locations = array();
     794       
     795        if ($wpm_options['js_placement'] === 'header-footer') {
     796            // Header and footer
     797            $split = explode('</head>', $content); // Head tag required
     798            preg_match_all('/<script([^>]*?)><\/script>/i', $split[0], $script_tags_match); // Header scripts
     799            preg_match_all('/<script([^>]*?)><\/script>/i', $split[1], $script_tags_footer_match); // Footer scripts
     800        } else {
     801            // Only one placement
     802            preg_match_all('/<script([^>]*?)><\/script>/i', $content, $script_tags_match);
     803        }
     804
     805        foreach ($script_tags_match[0] as $script_tag) {
     806            preg_match('/src=[\'"]([^\'"]+)/', $script_tag, $src_match);
     807            if ($src_match[1]) {
     808                // include it if it is in the include list
     809                $include = false;
     810                $inclusions = $wpm_options['js_include'];
     811                foreach ($inclusions as $include_pat) {
     812                    $include_pat = trim($include_pat);
     813                    if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
     814                        $include = true;
     815                        break;
     816                    }
     817                }
     818
     819                if (!$include) {
     820                    // support external files?
     821                    if (!$wpm_options['cache_external'] && $this->is_external($src_match[1])) {
     822                        continue; // skip if we don't cache externals and this file is external
     823                    }
     824
     825                    // do not include anything in excluded list
     826                    $skip = false;
     827                    $exclusions = array_merge($this->default_exclude, $wpm_options['js_exclude']);
     828                    foreach ($exclusions as $exclude_pat) {
     829                        $exclude_pat = trim($exclude_pat);
     830                        if (strlen($exclude_pat) > 0 && strpos($src_match[1], $exclude_pat) !== false) {
     831                            $skip = true;
     832                            break;
     833                        }
     834                    }
     835                    if ($skip) continue;
     836                }
     837
     838                $content = str_replace($script_tag, '', $content);
     839                $js_locations[] = $this->get_js_location($src_match[1]);
     840            }
     841        }
     842
     843        $js_locations = array_unique($js_locations);
     844       
     845        if ($wpm_options['js_placement'] === 'header-footer') {
     846            foreach ($script_tags_footer_match[0] as $script_tag) {
     847                preg_match('/src=[\'"]([^\'"]+)/', $script_tag, $src_match);
     848                if ($src_match[1]) {
     849                    // include it if it is in the include list
     850                    $include = false;
     851                    $inclusions = $wpm_options['js_include'];
     852                    foreach ($inclusions as $include_pat) {
     853                        $include_pat = trim($include_pat);
     854                        if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
     855                            $include = true;
     856                            break;
     857                        }
     858                    }
     859   
     860                    if (!$include) {
     861                        // support external files?
     862                        if (!$wpm_options['cache_external'] && $this->is_external($src_match[1])) {
     863                            continue; // skip if we don't cache externals and this file is external
     864                        }
     865   
     866                        // do not include anything in excluded list
     867                        $skip = false;
     868                        $exclusions = array_merge($this->default_exclude, $wpm_options['js_exclude']);
     869                        foreach ($exclusions as $exclude_pat) {
     870                            $exclude_pat = trim($exclude_pat);
     871                            if (strlen($exclude_pat) > 0 && strpos($src_match[1], $exclude_pat) !== false) {
     872                                $skip = true;
     873                                break;
     874                            }
     875                        }
     876                        if ($skip) continue;
     877                    }
     878   
     879                    $content = str_replace($script_tag, '', $content);
     880                    $js_locations_footer[] = $this->get_js_location($src_match[1]);
     881                }
     882            }
     883   
     884            $js_locations_footer = array_unique($js_locations_footer);
     885        }
     886
     887        return array($content, $js_locations, $js_locations_footer);
     888    }
     889
     890    function inject_js($content, $js_locations, $js_locations_footer) {
     891        if (count($js_locations) > 0) {
     892            // build minify URLS
     893            $js_tags = '';
     894            $minify_urls = $this->build_minify_urls($js_locations, '.js');
     895            if ($js_locations_footer) {
     896                $minify_urls_footer = $this->build_minify_urls($js_locations_footer, '.js');
     897            }
     898           
     899            $placeholderRemoved = false;
     900
     901            // Primary placement
     902            foreach ($minify_urls as $minify_url) {
     903                echo $minify_url;
     904                $minify_url = apply_filters('wp_minify_js_url', $minify_url); // Allow plugins to modify final minify URL
     905                $js_tags .= "<script type=\"text/javascript\" src=\"$minify_url\"". ($wpm_options['js_async'] === true && $wpm_options['js_placement'] !== 'footer' ? ' async' : '') ."></script>";
     906            }
     907
     908            $matches = preg_match('/<!-- WP-Minify JS -->/', $content);
     909
     910            if ($matches) {
     911                $content = preg_replace('/<!-- WP-Minify JS -->/', "$js_tags", $content, 1); // limit 1 replacement
     912            } else {
     913                $wpm_options = get_option($this->name);
     914                if ($wpm_options['js_placement'] === 'footer') {
     915                    $content = preg_replace('/<!-- WP Minify Footer Placeholder -->/', "$js_tags", $content, 1); // limit 1 replacement
     916                    $placeholderRemoved = true;
     917                } else {
     918                    // HTML5 has <header> tags so account for those in regex
     919                    $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$js_tags", $content, 1); // limit 1 replacement
     920                }
     921            }
     922       
     923            // If separate footer
     924            if ($js_locations_footer) {
     925                foreach ($minify_urls_footer as $minify_url) {
     926                    $minify_url = apply_filters('wp_minify_js_url', $minify_url); // Allow plugins to modify final minify URL
     927                    $js_tags .= "<script type='text/javascript' src='$minify_url'></script>";
     928                }
     929   
     930                $matches = preg_match('/<!-- WP-Minify JS Footer -->/', $content);
     931   
     932                if ($matches) {
     933                    $content = preg_replace('/<!-- WP-Minify JS Footer -->/', "$js_tags", $content, 1); // limit 1 replacement
     934                } else {
     935                    $content = preg_replace('/<!-- WP-Minify Footer Placeholder -->/', "$js_tags", $content, 1); // limit 1 replacement
     936                    $placeholderRemoved = true;
     937                }
     938            }
     939           
     940            // If necessary, remove placeholder comment
     941            if ($placeholderRemoved === false) {
     942                $content = preg_replace('/<!-- WP-Minify Footer Placeholder -->/', "$js_tags", $content, 1); // limit 1 replacement
     943            }
     944        }
     945        return $content;
     946    }
     947
     948    function pre_content() {
     949        if ( is_feed() ) return;
     950        $wpm_options = get_option($this->name);
     951        if ($wpm_options['uri_exclude'] && count($wpm_options['uri_exclude'])) {
     952            foreach ($wpm_options['uri_exclude'] as $exclude_pat) {
     953                $exclude_pat = trim($exclude_pat);
     954                if (strlen($exclude_pat) > 0 && strpos($_SERVER['REQUEST_URI'], $exclude_pat) !== false) {
     955                    return;
     956                }
     957            }
     958        }
     959
     960        ob_start(array($this, 'modify_buffer'));
     961
     962        // variable for sanity checking
     963        $this->buffer_started = true;
     964    }
     965
     966    function modify_buffer($buffer) {
     967        $wpm_options = get_option($this->name);
     968
     969        // if we do not want to force http to https then we need to exclude https
     970        if (!($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on")) {
     971            $this->default_exclude[] = 'https://';
     972        }
     973
     974        // minify JS
     975        if ($wpm_options['enable_js']) {
     976            list($buffer, $js_locations, $js_locations_footer) = $this->extract_js($buffer);
     977            $buffer= $this->inject_js($buffer, $js_locations, $js_locations_footer);
     978        }
     979
     980        // minify CSS (make sure to exclude CSS conditionals)
     981        if ($wpm_options['enable_css']) {
     982            list($buffer, $conditionals) = $this->extract_conditionals($buffer);
     983            list($buffer, $css_locations) = $this->extract_css($buffer);
     984            $buffer = $this->inject_css($buffer, $css_locations);
     985            $buffer = $this->inject_conditionals($buffer, $conditionals);
     986        }
     987
     988        // get rid of empty lines
     989        $buffer = preg_replace('/\s*(\r?\n)(\r?\n)*/', '$1', $buffer);
     990
     991        // minify HTML
     992        if ($wpm_options['enable_html']) {
     993            if (!class_exists('Minify_HTML')) {
     994                require_once('min/lib/Minify/HTML.php');
     995            }
     996            $buffer = Minify_HTML::minify($buffer);
     997        }
     998
     999        $buffer = apply_filters('wp_minify_content', $buffer); // allow plugins to modify buffer
     1000
     1001        return $buffer;
     1002    }
     1003
     1004    function post_content() {
     1005        if ( is_feed() ) return;
     1006        // sanity checking
     1007        if ($this->buffer_started) {
     1008            ob_end_flush();
     1009        }
     1010    }
     1011   
     1012    function footer_placeholder() {
     1013            printf('<!-- WP-Minify Footer Placeholder -->');
     1014    }
     1015
     1016    function advertise() {
     1017        $wpm_options = get_option($this->name);
     1018        if ($wpm_options['show_link']) {
     1019            printf("<p align='center'><small>Page optimized by <a href='$this->homepage' title='$this->name_proper WordPress Plugin' style='text-decoration:none;'>$this->name_proper</a> <a href='$this->author_homepage' title='WordPress Plugin' style='text-decoration:none;'>WordPress Plugin</a></small></p>");
     1020        }
     1021    }
    9251022
    9261023} // class WPMinify
  • wp-minify-fix/trunk/options-generic.php

    r889074 r1081305  
    11<script type="text/javascript">
    22function confirm_reset() {
    3   var answer = confirm("<?php _e('All of options will return to default settings. Are you sure you want to reset all settings?'); ?>");
    4   if(answer)
    5     return true;
    6   else
    7     return false;
     3    var answer = confirm("<?php _e('All of options will return to default settings. Are you sure you want to reset all settings?'); ?>");
     4    if(answer)
     5        return true;
     6    else
     7        return false;
    88}
    99
    1010jQuery(document).ready(function($){
    11   $("#wpm_options_toggle_advanced").click(function(e){
    12     e.preventDefault();
    13     state = $(this).attr("state");
    14     if(state == "visible"){
    15       $(".wpm_advanced").slideUp();
    16       $("#wpm_options_reset").fadeOut();
    17       $(this).attr("state", "hidden");
    18       $(this).attr("value", "<?php echo __('Show Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
    19       $.ajax({
    20         type    : "POST",
    21         url     : "admin-ajax.php",
    22         data    : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "hide_advanced" },
    23         success : function(resp){
    24           // do nothing visually
    25         },
    26         error   : function(resp){
    27           alert("Error:" + resp);
    28         }
    29       });
    30     }
    31     else{
    32       $(".wpm_advanced").slideDown();
    33       $("#wpm_options_reset").fadeIn();
    34       $(this).attr("state", "visible");
    35       $(this).attr("value", "<?php echo __('Hide Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
    36       $.ajax({
    37         type    : "POST",
    38         url     : "admin-ajax.php",
    39         data    : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "show_advanced" },
    40         success : function(resp){
    41           // do nothing visually
    42         },
    43         error   : function(resp){
    44           alert("Error:" + resp);
    45         }
    46       });
    47     }
    48   });
    49   $('#cache_external_checkbox').click(function(e) {
    50     state = $(this).attr("state");
    51     if (state == "on") {
    52       $(".wpm_include").slideDown();
    53       $(this).attr("state", "off");
    54     } else {
    55       $(".wpm_include").slideUp();
    56       $(this).attr("state", "on");
    57     }
    58   });
     11    $("#wpm_options_toggle_advanced").click(function(e){
     12        e.preventDefault();
     13        state = $(this).attr("state");
     14        if(state == "visible"){
     15            $(".wpm_advanced").slideUp();
     16            $("#wpm_options_reset").fadeOut();
     17            $(this).attr("state", "hidden");
     18            $(this).attr("value", "<?php echo __('Show Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
     19            $.ajax({
     20                type        : "POST",
     21                url         : "admin-ajax.php",
     22                data        : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "hide_advanced" },
     23                success : function(resp){
     24                    // do nothing visually
     25                },
     26                error       : function(resp){
     27                    alert("Error:" + resp);
     28                }
     29            });
     30        }
     31        else{
     32            $(".wpm_advanced").slideDown();
     33            $("#wpm_options_reset").fadeIn();
     34            $(this).attr("state", "visible");
     35            $(this).attr("value", "<?php echo __('Hide Advanced Options', $this->name); ?>" + " " + String.fromCharCode(187));
     36            $.ajax({
     37                type        : "POST",
     38                url         : "admin-ajax.php",
     39                data        : { action : "wpm", _ajax_nonce: "<?php echo wp_create_nonce($this->name); ?>", wpm_action : "show_advanced" },
     40                success : function(resp){
     41                    // do nothing visually
     42                },
     43                error       : function(resp){
     44                    alert("Error:" + resp);
     45                }
     46            });
     47        }
     48    });
     49    $('#cache_external_checkbox').click(function(e) {
     50        state = $(this).attr("state");
     51        if (state == "on") {
     52            $(".wpm_include").slideDown();
     53            $(this).attr("state", "off");
     54        } else {
     55            $(".wpm_include").slideUp();
     56            $(this).attr("state", "on");
     57        }
     58    });
    5959});
    6060</script>
    6161<form method="post"><fieldset>
    6262<?php
    63     // take care of advanced options
    64     if ($wpm_options['show_advanced']) {
    65       $advanced_style = '';
    66       $advanced_toggle_text = __('Hide Advanced Options', $this->name);
    67       $advanced_toggle_state = 'visible';
    68     }
    69     else {
    70       $advanced_style = 'style="display:none"';
    71       $advanced_toggle_text = __('Show Advanced Options', $this->name);
    72       $advanced_toggle_state = 'hidden';
    73     }
    74    
    75     if ($wpm_options['cache_external']) {
    76       $include_style = 'style="display:none"';
    77       $include_toggle_state = 'on';
    78     } else {
    79       $include_style = '';
    80       $include_toggle_state = 'off';
    81     }
    82 
    83     printf('
    84       <h2>%s</h2>
    85       <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="on" type="radio" '.checked(true, $wpm_options['show_link'], false).'/></label></p>
    86       <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="off" type="radio" '.checked(false, $wpm_options['show_link'], false).'/></label></p>
    87       ',
    88       __('Support this plugin!', $this->name),
    89       __('Display "Page optimized by WP Minify" link in the footer', $this->name),
    90       __('Do not display "Page optimized by WP Minify" link.', $this->name)
    91     );
    92 
    93     printf('
    94       <h2>%s</h2>
    95       <p><label>%s &nbsp; <input name="wpm_options_update[enable_js]" type="checkbox" '.checked(true, $wpm_options['enable_js'], false).'/></label></p>
    96       <p><label>%s &nbsp; <input name="wpm_options_update[enable_css]" type="checkbox" '.checked(true, $wpm_options['enable_css'], false).'/></label></p>
    97       <p><label>%s &nbsp; <input name="wpm_options_update[enable_html]" type="checkbox" '.checked(true, $wpm_options['enable_html'], false).'/></label></p>
    98       ',
    99       __('General Configuration', $this->name),
    100       __('Enable JavaScript Minification', $this->name),
    101       __('Enable CSS Minification', $this->name),
    102       __('Enable HTML Minification', $this->name)
    103     );
    104    
    105     printf('
    106       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    107       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[debug_nominify]" type="checkbox" '.checked(true, $wpm_options['debug_nominify'], false).'/></label></p>
    108       <p class="wpm_advanced" '.$advanced_style.'><label><a href="http://omninoggin.com/wordpress-posts/troubleshooting-wp-minify-with-firephp/">%s</a> &nbsp; <input name="wpm_options_update[debug_firephp]" type="checkbox" '.checked(true, $wpm_options['debug_firephp'], false).'/></label></p>
    109       ',
    110       __('Debugging', $this->name),
    111       __('Combine files but do not minify', $this->name),
    112       __('Show minify errors through FirePHP', $this->name)
    113     );
    114    
    115     printf('
    116       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    117       <p><label>%s<br/><textarea name="wpm_options_update[js_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_exclude'])).'</textarea></label></p>
    118       <p><label>%s<br/><textarea name="wpm_options_update[css_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_exclude'])).'</textarea></label></p>
    119       <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><textarea name="wpm_options_update[uri_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['uri_exclude'])).'</textarea></label></p>
    120       ',
    121       __('Local Files Minification', $this->name),
    122       __('JavaScript files to exclude from minify (line delimited).', $this->name),
    123       __('CSS files to exclude from minify (line delimited).', $this->name),
    124       __('URIs on which WP-Minify-Fix parsing will be disabled (line delimited)', $this->name)
    125     );
    126 
    127     printf('
    128       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    129       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[cache_external]" id="cache_external_checkbox" state="'.$include_toggle_state.'" type="checkbox" '.checked(true, $wpm_options['cache_external'], false).'/> &nbsp; (%s)</label></p>
    130       <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[js_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_include'])).'</textarea></label></p>
    131       <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[css_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_include'])).'</textarea></label></p>
    132       ',
    133       __('Non-Local Files Minification', $this->name),
    134       __('Enable minification on external files', $this->name),
    135       __('Not recommended unless you want to exclude a bunch of external .js/.css files', $this->name),
    136       __('External JavaScript files to include into minify.', $this->name),
    137       __('Only useful if "Minification on external files" is unchecked', $this->name),
    138       __('more info', $this->name),
    139       __('External CSS files to include into minify.', $this->name),
    140       __('Only useful if "Minification on external files" is unchecked', $this->name),
    141       __('more info', $this->name)
    142     );
    143 
    144     printf('
    145       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    146       <p class="wpm_advanced" '.$advanced_style.'><label>%s<input name="wpm_options_update[cache_interval]" type="text" size="4" value="'.attribute_escape($wpm_options['cache_interval']).'"/>%s <span class="submit"><input type="submit" name="wpm_options_clear_cache_submit" value="%s"/></span></p></label>
    147       ',
    148       __('Caching', $this->name),
    149       __('Cache expires after every', $this->name),
    150       __('seconds', $this->name),
    151       __('Manually Clear Cache', $this->name)
    152     );
    153 
    154     printf('
    155       <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
    156       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[pretty_url]" type="checkbox" '.checked(true, $wpm_options['pretty_url'], false).'/> &nbsp; (%s)</label></p>
    157       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_in_footer]" type="checkbox" '.checked(true, $wpm_options['js_in_footer'], false).'/> &nbsp; (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#manual_placement">%s</a>)</label></p>
    158       ',
    159       __('Tweaking/Tuning', $this->name),
    160       __('Use "pretty" URL"', $this->name),
    161       __('i.e. use "wp-minify-fix/cache/1234abcd.js" instead of "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js"', $this->name),
    162       __('Place Minified JavaScript in footer', $this->name),
    163       __('Not recommended', $this->name),
    164       __('more info', $this->name)
    165     );
    166 
    167     printf('
    168       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[force_https]" type="checkbox" '.checked(true, $wpm_options['force_https'], false).'/></label></p>
    169       ',
    170       __('Force all JavaScript/CSS calls to be HTTPS on HTTPS pages', $this->name)
    171     );
    172 
    173     printf('
    174       <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[auto_base]" type="checkbox" '.checked(true, $wpm_options['auto_base'], false).'/></label></p>
    175       <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><input name="wpm_options_update[extra_minify_options]" type="text" size="100" value="'.attribute_escape($wpm_options['extra_minify_options']).'"/><br/><em>%s</em></label></p>
    176       ',
    177       __('Automatically set your Minify base per siteurl setting (recommended)', $this->name),
    178       __('Extra arguments to pass to minify engine. This value will get append to calls to URL "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js".', $this->name),
    179       __('e.g. You can specify this value to be b=somepath to specify the base path for all files passed into Minify.', $this->name)
    180     );
    181 
    182     if ( function_exists( 'wp_nonce_field' ) && wp_nonce_field( $this->name ) ) {
    183       printf('
    184         <p class="submit">
    185           <input type="submit" name="wpm_options_update_submit" value="%s &#187;" />
    186           <input type="submit" name="wpm_options_reset_submit" id="wpm_options_reset" value="%s &#187;" onclick="return confirm_reset()" '.$advanced_style.'/>
    187           <input type="button" id="wpm_options_toggle_advanced" state="'.$advanced_toggle_state.'" value="'.$advanced_toggle_text.' &#187;"/>
    188         </p>
    189         ',
    190         __('Update Options', $this->name),
    191         __('Reset ALL Options', $this->name)
    192       );
    193     }
     63        // take care of advanced options
     64        if ($wpm_options['show_advanced']) {
     65            $advanced_style = '';
     66            $advanced_toggle_text = __('Hide Advanced Options', $this->name);
     67            $advanced_toggle_state = 'visible';
     68        }
     69        else {
     70            $advanced_style = 'style="display:none"';
     71            $advanced_toggle_text = __('Show Advanced Options', $this->name);
     72            $advanced_toggle_state = 'hidden';
     73        }
     74       
     75        if ($wpm_options['cache_external']) {
     76            $include_style = 'style="display:none"';
     77            $include_toggle_state = 'on';
     78        } else {
     79            $include_style = '';
     80            $include_toggle_state = 'off';
     81        }
     82
     83        printf('
     84            <h2>%s</h2>
     85            <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="on" type="radio" '.checked(true, $wpm_options['show_link'], false).'/></label></p>
     86            <p><label>%s &nbsp; <input name="wpm_options_update[show_link]" value="off" type="radio" '.checked(false, $wpm_options['show_link'], false).'/></label></p>
     87            ',
     88            __('Support this plugin!', $this->name),
     89            __('Display "Page optimized by WP Minify" link in the footer', $this->name),
     90            __('Do not display "Page optimized by WP Minify" link.', $this->name)
     91        );
     92
     93        printf('
     94            <h2>%s</h2>
     95            <p><label>%s &nbsp; <input name="wpm_options_update[enable_js]" type="checkbox" '.checked(true, $wpm_options['enable_js'], false).'/></label></p>
     96            <p><label>%s &nbsp; <input name="wpm_options_update[enable_css]" type="checkbox" '.checked(true, $wpm_options['enable_css'], false).'/></label></p>
     97            <p><label>%s &nbsp; <input name="wpm_options_update[enable_html]" type="checkbox" '.checked(true, $wpm_options['enable_html'], false).'/></label></p>
     98            ',
     99            __('General Configuration', $this->name),
     100            __('Enable JavaScript Minification', $this->name),
     101            __('Enable CSS Minification', $this->name),
     102            __('Enable HTML Minification', $this->name)
     103        );
     104       
     105        printf('
     106            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     107            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[debug_nominify]" type="checkbox" '.checked(true, $wpm_options['debug_nominify'], false).'/></label></p>
     108            <p class="wpm_advanced" '.$advanced_style.'><label><a href="http://omninoggin.com/wordpress-posts/troubleshooting-wp-minify-with-firephp/">%s</a> &nbsp; <input name="wpm_options_update[debug_firephp]" type="checkbox" '.checked(true, $wpm_options['debug_firephp'], false).'/></label></p>
     109            ',
     110            __('Debugging', $this->name),
     111            __('Combine files but do not minify', $this->name),
     112            __('Show minify errors through FirePHP', $this->name)
     113        );
     114       
     115        printf('
     116            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     117            <p><label>%s<br/><textarea name="wpm_options_update[js_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_exclude'])).'</textarea></label></p>
     118            <p><label>%s<br/><textarea name="wpm_options_update[css_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_exclude'])).'</textarea></label></p>
     119            <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><textarea name="wpm_options_update[uri_exclude]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['uri_exclude'])).'</textarea></label></p>
     120            ',
     121            __('Local Files Minification', $this->name),
     122            __('JavaScript files to exclude from minify (line delimited).', $this->name),
     123            __('CSS files to exclude from minify (line delimited).', $this->name),
     124            __('URIs on which WP-Minify-Fix parsing will be disabled (line delimited)', $this->name)
     125        );
     126
     127        printf('
     128            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     129            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[cache_external]" id="cache_external_checkbox" state="'.$include_toggle_state.'" type="checkbox" '.checked(true, $wpm_options['cache_external'], false).'/> &nbsp; (%s)</label></p>
     130            <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[js_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['js_include'])).'</textarea></label></p>
     131            <p class="wpm_advanced wpm_include" '.$advanced_style.' '.$include_style.'><label>%s (%s, <a href="http://omninoggin.com/wordpress-posts/tutorial-wp-minify-options/#include_external_files">%s</a>)<br/><textarea name="wpm_options_update[css_include]" style="width:600px" rows="5">'.attribute_escape(implode(chr(10), $wpm_options['css_include'])).'</textarea></label></p>
     132            ',
     133            __('Non-Local Files Minification', $this->name),
     134            __('Enable minification on external files', $this->name),
     135            __('Not recommended unless you want to exclude a bunch of external .js/.css files', $this->name),
     136            __('External JavaScript files to include into minify.', $this->name),
     137            __('Only useful if "Minification on external files" is unchecked', $this->name),
     138            __('more info', $this->name),
     139            __('External CSS files to include into minify.', $this->name),
     140            __('Only useful if "Minification on external files" is unchecked', $this->name),
     141            __('more info', $this->name)
     142        );
     143
     144        printf('
     145            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     146            <p class="wpm_advanced" '.$advanced_style.'><label>%s<input name="wpm_options_update[cache_interval]" type="text" size="4" value="'.attribute_escape($wpm_options['cache_interval']).'"/>%s <span class="submit"><input type="submit" name="wpm_options_clear_cache_submit" value="%s"/></span></p></label>
     147            ',
     148            __('Caching', $this->name),
     149            __('Cache expires after every', $this->name),
     150            __('seconds', $this->name),
     151            __('Manually Clear Cache', $this->name)
     152        );
     153       
     154        printf('
     155            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     156            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_placement]" value="header-footer" type="radio" '.checked('header-footer', $wpm_options['js_placement'], false).'/></label></p>
     157            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_placement]" value="header" type="radio" '.checked('header', $wpm_options['js_placement'], false).'/></label></p>
     158            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_placement]" value="footer" type="radio" '.checked('footer', $wpm_options['js_placement'], false).'/></label></p>
     159            ',
     160            __('JavaScript Placement', $this->name),
     161            __('In the header, and if necessary also in the footer (recommended)', $this->name),
     162            __('Everything in the header', $this->name),
     163            __('Everything in the footer', $this->name)
     164        );
     165
     166        printf('
     167            <h2 class="wpm_advanced" '.$advanced_style.'>%s</h2>
     168            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[pretty_url]" type="checkbox" '.checked(true, $wpm_options['pretty_url'], false).'/> &nbsp; (%s)</label></p>',
     169            __('Tweaking/Tuning', $this->name),
     170            __('Use "pretty" URL"', $this->name),
     171            __('i.e. use "wp-minify-fix/cache/1234abcd.js" instead of "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js"', $this->name)
     172        );
     173       
     174        printf('
     175            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[js_async]" type="checkbox" '.checked(true, $wpm_options['js_async'], false).'/> &nbsp; (%s, <a href="http://css-tricks.com/async-attribute-scripts-bottom/" target="_blank">%s</a>)</label></p>
     176            ',
     177            __('Add the HTML5 async tag', $this->name),
     178            __('Only for the header', $this->name),
     179            __('more info', $this->name)
     180        );
     181
     182        printf('
     183            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[force_https]" type="checkbox" '.checked(true, $wpm_options['force_https'], false).'/></label></p>
     184            ',
     185            __('Force all JavaScript/CSS calls to be HTTPS on HTTPS pages', $this->name)
     186        );
     187
     188        printf('
     189            <p class="wpm_advanced" '.$advanced_style.'><label>%s &nbsp; <input name="wpm_options_update[auto_base]" type="checkbox" '.checked(true, $wpm_options['auto_base'], false).'/></label></p>
     190            <p class="wpm_advanced" '.$advanced_style.'><label>%s<br/><input name="wpm_options_update[extra_minify_options]" type="text" size="100" value="'.attribute_escape($wpm_options['extra_minify_options']).'"/><br/><em>%s</em></label></p>
     191            ',
     192            __('Automatically set your Minify base per siteurl setting (recommended)', $this->name),
     193            __('Extra arguments to pass to minify engine. This value will get append to calls to URL "wp-minify-fix/min/?f=file1.js,file2.js,...,fileN.js".', $this->name),
     194            __('e.g. You can specify this value to be b=somepath to specify the base path for all files passed into Minify.', $this->name)
     195        );
     196
     197        if ( function_exists( 'wp_nonce_field' ) && wp_nonce_field( $this->name ) ) {
     198            printf('
     199                <p class="submit">
     200                    <input type="submit" name="wpm_options_update_submit" value="%s &#187;" />
     201                    <input type="submit" name="wpm_options_reset_submit" id="wpm_options_reset" value="%s &#187;" onclick="return confirm_reset()" '.$advanced_style.'/>
     202                    <input type="button" id="wpm_options_toggle_advanced" state="'.$advanced_toggle_state.'" value="'.$advanced_toggle_text.' &#187;"/>
     203                </p>
     204                ',
     205                __('Update Options', $this->name),
     206                __('Reset ALL Options', $this->name)
     207            );
     208        }
    194209?>
    195210</fieldset></form>
  • wp-minify-fix/trunk/readme.txt

    r892852 r1081305  
    33Contributors: NodeCode, madeinthayaland
    44Requires at least: 2.7
    5 Tested up to: 3.8.1
    6 Stable Tag: 1.3.4
     5Tested up to: 4.1
     6Stable Tag: 1.4.0
    77
    88[Fixed] This plugin uses the Minify engine to combine and compress JS and CSS files
     
    1010
    1111== Description ==
    12 This plugin is a fork of [WP Minify](http://wordpress.org/plugins/wp-minify/) to fix bugs, because it has not been updated since 2012-6-4.
     12This plugin is a fork of [WP Minify](http://wordpress.org/plugins/wp-minify/) to fix bugs and add features, because it has not been updated since 2012-6-4.
    1313
    1414This plugin integrates the [Minify engine](http://code.google.com/p/minify/)
     
    1818= What has been fixed? =
    1919
    20 * Minify engine 2.1.7 updated
    21 * cache interval option fixed
    22 * move CSS-@imports to the top of the output
    23 * bottom CSS- and JavaScript output fixed
    24 * support for script-tags without `type="text/javascript"`
    25 * detection of protocol-relative URLs as external file (e.g. Google AdSense)
     20* Minify engine updated to version 2.1.7
     21* Cache interval option has been fixed
     22* Move CSS-@imports to the top of the output
     23* Bottom CSS- and JavaScript output fixed
     24* Support for script tags without `type="text/javascript"`
     25* Detection of protocol-relative URLs as external file (e.g. Google AdSense)
     26* New option for the HTML5 async attribute
     27* A separate JavaScript file in the footer is now possible
    2628
    2729= How Does it Work? =
     
    4749
    4850== Changelog ==
     51= 1.4.0 =
     52* Added option for the HTML5 async attribute
     53* Added option for a separate JavaScript file in the footer
     54* Tabs are used instead of spaces in the PHP code
     55* Bugfixes
     56* Small changes
     57
    4958= 1.3.4 =
    50 * support for script-tags without `type="text/javascript"`
    51 * detection of protocol-relative URLs as external file (e.g. Google AdSense)
     59* Support for script-tags without `type="text/javascript"`
     60* Detection of protocol-relative URLs as external file (e.g. Google AdSense)
    5261
    5362= 1.3.3 =
    54 * bottom CSS- and JavaScript output fixed
     63* Bottom CSS- and JavaScript output fixed
    5564
    5665= 1.3.2 =
    57 * move CSS-@imports to the top of the output
     66* Move CSS-@imports to the top of the output
    5867
    5968= 1.3.1 =
     
    6271= 1.3.0 =
    6372* WP Minify Fix released
    64 * cache interval fixed
     73* Cache interval fixed
    6574
    6675= 1.2.0 =
  • wp-minify-fix/trunk/wp-minify.php

    r892852 r1081305  
    44Plugin URI: http://wordpress.org/plugins/wp-minify-fixed/
    55Description: [Fixed] This plugin uses the Minify engine to combine and compress JS and CSS files to improve page load time.
    6 Version: 1.3.4
     6Version: 1.4.0
    77Author: NodeCode
    88Author URI: http://nodecode.de
     
    2020This program is distributed in the hope that it will be useful,
    2121but WITHOUT ANY WARRANTY; without even the implied warranty of
    22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    2323GNU General Public License for more details.
    2424
    2525You should have received a copy of the GNU General Public License
    26 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     26along with this program.    If not, see <http://www.gnu.org/licenses/>.
    2727*/
    2828
    2929class WPMinify {
    3030
    31   var $author_homepage = 'http://nodecode.de/';
    32   var $homepage = 'http://wordpress.org/plugins/wp-minify-fixed/';
    33   var $name = 'wp_minify';
    34   var $name_dashed = 'wp-minify-fix';
    35   var $name_proper = 'WP Minify Fix';
    36   var $required_wp_version = '2.7';
    37   var $version = '1.3.4';
    38 
    39   var $c = null;
    40   var $debug = false;
    41   var $cache_location = 'wp-content/plugins/wp-minify-fix/cache/';
    42   var $url_len_limit = 2000;
    43   var $minify_limit = 50;
    44   var $buffer_started = false;
    45   var $default_exclude = array();
    46 
    47   function WPMinify() {
    48     // initialize common functions
    49     $this->c = new WPMinifyCommon($this);
    50 
    51     // load translation
    52     $this->c->load_text_domain();
    53 
    54     // register admin scripts
    55     add_action('admin_init', array($this->c, 'a_register_scripts'));
    56     add_action('admin_init', array($this->c, 'a_register_styles'));
    57 
    58     // check wp version
    59     add_action('admin_head', array($this->c, 'a_check_version'));
    60 
    61     // load admin menu
    62     add_action('admin_menu', array($this, 'a_menu'));
    63 
    64     // register ajax handler
    65     add_action('wp_ajax_wpm', array($this, 'a_ajax_handler'));
    66 
    67     // No need to minify admin stuff
    68     if (!is_admin() && !is_feed() && !defined('XMLRPC_REQUEST')) {
    69       // Don't minify if if user passes wp-minify-off=1 in GET parameter
    70       if (!(isset($_GET['wp-minify-off']) && $_GET['wp-minify-off'])) {
    71         add_action('init', array($this, 'pre_content'), 99999);
    72         add_action('wp_footer', array($this, 'post_content'), 99999);
    73       }
    74       // advertise hook
    75       add_action('wp_footer', array($this, 'advertise'));
    76     }
    77   }
    78 
    79   // admin functions
    80 
    81   function a_default_options() {
    82     return array(
    83       'cache_external' => false,
    84       'cache_interval' => 3600,
    85       'css_exclude' => array(),
    86       'css_include' => array(),
    87       'debug_nominify' => false,
    88       'debug_firephp' => false,
    89       'enable_css' => true,
    90       'enable_js' => true,
    91       'enable_html' => true,
    92       'auto_base' => true,
    93       'extra_minify_options' => '',
    94       'js_exclude' => array(),
    95       'js_include' => array(),
    96       'js_in_footer' => false,
    97       'force_https' => false,
    98       'pretty_url' => false,
    99       'show_link' => false,
    100       'show_advanced' => false,
    101       'uri_exclude' => array(),
    102       'version' => $this->version,
    103       'deprecated' => array(
    104         'wp_path', 'debug', 'debug_noprettyurl'
    105       )
    106     );
    107   }
    108 
    109   function a_update_options() {
    110     // new options
    111     $wpm_new_options = stripslashes_deep($_POST['wpm_options_update']);
    112 
    113     // current options
    114     $wpm_current_options = get_option($this->name);
    115 
    116     // convert "on" to true and "off" to false for checkbox fields
    117     // and set defaults for fields that are left blank
    118     if (isset($wpm_new_options['show_link']) && $wpm_new_options['show_link'] == "on")
    119       $wpm_new_options['show_link'] = true;
    120     else
    121       $wpm_new_options['show_link'] = false;
    122 
    123     if (isset($wpm_new_options['enable_js']))
    124       $wpm_new_options['enable_js'] = true;
    125     else
    126       $wpm_new_options['enable_js'] = false;
    127 
    128     if (isset($wpm_new_options['enable_css']))
    129       $wpm_new_options['enable_css'] = true;
    130     else
    131       $wpm_new_options['enable_css'] = false;
    132 
    133     if (isset($wpm_new_options['enable_html']))
    134       $wpm_new_options['enable_html'] = true;
    135     else
    136       $wpm_new_options['enable_html'] = false;
    137 
    138     if (isset($wpm_new_options['auto_base']))
    139       $wpm_new_options['auto_base'] = true;
    140     else
    141       $wpm_new_options['auto_base'] = false;
    142 
    143     if (isset($wpm_new_options['cache_external']))
    144       $wpm_new_options['cache_external'] = true;
    145     else
    146       $wpm_new_options['cache_external'] = false;
    147 
    148     if (isset($wpm_new_options['js_in_footer']))
    149       $wpm_new_options['js_in_footer'] = true;
    150     else
    151       $wpm_new_options['js_in_footer'] = false;
    152 
    153     if (isset($wpm_new_options['pretty_url']))
    154       $wpm_new_options['pretty_url'] = true;
    155     else
    156       $wpm_new_options['pretty_url'] = false;
    157 
    158     if (isset($wpm_new_options['debug_nominify']))
    159       $wpm_new_options['debug_nominify'] = true;
    160     else
    161       $wpm_new_options['debug_nominify'] = false;
    162 
    163     if (isset($wpm_new_options['debug_firephp']))
    164       $wpm_new_options['debug_firephp'] = true;
    165     else
    166       $wpm_new_options['debug_firephp'] = false;
    167 
    168     $this->a_set_minify_config($wpm_new_options['debug_nominify'], $wpm_new_options['debug_firephp']);
    169 
    170     if ( isset($wpm_new_options['force_https']) )
    171       $wpm_new_options['force_https'] = true;
    172     else
    173       $wpm_new_options['force_https'] = false;
    174 
    175     if (strlen(trim($wpm_new_options['js_include'])) > 0)
    176       $wpm_new_options['js_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_include'])));
    177     else
    178       $wpm_new_options['js_include'] = array();
    179 
    180     if (strlen(trim($wpm_new_options['js_exclude'])) > 0)
    181       $wpm_new_options['js_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_exclude'])));
    182     else
    183       $wpm_new_options['js_exclude'] = array();
    184 
    185     if (strlen(trim($wpm_new_options['css_include'])) > 0)
    186       $wpm_new_options['css_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_include'])));
    187     else
    188       $wpm_new_options['css_include'] = array();
    189 
    190     if (strlen(trim($wpm_new_options['css_exclude'])) > 0)
    191       $wpm_new_options['css_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_exclude'])));
    192     else
    193       $wpm_new_options['css_exclude'] = array();
    194 
    195     if ( strlen(trim($wpm_new_options['uri_exclude'])) > 0 )
    196       $wpm_new_options['uri_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['uri_exclude'])));
    197     else
    198       $wpm_new_options['uri_exclude'] = array();
    199 
    200     // Update options
    201     foreach ($wpm_new_options as $key => $value) {
    202       $wpm_current_options[$key] = $value;
    203     }
    204 
    205     update_option($this->name, $wpm_current_options);
    206   }
    207 
    208   function a_set_advanced_options($val) {
    209     $wpm_options = get_option($this->name);
    210     $wpm_options['show_advanced'] = $val;
    211     update_option($this->name, $wpm_options);
    212   }
    213 
    214   function a_ajax_handler() {
    215     check_ajax_referer($this->name);
    216     if (isset($_POST['wpm_action'])) {
    217       if (strtolower($_POST['wpm_action']) == 'show_advanced') {
    218         $this->a_set_advanced_options(true);
    219       }
    220       elseif (strtolower($_POST['wpm_action']) == 'hide_advanced') {
    221         $this->a_set_advanced_options(false);
    222       }
    223       else {
    224         echo 'Invalid wpm_action.';
    225       }
    226     }
    227     exit();
    228   }
    229 
    230   function a_request_handler() {
    231     if (isset($_POST['wpm_options_update_submit'])) {
    232       check_admin_referer($this->name);
    233       $this->a_update_options();
    234       add_action('admin_notices', array($this->c, 'a_notify_updated'));
    235     }
    236     elseif (isset($_POST['wpm_options_clear_cache_submit'])) {
    237       // if user wants to regenerate nonce
    238       check_admin_referer($this->name);
    239       $this->c->a_clear_cache();
    240       add_action('admin_notices', array($this->c, 'a_notify_cache_cleared'));
    241     }
    242     elseif (isset($_POST['wpm_options_upgrade_submit'])) {
    243       // if user wants to upgrade options (for new options on version upgrades)
    244       check_admin_referer($this->name);
    245       $this->c->a_upgrade_options();
    246       add_action('admin_notices', array($this->c, 'a_notify_upgraded'));
    247     }
    248     elseif (isset($_POST['wpm_options_reset_submit'])) {
    249       // if user wants to reset all options
    250       check_admin_referer($this->name);
    251       $this->c->a_reset_options();
    252       add_action('admin_notices', array($this->c, 'a_notify_reset'));
    253     }
    254 
    255     // only check these on plugin settings page
    256     $this->c->a_check_dir_writable($this->c->get_plugin_dir().'cache/', array($this, 'a_notify_cache_not_writable'));
    257     $this->c->a_check_orphan_options(array($this, 'a_notify_orphan_options'));
    258     if ($this->c->a_check_dir_writable($this->c->get_plugin_dir().'min/config.php', array($this, 'a_notify_config_not_writable'))) {
    259       $this->a_check_minify_config();
    260     }
    261   }
    262 
    263   function a_check_minify_config() {
    264     $fname = $this->c->get_plugin_dir().'min/config.php';
    265     $fhandle = fopen($fname,'r');
    266     $content = fread($fhandle,filesize($fname));
    267 
    268     $config_modified = false;
    269    
    270     preg_match('/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s', $content, $matches);
    271     $cache_path_code = $matches[1];
    272     if (!preg_match('/\$min_cachePath.*?/', $cache_path_code)) {
    273       $content = preg_replace(
    274         '/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s',
    275         "//###WPM-CACHE-PATH-BEFORE###\n".'$min_cachePath = \''.$this->c->get_plugin_dir()."cache/';\n//###WPM-CACHE-PATH-AFTER###",
    276         $content);
    277       $config_modified = true;
    278     }
    279 
    280     preg_match('/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s', $content, $matches);
    281     $cache_age_code = $matches[1];
    282     if (!preg_match('/\$min_serveOptions\[\'maxAge\'].*?/', $cache_age_code)) {
    283       $content = preg_replace(
    284         '/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s',
    285         "//###WPM-CACHE-AGE-BEFORE###\n".'$min_serveOptions[\'maxAge\'] = 2592000;'."\n//###WPM-CACHE-AGE-AFTER###",
    286         $content);
    287       $config_modified = true;
    288     }
    289 
    290     if ($config_modified) {
    291       $this->a_notify_modified_minify_config();
    292     }
    293    
    294     $fhandle = fopen($fname,"w");
    295     fwrite($fhandle,$content);
    296     fclose($fhandle);
    297   }
    298 
    299   function a_set_minify_config($nominify = false, $firephp = false) {
    300     if ($nominify) {
    301       $nominify = 'true';
    302     } else {
    303       $nominify = 'false';
    304     }
    305     if ($firephp) {
    306       $firephp = 'true';
    307     } else {
    308       $firephp = 'false';
    309     }
    310     $fname = $this->c->get_plugin_dir().'min/config.php';
    311     $fhandle = fopen($fname,'r');
    312     $content = fread($fhandle,filesize($fname));
    313 
    314     $content = preg_replace(
    315       '/\/\/###WPM-DEBUG-FLAG-BEFORE###(.*)\/\/###WPM-DEBUG-FLAG-AFTER###/s',
    316       "//###WPM-DEBUG-FLAG-BEFORE###\n".'$min_allowDebugFlag = '.$nominify.";\n//###WPM-DEBUG-FLAG-AFTER###",
    317       $content);
    318 
    319     $content = preg_replace(
    320       '/\/\/###WPM-ERROR-LOGGER-BEFORE###(.*)\/\/###WPM-ERROR-LOGGER-AFTER###/s',
    321       "//###WPM-ERROR-LOGGER-BEFORE###\n".'$min_errorLogger = '.$firephp.";\n//###WPM-ERROR-LOGGER-AFTER###",
    322       $content);
    323 
    324     $fhandle = fopen($fname,"w");
    325     fwrite($fhandle,$content);
    326     fclose($fhandle);
    327   }
    328 
    329   function a_notify_cache_not_writable() {
    330     $this->c->a_notify(
    331       sprintf('%s: %s',
    332         __('Cache directory is not writable. Please grant your server write permissions to the directory', $this->name),
    333         $this->c->get_plugin_dir().'cache/'),
    334       true);
    335   }
    336 
    337   function a_notify_config_not_writable() {
    338     $this->c->a_notify(
    339       sprintf('%s: %s',
    340         __('Minify Engine config.php is not writable. Please grant your server write permissions to file', $this->name),
    341         $this->c->get_plugin_dir().'min/config.php'));
    342   }
    343 
    344   function a_notify_orphan_options() {
    345     $this->c->a_notify(
    346       sprintf('%s',
    347         __('Some option settings are missing (possibly from plugin upgrade).', $this->name)));
    348   }
    349 
    350   function a_notify_modified_minify_config() {
    351     $this->c->a_notify(__('Minify Engine config.php was configured automatically.', $this->name));
    352   }
    353 
    354   function a_menu() {
    355     $options_page = add_options_page($this->name_proper, $this->name_proper, 'manage_options', 'wp-minify-fix', array($this, 'a_page'));
    356     add_action('admin_head-'.$options_page, array($this, 'a_request_handler'));
    357     add_action('admin_print_scripts-'.$options_page, array($this->c, 'a_enqueue_scripts'));
    358     add_action('admin_print_styles-'.$options_page, array($this->c, 'a_enqueue_styles'));
    359   }
    360 
    361   function a_page() {
    362     $wpm_options = get_option($this->name);
    363     printf('
    364       <div class="wrap omni_admin_content">
    365         <h2>%s</h2>
    366         <div>
    367           <a href="'.preg_replace('/&wpm-page=[^&]*/', '', $_SERVER['REQUEST_URI']).'">%s</a>&nbsp;|&nbsp;
    368           <a href="'.$this->homepage.'">%s</a>
    369         </div>',
    370       __('WP Minify Options', $this->name),
    371       __('General Configuration', $this->name),
    372       __('Documentation', $this->name)
    373     );
    374     printf('<div class="omni_admin_main">');
    375     if (isset($_GET['wpm-page'])) {
    376       if ($_GET['wpm-page'] || !$_GET['wpm-page']) {
    377         require_once('options-generic.php');
    378       }
    379     }
    380     else {
    381       require_once('options-generic.php');
    382     }
    383     printf('</div>'); // omni_admin_main
    384     require_once('options-sidebar.php');
    385     printf('</div>'); // wrap
    386 
    387   } // admin_page()
    388 
    389   // other functions
    390 
    391   function fetch_and_cache($url, $cache_file) {
    392     $ch = curl_init();
    393     $timeout = 5; // set to zero for no timeout
    394     curl_setopt ($ch, CURLOPT_URL, $url);
    395     curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    396     curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    397     curl_setopt ($ch, CURLOPT_USERAGENT, 'WP-Minify Fix');
    398     $content = curl_exec($ch);
    399     curl_close($ch);
    400     if ($content) {
    401       if (is_array($content)) {
    402         $content = implode($content);
    403       }
    404 
    405       // save cache file
    406       $fh = fopen($cache_file, 'w');
    407       if ($fh) {
    408         fwrite($fh, $content);
    409         fclose($fh);
    410       }
    411       else {
    412         // cannot open for write.  no error b/c something else is probably writing to the file.
    413       }
    414 
    415       return $content;
    416     }
    417     else {
    418       printf(
    419         '%s: '.$url.'. %s<br/>',
    420         __('Error: Could not fetch and cache URL'),
    421         __('You might need to exclude this file in WP Minify options.')
    422       );
    423       return '';
    424     }
    425   }
    426 
    427   function refetch_cache_if_expired($url, $cache_file) {
    428     $wpm_options = get_option($this->name);
    429     $cache_file_mtime = filemtime($cache_file);
    430     if ((time() - $cache_file_mtime) > $wpm_options['cache_interval']) {
    431       $this->fetch_and_cache($url, $cache_file);
    432     }
    433   }
    434 
    435   function tiny_filename($str) {
    436     $f = __FILE__;
    437     // no fancy shortening for Windows
    438     return ('/' === $f[0]) ? strtr(base64_encode(md5($str, true)), '+/=', '-_(') : md5($str);
    439   }
    440 
    441   function array_trim($arr, $charlist=null) {
    442     foreach ($arr as $key => $value) {
    443       if (is_array($value)) $result[$key] = array_trim($value, $charlist);
    444       else $result[$key] = trim($value, $charlist);
    445     }
    446     return $result;
    447   }
    448 
    449   function check_and_split_url($url, $latest_modified = 0) {
    450     $url_chunk = explode('?f=', $url);
    451     $base_url = array_shift($url_chunk);
    452     $files = explode(',', array_shift($url_chunk));
    453     $num_files = sizeof($files);
    454 
    455     if ($this->url_needs_splitting($url, $files)) {
    456       $first_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, 0, $num_files/2)), $latest_modified);
    457       $second_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, $num_files/2)), $latest_modified);
    458       return $first_half + $second_half;
    459     }
    460     else {
    461       $wpm_options = get_option($this->name);
    462 
    463       // append &debug if we need to
    464       if ($wpm_options['debug_nominify']) {
    465         $debug_string = '&amp;debug=true';
    466       } else {
    467         $debug_string = '';
    468       }
    469 
    470       // append base directory if needed
    471       $base = $this->get_base();
    472       if ($base != '') {
    473         $base_string = '&amp;b='.$base;
    474       } else {
    475         $base_string = '';
    476       }
    477 
    478       // get rid of any base directory specification in extra options
    479       $extra_minify_options = preg_replace('/(&|&amp;|\b)b=[^&]*/', '', trim($wpm_options['extra_minify_options']));
    480       if (trim($extra_minify_options) != '') {
    481         $extra_string = '&amp;'.$extra_minify_options;
    482       } else {
    483         $extra_string = '';
    484       }
    485 
    486       // append last modified time
    487       $latest_modified_string = '&amp;m='.$latest_modified;
    488 
    489       return array($base_url . '?f=' . implode(',', $files) . $debug_string . $base_string . $extra_string . $latest_modified_string);
    490     }
    491   }
    492 
    493   function fetch_content($url, $type = '') {
    494     $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
    495     $content = '';
    496     if (file_exists($cache_file)) {
    497       // check cache expiration
    498       $this->refetch_cache_if_expired($url, $cache_file);
    499 
    500       $fh = fopen($cache_file, 'r');
    501       if ($fh && filesize($cache_file) > 0) {
    502         $content = fread($fh, filesize($cache_file));
    503         fclose($fh);
    504       }
    505       else {
    506         // cannot open cache file so fetch it
    507         $content = $this->fetch_and_cache($url, $cache_file);
    508       }
    509     }
    510     else {
    511       // no cache file.  fetch from internet and save to local cache
    512       $content = $this->fetch_and_cache($url, $cache_file);
    513     }
    514     return $content;
    515   }
    516 
    517   function local_version($url) {
    518     $site_url = trailingslashit(get_option('siteurl'));
    519     $url = str_replace($site_url, '', $url); // relative paths only for local urls
    520     //$url = preg_replace('/^\//', '', $url); // strip front / if any
    521     $url = preg_replace('/\?.*/i', '', $url); // throws away parameters, if any
    522     return $url;
    523   }
    524 
    525   function is_external($url, $localize=true) {
    526     if ($localize) {
    527       $url = $this->local_version($url);
    528     }
    529 
    530     if (substr($url, 0, 4) != 'http' && substr($url, 0, 2) != '//'
    531       && (substr($url, -3, 3) == '.js' || substr($url, -4, 4) == '.css')) {
    532       return false;
    533     } else {
    534       return true;
    535     }
    536   }
    537 
    538   function get_js_location($src) {
    539     if ($this->debug)
    540       echo 'Script URL:'.$src."<br/>\n";
    541 
    542     $script_path = $this->local_version($src);
    543     if ($this->is_external($script_path, false)) {
    544       // fetch scripts if necessary
    545       $this->fetch_content($src, '.js');
    546       $location = $this->cache_location . md5($src) . '.js';
    547       if ($this->debug)
    548         echo 'External script detected, cached as:'. md5($src) . "<br/>\n";
    549     } else {
    550       // if script is local to server
    551       $location = $script_path;
    552       if ($this->debug)
    553         echo 'Local script detected:'.$script_path."<br/>\n";
    554     }
    555 
    556     return $location;
    557   }
    558 
    559   function get_css_location($src) {
    560     if ($this->debug)
    561       echo 'Style URL:'.$src."<br/>\n";
    562 
    563     $css_path = $this->local_version($src);
    564     if ($this->is_external($css_path, false)) {
    565       // fetch scripts if necessary
    566       $this->fetch_content($src, '.css');
    567       $location = $this->cache_location . md5($src) . '.css';
    568       if ($this->debug)
    569         echo 'External css detected, cached as:'. md5($src) . "<br/>\n";
    570     } else {
    571       $location = $css_path;
    572       // if css is local to server
    573       if ($this->debug)
    574         echo 'Local css detected:'.$css_path."<br/>\n";
    575     }
    576 
    577     return $location;
    578   }
    579 
    580   function url_needs_splitting($url, $locations) {
    581     if ($url > $this->url_len_limit || count($locations) > $this->minify_limit) {
    582       return true;
    583     } else {
    584       return false;
    585     }
    586   }
    587 
    588   function build_minify_urls($locations, $type) {
    589     $wpm_options = get_option($this->name);
    590     $minify_url = $this->c->get_plugin_url().'min/?f=';
    591     if ($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on") {
    592       $minify_url = preg_replace('/^http:\/\//', 'https://', $minify_url);
    593     }
    594     $minify_url .= implode(',', $locations);
    595     $latest_modified = $this->get_latest_modified_time($locations);
    596     $minify_urls = $this->check_and_split_url($minify_url, $latest_modified);
    597 
    598     if ($wpm_options['pretty_url']) {
    599       return $this->get_cached_minify_urls($minify_urls, $type);
    600     } else {
    601       return $minify_urls;
    602     }
    603   }
    604  
    605   function get_cached_minify_urls($urls, $type) {
    606     $wpm_options = get_option($this->name);
    607     $cached_urls = array();
    608     foreach ($urls as $url) {
    609       $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
    610       if (file_exists($cache_file)) {
    611         // check cache expiration
    612         $this->refetch_cache_if_expired($url, $cache_file);
    613  
    614         $fh = fopen($cache_file, 'r');
    615         if ($fh && filesize($cache_file) > 0) {
    616           $content = fread($fh, filesize($cache_file));
    617           fclose($fh);
    618         } else {
    619           // cannot open cache file so fetch it
    620           $this->fetch_and_cache($url, $cache_file);
    621         }
    622       } else {
    623         // no cache file. fetch it
    624         $this->fetch_and_cache($url, $cache_file);
    625       }
    626       $cache_url = $this->c->get_plugin_url().'cache/'.md5($url).$type.'?m='.filemtime($cache_file);
    627       $cached_urls[] = $cache_url;
    628     }
    629     return $cached_urls;
    630   }
    631 
    632   function get_base_from_minify_args() {
    633     $wpm_options = get_option($this->name);
    634     if (!empty($wpm_options['extra_minify_options'])) {
    635       if (preg_match('/\bb=([^&]*?)(&|$)/', trim($wpm_options['extra_minify_options']), $matches)) {
    636         return rtrim(trim($matches[1]), '\\/');
    637       }
    638     }
    639     return '';
    640   }
    641 
    642   function get_base_from_siteurl() {
    643     $site_url = trailingslashit(get_option('siteurl'));
    644     return rtrim(preg_replace('/^https?:\/\/.*?\//', '', $site_url), '\\/');
    645   }
    646 
    647   function get_base() {
    648     $base_from_min_args = $this->get_base_from_minify_args();
    649     if ($base_from_min_args != '') {
    650       return $base_from_min_args;
    651     }
    652 
    653     $wpm_options = get_option($this->name);
    654     if ($wpm_options['auto_base']) {
    655       return $this->get_base_from_siteurl();
    656     } else {
    657       return '';
    658     }
    659   }
    660 
    661   function get_latest_modified_time($locations = array()) {
    662     $latest_modified = 0;
    663     if (!empty($locations)) {
    664       $base_path = trailingslashit($_SERVER['DOCUMENT_ROOT']);
    665       $base_path .= trailingslashit($this->get_base());
    666 
    667       foreach ($locations as $location) {
    668         $path = $base_path.$location;
    669         $mtime = filemtime($path);
    670         if ($latest_modified < $mtime) {
    671           $latest_modified = $mtime;
    672         }
    673       }
    674     }
    675     return $latest_modified;
    676   }
    677 
    678   function extract_css($content) {
    679     $wpm_options = get_option($this->name);
    680     $css_locations = array();
    681 
    682     preg_match_all('/<link([^>]*?)>/i', $content, $link_tags_match);
    683 
    684     foreach ($link_tags_match[0] as $link_tag) {
    685       if (strpos(strtolower($link_tag), 'stylesheet')) {
    686         // check CSS media type
    687         if (!strpos(strtolower($link_tag), 'media=')
    688           || preg_match('/media=["\'](?:["\']|[^"\']*?(all|screen)[^"\']*?["\'])/', $link_tag)
    689         ) {
    690           preg_match('/href=[\'"]([^\'"]+)/', $link_tag, $href_match);
    691           if ($href_match[1]) {
    692             // include it if it is in the include list
    693             $include = false;
    694             $inclusions = $wpm_options['css_include'];
    695             foreach ($inclusions as $include_pat) {
    696               $include_pat = trim($include_pat);
    697               if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
    698                 $include = true;
    699                 break;
    700               }
    701             }
    702 
    703             if (!$include) {
    704               // support external files?
    705               if (!$wpm_options['cache_external'] && $this->is_external($href_match[1])) {
    706                 continue; // skip if we don't cache externals and this file is external
    707               }
    708 
    709               // do not include anything in excluded list
    710               $skip = false;
    711               $exclusions = array_merge($this->default_exclude, $wpm_options['css_exclude']);
    712               foreach ($exclusions as $exclude_pat) {
    713                 $exclude_pat = trim($exclude_pat);
    714                 if (strlen($exclude_pat) > 0 && strpos($href_match[1], $exclude_pat) !== false) {
    715                   $skip = true;
    716                   break;
    717                 }
    718               }
    719               if ($skip) continue;
    720             }
    721 
    722             $content = str_replace($link_tag . '</link>', '', $content);
    723             $content = str_replace($link_tag, '', $content);
    724             $css_locations[] = $this->get_css_location($href_match[1]);
    725           }
    726         }
    727       }
    728     }
    729 
    730     $css_locations = array_unique($css_locations);
    731 
    732     return array($content, $css_locations);
    733   }
    734 
    735   function inject_css($content, $css_locations) {
    736     if (count($css_locations) > 0) {
    737       $wpm_options = get_option($this->name);
    738       // build minify URLS
    739       $css_tags = '';
    740       $minify_urls = $this->build_minify_urls($css_locations, '.css');
    741 
    742       foreach ($minify_urls as $minify_url) {
    743         $minify_url = apply_filters('wp_minify_css_url', $minify_url); // Allow plugins to modify final minify URL
    744         $css_tags .= "<link rel='stylesheet' href='$minify_url' type='text/css' media='screen' />";
    745       }
    746 
    747       $matches = preg_match('/<!-- WP-Minify CSS -->/', $content);
    748 
    749       if ($matches) {
    750         $content = preg_replace('/<!-- WP-Minify CSS -->/', "$css_tags", $content, 1); // limit 1 replacement
    751       } else {
    752         // HTML5 has <header> tags so account for those in regex
    753         $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$css_tags", $content, 1); // limit 1 replacement
    754       }
    755     }
    756     return $content;
    757   }
    758 
    759   function extract_conditionals($content) {
    760     preg_match_all('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', $content, $conditionals_match);
    761     $content = preg_replace('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', '###WPM-CSS-CONDITIONAL###', $content);
    762 
    763     $conditionals = array();
    764     foreach ($conditionals_match[0] as $conditional) {
    765       $conditionals[] = $conditional;
    766     }
    767 
    768     return array($content, $conditionals);
    769   }
    770 
    771   function inject_conditionals($content, $conditionals) {
    772     while (count($conditionals) > 0 && strpos($content, '###WPM-CSS-CONDITIONAL###')) {
    773       $conditional = array_shift($conditionals);
    774       $content = preg_replace('/###WPM-CSS-CONDITIONAL###/', $conditional, $content, 1);
    775     }
    776 
    777     return $content;
    778   }
    779 
    780   function extract_js($content) {
    781     $wpm_options = get_option($this->name);
    782     $js_locations = array();
    783 
    784     preg_match_all('/<script([^>]*?)><\/script>/i', $content, $script_tags_match);
    785 
    786     foreach ($script_tags_match[0] as $script_tag) {
    787       preg_match('/src=[\'"]([^\'"]+)/', $script_tag, $src_match);
    788       if ($src_match[1]) {
    789         // include it if it is in the include list
    790         $include = false;
    791         $inclusions = $wpm_options['js_include'];
    792         foreach ($inclusions as $include_pat) {
    793           $include_pat = trim($include_pat);
    794           if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
    795             $include = true;
    796             break;
    797           }
    798         }
    799 
    800         if (!$include) {
    801           // support external files?
    802           if (!$wpm_options['cache_external'] && $this->is_external($src_match[1])) {
    803             continue; // skip if we don't cache externals and this file is external
    804           }
    805 
    806           // do not include anything in excluded list
    807           $skip = false;
    808           $exclusions = array_merge($this->default_exclude, $wpm_options['js_exclude']);
    809           foreach ($exclusions as $exclude_pat) {
    810             $exclude_pat = trim($exclude_pat);
    811             if (strlen($exclude_pat) > 0 && strpos($src_match[1], $exclude_pat) !== false) {
    812               $skip = true;
    813               break;
    814             }
    815           }
    816           if ($skip) continue;
    817         }
    818 
    819         $content = str_replace($script_tag, '', $content);
    820         $js_locations[] = $this->get_js_location($src_match[1]);
    821       }
    822     }
    823 
    824     $js_locations = array_unique($js_locations);
    825 
    826     return array($content, $js_locations);
    827   }
    828 
    829   function inject_js($content, $js_locations) {
    830     if (count($js_locations) > 0) {
    831       // build minify URLS
    832       $js_tags = '';
    833       $minify_urls = $this->build_minify_urls($js_locations, '.js');
    834 
    835       foreach ($minify_urls as $minify_url) {
    836         $minify_url = apply_filters('wp_minify_js_url', $minify_url); // Allow plugins to modify final minify URL
    837         $js_tags .= "<script type='text/javascript' src='$minify_url'></script>";
    838       }
    839 
    840       $matches = preg_match('/<!-- WP-Minify JS -->/', $content);
    841 
    842       if ($matches) {
    843         $content = preg_replace('/<!-- WP-Minify JS -->/', "$js_tags", $content, 1); // limit 1 replacement
    844       } else {
    845         $wpm_options = get_option($this->name);
    846         if ($wpm_options['js_in_footer']) {
    847           $content = preg_replace('/<\/body>/', "$js_tags\n</body>", $content, 1); // limit 1 replacement
    848         } else {
    849           // HTML5 has <header> tags so account for those in regex
    850           $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$js_tags", $content, 1); // limit 1 replacement
    851         }
    852       }
    853     }
    854     return $content;
    855   }
    856 
    857   function pre_content() {
    858     $wpm_options = get_option($this->name);
    859     if ($wpm_options['uri_exclude'] && count($wpm_options['uri_exclude'])) {
    860       foreach ($wpm_options['uri_exclude'] as $exclude_pat) {
    861         $exclude_pat = trim($exclude_pat);
    862         if (strlen($exclude_pat) > 0 && strpos($_SERVER['REQUEST_URI'], $exclude_pat) !== false) {
    863           return;
    864         }
    865       }
    866     }
    867 
    868     ob_start(array($this, 'modify_buffer'));
    869 
    870     // variable for sanity checking
    871     $this->buffer_started = true;
    872   }
    873 
    874   function modify_buffer($buffer) {
    875     $wpm_options = get_option($this->name);
    876 
    877     // if we do not want to force http to https then we need to exclude https
    878     if (!($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on")) {
    879       $this->default_exclude[] = 'https://';
    880     }
    881 
    882     // minify JS
    883     if ($wpm_options['enable_js']) {
    884       list($buffer, $js_locations) = $this->extract_js($buffer);
    885       $buffer= $this->inject_js($buffer, $js_locations);
    886     }
    887 
    888     // minify CSS (make sure to exclude CSS conditionals)
    889     if ($wpm_options['enable_css']) {
    890       list($buffer, $conditionals) = $this->extract_conditionals($buffer);
    891       list($buffer, $css_locations) = $this->extract_css($buffer);
    892       $buffer = $this->inject_css($buffer, $css_locations);
    893       $buffer = $this->inject_conditionals($buffer, $conditionals);
    894     }
    895 
    896     // get rid of empty lines
    897     $buffer = preg_replace('/\s*(\r?\n)(\r?\n)*/', '$1', $buffer);
    898 
    899     // minify HTML
    900     if ($wpm_options['enable_html']) {
    901       if (!class_exists('Minify_HTML')) {
    902         require_once('min/lib/Minify/HTML.php');
    903       }
    904       $buffer = Minify_HTML::minify($buffer);
    905     }
    906 
    907     $buffer = apply_filters('wp_minify_content', $buffer); // allow plugins to modify buffer
    908 
    909     return $buffer;
    910   }
    911 
    912   function post_content() {
    913     // sanity checking
    914     if ($this->buffer_started) {
    915       ob_end_flush();
    916     }
    917   }
    918 
    919   function advertise() {
    920     $wpm_options = get_option($this->name);
    921     if ($wpm_options['show_link']) {
    922       printf("<p align='center'><small>Page optimized by <a href='$this->homepage' title='$this->name_proper WordPress Plugin' style='text-decoration:none;'>$this->name_proper</a> <a href='$this->author_homepage' title='WordPress Plugin' style='text-decoration:none;'>WordPress Plugin</a></small></p>");
    923     }
    924   }
     31    var $author_homepage = 'http://nodecode.de/';
     32    var $homepage = 'http://wordpress.org/plugins/wp-minify-fixed/';
     33    var $name = 'wp_minify';
     34    var $name_dashed = 'wp-minify-fix';
     35    var $name_proper = 'WP Minify Fix';
     36    var $required_wp_version = '2.7';
     37    var $version = '1.4.0';
     38
     39    var $c = null;
     40    var $debug = false;
     41    var $cache_location = 'wp-content/plugins/wp-minify-fix/cache/';
     42    var $url_len_limit = 2000;
     43    var $minify_limit = 50;
     44    var $buffer_started = false;
     45    var $default_exclude = array();
     46   
     47    var $footer_scripts_string = 'abc';
     48
     49    function WPMinify() {
     50        // initialize common functions
     51        $this->c = new WPMinifyCommon($this);
     52
     53        // load translation
     54        $this->c->load_text_domain();
     55
     56        // register admin scripts
     57        add_action('admin_init', array($this->c, 'a_register_scripts'));
     58        add_action('admin_init', array($this->c, 'a_register_styles'));
     59
     60        // check wp version
     61        add_action('admin_head', array($this->c, 'a_check_version'));
     62
     63        // load admin menu
     64        add_action('admin_menu', array($this, 'a_menu'));
     65
     66        // register ajax handler
     67        add_action('wp_ajax_wpm', array($this, 'a_ajax_handler'));
     68
     69        // No need to minify admin stuff
     70        if (!is_admin() && !defined('XMLRPC_REQUEST')) {
     71            // Don't minify if if user passes wp-minify-off=1 in GET parameter
     72            if (!(isset($_GET['wp-minify-off']) && $_GET['wp-minify-off'])) {
     73                // footer scripts hook
     74                add_action('wp_footer', array($this, 'footer_placeholder'), 1);
     75               
     76                add_action('init', array($this, 'pre_content'), 99999);
     77                add_action('wp_footer', array($this, 'post_content'), 99999);
     78            }
     79            // advertise hook
     80            add_action('wp_footer', array($this, 'advertise'));
     81        }
     82    }
     83
     84    // admin functions
     85
     86    function a_default_options() {
     87        return array(
     88            'cache_external' => false,
     89            'cache_interval' => 3600,
     90            'css_exclude' => array(),
     91            'css_include' => array(),
     92            'debug_nominify' => false,
     93            'debug_firephp' => false,
     94            'enable_css' => true,
     95            'enable_js' => true,
     96            'enable_html' => true,
     97            'auto_base' => true,
     98            'extra_minify_options' => '',
     99            'js_exclude' => array(),
     100            'js_include' => array(),
     101            'js_placement' => 'header-footer', // header-footer, header or footer
     102            'js_async' => false, // Header only, see http://css-tricks.com/async-attribute-scripts-bottom/
     103            'force_https' => false,
     104            'pretty_url' => false,
     105            'show_link' => false,
     106            'show_advanced' => false,
     107            'uri_exclude' => array(),
     108            'version' => $this->version,
     109            'deprecated' => array(
     110                'wp_path', 'debug', 'debug_noprettyurl', 'js_in_footer'
     111            )
     112        );
     113    }
     114
     115    function a_update_options() {
     116        // new options
     117        $wpm_new_options = stripslashes_deep($_POST['wpm_options_update']);
     118
     119        // current options
     120        $wpm_current_options = get_option($this->name);
     121
     122        // convert "on" to true and "off" to false for checkbox fields
     123        // and set defaults for fields that are left blank
     124        if (isset($wpm_new_options['show_link']) && $wpm_new_options['show_link'] == "on")
     125            $wpm_new_options['show_link'] = true;
     126        else
     127            $wpm_new_options['show_link'] = false;
     128
     129        if (isset($wpm_new_options['enable_js']))
     130            $wpm_new_options['enable_js'] = true;
     131        else
     132            $wpm_new_options['enable_js'] = false;
     133
     134        if (isset($wpm_new_options['enable_css']))
     135            $wpm_new_options['enable_css'] = true;
     136        else
     137            $wpm_new_options['enable_css'] = false;
     138
     139        if (isset($wpm_new_options['enable_html']))
     140            $wpm_new_options['enable_html'] = true;
     141        else
     142            $wpm_new_options['enable_html'] = false;
     143
     144        if (isset($wpm_new_options['auto_base']))
     145            $wpm_new_options['auto_base'] = true;
     146        else
     147            $wpm_new_options['auto_base'] = false;
     148
     149        if (isset($wpm_new_options['cache_external']))
     150            $wpm_new_options['cache_external'] = true;
     151        else
     152            $wpm_new_options['cache_external'] = false;
     153
     154        if (isset($wpm_new_options['js_in_footer']))
     155            $wpm_new_options['js_in_footer'] = true;
     156        else
     157            $wpm_new_options['js_in_footer'] = false;
     158
     159        if (isset($wpm_new_options['pretty_url']))
     160            $wpm_new_options['pretty_url'] = true;
     161        else
     162            $wpm_new_options['pretty_url'] = false;
     163
     164        if (isset($wpm_new_options['debug_nominify']))
     165            $wpm_new_options['debug_nominify'] = true;
     166        else
     167            $wpm_new_options['debug_nominify'] = false;
     168
     169        if (isset($wpm_new_options['debug_firephp']))
     170            $wpm_new_options['debug_firephp'] = true;
     171        else
     172            $wpm_new_options['debug_firephp'] = false;
     173
     174        $this->a_set_minify_config($wpm_new_options['debug_nominify'], $wpm_new_options['debug_firephp']);
     175       
     176        if ( isset($wpm_new_options['js_async']) )
     177            $wpm_new_options['js_async'] = true;
     178        else
     179            $wpm_new_options['js_async'] = false;
     180
     181        if ( isset($wpm_new_options['force_https']) )
     182            $wpm_new_options['force_https'] = true;
     183        else
     184            $wpm_new_options['force_https'] = false;
     185
     186        if (strlen(trim($wpm_new_options['js_include'])) > 0)
     187            $wpm_new_options['js_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_include'])));
     188        else
     189            $wpm_new_options['js_include'] = array();
     190
     191        if (strlen(trim($wpm_new_options['js_exclude'])) > 0)
     192            $wpm_new_options['js_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['js_exclude'])));
     193        else
     194            $wpm_new_options['js_exclude'] = array();
     195
     196        if (strlen(trim($wpm_new_options['css_include'])) > 0)
     197            $wpm_new_options['css_include'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_include'])));
     198        else
     199            $wpm_new_options['css_include'] = array();
     200
     201        if (strlen(trim($wpm_new_options['css_exclude'])) > 0)
     202            $wpm_new_options['css_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['css_exclude'])));
     203        else
     204            $wpm_new_options['css_exclude'] = array();
     205
     206        if ( strlen(trim($wpm_new_options['uri_exclude'])) > 0 )
     207            $wpm_new_options['uri_exclude'] = $this->array_trim(split(chr(10), str_replace(chr(13), '', $wpm_new_options['uri_exclude'])));
     208        else
     209            $wpm_new_options['uri_exclude'] = array();
     210
     211        // Update options
     212        foreach ($wpm_new_options as $key => $value) {
     213            $wpm_current_options[$key] = $value;
     214        }
     215
     216        update_option($this->name, $wpm_current_options);
     217    }
     218
     219    function a_set_advanced_options($val) {
     220        $wpm_options = get_option($this->name);
     221        $wpm_options['show_advanced'] = $val;
     222        update_option($this->name, $wpm_options);
     223    }
     224
     225    function a_ajax_handler() {
     226        check_ajax_referer($this->name);
     227        if (isset($_POST['wpm_action'])) {
     228            if (strtolower($_POST['wpm_action']) == 'show_advanced') {
     229                $this->a_set_advanced_options(true);
     230            }
     231            elseif (strtolower($_POST['wpm_action']) == 'hide_advanced') {
     232                $this->a_set_advanced_options(false);
     233            }
     234            else {
     235                echo 'Invalid wpm_action.';
     236            }
     237        }
     238        exit();
     239    }
     240
     241    function a_request_handler() {
     242        if (isset($_POST['wpm_options_update_submit'])) {
     243            check_admin_referer($this->name);
     244            $this->a_update_options();
     245            add_action('admin_notices', array($this->c, 'a_notify_updated'));
     246        }
     247        elseif (isset($_POST['wpm_options_clear_cache_submit'])) {
     248            // if user wants to regenerate nonce
     249            check_admin_referer($this->name);
     250            $this->c->a_clear_cache();
     251            add_action('admin_notices', array($this->c, 'a_notify_cache_cleared'));
     252        }
     253        elseif (isset($_POST['wpm_options_upgrade_submit'])) {
     254            // if user wants to upgrade options (for new options on version upgrades)
     255            check_admin_referer($this->name);
     256            $this->c->a_upgrade_options();
     257            add_action('admin_notices', array($this->c, 'a_notify_upgraded'));
     258        }
     259        elseif (isset($_POST['wpm_options_reset_submit'])) {
     260            // if user wants to reset all options
     261            check_admin_referer($this->name);
     262            $this->c->a_reset_options();
     263            add_action('admin_notices', array($this->c, 'a_notify_reset'));
     264        }
     265
     266        // only check these on plugin settings page
     267        $this->c->a_check_dir_writable($this->c->get_plugin_dir().'cache/', array($this, 'a_notify_cache_not_writable'));
     268        $this->c->a_check_orphan_options(array($this, 'a_notify_orphan_options'));
     269        if ($this->c->a_check_dir_writable($this->c->get_plugin_dir().'min/config.php', array($this, 'a_notify_config_not_writable'))) {
     270            $this->a_check_minify_config();
     271        }
     272    }
     273
     274    function a_check_minify_config() {
     275        $fname = $this->c->get_plugin_dir().'min/config.php';
     276        $fhandle = fopen($fname,'r');
     277        $content = fread($fhandle,filesize($fname));
     278
     279        $config_modified = false;
     280       
     281        preg_match('/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s', $content, $matches);
     282        $cache_path_code = $matches[1];
     283        if (!preg_match('/\$min_cachePath.*?/', $cache_path_code)) {
     284            $content = preg_replace(
     285                '/\/\/###WPM-CACHE-PATH-BEFORE###(.*)\/\/###WPM-CACHE-PATH-AFTER###/s',
     286                "//###WPM-CACHE-PATH-BEFORE###\n".'$min_cachePath = \''.$this->c->get_plugin_dir()."cache/';\n//###WPM-CACHE-PATH-AFTER###",
     287                $content);
     288            $config_modified = true;
     289        }
     290
     291        preg_match('/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s', $content, $matches);
     292        $cache_age_code = $matches[1];
     293        if (!preg_match('/\$min_serveOptions\[\'maxAge\'].*?/', $cache_age_code)) {
     294            $content = preg_replace(
     295                '/\/\/###WPM-CACHE-AGE-BEFORE###(.*)\/\/###WPM-CACHE-AGE-AFTER###/s',
     296                "//###WPM-CACHE-AGE-BEFORE###\n".'$min_serveOptions[\'maxAge\'] = 2592000;'."\n//###WPM-CACHE-AGE-AFTER###",
     297                $content);
     298            $config_modified = true;
     299        }
     300
     301        if ($config_modified) {
     302            $this->a_notify_modified_minify_config();
     303        }
     304       
     305        $fhandle = fopen($fname,"w");
     306        fwrite($fhandle,$content);
     307        fclose($fhandle);
     308    }
     309
     310    function a_set_minify_config($nominify = false, $firephp = false) {
     311        if ($nominify) {
     312            $nominify = 'true';
     313        } else {
     314            $nominify = 'false';
     315        }
     316        if ($firephp) {
     317            $firephp = 'true';
     318        } else {
     319            $firephp = 'false';
     320        }
     321        $fname = $this->c->get_plugin_dir().'min/config.php';
     322        $fhandle = fopen($fname,'r');
     323        $content = fread($fhandle,filesize($fname));
     324
     325        $content = preg_replace(
     326            '/\/\/###WPM-DEBUG-FLAG-BEFORE###(.*)\/\/###WPM-DEBUG-FLAG-AFTER###/s',
     327            "//###WPM-DEBUG-FLAG-BEFORE###\n".'$min_allowDebugFlag = '.$nominify.";\n//###WPM-DEBUG-FLAG-AFTER###",
     328            $content);
     329
     330        $content = preg_replace(
     331            '/\/\/###WPM-ERROR-LOGGER-BEFORE###(.*)\/\/###WPM-ERROR-LOGGER-AFTER###/s',
     332            "//###WPM-ERROR-LOGGER-BEFORE###\n".'$min_errorLogger = '.$firephp.";\n//###WPM-ERROR-LOGGER-AFTER###",
     333            $content);
     334
     335        $fhandle = fopen($fname,"w");
     336        fwrite($fhandle,$content);
     337        fclose($fhandle);
     338    }
     339
     340    function a_notify_cache_not_writable() {
     341        $this->c->a_notify(
     342            sprintf('%s: %s',
     343                __('Cache directory is not writable. Please grant your server write permissions to the directory', $this->name),
     344                $this->c->get_plugin_dir().'cache/'),
     345            true);
     346    }
     347
     348    function a_notify_config_not_writable() {
     349        $this->c->a_notify(
     350            sprintf('%s: %s',
     351                __('Minify Engine config.php is not writable. Please grant your server write permissions to file', $this->name),
     352                $this->c->get_plugin_dir().'min/config.php'));
     353    }
     354
     355    function a_notify_orphan_options() {
     356        $this->c->a_notify(
     357            sprintf('%s',
     358                __('Some option settings are missing (possibly from plugin upgrade).', $this->name)));
     359    }
     360
     361    function a_notify_modified_minify_config() {
     362        $this->c->a_notify(__('Minify Engine config.php was configured automatically.', $this->name));
     363    }
     364
     365    function a_menu() {
     366        $options_page = add_options_page($this->name_proper, $this->name_proper, 'manage_options', 'wp-minify-fix', array($this, 'a_page'));
     367        add_action('admin_head-'.$options_page, array($this, 'a_request_handler'));
     368        add_action('admin_print_scripts-'.$options_page, array($this->c, 'a_enqueue_scripts'));
     369        add_action('admin_print_styles-'.$options_page, array($this->c, 'a_enqueue_styles'));
     370    }
     371
     372    function a_page() {
     373        $wpm_options = get_option($this->name);
     374        printf('
     375            <div class="wrap omni_admin_content">
     376                <h2>%s</h2>
     377                <div>
     378                    <a href="'.preg_replace('/&wpm-page=[^&]*/', '', $_SERVER['REQUEST_URI']).'">%s</a>&nbsp;|&nbsp;
     379                    <a href="'.$this->homepage.'">%s</a>
     380                </div>',
     381            __('WP Minify Options', $this->name),
     382            __('General Configuration', $this->name),
     383            __('Documentation', $this->name)
     384        );
     385        printf('<div class="omni_admin_main">');
     386        if (isset($_GET['wpm-page'])) {
     387            if ($_GET['wpm-page'] || !$_GET['wpm-page']) {
     388                require_once('options-generic.php');
     389            }
     390        }
     391        else {
     392            require_once('options-generic.php');
     393        }
     394        printf('</div>'); // omni_admin_main
     395        require_once('options-sidebar.php');
     396        printf('</div>'); // wrap
     397
     398    } // admin_page()
     399
     400    // other functions
     401
     402    function fetch_and_cache($url, $cache_file) {
     403        $ch = curl_init();
     404        $timeout = 5; // set to zero for no timeout
     405        curl_setopt ($ch, CURLOPT_URL, $url);
     406        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
     407        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
     408        curl_setopt ($ch, CURLOPT_USERAGENT, 'WP-Minify Fix');
     409        $content = curl_exec($ch);
     410        curl_close($ch);
     411        if ($content) {
     412            if (is_array($content)) {
     413                $content = implode($content);
     414            }
     415
     416            // save cache file
     417            $fh = fopen($cache_file, 'w');
     418            if ($fh) {
     419                fwrite($fh, $content);
     420                fclose($fh);
     421            }
     422            else {
     423                // cannot open for write.    no error b/c something else is probably writing to the file.
     424            }
     425
     426            return $content;
     427        }
     428        else {
     429            printf(
     430                '%s: '.$url.'. %s<br/>',
     431                __('Error: Could not fetch and cache URL'),
     432                __('You might need to exclude this file in WP Minify options.')
     433            );
     434            return '';
     435        }
     436    }
     437
     438    function refetch_cache_if_expired($url, $cache_file) {
     439        $wpm_options = get_option($this->name);
     440        $cache_file_mtime = filemtime($cache_file);
     441        if ((time() - $cache_file_mtime) > $wpm_options['cache_interval']) {
     442            $this->fetch_and_cache($url, $cache_file);
     443        }
     444    }
     445
     446    function tiny_filename($str) {
     447        $f = __FILE__;
     448        // no fancy shortening for Windows
     449        return ('/' === $f[0]) ? strtr(base64_encode(md5($str, true)), '+/=', '-_(') : md5($str);
     450    }
     451
     452    function array_trim($arr, $charlist=null) {
     453        foreach ($arr as $key => $value) {
     454            if (is_array($value)) $result[$key] = array_trim($value, $charlist);
     455            else $result[$key] = trim($value, $charlist);
     456        }
     457        return $result;
     458    }
     459
     460    function check_and_split_url($url, $latest_modified = 0) {
     461        $url_chunk = explode('?f=', $url);
     462        $base_url = array_shift($url_chunk);
     463        $files = explode(',', array_shift($url_chunk));
     464        $num_files = sizeof($files);
     465
     466        if ($this->url_needs_splitting($url, $files)) {
     467            $first_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, 0, $num_files/2)), $latest_modified);
     468            $second_half = $this->check_and_split_url($base_url . '?f=' . implode(',', array_slice($files, $num_files/2)), $latest_modified);
     469            return $first_half + $second_half;
     470        }
     471        else {
     472            $wpm_options = get_option($this->name);
     473
     474            // append &debug if we need to
     475            if ($wpm_options['debug_nominify']) {
     476                $debug_string = '&amp;debug=true';
     477            } else {
     478                $debug_string = '';
     479            }
     480
     481            // append base directory if needed
     482            $base = $this->get_base();
     483            if ($base != '') {
     484                $base_string = '&amp;b='.$base;
     485            } else {
     486                $base_string = '';
     487            }
     488
     489            // get rid of any base directory specification in extra options
     490            $extra_minify_options = preg_replace('/(&|&amp;|\b)b=[^&]*/', '', trim($wpm_options['extra_minify_options']));
     491            if (trim($extra_minify_options) != '') {
     492                $extra_string = '&amp;'.$extra_minify_options;
     493            } else {
     494                $extra_string = '';
     495            }
     496
     497            // append last modified time
     498            $latest_modified_string = '&amp;m='.$latest_modified;
     499
     500            return array($base_url . '?f=' . implode(',', $files) . $debug_string . $base_string . $extra_string . $latest_modified_string);
     501        }
     502    }
     503
     504    function fetch_content($url, $type = '') {
     505        $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
     506        $content = '';
     507        if (file_exists($cache_file)) {
     508            // check cache expiration
     509            $this->refetch_cache_if_expired($url, $cache_file);
     510
     511            $fh = fopen($cache_file, 'r');
     512            if ($fh && filesize($cache_file) > 0) {
     513                $content = fread($fh, filesize($cache_file));
     514                fclose($fh);
     515            }
     516            else {
     517                // cannot open cache file so fetch it
     518                $content = $this->fetch_and_cache($url, $cache_file);
     519            }
     520        }
     521        else {
     522            // no cache file.    fetch from internet and save to local cache
     523            $content = $this->fetch_and_cache($url, $cache_file);
     524        }
     525        return $content;
     526    }
     527
     528    function local_version($url) {
     529        $site_url = trailingslashit(get_option('siteurl'));
     530        $url = str_replace($site_url, '', $url); // relative paths only for local urls
     531        //$url = preg_replace('/^\//', '', $url); // strip front / if any
     532        $url = preg_replace('/\?.*/i', '', $url); // throws away parameters, if any
     533        return $url;
     534    }
     535
     536    function is_external($url, $localize=true) {
     537        if ($localize) {
     538            $url = $this->local_version($url);
     539        }
     540
     541        if (substr($url, 0, 4) != 'http' && substr($url, 0, 2) != '//'
     542            && (substr($url, -3, 3) == '.js' || substr($url, -4, 4) == '.css')) {
     543            return false;
     544        } else {
     545            return true;
     546        }
     547    }
     548
     549    function get_js_location($src) {
     550        if ($this->debug)
     551            echo 'Script URL:'.$src."<br/>\n";
     552
     553        $script_path = $this->local_version($src);
     554        if ($this->is_external($script_path, false)) {
     555            // fetch scripts if necessary
     556            $this->fetch_content($src, '.js');
     557            $location = $this->cache_location . md5($src) . '.js';
     558            if ($this->debug)
     559                echo 'External script detected, cached as:'. md5($src) . "<br/>\n";
     560        } else {
     561            // if script is local to server
     562            $location = $script_path;
     563            if ($this->debug)
     564                echo 'Local script detected:'.$script_path."<br/>\n";
     565        }
     566
     567        return $location;
     568    }
     569
     570    function get_css_location($src) {
     571        if ($this->debug)
     572            echo 'Style URL:'.$src."<br/>\n";
     573
     574        $css_path = $this->local_version($src);
     575        if ($this->is_external($css_path, false)) {
     576            // fetch scripts if necessary
     577            $this->fetch_content($src, '.css');
     578            $location = $this->cache_location . md5($src) . '.css';
     579            if ($this->debug)
     580                echo 'External css detected, cached as:'. md5($src) . "<br/>\n";
     581        } else {
     582            $location = $css_path;
     583            // if css is local to server
     584            if ($this->debug)
     585                echo 'Local css detected:'.$css_path."<br/>\n";
     586        }
     587
     588        return $location;
     589    }
     590
     591    function url_needs_splitting($url, $locations) {
     592        if ($url > $this->url_len_limit || count($locations) > $this->minify_limit) {
     593            return true;
     594        } else {
     595            return false;
     596        }
     597    }
     598
     599    function build_minify_urls($locations, $type) {
     600        $wpm_options = get_option($this->name);
     601        $minify_url = $this->c->get_plugin_url().'min/?f=';
     602        if ($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on") {
     603            $minify_url = preg_replace('/^http:\/\//', 'https://', $minify_url);
     604        }
     605        $minify_url .= implode(',', $locations);
     606        $latest_modified = $this->get_latest_modified_time($locations);
     607        $minify_urls = $this->check_and_split_url($minify_url, $latest_modified);
     608
     609        if ($wpm_options['pretty_url']) {
     610            return $this->get_cached_minify_urls($minify_urls, $type);
     611        } else {
     612            return $minify_urls;
     613        }
     614    }
     615   
     616    function get_cached_minify_urls($urls, $type) {
     617        $wpm_options = get_option($this->name);
     618        $cached_urls = array();
     619        foreach ($urls as $url) {
     620            $cache_file = $this->c->get_plugin_dir().'cache/'.md5($url).$type;
     621            if (file_exists($cache_file)) {
     622                // check cache expiration
     623                $this->refetch_cache_if_expired($url, $cache_file);
     624   
     625                $fh = fopen($cache_file, 'r');
     626                if ($fh && filesize($cache_file) > 0) {
     627                    $content = fread($fh, filesize($cache_file));
     628                    fclose($fh);
     629                } else {
     630                    // cannot open cache file so fetch it
     631                    $this->fetch_and_cache($url, $cache_file);
     632                }
     633            } else {
     634                // no cache file. fetch it
     635                $this->fetch_and_cache($url, $cache_file);
     636            }
     637            $cache_url = $this->c->get_plugin_url().'cache/'.md5($url).$type.'?m='.filemtime($cache_file);
     638            $cached_urls[] = $cache_url;
     639        }
     640        return $cached_urls;
     641    }
     642
     643    function get_base_from_minify_args() {
     644        $wpm_options = get_option($this->name);
     645        if (!empty($wpm_options['extra_minify_options'])) {
     646            if (preg_match('/\bb=([^&]*?)(&|$)/', trim($wpm_options['extra_minify_options']), $matches)) {
     647                return rtrim(trim($matches[1]), '\\/');
     648            }
     649        }
     650        return '';
     651    }
     652
     653    function get_base_from_siteurl() {
     654        $site_url = trailingslashit(get_option('siteurl'));
     655        return rtrim(preg_replace('/^https?:\/\/.*?\//', '', $site_url), '\\/');
     656    }
     657
     658    function get_base() {
     659        $base_from_min_args = $this->get_base_from_minify_args();
     660        if ($base_from_min_args != '') {
     661            return $base_from_min_args;
     662        }
     663
     664        $wpm_options = get_option($this->name);
     665        if ($wpm_options['auto_base']) {
     666            return $this->get_base_from_siteurl();
     667        } else {
     668            return '';
     669        }
     670    }
     671
     672    function get_latest_modified_time($locations = array()) {
     673        $latest_modified = 0;
     674        if (!empty($locations)) {
     675            $base_path = trailingslashit($_SERVER['DOCUMENT_ROOT']);
     676            $base_path .= trailingslashit($this->get_base());
     677
     678            foreach ($locations as $location) {
     679                $path = $base_path.$location;
     680                $mtime = filemtime($path);
     681                if ($latest_modified < $mtime) {
     682                    $latest_modified = $mtime;
     683                }
     684            }
     685        }
     686        return $latest_modified;
     687    }
     688
     689    function extract_css($content) {
     690        $wpm_options = get_option($this->name);
     691        $css_locations = array();
     692
     693        preg_match_all('/<link([^>]*?)>/i', $content, $link_tags_match);
     694
     695        foreach ($link_tags_match[0] as $link_tag) {
     696            if (strpos(strtolower($link_tag), 'stylesheet')) {
     697                // check CSS media type
     698                if (!strpos(strtolower($link_tag), 'media=')
     699                    || preg_match('/media=["\'](?:["\']|[^"\']*?(all|screen)[^"\']*?["\'])/', $link_tag)
     700                ) {
     701                    preg_match('/href=[\'"]([^\'"]+)/', $link_tag, $href_match);
     702                    if ($href_match[1]) {
     703                        // include it if it is in the include list
     704                        $include = false;
     705                        $inclusions = $wpm_options['css_include'];
     706                        foreach ($inclusions as $include_pat) {
     707                            $include_pat = trim($include_pat);
     708                            if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
     709                                $include = true;
     710                                break;
     711                            }
     712                        }
     713
     714                        if (!$include) {
     715                            // support external files?
     716                            if (!$wpm_options['cache_external'] && $this->is_external($href_match[1])) {
     717                                continue; // skip if we don't cache externals and this file is external
     718                            }
     719
     720                            // do not include anything in excluded list
     721                            $skip = false;
     722                            $exclusions = array_merge($this->default_exclude, $wpm_options['css_exclude']);
     723                            foreach ($exclusions as $exclude_pat) {
     724                                $exclude_pat = trim($exclude_pat);
     725                                if (strlen($exclude_pat) > 0 && strpos($href_match[1], $exclude_pat) !== false) {
     726                                    $skip = true;
     727                                    break;
     728                                }
     729                            }
     730                            if ($skip) continue;
     731                        }
     732
     733                        $content = str_replace($link_tag . '</link>', '', $content);
     734                        $content = str_replace($link_tag, '', $content);
     735                        $css_locations[] = $this->get_css_location($href_match[1]);
     736                    }
     737                }
     738            }
     739        }
     740
     741        $css_locations = array_unique($css_locations);
     742
     743        return array($content, $css_locations);
     744    }
     745
     746    function inject_css($content, $css_locations) {
     747        if (count($css_locations) > 0) {
     748            $wpm_options = get_option($this->name);
     749            // build minify URLS
     750            $css_tags = '';
     751            $minify_urls = $this->build_minify_urls($css_locations, '.css');
     752
     753            foreach ($minify_urls as $minify_url) {
     754                $minify_url = apply_filters('wp_minify_css_url', $minify_url); // Allow plugins to modify final minify URL
     755                $css_tags .= "<link rel='stylesheet' href='$minify_url' type='text/css' media='screen' />";
     756            }
     757
     758            $matches = preg_match('/<!-- WP-Minify CSS -->/', $content);
     759
     760            if ($matches) {
     761                $content = preg_replace('/<!-- WP-Minify CSS -->/', "$css_tags", $content, 1); // limit 1 replacement
     762            } else {
     763                // HTML5 has <header> tags so account for those in regex
     764                $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$css_tags", $content, 1); // limit 1 replacement
     765            }
     766        }
     767        return $content;
     768    }
     769
     770    function extract_conditionals($content) {
     771        preg_match_all('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', $content, $conditionals_match);
     772        $content = preg_replace('/<!--\[if[^\]]*?\]>.*?<!\[endif\]-->/is', '###WPM-CSS-CONDITIONAL###', $content);
     773
     774        $conditionals = array();
     775        foreach ($conditionals_match[0] as $conditional) {
     776            $conditionals[] = $conditional;
     777        }
     778
     779        return array($content, $conditionals);
     780    }
     781
     782    function inject_conditionals($content, $conditionals) {
     783        while (count($conditionals) > 0 && strpos($content, '###WPM-CSS-CONDITIONAL###')) {
     784            $conditional = array_shift($conditionals);
     785            $content = preg_replace('/###WPM-CSS-CONDITIONAL###/', $conditional, $content, 1);
     786        }
     787
     788        return $content;
     789    }
     790
     791    function extract_js($content) {
     792        $wpm_options = get_option($this->name);
     793        $js_locations = array();
     794       
     795        if ($wpm_options['js_placement'] === 'header-footer') {
     796            // Header and footer
     797            $split = explode('</head>', $content); // Head tag required
     798            preg_match_all('/<script([^>]*?)><\/script>/i', $split[0], $script_tags_match); // Header scripts
     799            preg_match_all('/<script([^>]*?)><\/script>/i', $split[1], $script_tags_footer_match); // Footer scripts
     800        } else {
     801            // Only one placement
     802            preg_match_all('/<script([^>]*?)><\/script>/i', $content, $script_tags_match);
     803        }
     804
     805        foreach ($script_tags_match[0] as $script_tag) {
     806            preg_match('/src=[\'"]([^\'"]+)/', $script_tag, $src_match);
     807            if ($src_match[1]) {
     808                // include it if it is in the include list
     809                $include = false;
     810                $inclusions = $wpm_options['js_include'];
     811                foreach ($inclusions as $include_pat) {
     812                    $include_pat = trim($include_pat);
     813                    if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
     814                        $include = true;
     815                        break;
     816                    }
     817                }
     818
     819                if (!$include) {
     820                    // support external files?
     821                    if (!$wpm_options['cache_external'] && $this->is_external($src_match[1])) {
     822                        continue; // skip if we don't cache externals and this file is external
     823                    }
     824
     825                    // do not include anything in excluded list
     826                    $skip = false;
     827                    $exclusions = array_merge($this->default_exclude, $wpm_options['js_exclude']);
     828                    foreach ($exclusions as $exclude_pat) {
     829                        $exclude_pat = trim($exclude_pat);
     830                        if (strlen($exclude_pat) > 0 && strpos($src_match[1], $exclude_pat) !== false) {
     831                            $skip = true;
     832                            break;
     833                        }
     834                    }
     835                    if ($skip) continue;
     836                }
     837
     838                $content = str_replace($script_tag, '', $content);
     839                $js_locations[] = $this->get_js_location($src_match[1]);
     840            }
     841        }
     842
     843        $js_locations = array_unique($js_locations);
     844       
     845        if ($wpm_options['js_placement'] === 'header-footer') {
     846            foreach ($script_tags_footer_match[0] as $script_tag) {
     847                preg_match('/src=[\'"]([^\'"]+)/', $script_tag, $src_match);
     848                if ($src_match[1]) {
     849                    // include it if it is in the include list
     850                    $include = false;
     851                    $inclusions = $wpm_options['js_include'];
     852                    foreach ($inclusions as $include_pat) {
     853                        $include_pat = trim($include_pat);
     854                        if (strlen($include_pat) > 0 && strpos($src_match[1], $include_pat) !== false) {
     855                            $include = true;
     856                            break;
     857                        }
     858                    }
     859   
     860                    if (!$include) {
     861                        // support external files?
     862                        if (!$wpm_options['cache_external'] && $this->is_external($src_match[1])) {
     863                            continue; // skip if we don't cache externals and this file is external
     864                        }
     865   
     866                        // do not include anything in excluded list
     867                        $skip = false;
     868                        $exclusions = array_merge($this->default_exclude, $wpm_options['js_exclude']);
     869                        foreach ($exclusions as $exclude_pat) {
     870                            $exclude_pat = trim($exclude_pat);
     871                            if (strlen($exclude_pat) > 0 && strpos($src_match[1], $exclude_pat) !== false) {
     872                                $skip = true;
     873                                break;
     874                            }
     875                        }
     876                        if ($skip) continue;
     877                    }
     878   
     879                    $content = str_replace($script_tag, '', $content);
     880                    $js_locations_footer[] = $this->get_js_location($src_match[1]);
     881                }
     882            }
     883   
     884            $js_locations_footer = array_unique($js_locations_footer);
     885        }
     886
     887        return array($content, $js_locations, $js_locations_footer);
     888    }
     889
     890    function inject_js($content, $js_locations, $js_locations_footer) {
     891        if (count($js_locations) > 0) {
     892            // build minify URLS
     893            $js_tags = '';
     894            $minify_urls = $this->build_minify_urls($js_locations, '.js');
     895            if ($js_locations_footer) {
     896                $minify_urls_footer = $this->build_minify_urls($js_locations_footer, '.js');
     897            }
     898           
     899            $placeholderRemoved = false;
     900
     901            // Primary placement
     902            foreach ($minify_urls as $minify_url) {
     903                echo $minify_url;
     904                $minify_url = apply_filters('wp_minify_js_url', $minify_url); // Allow plugins to modify final minify URL
     905                $js_tags .= "<script type=\"text/javascript\" src=\"$minify_url\"". ($wpm_options['js_async'] === true && $wpm_options['js_placement'] !== 'footer' ? ' async' : '') ."></script>";
     906            }
     907
     908            $matches = preg_match('/<!-- WP-Minify JS -->/', $content);
     909
     910            if ($matches) {
     911                $content = preg_replace('/<!-- WP-Minify JS -->/', "$js_tags", $content, 1); // limit 1 replacement
     912            } else {
     913                $wpm_options = get_option($this->name);
     914                if ($wpm_options['js_placement'] === 'footer') {
     915                    $content = preg_replace('/<!-- WP Minify Footer Placeholder -->/', "$js_tags", $content, 1); // limit 1 replacement
     916                    $placeholderRemoved = true;
     917                } else {
     918                    // HTML5 has <header> tags so account for those in regex
     919                    $content = preg_replace('/<head(>|\s[^>]*?>)/', "\\0\n$js_tags", $content, 1); // limit 1 replacement
     920                }
     921            }
     922       
     923            // If separate footer
     924            if ($js_locations_footer) {
     925                foreach ($minify_urls_footer as $minify_url) {
     926                    $minify_url = apply_filters('wp_minify_js_url', $minify_url); // Allow plugins to modify final minify URL
     927                    $js_tags .= "<script type='text/javascript' src='$minify_url'></script>";
     928                }
     929   
     930                $matches = preg_match('/<!-- WP-Minify JS Footer -->/', $content);
     931   
     932                if ($matches) {
     933                    $content = preg_replace('/<!-- WP-Minify JS Footer -->/', "$js_tags", $content, 1); // limit 1 replacement
     934                } else {
     935                    $content = preg_replace('/<!-- WP-Minify Footer Placeholder -->/', "$js_tags", $content, 1); // limit 1 replacement
     936                    $placeholderRemoved = true;
     937                }
     938            }
     939           
     940            // If necessary, remove placeholder comment
     941            if ($placeholderRemoved === false) {
     942                $content = preg_replace('/<!-- WP-Minify Footer Placeholder -->/', "$js_tags", $content, 1); // limit 1 replacement
     943            }
     944        }
     945        return $content;
     946    }
     947
     948    function pre_content() {
     949        if ( is_feed() ) return;
     950        $wpm_options = get_option($this->name);
     951        if ($wpm_options['uri_exclude'] && count($wpm_options['uri_exclude'])) {
     952            foreach ($wpm_options['uri_exclude'] as $exclude_pat) {
     953                $exclude_pat = trim($exclude_pat);
     954                if (strlen($exclude_pat) > 0 && strpos($_SERVER['REQUEST_URI'], $exclude_pat) !== false) {
     955                    return;
     956                }
     957            }
     958        }
     959
     960        ob_start(array($this, 'modify_buffer'));
     961
     962        // variable for sanity checking
     963        $this->buffer_started = true;
     964    }
     965
     966    function modify_buffer($buffer) {
     967        $wpm_options = get_option($this->name);
     968
     969        // if we do not want to force http to https then we need to exclude https
     970        if (!($wpm_options['force_https'] && $_SERVER["HTTPS"] == "on")) {
     971            $this->default_exclude[] = 'https://';
     972        }
     973
     974        // minify JS
     975        if ($wpm_options['enable_js']) {
     976            list($buffer, $js_locations, $js_locations_footer) = $this->extract_js($buffer);
     977            $buffer= $this->inject_js($buffer, $js_locations, $js_locations_footer);
     978        }
     979
     980        // minify CSS (make sure to exclude CSS conditionals)
     981        if ($wpm_options['enable_css']) {
     982            list($buffer, $conditionals) = $this->extract_conditionals($buffer);
     983            list($buffer, $css_locations) = $this->extract_css($buffer);
     984            $buffer = $this->inject_css($buffer, $css_locations);
     985            $buffer = $this->inject_conditionals($buffer, $conditionals);
     986        }
     987
     988        // get rid of empty lines
     989        $buffer = preg_replace('/\s*(\r?\n)(\r?\n)*/', '$1', $buffer);
     990
     991        // minify HTML
     992        if ($wpm_options['enable_html']) {
     993            if (!class_exists('Minify_HTML')) {
     994                require_once('min/lib/Minify/HTML.php');
     995            }
     996            $buffer = Minify_HTML::minify($buffer);
     997        }
     998
     999        $buffer = apply_filters('wp_minify_content', $buffer); // allow plugins to modify buffer
     1000
     1001        return $buffer;
     1002    }
     1003
     1004    function post_content() {
     1005        if ( is_feed() ) return;
     1006        // sanity checking
     1007        if ($this->buffer_started) {
     1008            ob_end_flush();
     1009        }
     1010    }
     1011   
     1012    function footer_placeholder() {
     1013            printf('<!-- WP-Minify Footer Placeholder -->');
     1014    }
     1015
     1016    function advertise() {
     1017        $wpm_options = get_option($this->name);
     1018        if ($wpm_options['show_link']) {
     1019            printf("<p align='center'><small>Page optimized by <a href='$this->homepage' title='$this->name_proper WordPress Plugin' style='text-decoration:none;'>$this->name_proper</a> <a href='$this->author_homepage' title='WordPress Plugin' style='text-decoration:none;'>WordPress Plugin</a></small></p>");
     1020        }
     1021    }
    9251022
    9261023} // class WPMinify
Note: See TracChangeset for help on using the changeset viewer.