Asset CleanUp: Page Speed Booster - Version 1.3.2

Version Description

  • Minify/Combine JS files & HEAD CleanUp features are now available in the Lite version
Download this release

Release Info

Developer gabelivan
Plugin Icon 128x128 Asset CleanUp: Page Speed Booster
Version 1.3.2
Comparing to
See all releases

Code changes from version 1.3.1 to 1.3.2

assets/script.min.js CHANGED
@@ -1 +1 @@
1
- function wpacuTabOpenSettingsArea(a,b){a.preventDefault();var c,d,e;for(d=document.getElementsByClassName("wpacu-settings-tab-content"),c=0;c<d.length;c++)d[c].style.display="none";for(e=document.getElementsByClassName("wpacu-settings-tab-link"),c=0;c<e.length;c++)e[c].className=e[c].className.replace(" active","");document.getElementById(b).style.display="table-cell",jQuery('a[href="#'+b+'"]').addClass("active"),jQuery("#wpacu-selected-tab-area").val(b),history.pushState(null,null,"#"+b)}if(jQuery(document).ready(function(a){function b(){var b={};"direct"===wpacu_object.dom_get_type?(b[wpacu_object.plugin_name+"_load"]=1,b[wpacu_object.plugin_name+"_time_r"]=(new Date).getTime(),a.ajax({method:"GET",url:wpacu_object.page_url,data:b,cache:!1,complete:function(b,c){if("error"===b.statusText){var d=wpacu_object.ajax_direct_fetch_error;d=d.replace(/\{wpacu_output\}/,b.responseText),d=d.replace(/\{wpacu_status_code_error\}/,b.status),a("#wpacu_meta_box_content").html(d)}}}).done(function(b){var c=b.substring(b.lastIndexOf(wpacu_object.start_del)+wpacu_object.start_del.length,b.lastIndexOf(wpacu_object.end_del)),d={action:wpacu_object.plugin_name+"_get_loaded_assets",wpacu_list:c,post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,time_r:(new Date).getTime()};a.post(wpacu_object.ajax_url,d,function(b){if(!b)return!1;a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){e.load()},200)})})):"wp_remote_post"===wpacu_object.dom_get_type&&(b={action:wpacu_object.plugin_name+"_get_loaded_assets",post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,time_r:(new Date).getTime()},a.post(wpacu_object.ajax_url,b,function(b){if(!b)return!1;a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){e.load()},200)}))}a("#wpacu-mark-license-valid-button").click(function(){return confirm(wpacu_object.mark_license_valid_confirm)});var c,d;a("#wpacu-reset-drop-down").on("change keyup keydown mouseup mousedown click",function(){""===a(this).val()?(a("#wpacu-warning-read").removeClass("wpacu-visible"),a("#wpacu-reset-submit-btn").attr("disabled","disabled").removeClass("button-primary").addClass("button-secondary")):("reset_everything"===a(this).val()?a("#wpacu-license-data-remove-area").addClass("wpacu-visible"):a("#wpacu-license-data-remove-area").removeClass("wpacu-visible"),a("#wpacu-warning-read").addClass("wpacu-visible"),a("#wpacu-reset-submit-btn").removeAttr("disabled").removeClass("button-secondary").addClass("button-primary")),a(".wpacu-tools-area .wpacu-warning").hide(),c=a(this).find("option:selected"),a("#"+c.attr("data-id")).show()}),a("#wpacu-reset-submit-btn").on("click",function(){if("reset_settings"===a("#wpacu-reset-drop-down").val()?d=wpacu_object.reset_settings_confirm_msg:"reset_everything"===a("#wpacu-reset-drop-down").val()&&(d=wpacu_object.reset_everything_confirm_msg),!confirm(d))return!1;a("#wpacu-action-confirmed").val("yes"),setTimeout(function(){"yes"===a("#wpacu-action-confirmed").val()&&a("#wpacu-tools-form").submit()},1e3)});var e={load:function(){var b;a(".input-unload-on-this-page").on("click change",function(){a(this).prop("checked")?a(this).closest("tr").addClass("wpacu_not_load"):a(this).closest("tr").removeClass("wpacu_not_load")}),a(".wpacu_global_unload").click(function(){b=a(this).attr("data-handle"),a(this).prop("checked")?a(this).parent("label").addClass("wpacu_global_checked"):a(this).parent("label").removeClass("wpacu_global_checked")}),a(".wpacu_keep_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").next().removeClass("remove_rule")}),a(".wpacu_remove_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").addClass("remove_rule")}),a(".wpacu_bulk_unload").click(function(){a(this).prop("checked")?a(this).parent("label").addClass("wpacu_bulk_unload_active"):a(this).parent("label").removeClass("wpacu_bulk_unload_active")}),a(".wpacu_load_it_option").click(function(){var b=a(this).attr("data-handle");if(a(this).prop("checked")){a(this).parent("label").addClass("wpacu_global_unload_exception");var c="";a(this).hasClass("wpacu_style")?c="style":a(this).hasClass("wpacu_script")&&(c="script"),a("#"+c+"_"+b).prop("checked",!1).trigger("change")}else a(this).parent("label").removeClass("wpacu_global_unload_exception")}),a(".wpacu-external-file-size").on("click",function(b){b.preventDefault();var c,d=a(this);d.hide(),c=d.next(),c.show(),a.post(wpacu_object.ajax_url,{action:"get_external_file_size",wpacu_remote_file:d.attr("data-src")},function(a){c.html(a)})})}};a(".wpacu-dom-get-type-selection").change(function(){a(this).is(":checked")&&(a(".wpacu-dom-get-type-info").hide(),a("#"+a(this).attr("data-target")).fadeIn("fast"))}),a("#wpacu_post_type_select").change(function(){a("#wpacu_post_type_form").submit()}),a("#wpacu_taxonomy_select").change(function(){a("#wpacu_taxonomy_form").submit()}),a("#wpacu_dashboard").click(function(){a(this).prop("checked")?a("#wpacu-settings-assets-retrieval-mode").fadeIn("fast"):a("#wpacu-settings-assets-retrieval-mode").fadeOut("fast")}),a("#wpacu_disable_jquery_migrate").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.jquery_migration_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("#wpacu_disable_comment_reply").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.comment_reply_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("#wpacu_combine_loaded_css_enable").click(function(){a(this).prop("checked")?a("#combine_loaded_css_info_area").css({opacity:1}):a("#combine_loaded_css_info_area").css({opacity:.4})}),a("#wpacu_combine_loaded_js_enable").click(function(){a(this).prop("checked")?a("#combine_loaded_js_info_area").css({opacity:1}):a("#combine_loaded_js_info_area").css({opacity:.4})}),a("#wpacu_minify_css_enable").click(function(){a(this).prop("checked")?a("#wpacu_minify_css_exceptions_area").css({opacity:1}):a("#wpacu_minify_css_exceptions_area").css({opacity:.4})}),a("#wpacu_minify_js_enable").click(function(){a(this).prop("checked")?a("#wpacu_minify_js_exceptions_area").css({opacity:1}):a("#wpacu_minify_js_exceptions_area").css({opacity:.4})}),a(".wpacu-combine-loaded-js-level").change(function(){a(this).is(":checked")&&(a(".wpacu_combine_loaded_js_level_area").removeClass("wpacu_active"),a("#"+a(this).attr("data-target")).addClass("wpacu_active"))});var f=a('#wpacu-update-button-area input[type="submit"]');if(f.click(function(){a("#wpacu-updating-settings").show()}),a("form#wpacu-settings-form").submit(function(){return f.attr("disabled","disabled"),!0}),a(".wpacu_remove_rule").click(function(){var b=a(this).parents(".wpacu_global_rule_row");a(this).prop("checked")?b.addClass("selected"):b.removeClass("selected")}),a("#wpacu_wrap_assets").length>0&&setTimeout(function(){e.load()},200),"undefined"==typeof wpacu_object||a("#wpacu_meta_box_content").length<1)return!1;b(),a(document).on("click","body.branch-5 .edit-post-header__settings button.is-primary",function(){var c=function(){0===a(".edit-post-header__settings .is-saving").length&&(b(),clearInterval(d))},d=setInterval(c,900)})}),-1!==location.href.indexOf("#")){var hashFromUrl=location.href.substr(location.href.indexOf("#"));jQuery('a[href="'+hashFromUrl+'"]').trigger("click")}
1
+ function wpacuTabOpenSettingsArea(a,b){a.preventDefault();var c,d,e;for(d=document.getElementsByClassName("wpacu-settings-tab-content"),c=0;c<d.length;c++)d[c].style.display="none";for(e=document.getElementsByClassName("wpacu-settings-tab-link"),c=0;c<e.length;c++)e[c].className=e[c].className.replace(" active","");document.getElementById(b).style.display="table-cell",jQuery('a[href="#'+b+'"]').addClass("active"),jQuery("#wpacu-selected-tab-area").val(b),history.pushState(null,null,"#"+b)}if(jQuery(document).ready(function(a){function b(){if(!a("#wpacu_ajax_fetch_assets_list_dashboard_view").length)return!1;var b={};"direct"===wpacu_object.dom_get_type?(b[wpacu_object.plugin_name+"_load"]=1,b[wpacu_object.plugin_name+"_time_r"]=(new Date).getTime(),a.ajax({method:"GET",url:wpacu_object.page_url,data:b,cache:!1,complete:function(b,c){if("error"===b.statusText){var d=wpacu_object.ajax_direct_fetch_error;d=d.replace(/\{wpacu_output\}/,b.responseText),d=d.replace(/\{wpacu_status_code_error\}/,b.status),a("#wpacu_meta_box_content").html(d)}}}).done(function(b){var c=b.substring(b.lastIndexOf(wpacu_object.start_del)+wpacu_object.start_del.length,b.lastIndexOf(wpacu_object.end_del)),d={action:wpacu_object.plugin_name+"_get_loaded_assets",wpacu_list:c,post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,time_r:(new Date).getTime()};a.post(wpacu_object.ajax_url,d,function(b){if(!b)return!1;a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){e.load()},200)})})):"wp_remote_post"===wpacu_object.dom_get_type&&(b={action:wpacu_object.plugin_name+"_get_loaded_assets",post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,time_r:(new Date).getTime()},a.post(wpacu_object.ajax_url,b,function(b){if(!b)return!1;a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){e.load()},200)}))}a("#wpacu-mark-license-valid-button").click(function(){return confirm(wpacu_object.mark_license_valid_confirm)});var c,d;a("#wpacu-reset-drop-down").on("change keyup keydown mouseup mousedown click",function(){""===a(this).val()?(a("#wpacu-warning-read").removeClass("wpacu-visible"),a("#wpacu-reset-submit-btn").attr("disabled","disabled").removeClass("button-primary").addClass("button-secondary")):("reset_everything"===a(this).val()?a("#wpacu-license-data-remove-area").addClass("wpacu-visible"):a("#wpacu-license-data-remove-area").removeClass("wpacu-visible"),a("#wpacu-warning-read").addClass("wpacu-visible"),a("#wpacu-reset-submit-btn").removeAttr("disabled").removeClass("button-secondary").addClass("button-primary")),a(".wpacu-tools-area .wpacu-warning").hide(),c=a(this).find("option:selected"),a("#"+c.attr("data-id")).show()}),a("#wpacu-reset-submit-btn").on("click",function(){if("reset_settings"===a("#wpacu-reset-drop-down").val()?d=wpacu_object.reset_settings_confirm_msg:"reset_everything"===a("#wpacu-reset-drop-down").val()&&(d=wpacu_object.reset_everything_confirm_msg),!confirm(d))return!1;a("#wpacu-action-confirmed").val("yes"),setTimeout(function(){"yes"===a("#wpacu-action-confirmed").val()&&a("#wpacu-tools-form").submit()},1e3)});var e={load:function(){var b;a(".input-unload-on-this-page").on("click change",function(){a(this).prop("checked")?a(this).closest("tr").addClass("wpacu_not_load"):a(this).closest("tr").removeClass("wpacu_not_load")}),a(".wpacu_global_unload").click(function(){b=a(this).attr("data-handle"),a(this).prop("checked")?a(this).parent("label").addClass("wpacu_global_checked"):a(this).parent("label").removeClass("wpacu_global_checked")}),a(".wpacu_keep_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").next().removeClass("remove_rule")}),a(".wpacu_remove_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").addClass("remove_rule")}),a(".wpacu_bulk_unload").click(function(){a(this).prop("checked")?a(this).parent("label").addClass("wpacu_bulk_unload_active"):a(this).parent("label").removeClass("wpacu_bulk_unload_active")}),a(".wpacu_load_it_option").click(function(){var b=a(this).attr("data-handle");if(a(this).prop("checked")){a(this).parent("label").addClass("wpacu_global_unload_exception");var c="";a(this).hasClass("wpacu_style")?c="style":a(this).hasClass("wpacu_script")&&(c="script"),a("#"+c+"_"+b).prop("checked",!1).trigger("change")}else a(this).parent("label").removeClass("wpacu_global_unload_exception")}),a(".wpacu-external-file-size").on("click",function(b){b.preventDefault();var c,d=a(this);d.hide(),c=d.next(),c.show(),a.post(wpacu_object.ajax_url,{action:"get_external_file_size",wpacu_remote_file:d.attr("data-src")},function(a){c.html(a)})})}};a(".wpacu-dom-get-type-selection").change(function(){a(this).is(":checked")&&(a(".wpacu-dom-get-type-info").hide(),a("#"+a(this).attr("data-target")).fadeIn("fast"))}),a("#wpacu_post_type_select").change(function(){a("#wpacu_post_type_form").submit()}),a("#wpacu_taxonomy_select").change(function(){a("#wpacu_taxonomy_form").submit()}),a("#wpacu_dashboard").click(function(){a(this).prop("checked")?a("#wpacu-settings-assets-retrieval-mode").fadeIn("fast"):a("#wpacu-settings-assets-retrieval-mode").fadeOut("fast")}),a("#wpacu_disable_jquery_migrate").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.jquery_migration_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("#wpacu_disable_comment_reply").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.comment_reply_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("#wpacu_combine_loaded_css_enable").click(function(){a(this).prop("checked")?a("#combine_loaded_css_info_area").css({opacity:1}):a("#combine_loaded_css_info_area").css({opacity:.4})}),a("#wpacu_combine_loaded_js_enable").click(function(){a(this).prop("checked")?a("#combine_loaded_js_info_area").css({opacity:1}):a("#combine_loaded_js_info_area").css({opacity:.4})}),a("#wpacu_minify_css_enable").click(function(){a(this).prop("checked")?a("#wpacu_minify_css_exceptions_area").css({opacity:1}):a("#wpacu_minify_css_exceptions_area").css({opacity:.4})}),a("#wpacu_minify_js_enable").click(function(){a(this).prop("checked")?a("#wpacu_minify_js_exceptions_area").css({opacity:1}):a("#wpacu_minify_js_exceptions_area").css({opacity:.4})}),a(".wpacu-combine-loaded-js-level").change(function(){a(this).is(":checked")&&(a(".wpacu_combine_loaded_js_level_area").removeClass("wpacu_active"),a("#"+a(this).attr("data-target")).addClass("wpacu_active"))});var f=a('#wpacu-update-button-area input[type="submit"]');if(f.click(function(){a("#wpacu-updating-settings").show()}),a("form#wpacu-settings-form").submit(function(){return f.attr("disabled","disabled"),!0}),a(".wpacu_remove_rule").click(function(){var b=a(this).parents(".wpacu_global_rule_row");a(this).prop("checked")?b.addClass("selected"):b.removeClass("selected")}),a("#wpacu_wrap_assets").length>0&&setTimeout(function(){e.load()},200),"undefined"==typeof wpacu_object||a("#wpacu_meta_box_content").length<1)return!1;b(),a(document).on("click",".wp-admin.wp-editor .edit-post-header__settings button.is-primary",function(){var c=function(){0===a(".edit-post-header__settings .is-saving").length&&(b(),clearInterval(d))},d=setInterval(c,900)})}),-1!==location.href.indexOf("#")){var hashFromUrl=location.href.substr(location.href.indexOf("#"));jQuery('a[href="'+hashFromUrl+'"]').trigger("click")}
classes/AdminBar.php CHANGED
@@ -12,7 +12,7 @@ class AdminBar
12
  */
13
  public function __construct()
14
  {
15
- add_action( 'plugins_loaded', array( $this, 'topBar' ) );
16
  }
17
 
18
  /**
12
  */
13
  public function __construct()
14
  {
15
+ add_action( 'init', array( $this, 'topBar' ) );
16
  }
17
 
18
  /**
classes/AssetsPagesManager.php CHANGED
@@ -14,8 +14,6 @@ class AssetsPagesManager
14
 
15
  /**
16
  * AssetsPagesManager constructor.
17
- *
18
- * @param $data
19
  */
20
  public function __construct()
21
  {
14
 
15
  /**
16
  * AssetsPagesManager constructor.
 
 
17
  */
18
  public function __construct()
19
  {
classes/CleanUp.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WpAssetCleanUp;
3
+
4
+ /**
5
+ * Class CleanUp
6
+ * @package WpAssetCleanUpPro
7
+ */
8
+ class CleanUp
9
+ {
10
+ /**
11
+ *
12
+ */
13
+ public function init()
14
+ {
15
+ // Is "Test Mode" is enabled and the page is viewed by a regular visitor (not administrator with plugin activation privileges)?
16
+ // Stop here as the script will NOT PREVENT any of the elements below to load
17
+ // They will load as they used to for the regular visitor while the admin debugs the website
18
+ add_action('init', function() {
19
+ if ( Main::instance()->preventUnloadAssets() ) {
20
+ return;
21
+ }
22
+
23
+ CleanUp::doClean();
24
+ });
25
+ }
26
+
27
+ /**
28
+ *
29
+ */
30
+ public function doClean()
31
+ {
32
+ $settings = Main::instance()->settings;
33
+
34
+ // Remove "Really Simple Discovery (RSD)" link?
35
+ if ($settings['remove_rsd_link'] == 1) {
36
+ // <link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://yourwebsite.com/xmlrpc.php?rsd" />
37
+ remove_action('wp_head', 'rsd_link');
38
+ }
39
+
40
+ // Remove "Windows Live Writer" link?
41
+ if ($settings['remove_wlw_link'] == 1) {
42
+ // <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://yourwebsite.com/wp-includes/wlwmanifest.xml">
43
+ remove_action('wp_head', 'wlwmanifest_link');
44
+ }
45
+
46
+ // Remove "REST API" link?
47
+ if ($settings['remove_rest_api_link'] == 1) {
48
+ // <link rel='https://api.w.org/' href='https://yourwebsite.com/wp-json/' />
49
+ remove_action('wp_head', 'rest_output_link_wp_head');
50
+ }
51
+
52
+ // Remove "Shortlink"?
53
+ if ($settings['remove_shortlink'] == 1) {
54
+ // <link rel='shortlink' href="https://yourdomain.com/?p=1">
55
+ remove_action('wp_head', 'wp_shortlink_wp_head');
56
+ }
57
+
58
+ // Remove "Post's Relational Links"?
59
+ if ($settings['remove_posts_rel_links'] == 1) {
60
+ // <link rel='prev' title='Title of adjacent post' href='https://yourdomain.com/adjacent-post-slug-here/' />
61
+ remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
62
+ }
63
+
64
+ // Remove "WordPress version" tag?
65
+ if ($settings['remove_wp_version']) {
66
+ // <meta name="generator" content="WordPress 4.9.8" />
67
+ remove_action('wp_head', 'wp_generator');
68
+
69
+ // also hide it from RSS
70
+ add_filter('the_generator', '__return_false');
71
+ }
72
+
73
+ // Remove Main RSS Feed Link?
74
+ if ($settings['remove_main_feed_link']) {
75
+ add_filter('feed_links_show_posts_feed', '__return_false');
76
+ remove_action('wp_head', 'feed_links_extra', 3);
77
+ }
78
+
79
+ // Remove Comment RSS Feed Link?
80
+ if ($settings['remove_comment_feed_link']) {
81
+ add_filter('feed_links_show_comments_feed', '__return_false');
82
+ }
83
+
84
+ // Remove "WordPress version" and all other "generator" meta tags?
85
+ if ($settings['remove_generator_tag']) {
86
+ add_action('wp_loaded', function () {
87
+ ob_start(function ($htmlSource) {
88
+ return self::removeMetaGenerators($htmlSource);
89
+ });
90
+ } );
91
+ }
92
+
93
+ // Disable XML-RPC protocol support (partially or completely)
94
+ if (in_array($settings['disable_xmlrpc'], array('disable_all', 'disable_pingback'))) {
95
+ // Partially or Completely Options / Pingback will be disabled
96
+ $this->disableXmlRpcPingback();
97
+
98
+ // Complete disable the service
99
+ if ($settings['disable_xmlrpc'] === 'disable_all') {
100
+ add_filter('xmlrpc_enabled', '__return_false');
101
+ }
102
+
103
+ // Also clean it up from the <head>
104
+ add_action('wp_loaded', function() {
105
+ ob_start(function ($htmlSource) {
106
+ $pingBackUrl = get_bloginfo('pingback_url');
107
+
108
+ $matchRegExps = array(
109
+ '#<link rel=("|\')pingback("|\') href=("|\')'.$pingBackUrl.'("|\')( /|)>#',
110
+ '#<link href=("|\')'.$pingBackUrl.'("|\') rel=("|\')pingback("|\')( /|)>#'
111
+ );
112
+
113
+ foreach ($matchRegExps as $matchRegExp) {
114
+ $htmlSource = preg_replace($matchRegExp, '', $htmlSource);
115
+ }
116
+
117
+ return $htmlSource;
118
+ });
119
+ });
120
+ }
121
+ }
122
+
123
+ /**
124
+ *
125
+ */
126
+ public function disableXmlRpcPingback()
127
+ {
128
+ // Disable Pingback method
129
+ add_filter('xmlrpc_methods', function ($methods) {
130
+ unset($methods['pingback.ping'], $methods['pingback.extensions.getPingbacks']);
131
+ return $methods;
132
+ } );
133
+
134
+ // Remove X-Pingback HTTP header
135
+ add_filter('wp_headers', function ($headers) {
136
+ unset($headers['X-Pingback']);
137
+ return $headers;
138
+ });
139
+ }
140
+
141
+ /**
142
+ * @param $htmlSource
143
+ *
144
+ * @return mixed
145
+ */
146
+ public static function removeMetaGenerators($htmlSource)
147
+ {
148
+ if (stripos($htmlSource, '<meta') === false) {
149
+ return $htmlSource;
150
+ }
151
+
152
+ // Use DOMDocument to alter the HTML Source and Remove the tags
153
+ $htmlSourceOriginal = $htmlSource;
154
+
155
+ if (function_exists('libxml_use_internal_errors')
156
+ && function_exists('libxml_clear_errors')
157
+ && class_exists('DOMDocument'))
158
+ {
159
+ $document = new \DOMDocument();
160
+ libxml_use_internal_errors(true);
161
+
162
+ $document->loadHTML($htmlSource);
163
+
164
+ $domUpdated = false;
165
+
166
+ foreach ($document->getElementsByTagName('meta') as $tagObject) {
167
+ $nameAttrValue = $tagObject->getAttribute('name');
168
+
169
+ if ($nameAttrValue === 'generator') {
170
+ $outerTag = $outerTagRegExp = trim(self::getOuterHTML($tagObject));
171
+ $last2Chars = substr($outerTag, -2);
172
+
173
+ if ($last2Chars === '">' || $last2Chars === "'>") {
174
+ $tagWithoutLastChar = substr($outerTag, 0, -1);
175
+ $outerTagRegExp = $tagWithoutLastChar.'(.*?)>';
176
+ }
177
+
178
+ if (strpos($outerTagRegExp, '<meta') !== false) {
179
+ preg_match_all('#' . $outerTagRegExp . '#si', $htmlSource, $matches);
180
+
181
+ if (isset($matches[0][0]) && ! empty($matches[0][0]) && strip_tags($matches[0][0]) === '') {
182
+ $htmlSource = str_replace( $matches[0][0], '', $htmlSource );
183
+ }
184
+
185
+ if ($htmlSource !== $htmlSourceOriginal) {
186
+ $domUpdated = true;
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ libxml_clear_errors();
193
+
194
+ if ($domUpdated) {
195
+ return $htmlSource;
196
+ }
197
+ }
198
+
199
+ // DOMDocument is not enabled. Use the RegExp instead (not as smooth, but does its job)!
200
+ preg_match_all('#<meta(.*?)>#si', $htmlSource, $matches);
201
+
202
+ if (isset($matches[0]) && ! empty($matches[0])) {
203
+ foreach ($matches[0] as $metaTag) {
204
+ if (strip_tags($metaTag) === ''
205
+ && (stripos($metaTag, 'name="generator"') !== false || stripos($metaTag, 'name=\'generator\'') !== false)
206
+ ) {
207
+ $htmlSource = str_replace($metaTag, '', $htmlSource);
208
+ }
209
+ }
210
+ }
211
+
212
+ return $htmlSource;
213
+ }
214
+
215
+ /**
216
+ * @param $e
217
+ *
218
+ * @return mixed
219
+ */
220
+ public static function getOuterHTML($e)
221
+ {
222
+ $doc = new \DOMDocument();
223
+ $doc->appendChild( $doc->importNode( $e, true ) );
224
+
225
+ return $doc->saveHTML();
226
+ }
227
+ }
classes/Main.php CHANGED
@@ -75,10 +75,15 @@ class Main
75
  */
76
  public $isFrontendEditView = false;
77
 
 
 
 
 
 
78
  /**
79
  * @var array
80
  */
81
- public $assetsInFooter = array();
82
 
83
  /**
84
  * @var array
@@ -116,8 +121,8 @@ class Main
116
  public $isAjaxCall = false;
117
 
118
  /**
119
- * Populated in the Parser constructor
120
- *
121
  * @var array
122
  */
123
  public $skipAssets = array('styles' => array(), 'scripts' => array());
@@ -125,7 +130,7 @@ class Main
125
  /**
126
  * @var Main|null
127
  */
128
- private static $singleton = null;
129
 
130
  /**
131
  * @return null|Main
@@ -144,20 +149,20 @@ class Main
144
  */
145
  public function __construct()
146
  {
147
- $this->skipAssets['styles'] = array(
148
- WPACU_PLUGIN_ID . '-style', // Asset CleanUp Styling (for admin use only)
149
- 'admin-bar', // The top admin bar
150
- 'yoast-seo-adminbar', // Yoast "WordPress SEO" plugin
151
- 'autoptimize-toolbar',
152
- 'query-monitor'
153
- );
154
 
155
  $this->skipAssets['scripts'] = array(
156
  WPACU_PLUGIN_ID . '-script', // Asset CleanUp Script (for admin use only)
157
  'admin-bar', // The top admin bar
158
  'autoptimize-toolbar',
159
  'query-monitor'
160
- );
161
 
162
  if (array_key_exists(WPACU_LOAD_ASSETS_REQ_KEY, $_REQUEST)) {
163
  add_filter('w3tc_minify_enable', '__return_false');
@@ -177,7 +182,7 @@ class Main
177
 
178
  // This is triggered AFTER "saveSettings" from 'Settings' class
179
  // In case the settings were just updated, the script will get the latest values
180
- add_action('plugins_loaded', array($this, 'initAfterPluginsLoaded'), 10);
181
 
182
  // Front-end View - Unload the assets
183
  // If there are reasons to prevent the unloading in case 'test mode' is enabled,
@@ -196,7 +201,7 @@ class Main
196
  add_action( 'wp_print_footer_scripts', array( $this, 'filterScripts' ), 1 );
197
  add_action( 'wp_print_footer_scripts', array( $this, 'filterStyles' ), 1 );
198
  }
199
-
200
  // This is recommended to keep active for Lite users as it helps spread the word about the plugin
201
  // To remove the notice, consider upgrading to PRO
202
 
@@ -207,7 +212,7 @@ class Main
207
  $this->wpacuUsageNotice();
208
  }
209
 
210
- add_action( 'admin_footer', array( $this, 'ajaxFetchActivePluginsJsFooterCode' ) );
211
  add_action( 'wp_ajax_' . WPACU_PLUGIN_ID . '_fetch_active_plugins_icons',
212
  array( $this, 'ajaxFetchActivePluginsIcons' ) );
213
 
@@ -217,30 +222,37 @@ class Main
217
  /**
218
  *
219
  */
220
- public function initAfterPluginsLoaded()
221
- {
222
- $wpacuSettingsClass = new Settings();
223
- $this->settings = $wpacuSettingsClass->getAll();
224
 
225
- if ($this->settings['dashboard_show'] && $this->settings['dom_get_type']) {
226
- self::$domGetType = $this->settings['dom_get_type'];
227
- }
228
 
229
- // Fetch the page in the background to see what scripts/styles are already loading
230
- if (isset($_REQUEST[WPACU_LOAD_ASSETS_REQ_KEY]) || $this->settings['frontend_show']) {
231
- if (isset($_REQUEST[WPACU_LOAD_ASSETS_REQ_KEY])) {
232
- Misc::noAdminBarLoad();
233
- }
234
 
235
- add_action('wp_head', array($this, 'saveFooterAssets'), 100000000);
236
- add_action('wp_footer', array($this, 'printScriptsStyles'), PHP_INT_MAX);
237
- }
 
 
 
 
 
238
 
239
- $metaboxes = new MetaBoxes;
 
240
 
241
- if ( is_admin() ) {
242
- // Do not load the meta box nor do any AJAX calls
243
- // if the asset management is not enabled for the Dashboard
 
 
 
 
 
244
  if ($this->settings['dashboard_show'] == 1) {
245
  // Send an AJAX request to get the list of loaded scripts and styles and print it nicely
246
  add_action(
@@ -252,17 +264,15 @@ class Main
252
  }
253
 
254
  // Side Meta Box: Asset CleanUp Options
255
- $metaboxes->initCustomOptionsMetaBox();
256
- }
257
 
258
- if ($this->settings['disable_emojis'] == 1) {
259
- add_action('init', array($this, 'doDisableEmojis'));
260
- }
261
- }
262
 
263
  /**
264
- * This has to be triggered after 'plugins_loaded' (e.g. in 'wp')
265
- *
266
  * Priority: 8 (earliest)
267
  */
268
  public function setVarsBeforeUpdate()
@@ -330,7 +340,7 @@ class Main
330
  $globalUnload = $this->globalUnloaded;
331
 
332
  // [wpacu_lite]
333
- if (! empty($globalUnload['scripts']) && $nonAssetConfigPage) {
334
  $list = $globalUnload['scripts'];
335
  } else { // [/wpacu_lite]
336
  // Post, Page or Front-page?
@@ -453,7 +463,7 @@ class Main
453
  $globalUnload = $this->globalUnloaded;
454
 
455
  // [wpacu_lite]
456
- if (! empty($globalUnload['styles']) && $nonAssetConfigPage) {
457
  $list = $globalUnload['styles'];
458
  } else { // [/wpacu_lite]
459
  // Post, Page, Front-page
@@ -505,11 +515,11 @@ class Main
505
  }
506
  }
507
 
508
- global $wp_styles;
509
 
510
  $allStyles = $wp_styles;
511
 
512
- if ($allStyles !== null && isset($allStyles->registered)) {
513
  $i = $this->lastStylePos;
514
 
515
  foreach ($allStyles->registered as $handle => $value) {
@@ -650,15 +660,37 @@ class Main
650
  return $existingList;
651
  }
652
 
 
 
 
 
 
 
 
 
 
 
653
  /**
654
  *
655
  */
656
- public function saveFooterAssets()
657
  {
658
  global $wp_scripts;
 
659
 
660
- $this->assetsInFooter = $wp_scripts->in_footer;
661
- }
 
 
 
 
 
 
 
 
 
 
 
662
 
663
  /**
664
  * This output will be extracted and the JSON will be processed
@@ -736,11 +768,11 @@ class Main
736
  $manageScripts = $wp_scripts->done;
737
 
738
  if ($isFrontEndEditView) {
739
- if (isset($this->wpAllStyles['queue']) && ! empty($this->wpAllStyles)) {
740
  $manageStyles = $this->wpAllStyles['queue'];
741
  }
742
 
743
- if (isset($this->wpAllScripts['queue']) && ! empty($this->wpAllScripts)) {
744
  $manageScripts = $this->wpAllScripts['queue'];
745
  }
746
 
@@ -793,12 +825,12 @@ class Main
793
  if (! empty($stylesList)) {
794
  /* These styles below are used by this plugin (except admin-bar) and they should not show in the list
795
  as they are loaded only when you (or other admin) manage the assets, never for your website visitors */
796
- if (is_admin_bar_showing() && is_admin()) {
797
- $this->skipAssets['styles'][] = 'dashicons';
798
- }
799
 
800
  foreach ($manageStyles as $handle) {
801
- if (in_array($handle, $this->skipAssets['styles']) || (! isset($stylesList[$handle]))) {
802
  continue;
803
  }
804
 
@@ -814,7 +846,7 @@ class Main
814
  }
815
 
816
  // Append unloaded ones (if any)
817
- if (! empty($currentUnloadedAll['styles']) && !empty($stylesBeforeUnload)) {
818
  foreach ($currentUnloadedAll['styles'] as $sbuHandle) {
819
  if (! in_array($sbuHandle, $manageStyles)) {
820
  // Could be an old style that is not loaded anymore
@@ -847,7 +879,7 @@ class Main
847
  /* These scripts below are used by this plugin (except admin-bar) and they should not show in the list
848
  as they are loaded only when you (or other admin) manage the assets, never for your website visitors */
849
  foreach ($manageScripts as $handle) {
850
- if (in_array($handle, $this->skipAssets['scripts']) || (! isset($scriptsList[$handle]))) {
851
  continue;
852
  }
853
 
@@ -863,7 +895,7 @@ class Main
863
  }
864
 
865
  // Append unloaded ones (if any)
866
- if (! empty($currentUnloadedAll['scripts']) && !empty($scriptsBeforeUnload)) {
867
  foreach ($currentUnloadedAll['scripts'] as $sbuHandle) {
868
  if (! in_array($sbuHandle, $manageScripts)) {
869
  // Could be an old script that is not loaded anymore
@@ -993,7 +1025,7 @@ class Main
993
  );
994
 
995
  if (! file_exists($templateFile)) {
996
- return 'Template '.$name.' not found.';
997
  }
998
 
999
  ob_start();
@@ -1185,13 +1217,19 @@ class Main
1185
  if (! empty($data['all']['styles'])) {
1186
  $data['core_styles_loaded'] = false;
1187
 
1188
- foreach ($data['all']['styles'] as $key => $obj) {
1189
  if (! isset($obj->handle)) {
1190
  unset($data['all']['styles']['']);
1191
  continue;
1192
  }
1193
 
1194
- if (isset($obj->src, $data['all']['styles'][$key]) && $obj->src) {
 
 
 
 
 
 
1195
  $part = str_replace(
1196
  array(
1197
  'http://',
@@ -1210,10 +1248,10 @@ class Main
1210
  $data['core_styles_loaded'] = true;
1211
  }
1212
 
1213
- // Determine source href
1214
- if (substr($obj->src, 0, 1) === '/' && substr($obj->src, 0, 2) !== '//') {
1215
  $obj->srcHref = $siteUrl . $obj->src;
1216
- } else {
1217
  $obj->srcHref = $obj->src;
1218
  }
1219
  }
@@ -1223,18 +1261,6 @@ class Main
1223
  if (! empty($data['all']['scripts'])) {
1224
  $data['core_scripts_loaded'] = false;
1225
 
1226
- $headPart = $bodyPart = '';
1227
-
1228
- if (isset($data['contents'])) {
1229
- // Extract 'HEAD' part
1230
- $headPart = Misc::extractBetween($data['contents'], '<head', '</head>');
1231
-
1232
- // Extract 'BODY' part
1233
- $contentsAltered = str_replace($headPart, '', $data['contents']);
1234
- $bodyDel = '<body'; // Get everything after $bodyDel
1235
- $bodyPart = substr($data['contents'], stripos($contentsAltered, $bodyDel) + strlen($bodyDel));
1236
- }
1237
-
1238
  foreach ($data['all']['scripts'] as $key => $obj) {
1239
  if (! isset($obj->handle)) {
1240
  unset($data['all']['scripts']['']);
@@ -1244,20 +1270,9 @@ class Main
1244
  // From WordPress directories (false by default)
1245
  $data['all']['scripts'][$key]->wp = false;
1246
 
1247
- $toCheck = $obj->src;
1248
- $toCheckExtra = str_replace(
1249
- array(',', '&'),
1250
- array('%2C', '&#038;'),
1251
- $obj->src
1252
- );
1253
 
1254
- if (isset($data['contents'])) {
1255
- if (stripos($headPart, $toCheck) !== false || stripos($headPart, $toCheckExtra) !== false) {
1256
- $data['all']['scripts'][$key]->position = 'head';
1257
- } elseif (stripos($bodyPart, $toCheck) !== false || stripos($bodyPart, $toCheckExtra) !== false) {
1258
- $data['all']['scripts'][$key]->position = 'body';
1259
- }
1260
- } elseif (in_array($obj->handle, $this->assetsInFooter)) {
1261
  $data['all']['scripts'][$key]->position = 'body';
1262
  } else {
1263
  $data['all']['scripts'][$key]->position = 'head';
@@ -1295,7 +1310,8 @@ class Main
1295
  $data['all']['scripts'][$key]->wp = true;
1296
  $data['core_scripts_loaded'] = true;
1297
  }
1298
- }
 
1299
  }
1300
  }
1301
 
@@ -1313,7 +1329,7 @@ class Main
1313
  {
1314
  // Post Type (Overwrites 'front' - home page - if we are in a singular post)
1315
  if ($postId == 0) {
1316
- $postId = $this->getCurrentPostId();
1317
  }
1318
 
1319
  $isInAdminPageViaAjax = (is_admin() && defined('DOING_AJAX') && DOING_AJAX);
@@ -1367,16 +1383,14 @@ class Main
1367
  $this->vars['is_woo_shop_page'] = true;
1368
  }
1369
  } else {
1370
- if ($wooCommerceShopPageId > 0 && Misc::isHomePage()) {
1371
- if (strpos(get_site_url(), '://') !== false) {
1372
- list($siteUrlAfterProtocol) = explode('://', get_site_url());
1373
- $currentPageUrlAfterProtocol = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
1374
-
1375
- if ($siteUrlAfterProtocol != $currentPageUrlAfterProtocol && (strpos($siteUrlAfterProtocol,
1376
- '/shop') !== false)
1377
- ) {
1378
- $this->vars['woo_url_not_match'] = true;
1379
- }
1380
  }
1381
  }
1382
  }
@@ -1387,7 +1401,7 @@ class Main
1387
  }
1388
 
1389
  // It has to be a single page (no "Posts page")
1390
- if (is_singular() && ($this->currentPostId < 1)) {
1391
  global $post;
1392
  $this->currentPostId = isset($post->ID) ? $post->ID : 0;
1393
  }
75
  */
76
  public $isFrontendEditView = false;
77
 
78
+ /**
79
+ * @var array
80
+ */
81
+ public $stylesInHead = array();
82
+
83
  /**
84
  * @var array
85
  */
86
+ public $assetsInFooter = array('styles' => array(), 'scripts' => array());
87
 
88
  /**
89
  * @var array
121
  public $isAjaxCall = false;
122
 
123
  /**
124
+ * Populated in the Parser constructor
125
+ *
126
  * @var array
127
  */
128
  public $skipAssets = array('styles' => array(), 'scripts' => array());
130
  /**
131
  * @var Main|null
132
  */
133
+ private static $singleton;
134
 
135
  /**
136
  * @return null|Main
149
  */
150
  public function __construct()
151
  {
152
+ $this->skipAssets['styles'] = array(
153
+ WPACU_PLUGIN_ID . '-style', // Asset CleanUp Styling (for admin use only)
154
+ 'admin-bar', // The top admin bar
155
+ 'yoast-seo-adminbar', // Yoast "WordPress SEO" plugin
156
+ 'autoptimize-toolbar',
157
+ 'query-monitor'
158
+ );
159
 
160
  $this->skipAssets['scripts'] = array(
161
  WPACU_PLUGIN_ID . '-script', // Asset CleanUp Script (for admin use only)
162
  'admin-bar', // The top admin bar
163
  'autoptimize-toolbar',
164
  'query-monitor'
165
+ );
166
 
167
  if (array_key_exists(WPACU_LOAD_ASSETS_REQ_KEY, $_REQUEST)) {
168
  add_filter('w3tc_minify_enable', '__return_false');
182
 
183
  // This is triggered AFTER "saveSettings" from 'Settings' class
184
  // In case the settings were just updated, the script will get the latest values
185
+ add_action('init', array($this, 'triggersAfterInit'), 10);
186
 
187
  // Front-end View - Unload the assets
188
  // If there are reasons to prevent the unloading in case 'test mode' is enabled,
201
  add_action( 'wp_print_footer_scripts', array( $this, 'filterScripts' ), 1 );
202
  add_action( 'wp_print_footer_scripts', array( $this, 'filterStyles' ), 1 );
203
  }
204
+
205
  // This is recommended to keep active for Lite users as it helps spread the word about the plugin
206
  // To remove the notice, consider upgrading to PRO
207
 
212
  $this->wpacuUsageNotice();
213
  }
214
 
215
+ add_action( 'admin_footer', array( $this, 'ajaxFetchActivePluginsJsFooterCode' ) );
216
  add_action( 'wp_ajax_' . WPACU_PLUGIN_ID . '_fetch_active_plugins_icons',
217
  array( $this, 'ajaxFetchActivePluginsIcons' ) );
218
 
222
  /**
223
  *
224
  */
225
+ public function triggersAfterInit()
226
+ {
227
+ $wpacuSettingsClass = new Settings();
228
+ $this->settings = $wpacuSettingsClass->getAll();
229
 
230
+ if ($this->settings['dashboard_show'] && $this->settings['dom_get_type']) {
231
+ self::$domGetType = $this->settings['dom_get_type'];
232
+ }
233
 
234
+ $calledFromDashboard = isset($_REQUEST[WPACU_LOAD_ASSETS_REQ_KEY]);
 
 
 
 
235
 
236
+ // Fetch the page in the background to see what scripts/styles are already loading
237
+ if ($calledFromDashboard || $this->settings['frontend_show']) {
238
+ if ($calledFromDashboard) {
239
+ Misc::noAdminBarLoad();
240
+ }
241
+
242
+ // Save CSS list that is printed in the <HEAD>
243
+ add_action('wp_head', array($this, 'saveFooterStyles'), PHP_INT_MAX - 1);
244
 
245
+ // Save CSS/JS list that is printed in the <BODY>
246
+ add_action('wp_footer', array($this, 'saveFooterScripts'), 100000000);
247
 
248
+ add_action('wp_footer', array($this, 'printScriptsStyles'), PHP_INT_MAX);
249
+ }
250
+
251
+ $metaboxes = new MetaBoxes;
252
+
253
+ if ( is_admin() ) {
254
+ // Do not load the meta box nor do any AJAX calls
255
+ // if the asset management is not enabled for the Dashboard
256
  if ($this->settings['dashboard_show'] == 1) {
257
  // Send an AJAX request to get the list of loaded scripts and styles and print it nicely
258
  add_action(
264
  }
265
 
266
  // Side Meta Box: Asset CleanUp Options
267
+ $metaboxes->initCustomOptionsMetaBox();
268
+ }
269
 
270
+ if ($this->settings['disable_emojis'] == 1) {
271
+ add_action('init', array($this, 'doDisableEmojis'));
272
+ }
273
+ }
274
 
275
  /**
 
 
276
  * Priority: 8 (earliest)
277
  */
278
  public function setVarsBeforeUpdate()
340
  $globalUnload = $this->globalUnloaded;
341
 
342
  // [wpacu_lite]
343
+ if ($nonAssetConfigPage && ! empty($globalUnload['scripts'])) {
344
  $list = $globalUnload['scripts'];
345
  } else { // [/wpacu_lite]
346
  // Post, Page or Front-page?
463
  $globalUnload = $this->globalUnloaded;
464
 
465
  // [wpacu_lite]
466
+ if ($nonAssetConfigPage && ! empty($globalUnload['styles'])) {
467
  $list = $globalUnload['styles'];
468
  } else { // [/wpacu_lite]
469
  // Post, Page, Front-page
515
  }
516
  }
517
 
518
+ global $wp_styles;
519
 
520
  $allStyles = $wp_styles;
521
 
522
+ if ($allStyles !== null && ! empty($allStyles->registered)) {
523
  $i = $this->lastStylePos;
524
 
525
  foreach ($allStyles->registered as $handle => $value) {
660
  return $existingList;
661
  }
662
 
663
+ /**
664
+ *
665
+ */
666
+ public function saveFooterStyles()
667
+ {
668
+ if (isset($this->wpAllStyles['queue']) && ! empty($this->wpAllStyles['queue'])) {
669
+ $this->stylesInHead = $this->wpAllStyles['queue'];
670
+ }
671
+ }
672
+
673
  /**
674
  *
675
  */
676
+ public function saveFooterScripts()
677
  {
678
  global $wp_scripts;
679
+ $this->assetsInFooter['scripts'] = (isset($wp_scripts->in_footer) && ! empty($wp_scripts->in_footer)) ? $wp_scripts->in_footer : array();
680
 
681
+ $footerStyles = array();
682
+
683
+ if (isset($this->wpAllStyles['queue']) && ! empty($this->wpAllStyles['queue'])) {
684
+ foreach ( $this->wpAllStyles['queue'] as $handle ) {
685
+ if ( ! in_array( $handle, $this->stylesInHead ) ) {
686
+ $footerStyles[] = $handle;
687
+ }
688
+ }
689
+ }
690
+
691
+ $this->assetsInFooter['styles'] = $footerStyles;
692
+
693
+ }
694
 
695
  /**
696
  * This output will be extracted and the JSON will be processed
768
  $manageScripts = $wp_scripts->done;
769
 
770
  if ($isFrontEndEditView) {
771
+ if (! empty($this->wpAllStyles) && isset($this->wpAllStyles['queue'])) {
772
  $manageStyles = $this->wpAllStyles['queue'];
773
  }
774
 
775
+ if (! empty($this->wpAllScripts) && isset($this->wpAllScripts['queue'])) {
776
  $manageScripts = $this->wpAllScripts['queue'];
777
  }
778
 
825
  if (! empty($stylesList)) {
826
  /* These styles below are used by this plugin (except admin-bar) and they should not show in the list
827
  as they are loaded only when you (or other admin) manage the assets, never for your website visitors */
828
+ if (is_admin_bar_showing() && is_admin()) {
829
+ $this->skipAssets['styles'][] = 'dashicons';
830
+ }
831
 
832
  foreach ($manageStyles as $handle) {
833
+ if (! isset($stylesList[$handle]) || in_array($handle, $this->skipAssets['styles'])) {
834
  continue;
835
  }
836
 
846
  }
847
 
848
  // Append unloaded ones (if any)
849
+ if (!empty($stylesBeforeUnload) && ! empty($currentUnloadedAll['styles'])) {
850
  foreach ($currentUnloadedAll['styles'] as $sbuHandle) {
851
  if (! in_array($sbuHandle, $manageStyles)) {
852
  // Could be an old style that is not loaded anymore
879
  /* These scripts below are used by this plugin (except admin-bar) and they should not show in the list
880
  as they are loaded only when you (or other admin) manage the assets, never for your website visitors */
881
  foreach ($manageScripts as $handle) {
882
+ if (! isset($scriptsList[$handle]) || in_array($handle, $this->skipAssets['scripts'])) {
883
  continue;
884
  }
885
 
895
  }
896
 
897
  // Append unloaded ones (if any)
898
+ if (!empty($scriptsBeforeUnload) && ! empty($currentUnloadedAll['scripts'])) {
899
  foreach ($currentUnloadedAll['scripts'] as $sbuHandle) {
900
  if (! in_array($sbuHandle, $manageScripts)) {
901
  // Could be an old script that is not loaded anymore
1025
  );
1026
 
1027
  if (! file_exists($templateFile)) {
1028
+ return 'Template '.$templateFile.' not found.';
1029
  }
1030
 
1031
  ob_start();
1217
  if (! empty($data['all']['styles'])) {
1218
  $data['core_styles_loaded'] = false;
1219
 
1220
+ foreach ($data['all']['styles'] as $key => $obj) {
1221
  if (! isset($obj->handle)) {
1222
  unset($data['all']['styles']['']);
1223
  continue;
1224
  }
1225
 
1226
+ if (in_array($obj->handle, $this->assetsInFooter['styles'])) {
1227
+ $data['all']['styles'][$key]->position = 'body';
1228
+ } else {
1229
+ $data['all']['styles'][$key]->position = 'head';
1230
+ }
1231
+
1232
+ if (isset($data['all']['styles'][$key], $obj->src) && $obj->src) {
1233
  $part = str_replace(
1234
  array(
1235
  'http://',
1248
  $data['core_styles_loaded'] = true;
1249
  }
1250
 
1251
+ // Determine source href (starting with '/' but not starting with '//')
1252
+ if (strpos($obj->src, '/') === 0 && strpos($obj->src, '//') !== 0) {
1253
  $obj->srcHref = $siteUrl . $obj->src;
1254
+ } else{
1255
  $obj->srcHref = $obj->src;
1256
  }
1257
  }
1261
  if (! empty($data['all']['scripts'])) {
1262
  $data['core_scripts_loaded'] = false;
1263
 
 
 
 
 
 
 
 
 
 
 
 
 
1264
  foreach ($data['all']['scripts'] as $key => $obj) {
1265
  if (! isset($obj->handle)) {
1266
  unset($data['all']['scripts']['']);
1270
  // From WordPress directories (false by default)
1271
  $data['all']['scripts'][$key]->wp = false;
1272
 
1273
+ $initialScriptPos = wp_cache_get($obj->handle, 'wpacu_scripts_initial_positions');
 
 
 
 
 
1274
 
1275
+ if ($initialScriptPos === 'body' || in_array($obj->handle, $this->assetsInFooter['scripts'])) {
 
 
 
 
 
 
1276
  $data['all']['scripts'][$key]->position = 'body';
1277
  } else {
1278
  $data['all']['scripts'][$key]->position = 'head';
1310
  $data['all']['scripts'][$key]->wp = true;
1311
  $data['core_scripts_loaded'] = true;
1312
  }
1313
+
1314
+ }
1315
  }
1316
  }
1317
 
1329
  {
1330
  // Post Type (Overwrites 'front' - home page - if we are in a singular post)
1331
  if ($postId == 0) {
1332
+ $postId = (int)$this->getCurrentPostId();
1333
  }
1334
 
1335
  $isInAdminPageViaAjax = (is_admin() && defined('DOING_AJAX') && DOING_AJAX);
1383
  $this->vars['is_woo_shop_page'] = true;
1384
  }
1385
  } else {
1386
+ if ($wooCommerceShopPageId > 0 && Misc::isHomePage() && strpos(get_site_url(), '://') !== false) {
1387
+ list($siteUrlAfterProtocol) = explode('://', get_site_url());
1388
+ $currentPageUrlAfterProtocol = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
1389
+
1390
+ if ($siteUrlAfterProtocol != $currentPageUrlAfterProtocol && (strpos($siteUrlAfterProtocol,
1391
+ '/shop') !== false)
1392
+ ) {
1393
+ $this->vars['woo_url_not_match'] = true;
 
 
1394
  }
1395
  }
1396
  }
1401
  }
1402
 
1403
  // It has to be a single page (no "Posts page")
1404
+ if (($this->currentPostId < 1) && is_singular()) {
1405
  global $post;
1406
  $this->currentPostId = isset($post->ID) ? $post->ID : 0;
1407
  }
classes/MetaBoxes.php CHANGED
@@ -53,23 +53,21 @@ class MetaBoxes
53
  return;
54
  }
55
 
56
- $postId = $post->ID;
57
 
58
  $getAssets = true;
59
 
60
- if (get_post_status($postId) !== 'publish') {
61
  $getAssets = false;
62
  }
63
 
64
- if ($getAssets) {
65
- // Add an nonce field so we can check for it later.
66
- wp_nonce_field( WPACU_PLUGIN_ID . '_meta_box', WPACU_PLUGIN_ID . '_nonce');
67
- }
68
-
69
  $data = array();
70
 
71
  $data['get_assets'] = $getAssets;
72
- $data['fetch_url'] = Misc::getPageUrl($postId);
 
 
 
73
 
74
  Main::instance()->parseTemplate('meta-box', $data, true);
75
  }
53
  return;
54
  }
55
 
56
+ $postId = (isset($post->ID) && $post->ID > 0) ? $post->ID : 0;
57
 
58
  $getAssets = true;
59
 
60
+ if ($postId < 1 || get_post_status($postId) !== 'publish') {
61
  $getAssets = false;
62
  }
63
 
 
 
 
 
 
64
  $data = array();
65
 
66
  $data['get_assets'] = $getAssets;
67
+
68
+ if ($getAssets) {
69
+ $data['fetch_url'] = Misc::getPageUrl( $postId );
70
+ }
71
 
72
  Main::instance()->parseTemplate('meta-box', $data, true);
73
  }
classes/OptimiseAssets/MinifyCss.php CHANGED
@@ -18,7 +18,8 @@ class MinifyCss
18
  public function __construct()
19
  {
20
  add_action('wp_footer', function() {
21
- if ( is_admin() || // not for Dashboard view
 
22
  (! Main::instance()->settings['minify_loaded_css']) || // Minify CSS has to be Enabled
23
  (Main::instance()->settings['test_mode'] && ! Menu::userCanManageAssets()) ) { // Does not trigger if "Test Mode" is Enabled
24
  return;
@@ -108,9 +109,10 @@ class MinifyCss
108
  }
109
 
110
  /**
111
- *
112
  * @param $value
113
- */
 
 
114
  public function maybeMinifyIt($value)
115
  {
116
  global $wp_version;
18
  public function __construct()
19
  {
20
  add_action('wp_footer', function() {
21
+ if ( array_key_exists('wpacu_no_css_minify', $_GET) || // not on query string request (debugging purposes)
22
+ is_admin() || // not for Dashboard view
23
  (! Main::instance()->settings['minify_loaded_css']) || // Minify CSS has to be Enabled
24
  (Main::instance()->settings['test_mode'] && ! Menu::userCanManageAssets()) ) { // Does not trigger if "Test Mode" is Enabled
25
  return;
109
  }
110
 
111
  /**
 
112
  * @param $value
113
+ *
114
+ * @return array
115
+ */
116
  public function maybeMinifyIt($value)
117
  {
118
  global $wp_version;
classes/OptimiseAssets/MinifyJs.php ADDED
@@ -0,0 +1,430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WpAssetCleanUp\OptimiseAssets;
3
+
4
+ use WpAssetCleanUp\Main;
5
+ use WpAssetCleanUp\Menu;
6
+ use WpAssetCleanUp\Misc;
7
+ use WpAssetCleanUp\MetaBoxes;
8
+
9
+ /**
10
+ * Class MinifyJs
11
+ * @package WpAssetCleanUp\OptimiseAssets
12
+ */
13
+ class MinifyJs
14
+ {
15
+ /**
16
+ * MinifyJs constructor.
17
+ */
18
+ public function __construct()
19
+ {
20
+ /*
21
+ * #minifying
22
+ * STEP 1: Prepare minify-able caching list
23
+ */
24
+ add_action('wp_print_footer_scripts', function() {
25
+ if ( array_key_exists('wpacu_no_js_minify', $_GET) || // not on query string request (debugging purposes)
26
+ is_admin() || // not for Dashboard view
27
+ (! Main::instance()->settings['minify_loaded_js']) || // Minify JS has to be Enabled
28
+ (Main::instance()->settings['test_mode'] && ! Menu::userCanManageAssets()) ) { // Does not trigger if "Test Mode" is Enabled
29
+ return;
30
+ }
31
+
32
+ if (defined('WPACU_CURRENT_PAGE_ID') && WPACU_CURRENT_PAGE_ID > 0 && is_singular()) {
33
+ // If "Do not minify JS on this page" is checked in "Asset CleanUp: Options" side meta box
34
+ $pageOptions = MetaBoxes::getPageOptions( WPACU_CURRENT_PAGE_ID );
35
+
36
+ if ( isset( $pageOptions['no_js_minify'] ) && $pageOptions['no_js_minify'] ) {
37
+ return;
38
+ }
39
+ }
40
+
41
+ global $wp_scripts;
42
+
43
+ $jsMinifyList = array();
44
+
45
+ $wpScriptsList = array_unique(array_merge($wp_scripts->done, $wp_scripts->queue));
46
+
47
+ // [Start] Collect for caching
48
+ foreach ($wpScriptsList as $handle) {
49
+ if (isset($wp_scripts->registered[$handle])) {
50
+ $value = $wp_scripts->registered[$handle];
51
+ $minifyValues = $this->maybeMinifyIt( $value );
52
+
53
+ if ( ! empty( $minifyValues ) ) {
54
+ $jsMinifyList[] = $minifyValues;
55
+ }
56
+ }
57
+ }
58
+
59
+ wp_cache_add('wpacu_js_minify_list', $jsMinifyList);
60
+ // [End] Collect for caching
61
+ }, PHP_INT_MAX);
62
+ }
63
+
64
+ /**
65
+ * @param $htmlSource
66
+ *
67
+ * @return mixed
68
+ */
69
+ public static function updateHtmlSourceOriginalToMinJs($htmlSource)
70
+ {
71
+ $jsMinifyList = wp_cache_get('wpacu_js_minify_list');
72
+
73
+ if (empty($jsMinifyList)) {
74
+ return $htmlSource;
75
+ }
76
+
77
+ $regExpPattern = '#<script[^>]*src(|\s+)=(|\s+)[^>]*(>)#Usmi';
78
+
79
+ preg_match_all($regExpPattern, OptimizeCommon::cleanerHtmlSource($htmlSource), $matchesSourcesFromTags, PREG_SET_ORDER);
80
+
81
+ foreach ($matchesSourcesFromTags as $matches) {
82
+ $scriptSourceTag = $matches[0];
83
+
84
+ if (strip_tags($scriptSourceTag) !== '') {
85
+ // Hmm? Not a valid tag... Skip it...
86
+ continue;
87
+ }
88
+
89
+ foreach ($jsMinifyList as $listValues) {
90
+ $sourceUrl = site_url() . $listValues[0];
91
+ $minUrl = site_url() . $listValues[1];
92
+
93
+ $newScriptSourceTag = str_ireplace($sourceUrl, $minUrl, $scriptSourceTag);
94
+
95
+ if ($scriptSourceTag !== $newScriptSourceTag) {
96
+ // Strip ?ver=
97
+ $toStrip = Misc::extractBetween($newScriptSourceTag, '?ver=', '>');
98
+
99
+ if (in_array(substr($toStrip, -1), array('"', "'"))) {
100
+ $toStrip = '?ver='. trim(trim($toStrip, '"'), "'");
101
+ $newScriptSourceTag = str_replace($toStrip, '', $newScriptSourceTag);
102
+ }
103
+
104
+ $htmlSource = str_replace($scriptSourceTag, $newScriptSourceTag, $htmlSource);
105
+ break;
106
+ }
107
+ }
108
+ }
109
+
110
+ return $htmlSource;
111
+ }
112
+
113
+ /**
114
+ * @param $value
115
+ *
116
+ * @return array
117
+ */
118
+ public function maybeMinifyIt($value)
119
+ {
120
+ global $wp_version;
121
+
122
+ $src = isset($value->src) ? $value->src : false;
123
+
124
+ if (! $src || $this->skipMinify($src)) {
125
+ return array();
126
+ }
127
+
128
+ $handleDbStr = md5($value->handle);
129
+
130
+ $transientName = 'wpacu_js_minify_'.$handleDbStr;
131
+
132
+ $savedValues = get_transient( $transientName );
133
+
134
+ if ( $savedValues ) {
135
+ $savedValuesArray = json_decode( $savedValues, ARRAY_A );
136
+
137
+ if ( $savedValuesArray['ver'] !== $value->ver ) {
138
+ // New File Version? Delete transient as it will be re-added to the database with the new version
139
+ delete_transient( $transientName );
140
+ } else {
141
+ $localPathToJsMin = str_replace( '//', '/', ABSPATH . $savedValuesArray['min_uri'] );
142
+
143
+ // Do not load any minified JS file (from the database transient cache) if it doesn't exist
144
+ // It will fallback to the original JS file
145
+ if ( isset( $savedValuesArray['source_uri'] ) && file_exists( $localPathToJsMin ) ) {
146
+ return array(
147
+ $savedValuesArray['source_uri'],
148
+ $savedValuesArray['min_uri'],
149
+ );
150
+ }
151
+ }
152
+ }
153
+
154
+ if (strpos($src, '/wp-includes/') === 0) {
155
+ $src = site_url() . $src;
156
+ }
157
+
158
+ $localAssetPath = OptimizeCommon::getLocalAssetPath($src, 'js');
159
+
160
+ if (! file_exists($localAssetPath)) {
161
+ return array();
162
+ }
163
+
164
+ $assetHref = $value->src;
165
+
166
+ $posLastSlash = strrpos($assetHref, '/');
167
+ $pathToAssetDir = substr($assetHref, 0, $posLastSlash);
168
+
169
+ $parseUrl = parse_url($pathToAssetDir);
170
+
171
+ if (isset($parseUrl['scheme']) && $parseUrl['scheme'] !== '') {
172
+ $pathToAssetDir = str_replace(
173
+ array('http://'.$parseUrl['host'], 'https://'.$parseUrl['host']),
174
+ '',
175
+ $pathToAssetDir
176
+ );
177
+ } elseif (strpos($pathToAssetDir, '//') === 0) {
178
+ $pathToAssetDir = str_replace(
179
+ array('//'.$parseUrl['host'], '//'.$parseUrl['host']),
180
+ '',
181
+ $pathToAssetDir
182
+ );
183
+ }
184
+
185
+ $jsContent = @file_get_contents($localAssetPath);
186
+ $jsContent = OptimizeJs::maybeDoJsFixes($jsContent, $pathToAssetDir . '/'); // Minify it and save it to /wp-content/cache/js/min/
187
+
188
+ $jsContent = self::applyMinification($jsContent);
189
+
190
+ // Relative path to the new file
191
+ $ver = (isset($value->ver) && $value->ver) ? $value->ver : $wp_version;
192
+
193
+ $newFilePathUri = OptimizeJs::$relPathJsCacheDir . 'min/' . $value->handle . '-v' . $ver . '.js';
194
+
195
+ $newLocalPath = WP_CONTENT_DIR . $newFilePathUri; // Ful Local path
196
+ $newLocalPathUrl = WP_CONTENT_URL . $newFilePathUri; // Full URL path
197
+
198
+ $saveFile = @file_put_contents($newLocalPath, $jsContent);
199
+
200
+ if (! $saveFile || ! $jsContent) {
201
+ // Fallback to the original JS if the minified version can't be created or updated
202
+ return array();
203
+ }
204
+
205
+ $saveValues = array(
206
+ 'source_uri' => OptimizeCommon::getHrefRelPath($value->src),
207
+ 'min_uri' => OptimizeCommon::getHrefRelPath($newLocalPathUrl),
208
+ 'ver' => $ver
209
+ );
210
+
211
+ // Add / Re-add (with new version) transient
212
+ set_transient($transientName, json_encode($saveValues));
213
+
214
+ return array(
215
+ OptimizeCommon::getHrefRelPath($value->src),
216
+ OptimizeCommon::getHrefRelPath($newLocalPathUrl),
217
+ );
218
+ }
219
+
220
+ /**
221
+ * @param $jsContent
222
+ *
223
+ * @return string|string[]|null
224
+ */
225
+ public static function applyMinification($jsContent)
226
+ {
227
+ $jsContent = preg_replace(array("/\s+\n/", "/\n\s+/", '/ +/'), array("\n", "\n ", ' '), $jsContent);
228
+
229
+ // Going line by line
230
+ $jsContentsLines = explode( "\n", $jsContent );
231
+
232
+ $jsContent = '';
233
+
234
+ foreach ( $jsContentsLines as $jsLineIndex => $jsContentLine ) {
235
+ $jsContentLine = trim( $jsContentLine );
236
+
237
+ if (strpos(trim($jsContentLine), '//') === 0) {
238
+ continue;
239
+ }
240
+
241
+ $appendNewLine = true;
242
+ $mergeDelimiter = '';
243
+
244
+ if (strpos($jsContentLine, '//') !== false) {
245
+ $appendNewLine = true;
246
+ }
247
+
248
+ // When to keep the new line
249
+ elseif ( strpos( $jsContentLine, '/*' ) !== false
250
+ || strpos( $jsContentLine, '*/' ) !== false
251
+ || strpos( $jsContentLine, '*' ) === 0
252
+ || in_array(substr( trim( $jsContentLine ),
253
+ - 1 ), array('}', ')')) // Later, consider a solution to skip this from having a new line added
254
+ ) {
255
+ $appendNewLine = true;
256
+ } else {
257
+ $mergeDelimiter = in_array(
258
+ substr( trim( $jsContentLine ), - 1 ),
259
+ array( '{', '}', ';', ',' )
260
+ ) ? '' : ' ';
261
+ }
262
+
263
+ $jsContent .= self::basicReplacementOnLine($jsContentLine) . ($appendNewLine ? "\n" : $mergeDelimiter);
264
+ }
265
+
266
+ //return $jsContent;
267
+
268
+ /*
269
+ * Step 1: Make sure content between quotes (could be message alerts, plain text) is not replaced
270
+ * It will be replaced later on
271
+ */
272
+ preg_match_all("/(\"(.*?)\")|('(.*?)')/", $jsContent,$matchesBetweenQuotes);
273
+
274
+ $wpacuSpaceDel = '@[wpacu-plugin-space-del]@';
275
+
276
+ if (isset($matchesBetweenQuotes[0]) && ! empty($matchesBetweenQuotes[0])) {
277
+ foreach ($matchesBetweenQuotes[0] as $matchBetweenQuotes) {
278
+ if (strpos($matchBetweenQuotes, ' ') !== false) {
279
+ $newMatch = str_replace( ' ', $wpacuSpaceDel, $matchBetweenQuotes );
280
+ $jsContent = str_replace( $matchBetweenQuotes, $newMatch, $jsContent );
281
+ }
282
+ }
283
+ }
284
+
285
+ // Source: https://github.com/Letractively/samstyle-php-framework/blob/master/sp.php
286
+ $regex = array(
287
+ "`^([\t\s]+)`ism" => '',
288
+ "`^\/\*(.+?)\*\/`ism" => '',
289
+ "`([\n\A;]+)\/\*(.+?)\*\/`ism" => '$1',
290
+ "`([\n\A;\s]+)//(.+?)[\n\r]`ism" => "$1\n",
291
+ "`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism" => "\n",
292
+
293
+ "/}\);\n}\)/" => '});})',
294
+
295
+ "/([{|;|,]+)(\n+)('|\"|var|if|else|for|this|return|ready|jQuery|\\$|})/i" => '$1 $3',
296
+
297
+ '/} else {/i' => '}else{',
298
+ '/if \(/i' => 'if('
299
+ );
300
+
301
+ $jsContent = preg_replace(array_keys($regex), array_values($regex), $jsContent);
302
+
303
+ $newReps = array(
304
+ ";\n" => ';',
305
+ //",\n" => ',',
306
+ "}\n}" => '}}'
307
+ );
308
+
309
+ $jsContent = str_replace(array_keys($newReps), array_values($newReps), $jsContent);
310
+
311
+ /*
312
+ * Step: Make sure content between quotes (could be message alerts, plain text) is not replaced
313
+ * Restore the spacing between quotes
314
+ */
315
+ $jsContent = str_replace($wpacuSpaceDel, ' ', $jsContent);
316
+
317
+ // Remove whitespaces before and after the content
318
+ return trim($jsContent);
319
+ }
320
+
321
+ /**
322
+ * @param $jsContentLine
323
+ *
324
+ * @return mixed
325
+ */
326
+ public static function basicReplacementOnLine($jsContentLine)
327
+ {
328
+ // Regular Expression in the line? Don't make any changes
329
+ if ( strpos($jsContentLine, 'RegExp') !== false
330
+ || preg_match('/\=\s\//', $jsContentLine)) {
331
+ return $jsContentLine;
332
+ }
333
+
334
+ $repsOne = array(
335
+ // Remove space before & after colons
336
+ ' :' => ':',
337
+ ': ' => ':',
338
+
339
+ // Remove space before & after equal signs
340
+ ' =' => '=',
341
+ '= ' => '=',
342
+
343
+ "' ? '" => "'?'",
344
+ ') {' => '){',
345
+ ') !' => ')!'
346
+ );
347
+ $jsContentLine = str_replace(array_keys($repsOne), array_values($repsOne), $jsContentLine);
348
+
349
+ $repsTwo = array(
350
+ "{ '" => "{'",
351
+ "' }" => "'}",
352
+ ", '" => ",'",
353
+ ' || ' => '||',
354
+
355
+ '=true;' => '=!0;',
356
+ ':true;' => ':!0;',
357
+ '(true)' => '(!0)',
358
+ '(true,' => '(!0,',
359
+ 'return true;' => 'return !0;',
360
+ 'return true}' => 'return !0}',
361
+
362
+ '=false;' => '=!1;',
363
+ ':false;' => ':!1;',
364
+ '(false)' => '(!1)',
365
+ '(false,' => '(!1,',
366
+ 'return false;' => 'return !1;',
367
+ 'return false}' => 'return !1}',
368
+
369
+ );
370
+
371
+ $jsContentLine = str_ireplace(array_keys($repsTwo), array_values($repsTwo), $jsContentLine);
372
+
373
+ $repsThree = array(
374
+ '; ' => ';',
375
+ '{ ' => '{',
376
+ '} ' => '}',
377
+ '( ' => '(',
378
+ ' (' => '(',
379
+ ' )' => ')',
380
+ ') ' => ')',
381
+ ', ' => ',',
382
+ ' + ' => '+'
383
+ );
384
+
385
+ $jsContentLine = str_ireplace(array_keys($repsThree), array_values($repsThree), $jsContentLine);
386
+
387
+ return $jsContentLine;
388
+ }
389
+
390
+ /**
391
+ * @param $src
392
+ *
393
+ * @return bool
394
+ */
395
+ public function skipMinify($src)
396
+ {
397
+ $regExps = array(
398
+ '#/wp-content/plugins/wp-asset-clean-up(.*?).min.js#',
399
+
400
+ // Other libraries from the core that end in .min.js
401
+ '#/wp-includes/(.*?).min.js#',
402
+
403
+ // jQuery library
404
+ '#/wp-includes/js/jquery/jquery.js#'
405
+
406
+ );
407
+
408
+ if (Main::instance()->settings['minify_loaded_js_exceptions'] !== '') {
409
+ $loadedJsExceptionsPatterns = trim(Main::instance()->settings['minify_loaded_js_exceptions']);
410
+
411
+ if (strpos($loadedJsExceptionsPatterns, "\n")) {
412
+ // Multiple values (one per line)
413
+ foreach ($loadedJsExceptionsPatterns as $loadedJsExceptionPattern) {
414
+ $regExps[] = '#'.$loadedJsExceptionPattern.'#';
415
+ }
416
+ } else {
417
+ // Only one value?
418
+ $regExps[] = '#'.$loadedJsExceptionsPatterns.'#';
419
+ }
420
+ }
421
+
422
+ foreach ($regExps as $regExp) {
423
+ if ( preg_match( $regExp, $src ) ) {
424
+ return true;
425
+ }
426
+ }
427
+
428
+ return false;
429
+ }
430
+ }
classes/OptimiseAssets/OptimizeCommon.php CHANGED
@@ -139,17 +139,29 @@ class OptimizeCommon
139
  */
140
  public static function getLocalAssetPath($href, $assetType)
141
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  /*
143
  * Validate it first
144
  */
145
- // Asset's Host
146
  $assetHost = strtolower(parse_url($href, PHP_URL_HOST));
147
 
148
- // First check the host name
149
- $siteDbUrl = get_option('siteurl');
150
- $siteUrlHost = strtolower(parse_url($siteDbUrl, PHP_URL_HOST));
151
 
152
- // Different host name (most likely 3rd party one such as fonts.googleapis.com or a CDN)
153
  // Do not add it to the combine list
154
  if ($assetHost !== $siteUrlHost) {
155
  return false;
@@ -226,7 +238,7 @@ class OptimizeCommon
226
 
227
  $requestUriPart = $requestUri;
228
 
229
- if ($requestUri === '/') {
230
  $requestUriPart = '';
231
  }
232
 
@@ -242,11 +254,13 @@ class OptimizeCommon
242
  return array();
243
  }
244
 
245
- //if ($assetType === 'css') {
246
  $cachedAssetsFileExpiresIn = OptimizeCss::$cachedCssAssetsFileExpiresIn;
247
- //} else {
248
- // return array();
249
- //}
 
 
250
 
251
  // Delete cached file after it expired as it will be regenerated
252
  if (filemtime($assetsFile) < (time() - 1 * $cachedAssetsFileExpiresIn)) {
@@ -259,10 +273,14 @@ class OptimizeCommon
259
  if ($optionValue) {
260
  $optionValueArray = @json_decode($optionValue, ARRAY_A);
261
 
262
- if (! empty( $optionValueArray) && (isset($optionValueArray['head']['link_hrefs']) || isset($optionValueArray['body']['link_hrefs']))) {
263
- return $optionValueArray;
264
- }
265
- }
 
 
 
 
266
 
267
  // File exists, but it's invalid or outdated; Delete it as it has to be re-generated
268
  self::clearAssetCachedData($jsonStorageFile);
@@ -285,7 +303,7 @@ class OptimizeCommon
285
 
286
  $requestUriPart = $requestUri;
287
 
288
- if ($requestUri === '/') {
289
  $requestUriPart = '';
290
  }
291
 
@@ -301,7 +319,7 @@ class OptimizeCommon
301
 
302
  $assetsFile = $dirToFilename . self::filterStorageFileName($jsonStorageFile);
303
 
304
- // CSS JSON FILE DATA
305
  $assetsValue = $list;
306
 
307
  @file_put_contents($assetsFile, $assetsValue);
@@ -321,7 +339,7 @@ class OptimizeCommon
321
 
322
  $requestUriPart = $requestUri;
323
 
324
- if ($requestUri === '/') {
325
  $requestUriPart = '';
326
  }
327
 
@@ -355,9 +373,10 @@ class OptimizeCommon
355
  */
356
  $fileExtToRemove = array('.json');
357
 
358
- // Also delete .css
359
  if (! $keepAssetFiles) {
360
  $fileExtToRemove[] = '.css';
 
361
  }
362
 
363
  $assetCleanUpCacheDir = WP_CONTENT_DIR . self::$relPathPluginCacheDir;
@@ -373,10 +392,8 @@ class OptimizeCommon
373
 
374
  if ( is_file( $item ) && in_array( strrchr( $fileBaseName, '.' ), $fileExtToRemove ) ) {
375
  @unlink( $item );
376
- } else {
377
- if ( strpos( $item, $storageDir ) !== false && $item != $storageDir ) {
378
- $storageEmptyDirs[] = $item;
379
- }
380
  }
381
  }
382
 
@@ -425,17 +442,23 @@ class OptimizeCommon
425
  */
426
  public static function filterStorageFileName($fileName)
427
  {
 
 
 
 
 
 
428
  $current_user = wp_get_current_user();
429
 
430
  if (isset($current_user->ID) && $current_user->ID > 0) {
431
  $fileName = str_replace(
432
  '{maybe-extra-info}',
433
- '-logged-in-'.$current_user->ID,
434
  $fileName
435
  );
436
  } else {
437
  // Just clear {maybe-extra-info}
438
- $fileName = str_replace('{maybe-extra-info}', '', $fileName);
439
  }
440
 
441
  return $fileName;
139
  */
140
  public static function getLocalAssetPath($href, $assetType)
141
  {
142
+ // Check the host name
143
+ $siteDbUrl = get_option('siteurl');
144
+ $siteUrlHost = strtolower(parse_url($siteDbUrl, PHP_URL_HOST));
145
+
146
+ if (strpos($href, '//') === 0) {
147
+ list ($urlPrefix) = explode('//', $siteDbUrl);
148
+ $href = $urlPrefix . $href;
149
+ }
150
+
151
+ $externalHostsList = array(
152
+ 'fonts.googleapis.com'
153
+ );
154
+
155
  /*
156
  * Validate it first
157
  */
 
158
  $assetHost = strtolower(parse_url($href, PHP_URL_HOST));
159
 
160
+ if (in_array($assetHost, $externalHostsList)) {
161
+ return false;
162
+ }
163
 
164
+ // Different host name (most likely 3rd party one such as fonts.googleapis.com or an external CDN)
165
  // Do not add it to the combine list
166
  if ($assetHost !== $siteUrlHost) {
167
  return false;
238
 
239
  $requestUriPart = $requestUri;
240
 
241
+ if ($requestUri === '/' || is_404()) {
242
  $requestUriPart = '';
243
  }
244
 
254
  return array();
255
  }
256
 
257
+ if ($assetType === 'css') {
258
  $cachedAssetsFileExpiresIn = OptimizeCss::$cachedCssAssetsFileExpiresIn;
259
+ } elseif ($assetType === 'js') {
260
+ $cachedAssetsFileExpiresIn = OptimizeJs::$cachedJsAssetsFileExpiresIn;
261
+ } else {
262
+ return array();
263
+ }
264
 
265
  // Delete cached file after it expired as it will be regenerated
266
  if (filemtime($assetsFile) < (time() - 1 * $cachedAssetsFileExpiresIn)) {
273
  if ($optionValue) {
274
  $optionValueArray = @json_decode($optionValue, ARRAY_A);
275
 
276
+ if ($assetType === 'css' && ! empty( $optionValueArray) && (isset($optionValueArray['head']['link_hrefs']) || isset($optionValueArray['body']['link_hrefs']))) {
277
+ return $optionValueArray;
278
+ }
279
+
280
+ if ($assetType === 'js' && ! empty($optionValueArray)) {
281
+ return $optionValueArray;
282
+ }
283
+ }
284
 
285
  // File exists, but it's invalid or outdated; Delete it as it has to be re-generated
286
  self::clearAssetCachedData($jsonStorageFile);
303
 
304
  $requestUriPart = $requestUri;
305
 
306
+ if ($requestUri === '/' || is_404()) {
307
  $requestUriPart = '';
308
  }
309
 
319
 
320
  $assetsFile = $dirToFilename . self::filterStorageFileName($jsonStorageFile);
321
 
322
+ // CSS/JS JSON FILE DATA
323
  $assetsValue = $list;
324
 
325
  @file_put_contents($assetsFile, $assetsValue);
339
 
340
  $requestUriPart = $requestUri;
341
 
342
+ if ($requestUri === '/' || is_404()) {
343
  $requestUriPart = '';
344
  }
345
 
373
  */
374
  $fileExtToRemove = array('.json');
375
 
376
+ // Also delete .css & .js
377
  if (! $keepAssetFiles) {
378
  $fileExtToRemove[] = '.css';
379
+ $fileExtToRemove[] = '.js';
380
  }
381
 
382
  $assetCleanUpCacheDir = WP_CONTENT_DIR . self::$relPathPluginCacheDir;
392
 
393
  if ( is_file( $item ) && in_array( strrchr( $fileBaseName, '.' ), $fileExtToRemove ) ) {
394
  @unlink( $item );
395
+ } elseif ( strpos( $item, $storageDir ) !== false && $item != $storageDir ) {
396
+ $storageEmptyDirs[] = $item;
 
 
397
  }
398
  }
399
 
442
  */
443
  public static function filterStorageFileName($fileName)
444
  {
445
+ $filterString = '';
446
+
447
+ if (is_404()) {
448
+ $filterString = '-404-not-found';
449
+ }
450
+
451
  $current_user = wp_get_current_user();
452
 
453
  if (isset($current_user->ID) && $current_user->ID > 0) {
454
  $fileName = str_replace(
455
  '{maybe-extra-info}',
456
+ $filterString.'-logged-in-'.$current_user->ID,
457
  $fileName
458
  );
459
  } else {
460
  // Just clear {maybe-extra-info}
461
+ $fileName = str_replace('{maybe-extra-info}', $filterString, $fileName);
462
  }
463
 
464
  return $fileName;
classes/OptimiseAssets/OptimizeCss.php CHANGED
@@ -32,9 +32,13 @@ class OptimizeCss
32
  public function init()
33
  {
34
  add_action('wp_loaded', function() {
 
 
 
 
35
  ob_start(function ($htmlSource) {
36
  // Do not do any optimization if "Test Mode" is Enabled
37
- if (Main::instance()->settings['test_mode'] && ! Menu::userCanManageAssets()) {
38
  return $htmlSource;
39
  }
40
 
@@ -86,8 +90,8 @@ class OptimizeCss
86
  OptimizeCommon::clearAssetCachedData( $this->jsonStorageFile );
87
 
88
  // Fetch the DOM, and then set a new transient
89
- $document = new \DOMDocument();
90
- $document->loadHTML( $htmlSource );
91
  libxml_use_internal_errors( true );
92
 
93
  $storageJsonContents = array();
@@ -95,7 +99,7 @@ class OptimizeCss
95
  foreach ( array( 'head', 'body' ) as $docLocationTag ) {
96
  $combinedUriPaths = $hrefUriNotCombinableList = $localAssetsPaths = $linkHrefs = array();
97
 
98
- $docLocationElements = $document->getElementsByTagName( $docLocationTag )->item( 0 );
99
  $linkTags = $docLocationElements->getElementsByTagName( 'link' );
100
 
101
  if ( $linkTags === null ) {
@@ -194,7 +198,7 @@ class OptimizeCss
194
  }
195
 
196
  $maybeDoCssCombine = $this->maybeDoCssCombine( sha1( implode( '', $combinedUriPaths ) ),
197
- $localAssetsPaths );
198
 
199
  // Local path to combined CSS file
200
  $localFinalCssFile = $maybeDoCssCombine['local_final_css_file'];
@@ -202,6 +206,9 @@ class OptimizeCss
202
  // URI (e.g. /wp-content/cache/asset-cleanup/[file-name-here.css]) to the combined CSS file
203
  $uriToFinalCssFile = $maybeDoCssCombine['uri_final_css_file'];
204
 
 
 
 
205
  if ( file_exists( $localFinalCssFile ) ) {
206
  $storageJsonContents[$docLocationTag] = array(
207
  'uri_to_final_css_file' => $uriToFinalCssFile,
@@ -286,10 +293,11 @@ HTML;
286
  /**
287
  * @param $shaOneCombinedUriPaths
288
  * @param $localAssetsPaths
 
289
  *
290
  * @return array
291
  */
292
- public function maybeDoCssCombine($shaOneCombinedUriPaths, $localAssetsPaths)
293
  {
294
  $current_user = wp_get_current_user();
295
  $dirToUserCachedFile = ((isset($current_user->ID) && $current_user->ID > 0) ? 'logged-in/'.$current_user->ID.'/' : '');
@@ -303,7 +311,9 @@ HTML;
303
  // If "?ver" value changes on any of the assets or the asset list changes in any way
304
  // then $shaOneCombinedUriPaths will change too and a new CSS file will be generated and loaded
305
 
306
- if (! file_exists($localFinalCssFile)) {
 
 
307
  // Change $assetsContents as paths to fonts and images that are relative (e.g. ../, ../../) have to be updated
308
  $finalAssetsContents = '';
309
 
@@ -330,6 +340,14 @@ HTML;
330
  $assetContent = @file_get_contents($localAssetsPath);
331
 
332
  if ($assetContent) {
 
 
 
 
 
 
 
 
333
  $finalAssetsContents .= self::maybeFixCssBackgroundUrls($assetContent, $pathToAssetDir . '/') . "\n\n";
334
  }
335
  }
@@ -348,7 +366,8 @@ HTML;
348
 
349
  return array(
350
  'uri_final_css_file' => $uriToFinalCssFile,
351
- 'local_final_css_file' => $localFinalCssFile
 
352
  );
353
  }
354
 
32
  public function init()
33
  {
34
  add_action('wp_loaded', function() {
35
+ if (is_admin()) { // don't apply any changes if not in the front-end view (e.g. Dashboard view)
36
+ return;
37
+ }
38
+
39
  ob_start(function ($htmlSource) {
40
  // Do not do any optimization if "Test Mode" is Enabled
41
+ if (! Menu::userCanManageAssets() && Main::instance()->settings['test_mode']) {
42
  return $htmlSource;
43
  }
44
 
90
  OptimizeCommon::clearAssetCachedData( $this->jsonStorageFile );
91
 
92
  // Fetch the DOM, and then set a new transient
93
+ $documentForCSS = new \DOMDocument();
94
+ $documentForCSS->loadHTML( $htmlSource );
95
  libxml_use_internal_errors( true );
96
 
97
  $storageJsonContents = array();
99
  foreach ( array( 'head', 'body' ) as $docLocationTag ) {
100
  $combinedUriPaths = $hrefUriNotCombinableList = $localAssetsPaths = $linkHrefs = array();
101
 
102
+ $docLocationElements = $documentForCSS->getElementsByTagName( $docLocationTag )->item( 0 );
103
  $linkTags = $docLocationElements->getElementsByTagName( 'link' );
104
 
105
  if ( $linkTags === null ) {
198
  }
199
 
200
  $maybeDoCssCombine = $this->maybeDoCssCombine( sha1( implode( '', $combinedUriPaths ) ),
201
+ $localAssetsPaths, $linkHrefs );
202
 
203
  // Local path to combined CSS file
204
  $localFinalCssFile = $maybeDoCssCombine['local_final_css_file'];
206
  // URI (e.g. /wp-content/cache/asset-cleanup/[file-name-here.css]) to the combined CSS file
207
  $uriToFinalCssFile = $maybeDoCssCombine['uri_final_css_file'];
208
 
209
+ // Any link hrefs removed perhaps if the file wasn't combined?
210
+ $linkHrefs = $maybeDoCssCombine['link_hrefs'];
211
+
212
  if ( file_exists( $localFinalCssFile ) ) {
213
  $storageJsonContents[$docLocationTag] = array(
214
  'uri_to_final_css_file' => $uriToFinalCssFile,
293
  /**
294
  * @param $shaOneCombinedUriPaths
295
  * @param $localAssetsPaths
296
+ * @param $linkHrefs
297
  *
298
  * @return array
299
  */
300
+ public function maybeDoCssCombine($shaOneCombinedUriPaths, $localAssetsPaths, $linkHrefs)
301
  {
302
  $current_user = wp_get_current_user();
303
  $dirToUserCachedFile = ((isset($current_user->ID) && $current_user->ID > 0) ? 'logged-in/'.$current_user->ID.'/' : '');
311
  // If "?ver" value changes on any of the assets or the asset list changes in any way
312
  // then $shaOneCombinedUriPaths will change too and a new CSS file will be generated and loaded
313
 
314
+ $skipIfFileExists = true;
315
+
316
+ if ($skipIfFileExists || ! file_exists($localFinalCssFile)) {
317
  // Change $assetsContents as paths to fonts and images that are relative (e.g. ../, ../../) have to be updated
318
  $finalAssetsContents = '';
319
 
340
  $assetContent = @file_get_contents($localAssetsPath);
341
 
342
  if ($assetContent) {
343
+ // Do not combine it if it contains "@import"
344
+ if (stripos($assetContent, '@import') !== false) {
345
+ unset($localAssetsPaths[$assetHref]);
346
+ $linkHrefKey = array_search($assetHref, $linkHrefs);
347
+ unset($linkHrefs[$linkHrefKey]);
348
+ continue;
349
+ }
350
+
351
  $finalAssetsContents .= self::maybeFixCssBackgroundUrls($assetContent, $pathToAssetDir . '/') . "\n\n";
352
  }
353
  }
366
 
367
  return array(
368
  'uri_final_css_file' => $uriToFinalCssFile,
369
+ 'local_final_css_file' => $localFinalCssFile,
370
+ 'link_hrefs' => $linkHrefs
371
  );
372
  }
373
 
classes/OptimiseAssets/OptimizeJs.php ADDED
@@ -0,0 +1,605 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WpAssetCleanUp\OptimiseAssets;
3
+
4
+ use WpAssetCleanUp\Main;
5
+ use WpAssetCleanUp\Menu;
6
+ use WpAssetCleanUp\MetaBoxes;
7
+ use WpAssetCleanUp\Misc;
8
+
9
+ /**
10
+ * Class CombineJs
11
+ * @package WpAssetCleanUp
12
+ */
13
+ class OptimizeJs
14
+ {
15
+ /**
16
+ * @var string
17
+ */
18
+ public static $relPathJsCacheDir = '/cache/asset-cleanup/js/'; // keep trailing slash at the end
19
+
20
+ /**
21
+ * @var float|int
22
+ */
23
+ public static $cachedJsAssetsFileExpiresIn = 28800; // 8 hours in seconds (60 * 60 * 8)
24
+
25
+ /**
26
+ * @var string
27
+ */
28
+ public $jsonStorageFile = 'js-combined{maybe-extra-info}.json';
29
+
30
+ /**
31
+ *
32
+ */
33
+ public function init()
34
+ {
35
+ add_action('wp_loaded', function() {
36
+ if (is_admin()) { // don't apply any changes if not in the front-end view (e.g. Dashboard view)
37
+ return;
38
+ }
39
+
40
+ ob_start(function($htmlSource) {
41
+ // Do not do any optimization if "Test Mode" is Enabled
42
+ if (! Menu::userCanManageAssets() && Main::instance()->settings['test_mode']) {
43
+ return $htmlSource;
44
+ }
45
+
46
+ // There has to be at least one "<script", otherwise, it could be a feed request or something similar (not page, post, homepage etc.)
47
+ if (stripos($htmlSource, '<script') === false) {
48
+ return $htmlSource;
49
+ }
50
+
51
+ /*
52
+ * #minifying
53
+ * STEP 2: Load minify-able caching list and replace the original source URLs with the new cached ones
54
+ */
55
+ if (Main::instance()->settings['minify_loaded_js']) {
56
+ // 'wpacu_js_minify_list' caching list is also checked; if it's empty, no minification is made
57
+ $htmlSource = MinifyJs::updateHtmlSourceOriginalToMinJs( $htmlSource );
58
+ }
59
+
60
+ if ( array_key_exists('wpacu_no_js_combine', $_GET) || // not on query string request (debugging purposes)
61
+ ! $this->doJsCombine() ) {
62
+ return $htmlSource;
63
+ }
64
+
65
+ // If "Do not combine CSS on this page" is checked in "Asset CleanUp Options" side meta box
66
+ // Works for posts, pages and custom post types
67
+ if (defined('WPACU_CURRENT_PAGE_ID') && WPACU_CURRENT_PAGE_ID > 0) {
68
+ $pageOptions = MetaBoxes::getPageOptions( WPACU_CURRENT_PAGE_ID );
69
+
70
+ if ( isset( $pageOptions['no_js_optimize'] ) && $pageOptions['no_js_optimize'] ) {
71
+ return $htmlSource;
72
+ }
73
+ }
74
+
75
+ $useDom = function_exists('libxml_use_internal_errors') && function_exists('libxml_clear_errors') && class_exists('DOMDocument');
76
+
77
+ if (! $useDom) {
78
+ return $htmlSource;
79
+ }
80
+
81
+ $combineLevel = 2;
82
+
83
+ // Speed up processing by getting the already existing final CSS file URI
84
+ // This will avoid parsing the HTML DOM and determine the combined URI paths for all the CSS files
85
+ $finalCacheList = OptimizeCommon::getAssetCachedData($this->jsonStorageFile, self::$relPathJsCacheDir, 'js');
86
+
87
+ // $uriToFinalJsFile will always be relative ONLY within WP_CONTENT_DIR . self::$relPathJsCacheDir
88
+ // which is usually "wp-content/cache/asset-cleanup/js/"
89
+
90
+ // "false" would make it avoid checking the cache and always use the DOM Parser / RegExp
91
+ // for DEV purposes ONLY as it uses more resources
92
+ if (empty($finalCacheList)) {
93
+ /*
94
+ * NO CACHING TRANSIENT; Parse the DOM
95
+ */
96
+ // Nothing in the database records or the retrieved cached file does not exist?
97
+ OptimizeCommon::clearAssetCachedData($this->jsonStorageFile);
98
+
99
+ $regExpPattern = '#<script[^>]*>.*?</script>#is';
100
+
101
+ preg_match_all($regExpPattern, OptimizeCommon::cleanerHtmlSource($htmlSource), $matchesSourcesFromTags, PREG_SET_ORDER);
102
+
103
+ // No <script> tag found? Do not continue
104
+ if (empty($matchesSourcesFromTags)) {
105
+ return $htmlSource;
106
+ }
107
+
108
+ if ($combineLevel === 2) {
109
+ $matchesSourcesFromTags = $this->clearInlineScriptTags($matchesSourcesFromTags);
110
+ }
111
+
112
+ if (empty($matchesSourcesFromTags)) {
113
+ return $htmlSource;
114
+ }
115
+
116
+ $combinableList = $bodyGroupIndexes = array();
117
+
118
+ $groupIndex = 1;
119
+ $jQueryAndMigrateGroup = 0;
120
+
121
+ $jQueryGroupIndex = $loadsLocaljQuery = $loadsLocaljQueryMigrate = false;
122
+
123
+ $lastScriptSrcFromHead = $this->lastScriptSrcFromHead($htmlSource);
124
+
125
+ $reachedBody = false;
126
+
127
+ // Only keep combinable JS files
128
+ foreach ($matchesSourcesFromTags as $matchSourceFromTag) {
129
+ $matchedSourceFromTag = trim( $matchSourceFromTag[0] );
130
+
131
+ $domTag = new \DOMDocument();
132
+ $domTag->loadHTML($matchedSourceFromTag);
133
+
134
+ $hasSrc = $src = false;
135
+
136
+ foreach ($domTag->getElementsByTagName( 'script' ) as $tagObject) {
137
+ if (! $tagObject->hasAttributes()) {
138
+ continue;
139
+ }
140
+
141
+ foreach ( $tagObject->attributes as $attrObj ) {
142
+ if ($attrObj->nodeName === 'src' && $attrObj->nodeValue) {
143
+ $hasSrc = true;
144
+ $src = (string) $attrObj->nodeValue;
145
+
146
+ if ($this->skipCombine($src)) {
147
+ $hasSrc = false;
148
+ break;
149
+ }
150
+ }
151
+
152
+ // Do not add it to the combination list if it has "async" or "defer" attributes
153
+ if (in_array($attrObj->nodeName, array('async', 'defer'))) {
154
+ $hasSrc = false;
155
+ break;
156
+ }
157
+ }
158
+
159
+ }
160
+
161
+ if ( $hasSrc ) {
162
+ $localAssetPath = OptimizeCommon::getLocalAssetPath( $src, 'js' );
163
+
164
+ if ( $localAssetPath ) {
165
+ $combinableList[ $groupIndex ][] = array(
166
+ 'src' => $src,
167
+ 'local' => $localAssetPath,
168
+ 'html' => $matchedSourceFromTag
169
+ );
170
+
171
+ if ( strpos( $localAssetPath, '/wp-includes/js/jquery/jquery.js' ) !== false ) {
172
+ $loadsLocaljQuery = true;
173
+ $jQueryGroupIndex = $groupIndex;
174
+
175
+ $jQueryArrayGroupKeys = array_keys( $combinableList[ $groupIndex ] );
176
+ $jQueryScriptIndex = array_pop( $jQueryArrayGroupKeys );
177
+
178
+ $jQueryAndMigrateGroup ++;
179
+ } elseif ( strpos( $localAssetPath,
180
+ '/wp-includes/js/jquery/jquery-migrate.' ) !== false ) {
181
+ $loadsLocaljQueryMigrate = true;
182
+ $jQueryAndMigrateGroup ++;
183
+ }
184
+ }
185
+
186
+ // We'll check the current group
187
+ // If we have jQuery and jQuery migrate, we will consider the group completed
188
+ // and we will move on to the next group
189
+ if ( $jQueryAndMigrateGroup > 1 ) {
190
+ $groupIndex ++;
191
+ $jQueryAndMigrateGroup = 0; // reset it to avoid having one file per group!
192
+ }
193
+
194
+ // Have we passed <head> and stumbled upon the first script tag from the <body>
195
+ // Then consider the group completed
196
+ if ($lastScriptSrcFromHead && ($src === $lastScriptSrcFromHead)) {
197
+ $groupIndex++;
198
+ $reachedBody = true;
199
+ }
200
+ } else {
201
+ $groupIndex ++;
202
+ }
203
+
204
+ if ($reachedBody && Main::instance()->settings['combine_loaded_js_defer_body']) {
205
+ $bodyGroupIndexes[] = $groupIndex;
206
+ }
207
+ }
208
+
209
+ // Is the page loading local jQuery but not local jQuery Migrate?
210
+ // Keep jQuery as standalone file (not in the combinable list)
211
+ if ( $loadsLocaljQuery && ! $loadsLocaljQueryMigrate && isset($jQueryScriptIndex) ) {
212
+ unset($combinableList[$jQueryGroupIndex][$jQueryScriptIndex]);
213
+ }
214
+
215
+ // Could be pages such as maintenance mode with no external JavaScript files
216
+ if (empty($combinableList)) {
217
+ return $htmlSource;
218
+ }
219
+
220
+ $groupNo = 1;
221
+
222
+ $finalCacheList = array();
223
+
224
+ foreach ($combinableList as $groupIndex => $groupFiles) {
225
+ // Any groups having one file? Then it's not really a group and the file should load on its own
226
+ // Could be one extra file besides the jQuery & jQuery Migrate group or the only JS file called within the HEAD
227
+ if (count($groupFiles) < 2) {
228
+ continue;
229
+ }
230
+
231
+ $combinedUriPaths = $localAssetsPaths = $groupScriptTags = $groupScriptSrcs = array();
232
+
233
+ foreach ( $groupFiles as $groupFileData ) {
234
+ $src = $groupFileData['src'];
235
+ $groupScriptSrcs[] = $src;
236
+ $combinedUriPaths[] = OptimizeCommon::getHrefRelPath( $src );
237
+ $localAssetsPaths[ $src ] = $groupFileData['local'];
238
+ $groupScriptTags[] = $groupFileData['html'];
239
+ }
240
+
241
+ $maybeDoJsCombine = $this->maybeDoJsCombine(
242
+ sha1( implode( '', $combinedUriPaths ) ) . '-' . $groupNo,
243
+ $localAssetsPaths
244
+ );
245
+
246
+ // Local path to combined CSS file
247
+ $localFinalJsFile = $maybeDoJsCombine['local_final_js_file'];
248
+
249
+ // URI (e.g. /wp-content/cache/asset-cleanup/[file-name-here.js]) to the combined JS file
250
+ $uriToFinalJsFile = $maybeDoJsCombine['uri_final_js_file'];
251
+
252
+ if ( ! file_exists( $localFinalJsFile ) ) {
253
+ return $htmlSource; // something is not right as the file wasn't created, we will return the original HTML source
254
+ }
255
+
256
+ $groupScriptSrcsFilter = array_map( function ( $src ) {
257
+ return str_replace( site_url(), '{site_url}', $src );
258
+ }, $groupScriptSrcs );
259
+
260
+ $groupScriptTagsFilter = array_map( function ( $scriptTag ) {
261
+ return str_replace( site_url(), '{site_url}', $scriptTag );
262
+ }, $groupScriptTags );
263
+
264
+ $finalCacheList[ $groupNo ] = array(
265
+ 'uri_to_final_js_file' => $uriToFinalJsFile,
266
+ 'script_srcs' => $groupScriptSrcsFilter,
267
+ 'script_tags' => $groupScriptTagsFilter
268
+ );
269
+
270
+ if (in_array($groupIndex, $bodyGroupIndexes)) {
271
+ $finalCacheList[ $groupNo ]['extras'][] = 'defer';
272
+ }
273
+
274
+ $groupNo++;
275
+ }
276
+
277
+ OptimizeCommon::setAssetCachedData($this->jsonStorageFile, self::$relPathJsCacheDir, json_encode($finalCacheList));
278
+ }
279
+
280
+ if (! empty($finalCacheList)) {
281
+ foreach ( $finalCacheList as $groupNo => $cachedValues ) {
282
+ $htmlSourceBeforeGroupReplacement = $htmlSource;
283
+
284
+ $uriToFinalJsFile = $cachedValues['uri_to_final_js_file'];
285
+
286
+ // Basic Combining (1) -> replace "first" tag with the final combination tag (there would be most likely multiple groups)
287
+ // Enhanced Combining (2) -> replace "last" tag with the final combination tag (most likely one group)
288
+ $indexReplacement = ($combineLevel === 2) ? (count($cachedValues['script_tags']) - 1) : 0;
289
+
290
+ $finalTagUrl = WP_CONTENT_URL . self::$relPathJsCacheDir . $uriToFinalJsFile;
291
+
292
+ $deferAttr = (isset($cachedValues['extras']) && in_array('defer', $cachedValues['extras'])) ? 'defer="defer"' : '';
293
+
294
+ $finalJsTag = <<<HTML
295
+ <script {$deferAttr} id='asset-cleanup-combined-js-group-{$groupNo}' type='text/javascript' src='{$finalTagUrl}'></script>
296
+ HTML;
297
+ $tagsStripped = 0;
298
+
299
+ foreach ( $cachedValues['script_tags'] as $groupScriptTagIndex => $scriptTag ) {
300
+ $scriptTag = str_replace( '{site_url}', site_url(), $scriptTag );
301
+
302
+ if ( $groupScriptTagIndex === $indexReplacement ) {
303
+ $htmlSourceBeforeTagReplacement = $htmlSource;
304
+ $htmlSource = $this->strReplaceOnce( $scriptTag, $finalJsTag, $htmlSource );
305
+ } else {
306
+ $htmlSourceBeforeTagReplacement = $htmlSource;
307
+ $htmlSource = $this->strReplaceOnce( $scriptTag, '', $htmlSource );
308
+ }
309
+
310
+ if ($htmlSource !== $htmlSourceBeforeTagReplacement) {
311
+ $tagsStripped++;
312
+ }
313
+ }
314
+
315
+ // At least two tags has have be stripped from the group to consider doing the group replacement
316
+ // If the tags weren't replaced it's likely there were changes to their structure after they were cached for the group merging
317
+ if ($tagsStripped < 2) {
318
+ $htmlSource = $htmlSourceBeforeGroupReplacement;
319
+ }
320
+ }
321
+ }
322
+
323
+ return $htmlSource;
324
+ });
325
+ }, 1);
326
+ }
327
+
328
+ /**
329
+ * @param $matchesSourcesFromTags
330
+ *
331
+ * @return mixed
332
+ */
333
+ public function clearInlineScriptTags($matchesSourcesFromTags)
334
+ {
335
+ foreach ($matchesSourcesFromTags as $scriptTagIndex => $matchSourceFromTag) {
336
+ $matchedSourceFromTag = trim( $matchSourceFromTag[0] );
337
+
338
+ $domTag = new \DOMDocument();
339
+ $domTag->loadHTML( $matchedSourceFromTag );
340
+
341
+ foreach ( $domTag->getElementsByTagName( 'script' ) as $tagObject ) {
342
+ $hasSrc = false;
343
+
344
+ if ( ! $tagObject->hasAttributes() ) {
345
+ $hasSrc = false;
346
+ } else {
347
+ // Has attributes? Check them
348
+ foreach ( $tagObject->attributes as $attrObj ) {
349
+ if ( $attrObj->nodeName === 'src' && $attrObj->nodeValue ) {
350
+ $hasSrc = true;
351
+ }
352
+ }
353
+ }
354
+
355
+ if (! $hasSrc) {
356
+ unset($matchesSourcesFromTags[$scriptTagIndex]);
357
+ }
358
+ }
359
+ }
360
+
361
+ return $matchesSourcesFromTags;
362
+ }
363
+
364
+ /**
365
+ * @param $htmlSource
366
+ *
367
+ * @return string
368
+ */
369
+ public function lastScriptSrcFromHead($htmlSource)
370
+ {
371
+ $bodyHtml = Misc::extractBetween( $htmlSource, '<head', '</head>' );
372
+
373
+ $regExpPattern = '#<script[^>]*>.*?</script>#is';
374
+
375
+ preg_match_all( $regExpPattern, $bodyHtml, $matchesSourcesFromTags, PREG_SET_ORDER );
376
+
377
+ // Only keep combinable JS files
378
+ foreach ( array_reverse($matchesSourcesFromTags) as $matchSourceFromTag ) {
379
+ $matchedSourceFromTag = trim( $matchSourceFromTag[0] );
380
+
381
+ $domTag = new \DOMDocument();
382
+ $domTag->loadHTML( $matchedSourceFromTag );
383
+
384
+ foreach ( $domTag->getElementsByTagName( 'script' ) as $tagObject ) {
385
+ if ( ! $tagObject->hasAttributes() ) {
386
+ continue;
387
+ }
388
+
389
+ foreach ( $tagObject->attributes as $attrObj ) {
390
+ if ( $attrObj->nodeName === 'src' && $attrObj->nodeValue ) {
391
+ return (string) $attrObj->nodeValue;
392
+ break;
393
+ }
394
+ }
395
+ }
396
+ }
397
+
398
+ return '';
399
+ }
400
+
401
+ /**
402
+ * @param $shaOneCombinedUriPaths
403
+ * @param $localAssetsPaths
404
+ *
405
+ * @return array
406
+ */
407
+ public function maybeDoJsCombine($shaOneCombinedUriPaths, $localAssetsPaths)
408
+ {
409
+ $current_user = wp_get_current_user();
410
+ $dirToUserCachedFile = ((isset($current_user->ID) && $current_user->ID > 0) ? 'logged-in/'.$current_user->ID.'/' : '');
411
+
412
+ $uriToFinalJsFile = $dirToUserCachedFile . $shaOneCombinedUriPaths . '.js';
413
+
414
+ $localFinalJsFile = WP_CONTENT_DIR . self::$relPathJsCacheDir . $uriToFinalJsFile;
415
+ $localDirForJsFile = WP_CONTENT_DIR . self::$relPathJsCacheDir . $dirToUserCachedFile;
416
+
417
+ // Only combine if $shaOneCombinedUriPaths.js does not exist
418
+ // If "?ver" value changes on any of the assets or the asset list changes in any way
419
+ // then $shaOneCombinedUriPaths will change too and a new JS file will be generated and loaded
420
+
421
+ $skipIfFileExists = true;
422
+
423
+ if ($skipIfFileExists || ! file_exists($localFinalJsFile)) {
424
+ // Change $assetsContents as paths to fonts and images that are relative (e.g. ../, ../../) have to be updated
425
+ $finalJsContentsGroupsArray = array();
426
+
427
+ foreach ($localAssetsPaths as $assetHref => $localAssetsPath) {
428
+ $posLastSlash = strrpos($assetHref, '/');
429
+ $pathToAssetDir = substr($assetHref, 0, $posLastSlash);
430
+
431
+ $parseUrl = parse_url($pathToAssetDir);
432
+
433
+ if (isset($parseUrl['scheme']) && $parseUrl['scheme'] !== '') {
434
+ $pathToAssetDir = str_replace(
435
+ array('http://'.$parseUrl['host'], 'https://'.$parseUrl['host']),
436
+ '',
437
+ $pathToAssetDir
438
+ );
439
+ } elseif (strpos($pathToAssetDir, '//') === 0) {
440
+ $pathToAssetDir = str_replace(
441
+ array('//'.$parseUrl['host'], '//'.$parseUrl['host']),
442
+ '',
443
+ $pathToAssetDir
444
+ );
445
+ }
446
+
447
+ $jsContent = @file_get_contents($localAssetsPath);
448
+
449
+ if ($jsContent) {
450
+ $finalJsContentsIndex = 1;
451
+
452
+ $finalJsContentsGroupsArray[$finalJsContentsIndex][] = self::maybeDoJsFixes($jsContent, $pathToAssetDir . '/') . "\n\n";
453
+ }
454
+ }
455
+
456
+ if (! empty($finalJsContentsGroupsArray)) {
457
+ $finalJsContents = implode( '', $finalJsContentsGroupsArray[1] ) . implode( '',
458
+ $finalJsContentsGroupsArray[2] );
459
+
460
+ if ( $dirToUserCachedFile !== '' && isset( $current_user->ID ) && $current_user->ID > 0
461
+ && ! mkdir( $localDirForJsFile ) && ! is_dir( $localDirForJsFile) ) {
462
+ return array( 'uri_final_js_file' => '', 'local_final_js_file' => '' );
463
+ }
464
+
465
+ @file_put_contents( $localFinalJsFile, $finalJsContents );
466
+ }
467
+ }
468
+
469
+ return array(
470
+ 'uri_final_js_file' => $uriToFinalJsFile,
471
+ 'local_final_js_file' => $localFinalJsFile
472
+ );
473
+ }
474
+
475
+ /**
476
+ * @param $jsContent
477
+ * @param $appendBefore
478
+ *
479
+ * @return mixed
480
+ */
481
+ public static function maybeDoJsFixes($jsContent, $appendBefore)
482
+ {
483
+ // Relative URIs for CSS Paths
484
+ // For code such as:
485
+ // $(this).css("background", "url('../images/image-1.jpg')");
486
+ $jsContent = str_replace(
487
+ array('url("../', "url('../", 'url(../'),
488
+ array('url("'.$appendBefore.'../', "url('".$appendBefore.'../', 'url('.$appendBefore.'../'),
489
+ $jsContent
490
+ );
491
+
492
+ $jsContent = trim($jsContent);
493
+
494
+ if (substr($jsContent, -1) !== ';') {
495
+ $jsContent .= "\n" . ';'; // add semicolon as the last character
496
+ }
497
+ return $jsContent;
498
+ }
499
+
500
+ /**
501
+ * @param $src
502
+ *
503
+ * @return bool
504
+ */
505
+ public function skipCombine($src)
506
+ {
507
+ $regExps = array();
508
+
509
+ if (Main::instance()->settings['combine_loaded_js_exceptions'] !== '') {
510
+ $loadedCssExceptionsPatterns = trim(Main::instance()->settings['combine_loaded_js_exceptions']);
511
+
512
+ if (strpos($loadedCssExceptionsPatterns, "\n")) {
513
+ // Multiple values (one per line)
514
+ foreach (explode("\n", $loadedCssExceptionsPatterns) as $loadedCssExceptionPattern) {
515
+ $regExps[] = '#'.trim($loadedCssExceptionPattern).'#';
516
+ }
517
+ } else {
518
+ // Only one value?
519
+ $regExps[] = '#'.trim($loadedCssExceptionsPatterns).'#';
520
+ }
521
+ }
522
+
523
+ // No exceptions set? Do not skip combination
524
+ if (empty($regExps)) {
525
+ return false;
526
+ }
527
+
528
+ foreach ($regExps as $regExp) {
529
+ if ( preg_match( $regExp, $src ) ) {
530
+ // Skip combination
531
+ return true;
532
+ }
533
+ }
534
+
535
+ return false;
536
+ }
537
+
538
+ /**
539
+ * @return bool
540
+ */
541
+ public function doJsCombine()
542
+ {
543
+ // No JS files are combined in the Dashboard
544
+ // Always in the front-end view
545
+ // Do not combine if there's a POST request as there could be assets loading conditionally
546
+ // that might not be needed when the page is accessed without POST, making the final JS file larger
547
+ if (! empty($_POST) || is_admin()) {
548
+ return false; // Do not combine
549
+ }
550
+
551
+ // Only clean request URIs allowed (with few exceptions)
552
+ if (strpos($_SERVER['REQUEST_URI'], '?') !== false) {
553
+ // Exceptions
554
+ if (! OptimizeCommon::loadOptimizedAssetsIfQueryStrings()) {
555
+ return false;
556
+ }
557
+ }
558
+
559
+ if (! OptimizeCommon::doCombineIsRegularPage()) {
560
+ return false;
561
+ }
562
+
563
+ $pluginSettings = Main::instance()->settings;
564
+
565
+ if ($pluginSettings['test_mode'] && ! Menu::userCanManageAssets()) {
566
+ return false; // Do not combine anything if "Test Mode" is ON
567
+ }
568
+
569
+ if ($pluginSettings['combine_loaded_js'] === '') {
570
+ return false; // Do not combine
571
+ }
572
+
573
+ if ( ($pluginSettings['combine_loaded_js'] === 'for_admin'
574
+ || $pluginSettings['combine_loaded_js_for_admin_only'] == 1)
575
+ && Menu::userCanManageAssets() ) {
576
+ return true; // Do combine
577
+ }
578
+
579
+ if ( $pluginSettings['combine_loaded_js_for_admin_only'] === ''
580
+ && in_array($pluginSettings['combine_loaded_js'], array('for_all', 1)) ) {
581
+ return true; // Do combine
582
+ }
583
+
584
+ // Finally, return false as none of the checks above matched
585
+ return false;
586
+ }
587
+
588
+ /**
589
+ * @param $strFind
590
+ * @param $strReplaceWith
591
+ * @param $string
592
+ *
593
+ * @return mixed
594
+ */
595
+ public static function strReplaceOnce($strFind, $strReplaceWith, $string)
596
+ {
597
+ if ( strpos($string, $strFind) === false ) {
598
+ return $string;
599
+ }
600
+
601
+ $occurrence = strpos($string, $strFind);
602
+ return substr_replace($string, $strReplaceWith, $occurrence, strlen($strFind));
603
+ }
604
+
605
+ }
classes/Settings.php CHANGED
@@ -14,6 +14,8 @@ class Settings
14
  */
15
  public $settingsKeys = array(
16
  // Stored in 'wpassetcleanup_settings'
 
 
17
  'dashboard_show',
18
  'dom_get_type',
19
  'frontend_show',
@@ -27,20 +29,47 @@ class Settings
27
  'hide_core_files',
28
  'test_mode',
29
 
30
- // Combine loaded CSS (remaining ones after unloading the useless ones) into one file
31
  'combine_loaded_css',
32
  'combine_loaded_css_exceptions',
33
  'combine_loaded_css_for_admin_only',
34
 
 
 
 
 
 
 
35
  // Minify each loaded CSS (remaining ones after unloading the useless ones)
36
- 'minify_loaded_css',
37
- 'minify_loaded_css_exceptions',
 
 
 
 
38
 
39
  'disable_emojis',
40
 
41
  // Stored in 'wpassetcleanup_global_unload' option
42
  'disable_jquery_migrate',
43
- 'disable_comment_reply'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  );
45
 
46
  /**
@@ -66,6 +95,7 @@ class Settings
66
  'assets_list_inline_code_status' => 'contracted',
67
 
68
  'minify_loaded_css_exceptions' => '(.*?).min.css',
 
69
 
70
  'input_style' => 'enhanced',
71
 
14
  */
15
  public $settingsKeys = array(
16
  // Stored in 'wpassetcleanup_settings'
17
+ 'wiki_read',
18
+
19
  'dashboard_show',
20
  'dom_get_type',
21
  'frontend_show',
29
  'hide_core_files',
30
  'test_mode',
31
 
32
+ // Combine loaded CSS (remaining ones after unloading the useless ones) into fewer files
33
  'combine_loaded_css',
34
  'combine_loaded_css_exceptions',
35
  'combine_loaded_css_for_admin_only',
36
 
37
+ // Combine loaded JS (remaining ones after unloading the useless ones) into fewer files
38
+ 'combine_loaded_js',
39
+ 'combine_loaded_js_exceptions',
40
+ 'combine_loaded_js_for_admin_only',
41
+ 'combine_loaded_js_defer_body', // Applies defer="defer" to the combined file(s) within BODY tag
42
+
43
  // Minify each loaded CSS (remaining ones after unloading the useless ones)
44
+ 'minify_loaded_css',
45
+ 'minify_loaded_css_exceptions',
46
+
47
+ // Minify each loaded JS (remaining ones after unloading the useless ones)
48
+ 'minify_loaded_js',
49
+ 'minify_loaded_js_exceptions',
50
 
51
  'disable_emojis',
52
 
53
  // Stored in 'wpassetcleanup_global_unload' option
54
  'disable_jquery_migrate',
55
+ 'disable_comment_reply',
56
+
57
+ // <head> CleanUp
58
+ 'remove_rsd_link',
59
+ 'remove_wlw_link',
60
+ 'remove_rest_api_link',
61
+ 'remove_shortlink',
62
+ 'remove_posts_rel_links',
63
+ 'remove_wp_version',
64
+
65
+ // all "generator" meta tags including the WordPress version
66
+ 'remove_generator_tag',
67
+
68
+ // RSS Feed Links
69
+ 'remove_main_feed_link',
70
+ 'remove_comment_feed_link',
71
+
72
+ 'disable_xmlrpc'
73
  );
74
 
75
  /**
95
  'assets_list_inline_code_status' => 'contracted',
96
 
97
  'minify_loaded_css_exceptions' => '(.*?).min.css',
98
+ 'minify_loaded_js_exceptions' => '(.*?).min.js',
99
 
100
  'input_style' => 'enhanced',
101
 
classes/Tools.php CHANGED
@@ -144,7 +144,7 @@ class Tools
144
  // Must-use plugins.
145
  // NOTE: MU plugins can't show updates!
146
  $muplugins = get_mu_plugins();
147
- if ( count( $muplugins ) > 0 && ! empty( $muplugins ) ) {
148
  $return .= "\n" . '# Must-Use Plugins ("mu-plugins" directory)' . "\n";
149
 
150
  foreach ( $muplugins as $plugin => $plugin_data ) {
@@ -162,7 +162,7 @@ class Tools
162
  if ( ! in_array( $plugin_path, $active_plugins, true ) ) {
163
  continue;
164
  }
165
- $update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (new version available - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
166
  $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
167
  }
168
 
@@ -173,7 +173,7 @@ class Tools
173
  if ( in_array( $plugin_path, $active_plugins, true ) ) {
174
  continue;
175
  }
176
- $update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (new version available - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
177
  $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
178
  }
179
 
@@ -189,7 +189,7 @@ class Tools
189
  if ( ! array_key_exists( $plugin_base, $active_plugins ) ) {
190
  continue;
191
  }
192
- $update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (new version available - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
193
  $plugin = get_plugin_data( $plugin_path );
194
  $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
195
  }
@@ -290,15 +290,13 @@ class Tools
290
 
291
  $this->resetChoice = $wpacuResetValue;
292
 
293
- $resetStatus = false;
294
-
295
  if ($wpacuResetValue === 'reset_everything') {
296
  // `usermeta` and `termmeta` might have traces from the Pro version (if ever used)
297
  foreach (array('postmeta', 'usermeta', 'termmeta') as $tableBaseName) {
298
  $sqlQuery = <<<SQL
299
  DELETE FROM `{$wpdb->prefix}{$tableBaseName}` WHERE meta_key LIKE '_wpassetcleanup_%'
300
  SQL;
301
- $resetStatus = $wpdb->query($sqlQuery);
302
  }
303
 
304
  $sqlQuery = <<<SQL
@@ -306,7 +304,7 @@ DELETE FROM `{$wpdb->prefix}options`
306
  WHERE option_name LIKE 'wpassetcleanup_%'
307
  AND option_name NOT IN('wpassetcleanup_pro_license_key', 'wpassetcleanup_pro_license_status')
308
  SQL;
309
- $resetStatus = $wpdb->query($sqlQuery);
310
 
311
  delete_option(WPACU_PLUGIN_ID.'_do_activation_redirect_first_time');
312
 
@@ -326,18 +324,16 @@ SQL;
326
  $sqlQuery = <<<SQL
327
  DELETE FROM `{$wpdb->prefix}options` WHERE option_name='wpassetcleanup_settings'
328
  SQL;
329
- $resetStatus = $wpdb->query($sqlQuery);
330
  }
331
 
332
  // Also make 'jQuery Migrate' and 'Comment Reply' core files to load again
333
  // As they were enabled (not unloaded) in the default settings
334
- if ($resetStatus !== false) {
335
- $wpacuUpdate = new Update();
336
- $wpacuUpdate->removeEverywhereUnloads(
337
- array(),
338
- array('jquery-migrate' => 'remove', 'comment-reply' => 'remove')
339
- );
340
- }
341
 
342
  add_action('wpacu_admin_notices', array($this, 'resetDone'));
343
  }
144
  // Must-use plugins.
145
  // NOTE: MU plugins can't show updates!
146
  $muplugins = get_mu_plugins();
147
+ if ( ! empty( $muplugins ) && count( $muplugins ) > 0 ) {
148
  $return .= "\n" . '# Must-Use Plugins ("mu-plugins" directory)' . "\n";
149
 
150
  foreach ( $muplugins as $plugin => $plugin_data ) {
162
  if ( ! in_array( $plugin_path, $active_plugins, true ) ) {
163
  continue;
164
  }
165
+ $update = array_key_exists($plugin_path, $updates) ? ' (new version available - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
166
  $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
167
  }
168
 
173
  if ( in_array( $plugin_path, $active_plugins, true ) ) {
174
  continue;
175
  }
176
+ $update = array_key_exists($plugin_path, $updates) ? ' (new version available - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
177
  $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
178
  }
179
 
189
  if ( ! array_key_exists( $plugin_base, $active_plugins ) ) {
190
  continue;
191
  }
192
+ $update = array_key_exists($plugin_path, $updates) ? ' (new version available - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
193
  $plugin = get_plugin_data( $plugin_path );
194
  $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
195
  }
290
 
291
  $this->resetChoice = $wpacuResetValue;
292
 
 
 
293
  if ($wpacuResetValue === 'reset_everything') {
294
  // `usermeta` and `termmeta` might have traces from the Pro version (if ever used)
295
  foreach (array('postmeta', 'usermeta', 'termmeta') as $tableBaseName) {
296
  $sqlQuery = <<<SQL
297
  DELETE FROM `{$wpdb->prefix}{$tableBaseName}` WHERE meta_key LIKE '_wpassetcleanup_%'
298
  SQL;
299
+ $wpdb->query($sqlQuery);
300
  }
301
 
302
  $sqlQuery = <<<SQL
304
  WHERE option_name LIKE 'wpassetcleanup_%'
305
  AND option_name NOT IN('wpassetcleanup_pro_license_key', 'wpassetcleanup_pro_license_status')
306
  SQL;
307
+ $wpdb->query($sqlQuery);
308
 
309
  delete_option(WPACU_PLUGIN_ID.'_do_activation_redirect_first_time');
310
 
324
  $sqlQuery = <<<SQL
325
  DELETE FROM `{$wpdb->prefix}options` WHERE option_name='wpassetcleanup_settings'
326
  SQL;
327
+ $wpdb->query($sqlQuery);
328
  }
329
 
330
  // Also make 'jQuery Migrate' and 'Comment Reply' core files to load again
331
  // As they were enabled (not unloaded) in the default settings
332
+ $wpacuUpdate = new Update();
333
+ $wpacuUpdate->removeEverywhereUnloads(
334
+ array(),
335
+ array('jquery-migrate' => 'remove', 'comment-reply' => 'remove')
336
+ );
 
 
337
 
338
  add_action('wpacu_admin_notices', array($this, 'resetDone'));
339
  }
classes/Update.php CHANGED
@@ -56,7 +56,7 @@ HTML;
56
  public function init()
57
  {
58
  // Triggers on front-end view
59
- add_action('plugins_loaded', array($this, 'initAfterPluginsLoaded'), 11);
60
 
61
  // After post/page is saved - update your styles/scripts lists
62
  // This triggers ONLY in the Dashboard after "Update" button is clicked (on Edit mode)
@@ -66,7 +66,7 @@ HTML;
66
  /**
67
  *
68
  */
69
- public function initAfterPluginsLoaded()
70
  {
71
  if (! is_admin() && Main::instance()->settings['frontend_show']) {
72
  if (! empty($_POST)) {
@@ -120,7 +120,7 @@ HTML;
120
 
121
  // Form submitted from the homepage
122
  // e.g. from a page such as latest blog posts, not a static page that was selected as home page)
123
- if (Misc::isHomePage() && ! ($postId > 0)) {
124
  $wpacuNoLoadAssets = isset($_POST[WPACU_PLUGIN_ID])
125
  ? $_POST[WPACU_PLUGIN_ID] : array();
126
 
56
  public function init()
57
  {
58
  // Triggers on front-end view
59
+ add_action('init', array($this, 'triggersAfterInit'), 11);
60
 
61
  // After post/page is saved - update your styles/scripts lists
62
  // This triggers ONLY in the Dashboard after "Update" button is clicked (on Edit mode)
66
  /**
67
  *
68
  */
69
+ public function triggersAfterInit()
70
  {
71
  if (! is_admin() && Main::instance()->settings['frontend_show']) {
72
  if (! empty($_POST)) {
120
 
121
  // Form submitted from the homepage
122
  // e.g. from a page such as latest blog posts, not a static page that was selected as home page)
123
+ if (! ($postId > 0) && Misc::isHomePage()) {
124
  $wpacuNoLoadAssets = isset($_POST[WPACU_PLUGIN_ID])
125
  ? $_POST[WPACU_PLUGIN_ID] : array();
126
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: pagespeed, page speed, dequeue, performance, gtmetrix
4
  Donate link: https://gabelivan.com/items/wp-asset-cleanup-pro/?utm_source=wp_org_lite&utm_medium=donate
5
  Requires at least: 4.4
6
  Tested up to: 5.1
7
- Stable tag: 1.3.1
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl.html
10
 
@@ -23,11 +23,9 @@ For instance, you might use a plugin that generates contact forms and it loads i
23
 
24
  The plugin works best in combination with a cache plugin such as [WP Rocket](https://gabelivan.com/visit/wp-rocket).
25
 
26
- = This plugin's benefits include =
27
  * Decreases number of HTTP requests loaded (important for faster page load) by unloading useless CSS/JS
28
- * Minify loaded CSS files
29
- * Minify loaded JavaScript files (Pro version)
30
- * Combine loaded CSS & JavaScript files (after any minification) into fewer files to further reduce the number of HTTP Requests
31
  * Reduces the HTML code of the actual page (that's even better if GZIP compression is enabled)
32
  * Makes source code easier to scan in case you're a developer and want to search for something
33
  * Remove possible conflicts between plugins/theme (e.g. 2 JavaScript files that are loading from different plugins and they interfere one with another)
@@ -35,6 +33,21 @@ The plugin works best in combination with a cache plugin such as [WP Rocket](htt
35
  * Google will love your website more as it would be faster and fast page load is nowadays a factor in search ranking
36
  * Your server access log files (e.g the Apache ones) will be easier to scan and would take less space on your server
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  Plugin works with WordPress Multisite Network enabled!
39
 
40
  > <strong>Asset CleanUp Pro</strong><br />
@@ -44,7 +57,12 @@ Plugin works with WordPress Multisite Network enabled!
44
  People that have tested the plugin are so far happy with it and I want to keep a good reputation for it. In case something is not working for you or have any suggestions, please write to me on the forum and I will be happy to assist you. **BEFORE rating this plugin**, please check the following post http://chrislema.com/theres-wrong-way-give-plugin-feedback-wordpress-org/ and then use your common sense when writing the feedback :)
45
 
46
  = GO PRO =
47
- Give Asset CleanUp a try! If you want to unlock more features, you can <a href="https://gabelivan.com/items/wp-asset-cleanup-pro/?utm_source=wp_org_lite&utm_medium=go_pro">Upgrade to the Pro version</a>.
 
 
 
 
 
48
 
49
  == Installation ==
50
  * If you're planning to use the Lite version of the plugin:
@@ -77,9 +95,9 @@ Web assets are elements such as CSS, JavaScript, Fonts, and image files that mak
77
 
78
  No, Asset CleanUp does not do any page caching. It just helps you unload .css and .js that you choose as not needed from specific pages (or all pages). This, combined with an existing caching plugin, will make your website pages load faster and get a higher score in speed checking tools such as GTMetrix (Google PageSpeed and YSlow).
79
 
80
- = Has this plugin been tested with other caching / speed booster plugins?
81
 
82
- Yes, this plugin was tested with W3 Total Cache, WP Rocket and Autoptimize and should work with any caching plugin as any page should be cached only after the page (HTML Source) was rendered and all the enqueueing / dequeueing was already completed (from either the plugins or the theme).
83
 
84
  = I've noticed scripts and styles that are loaded on the page, but they do not show in the "Asset CleanUp" list when editing the page or no assets are showing at all. Why is that? =
85
 
@@ -135,6 +153,9 @@ With the recently released "Test Mode" feature, you can safely unload assets on
135
  4. Homepage CSS & JS Management (List sorted by location)
136
 
137
  == Changelog ==
 
 
 
138
  = 1.3.1 =
139
  * CSS Files within <body> are also combined just like the ones from <head>
140
  * Offer the option to clear the CSS/JS caching even if CSS/JS Minify/Combine options were deactivated
4
  Donate link: https://gabelivan.com/items/wp-asset-cleanup-pro/?utm_source=wp_org_lite&utm_medium=donate
5
  Requires at least: 4.4
6
  Tested up to: 5.1
7
+ Stable tag: 1.3.2
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl.html
10
 
23
 
24
  The plugin works best in combination with a cache plugin such as [WP Rocket](https://gabelivan.com/visit/wp-rocket).
25
 
26
+ = Main plugin's benefits include =
27
  * Decreases number of HTTP requests loaded (important for faster page load) by unloading useless CSS/JS
28
+ * Minify/Combine remaining loaded CSS/JavaScript files
 
 
29
  * Reduces the HTML code of the actual page (that's even better if GZIP compression is enabled)
30
  * Makes source code easier to scan in case you're a developer and want to search for something
31
  * Remove possible conflicts between plugins/theme (e.g. 2 JavaScript files that are loading from different plugins and they interfere one with another)
33
  * Google will love your website more as it would be faster and fast page load is nowadays a factor in search ranking
34
  * Your server access log files (e.g the Apache ones) will be easier to scan and would take less space on your server
35
 
36
+ = Remove useless links & meta tags within the <head> section of the website =
37
+ * Really Simple Discovery (RSD) link tag
38
+ * Windows Live Writer link tag
39
+ * REST API link tag
40
+ * Pages/Posts Shortlink tag
41
+ * Post's Relational Links tag
42
+ * WordPress version meta tag (also good for security reasons)
43
+ * All "generator" meta tags (also good for security reasons)
44
+ * RSS Feed Link Tags (usually they are not needed if your website is not used for blogging purposes)
45
+
46
+ Each that was just mentioned can be turned on/off depending on your needs. Instructions about each of them are given in the plugin's settings page.
47
+
48
+ = Disable partially or completely XML-RPC protocol =
49
+ This is an API service used by WordPress for 3rd party applications, such as mobile apps, communication between blogs and plugins such as Jetpack. If you use or are planning to use a remote system to post content to your website, you can keep this feature enabled (which it is by default). Many users do not use this function at all and if you’re one of them, you can disable it.
50
+
51
  Plugin works with WordPress Multisite Network enabled!
52
 
53
  > <strong>Asset CleanUp Pro</strong><br />
57
  People that have tested the plugin are so far happy with it and I want to keep a good reputation for it. In case something is not working for you or have any suggestions, please write to me on the forum and I will be happy to assist you. **BEFORE rating this plugin**, please check the following post http://chrislema.com/theres-wrong-way-give-plugin-feedback-wordpress-org/ and then use your common sense when writing the feedback :)
58
 
59
  = GO PRO =
60
+ * Unload CSS/JS files on all WordPress pages including Categories, Tags, Custom Taxonomy (e.g. WooCommerce product category), 404 Not Found, Date & Author Archives, Search Results)
61
+ * Change the location of the CSS/JS files (could be moved from HEAD to BODY to prevent render-blocking or vice-versa if you need early triggering of specific files)
62
+ * Async & Defer options for JavaScript files
63
+ * Premium support and updates within the Dashboard
64
+
65
+ Give Asset CleanUp a try! If you want to unlock all features, you can <a href="https://gabelivan.com/items/wp-asset-cleanup-pro/?utm_source=wp_org_lite&utm_medium=go_pro">Upgrade to the Pro version</a>.
66
 
67
  == Installation ==
68
  * If you're planning to use the Lite version of the plugin:
95
 
96
  No, Asset CleanUp does not do any page caching. It just helps you unload .css and .js that you choose as not needed from specific pages (or all pages). This, combined with an existing caching plugin, will make your website pages load faster and get a higher score in speed checking tools such as GTMetrix (Google PageSpeed and YSlow).
97
 
98
+ = Has this plugin been tested with other caching plugins?
99
 
100
+ Yes, this plugin was tested with W3 Total Cache, WP Rocket and WP Fastest Caching and should work with any caching plugin as any page should be cached only after the page (HTML Source) was rendered and all the enqueueing / dequeueing was already completed (from either the plugins or the theme). Asset CleanUp comes with minify/combine files feature. Please do not also enable the same feature on a caching plugin. Example: If you already minified CSS/JS files with Asset CleanUp, do not enable Minify CSS/JS in WP Rocket or other caching plugin.
101
 
102
  = I've noticed scripts and styles that are loaded on the page, but they do not show in the "Asset CleanUp" list when editing the page or no assets are showing at all. Why is that? =
103
 
153
  4. Homepage CSS & JS Management (List sorted by location)
154
 
155
  == Changelog ==
156
+ = 1.3.2 =
157
+ * Minify/Combine JS files & HEAD CleanUp features are now available in the Lite version
158
+
159
  = 1.3.1 =
160
  * CSS Files within <body> are also combined just like the ones from <head>
161
  * Offer the option to clear the CSS/JS caching even if CSS/JS Minify/Combine options were deactivated
templates/_admin-page-settings-plugin-areas/_combine-loaded-files.php CHANGED
@@ -23,28 +23,28 @@ $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-ce
23
  <p class="wpacu_subtitle"><small><em>Helps reducing the number of HTTP Requests even further</em></small></p>
24
  </th>
25
  <td>
26
- <label class="wpacu_switch">
27
- <input id="wpacu_combine_loaded_css_enable"
28
- type="checkbox"
29
  <?php echo (in_array($data['combine_loaded_css'], array('for_admin', 'for_all', 1)) ? 'checked="checked"' : ''); ?>
30
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_css]"
31
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
32
-
33
- <small>* if /wp-content/cache/ directory is not writable for some reason, this feature will not work; requires the DOMDocument XML DOM Parser to be enabled in PHP (which it is by default) for maximum performance</small>
34
-
35
- <div id="combine_loaded_css_info_area" <?php if (in_array($data['combine_loaded_css'], array('for_admin', 'for_all', 1))) { ?> style="opacity: 1;" <?php } else { ?>style="opacity: 0.4;"<?php } ?>>
36
- <p style="margin-top: 8px; padding: 10px; background: #f2faf2;">
37
- <label for="combine_loaded_css_for_admin_only_checkbox">
38
- <input id="combine_loaded_css_for_admin_only_checkbox"
39
  <?php echo ((in_array($data['combine_loaded_css_for_admin_only'], array('for_admin', 1))
40
  || $data['combine_loaded_css'] === 'for_admin')
41
  ? 'checked="checked"' : ''); ?>
42
- type="checkbox"
43
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_css_for_admin_only]"
44
- value="1" />
45
- Apply combination only for logged-in administrator (for debugging purposes)
46
- </label>
47
- </p>
48
 
49
  <div id="wpacu_combine_loaded_css_exceptions_area">
50
  <div style="margin: 0 0 6px;">Do not combine the CSS files matching the patterns below (one per line, see pattern examples below):</div>
@@ -76,38 +76,41 @@ $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-ce
76
  </td>
77
  </tr>
78
 
79
- <tr valign="top">
80
- <th scope="row" class="setting_title">
81
- <label for="wpacu_combine_loaded_js_enable">Combine loaded JS (JavaScript) into fewer files?</label>
82
- <p class="wpacu_subtitle"><small><em>Helps reducing the number of HTTP Requests even further</em></small></p>
83
- </th>
84
- <td>
85
- <?php echo $availableForPro; ?>
86
- <label class="wpacu_switch wpacu_locked_for_pro">
87
- <input id="wpacu_combine_loaded_js_enable"
88
- type="checkbox"
89
- disabled="disabled"
90
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_js]"
91
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
92
-
93
- &nbsp;<small>* if /wp-content/cache/ directory is not writable for some reason, this feature will not work; requires the DOMDocument XML DOM Parser to be enabled in PHP (which it is by default) for maximum performance</small>
94
-
95
- <div id="combine_loaded_js_info_area" style="opacity: 0.4;">
96
- <p style="margin-top: 8px; padding: 10px; background: #f2faf2;">
97
- <label for="combine_loaded_js_for_admin_only_checkbox">
98
- <input id="combine_loaded_js_for_admin_only_checkbox"
99
- type="checkbox"
100
- disabled="disabled"
101
- value="1" />
102
- Apply combination only for logged-in administrator (for debugging purposes)
103
- </label>
104
- </p>
 
 
105
 
106
  <p style="padding: 10px; background: #f2faf2;">
107
  <label for="wpacu_combine_loaded_js_defer_body_checkbox">
108
  <input id="wpacu_combine_loaded_js_defer_body_checkbox"
 
109
  type="checkbox"
110
- disabled="disabled"
111
  value="1" />
112
  Defer loading JavaScript combined files from <code>&lt;body&gt;</code> (applies <code>defer="defer"</code> attribute to the combined script tags)
113
  </label>
@@ -115,31 +118,57 @@ $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-ce
115
 
116
  <hr />
117
 
118
- <p>
119
- This results in as less JS combination groups as possible (this combines all JS files into 2/3 files, keeping their HEAD and BODY locations and most of the inline script tags before them for maximum compatibility)
120
- </p>
121
-
122
- <p>Any inline JavaScript code associated with the combined scripts, will not be altered or moved in any way.</p>
123
- <p><strong>Example:</strong> If you have 5 JS files (including jQuery library) loading in the <code>&lt;head&gt;</code> location and 7 JS files loading in <code>&lt;body&gt;</code> location, you will end up with a total of 3 JS files: jQuery library &amp; jQuery Migrate (they are not combined together with other JS files for maximum performance) in 1 file and the 2 JS files for HEAD and BODY, respectively.</p>
124
-
125
- <hr />
126
-
127
- <div class="clearfix"></div>
128
-
129
- <p><span style="color: #ffc107;" class="dashicons dashicons-lightbulb"></span> To be 100% sure everything works fine after activation, consider using the checkbox option above to apply the changes only for logged-in administrator (yourself). If all looks good, you can later uncheck so the changes will apply to everyone.</p>
130
 
131
- <hr />
 
132
 
133
- <p style="margin-bottom: -7px;"><span style="color: #ffc107;" class="dashicons dashicons-lightbulb"></span> Any scripts having "defer" or "async" attributes (which are there for a reason) will not be combined together with other render-blocking scripts.</p>
 
134
 
135
- <p style="margin-bottom: -7px; margin-top: 20px;"><span style="color: #ffc107;" class="dashicons dashicons-lightbulb"></span> This feature will not work <strong>IF</strong>:</p>
136
- <ul style="list-style: disc; margin-left: 35px; margin-bottom: 0;">
137
- <li>"Test Mode" is enabled and a guest (not logged-in) user visits the page, as the feature's ultimate purpose is to make the plugin inactive for non logged-in administrators for ultimate debugging.</li>
138
- <li>The URL has query strings (e.g. an URL such as //www.yourdomain.com/product/title-here/?param=1&amp;param_two=value_here)</li>
139
- </ul>
140
- </div>
141
- </td>
142
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  </table>
144
  </div>
145
 
23
  <p class="wpacu_subtitle"><small><em>Helps reducing the number of HTTP Requests even further</em></small></p>
24
  </th>
25
  <td>
26
+ <label class="wpacu_switch">
27
+ <input id="wpacu_combine_loaded_css_enable"
28
+ type="checkbox"
29
  <?php echo (in_array($data['combine_loaded_css'], array('for_admin', 'for_all', 1)) ? 'checked="checked"' : ''); ?>
30
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_css]"
31
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
32
+
33
+ &nbsp;<small>* if /wp-content/cache/ directory is not writable for some reason, this feature will not work; requires the DOMDocument XML DOM Parser to be enabled in PHP (which it is by default) for maximum performance</small>
34
+ &nbsp;
35
+ <div id="combine_loaded_css_info_area" <?php if (in_array($data['combine_loaded_css'], array('for_admin', 'for_all', 1))) { ?> style="opacity: 1;" <?php } else { ?>style="opacity: 0.4;"<?php } ?>>
36
+ <p style="margin-top: 8px; padding: 10px; background: #f2faf2;">
37
+ <label for="combine_loaded_css_for_admin_only_checkbox">
38
+ <input id="combine_loaded_css_for_admin_only_checkbox"
39
  <?php echo ((in_array($data['combine_loaded_css_for_admin_only'], array('for_admin', 1))
40
  || $data['combine_loaded_css'] === 'for_admin')
41
  ? 'checked="checked"' : ''); ?>
42
+ type="checkbox"
43
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_css_for_admin_only]"
44
+ value="1" />
45
+ Apply combination only for logged-in administrator (for debugging purposes)
46
+ </label>
47
+ </p>
48
 
49
  <div id="wpacu_combine_loaded_css_exceptions_area">
50
  <div style="margin: 0 0 6px;">Do not combine the CSS files matching the patterns below (one per line, see pattern examples below):</div>
76
  </td>
77
  </tr>
78
 
79
+ <tr valign="top">
80
+ <th scope="row" class="setting_title">
81
+ <label for="wpacu_combine_loaded_js_enable">Combine loaded JS (JavaScript) into fewer files?</label>
82
+ <p class="wpacu_subtitle"><small><em>Helps reducing the number of HTTP Requests even further</em></small></p>
83
+ </th>
84
+ <td>
85
+ <label class="wpacu_switch">
86
+ <input id="wpacu_combine_loaded_js_enable"
87
+ type="checkbox"
88
+ <?php echo (in_array($data['combine_loaded_js'], array('for_admin', 'for_all', 1)) ? 'checked="checked"' : ''); ?>
89
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_js]"
90
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
91
+
92
+ &nbsp;<small>* if /wp-content/cache/ directory is not writable for some reason, this feature will not work; requires the DOMDocument XML DOM Parser to be enabled in PHP (which it is by default) for maximum performance</small>
93
+
94
+ <div id="combine_loaded_js_info_area" <?php if (in_array($data['combine_loaded_js'], array('for_admin', 'for_all', 1))) { ?> style="opacity: 1;" <?php } else { ?>style="opacity: 0.4;"<?php } ?>>
95
+ <p style="margin-top: 8px; padding: 10px; background: #f2faf2;">
96
+ <label for="combine_loaded_js_for_admin_only_checkbox">
97
+ <input id="combine_loaded_js_for_admin_only_checkbox"
98
+ <?php echo ((in_array($data['combine_loaded_js_for_admin_only'], array('for_admin', 1))
99
+ || $data['combine_loaded_js'] === 'for_admin')
100
+ ? 'checked="checked"' : ''); ?>
101
+ type="checkbox"
102
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_js_for_admin_only]"
103
+ value="1" />
104
+ Apply combination only for logged-in administrator (for debugging purposes)
105
+ </label>
106
+ </p>
107
 
108
  <p style="padding: 10px; background: #f2faf2;">
109
  <label for="wpacu_combine_loaded_js_defer_body_checkbox">
110
  <input id="wpacu_combine_loaded_js_defer_body_checkbox"
111
+ <?php echo (($data['combine_loaded_js_defer_body'] == 1) ? 'checked="checked"' : ''); ?>
112
  type="checkbox"
113
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_js_defer_body]"
114
  value="1" />
115
  Defer loading JavaScript combined files from <code>&lt;body&gt;</code> (applies <code>defer="defer"</code> attribute to the combined script tags)
116
  </label>
118
 
119
  <hr />
120
 
121
+ <div id="wpacu_combine_loaded_js_exceptions_area">
122
+ <div style="margin: 0 0 6px;">Do not combine the JavaScript files matching the patterns below (one per line, see pattern examples below):</div>
123
+ <label for="combine_loaded_js_exceptions">
124
+ <textarea style="width: 100%;"
125
+ rows="4"
126
+ id="combine_loaded_js_exceptions"
127
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[combine_loaded_js_exceptions]"><?php echo $data['combine_loaded_js_exceptions']; ?></textarea>
128
+ </label>
 
 
 
 
129
 
130
+ <p>Pattern Examples (you don't have to add the full URL, as it's recommended to use relative paths):</p>
131
+ <code>/wp-includes/js/admin-bar.min.js<br />/wp-includes/js/masonry.min.js<br />/wp-content/plugins/plugin-title/js/(.*?).js</code>
132
 
133
+ <div style="margin-top: 15px; margin-bottom: 0;"><hr /></div>
134
+ </div>
135
 
136
+ <!--
137
+ -->
138
+ <p>
139
+ This results in as less JS combination groups as possible (this combines all JS files into 2/3 files, keeping their HEAD and BODY locations and most of the inline script tags before them for maximum compatibility) - <a id="wpacu-combine-js-method-info-link" href="#wpacu-combine-js-method-info">Read more</a>
140
+ </p>
141
+
142
+ <hr />
143
+
144
+ <div class="clearfix"></div>
145
+
146
+ <p><span style="color: #ffc107;" class="dashicons dashicons-lightbulb"></span> To be 100% sure everything works fine after activation, consider using the checkbox option above to apply the changes only for logged-in administrator (yourself). If all looks good, you can later uncheck so the changes will apply to everyone.</p>
147
+
148
+ <hr />
149
+
150
+ <p style="margin-bottom: -7px;"><span style="color: #ffc107;" class="dashicons dashicons-lightbulb"></span> Any scripts having "defer" or "async" attributes (which are there for a reason) will not be combined together with other render-blocking scripts.</p>
151
+
152
+ <p style="margin-bottom: -7px; margin-top: 20px;"><span style="color: #ffc107;" class="dashicons dashicons-lightbulb"></span> This feature will not work <strong>IF</strong>:</p>
153
+ <ul style="list-style: disc; margin-left: 35px; margin-bottom: 0;">
154
+ <li>"Test Mode" is enabled and a guest (not logged-in) user visits the page, as the feature's ultimate purpose is to make the plugin inactive for non logged-in administrators for ultimate debugging.</li>
155
+ <li>The URL has query strings (e.g. an URL such as //www.yourdomain.com/product/title-here/?param=1&amp;param_two=value_here)</li>
156
+ </ul>
157
+ </div>
158
+
159
+ <!--
160
+ -->
161
+ <div id="wpacu-combine-js-method-info" class="wpacu-modal">
162
+ <div class="wpacu-modal-content">
163
+ <span class="wpacu-close">&times;</span>
164
+ <h2>How the JavaScript files are combined?</h2>
165
+ <p style="margin-top: 0;">Scans the remaining JavaScript files (left after cleaning up the unnecessary ones) from the <code>&lt;head&gt;</code> and <code>&lt;body&gt;</code> locations and combines them into one file per each location.</p>
166
+ <p>Any inline JavaScript code associated with the combined scripts, will not be altered or moved in any way.</p>
167
+ <p><strong>Example:</strong> If you have 5 JS files (including jQuery library) loading in the <code>&lt;head&gt;</code> location and 7 JS files loading in <code>&lt;body&gt;</code> location, you will end up with a total of 3 JS files: jQuery library &amp; jQuery Migrate (they are not combined together with other JS files for maximum performance) in 1 file and the 2 JS files for HEAD and BODY, respectively.</p>
168
+ </div>
169
+ </div>
170
+ </td>
171
+ </tr>
172
  </table>
173
  </div>
174
 
templates/_admin-page-settings-plugin-areas/_disable-xml-rpc-protocol.php CHANGED
@@ -10,21 +10,30 @@ $tabIdArea = 'wpacu-setting-disable-xml-rpc';
10
  $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-cell;"' : '';
11
  ?>
12
  <div id="<?php echo $tabIdArea; ?>" class="wpacu-settings-tab-content" <?php echo $styleTabContent; ?>>
13
- <h2><?php _e('Disable XML-RPC Protocol Support partially or completely', WPACU_PLUGIN_TEXT_DOMAIN); ?></h2>
14
- <p><?php echo $settingsWithLock; ?></p>
15
- <table class="wpacu-form-table">
16
- <!-- Disable "XML-RPC" protocol support? -->
17
- <tr valign="top">
18
- <td>
19
- <?php echo $availableForPro; ?>
20
- <code>&lt;link rel=&quot;pingback&quot; href=&quot;https://www.yourwebsite.com/xmlrpc.php&quot; /&gt;</code>
21
- <p style="margin-bottom: 10px;">This will disable XML-RPC protocol support and cleans up the "pingback" tag from the HEAD section of your website.</p>
22
- <p style="margin-bottom: 10px;">This is an API service used by WordPress for 3rd party applications, such as mobile apps, communication between blogs, plugins such as Jetpack. If you use, or are planning to use a remote system to post content to your website, you can keep this feature enabled (which it is by default). Many users do not use this function at all and if you're one of them, you can disable it.</p>
23
 
24
- <p style="margin-bottom: 10px;"><strong>Disable XML-RPC Pingback Only</strong>: If you need the XML-RPC protocol support, but you do not use the pingbacks which are used by your website to notify another website that you have linked to it from your page(s), you can just disable the pinbacks and keep the other XML-RPC functionality. This is also a security measure to prevent DDoS attacks.</p>
 
25
 
26
- <p style="margin-bottom: 0;"><strong>Disable XML-RPC Completely</strong>: If you do not use Jetpack plugin for off-site server communication or you only use the Dashboard to post content (without any remote software connection to the WordPress website such as Windows Live Writer or mobile apps), then you can disable the XML-RPC functionality. You can always re-enable it whenever you believe you'll need it.</p>
27
- </td>
28
- </tr>
29
- </table>
 
 
 
 
 
 
 
 
 
30
  </div>
10
  $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-cell;"' : '';
11
  ?>
12
  <div id="<?php echo $tabIdArea; ?>" class="wpacu-settings-tab-content" <?php echo $styleTabContent; ?>>
13
+ <h2><?php _e('Disable XML-RPC Protocol Support partially or completely', WPACU_PLUGIN_TEXT_DOMAIN); ?></h2>
14
+ <table class="wpacu-form-table">
15
+ <!-- Disable "XML-RPC" protocol support? -->
16
+ <tr valign="top">
17
+ <td>
18
+ <select id="wpacu_disable_xmlrpc"
19
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[disable_xmlrpc]">
20
+ <option <?php if (! in_array($data['disable_xmlrpc'], array('disable_pingback', 'disable_all'))) { echo 'selected="selected"'; } ?>
21
+ value="keep_it_on">Keep it enabled (default)</option>
 
22
 
23
+ <option <?php if ($data['disable_xmlrpc'] === 'disable_pingback') { echo 'selected="selected"'; } ?>
24
+ value="disable_pingback">Disable XML-RPC Pingback Only
25
 
26
+ <option <?php if ($data['disable_xmlrpc'] === 'disable_all') { echo 'selected="selected"'; } ?>
27
+ value="disable_all">Disable XML-RPC Completely</option>
28
+ </select>
29
+ <code>&lt;link rel=&quot;pingback&quot; href=&quot;https://www.yourwebsite.com/xmlrpc.php&quot; /&gt;</code>
30
+ <p style="margin-bottom: 10px;">This will disable XML-RPC protocol support and cleans up the "pingback" tag from the HEAD section of your website.</p>
31
+ <p style="margin-bottom: 10px;">This is an API service used by WordPress for 3rd party applications, such as mobile apps, communication between blogs, plugins such as Jetpack. If you use, or are planning to use a remote system to post content to your website, you can keep this feature enabled (which it is by default). Many users do not use this function at all and if you're one of them, you can disable it.</p>
32
+
33
+ <p style="margin-bottom: 10px;"><strong>Disable XML-RPC Pingback Only</strong>: If you need the XML-RPC protocol support, but you do not use the pingbacks which are used by your website to notify another website that you have linked to it from your page(s), you can just disable the pinbacks and keep the other XML-RPC functionality. This is also a security measure to prevent DDoS attacks.</p>
34
+
35
+ <p style="margin-bottom: 0;"><strong>Disable XML-RPC Completely</strong>: If you do not use Jetpack plugin for off-site server communication or you only use the Dashboard to post content (without any remote software connection to the WordPress website such as Windows Live Writer or mobile apps), then you can disable the XML-RPC functionality. You can always re-enable it whenever you believe you'll need it.</p>
36
+ </td>
37
+ </tr>
38
+ </table>
39
  </div>
templates/_admin-page-settings-plugin-areas/_head-cleanup.php CHANGED
@@ -10,180 +10,164 @@ $tabIdArea = 'wpacu-setting-head-cleanup';
10
  $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-cell;"' : '';
11
  ?>
12
  <div id="<?php echo $tabIdArea; ?>" class="wpacu-settings-tab-content" <?php echo $styleTabContent; ?>>
13
- <h2><?php _e('Remove unused elements from the &lthead&gt; section', WPACU_PLUGIN_TEXT_DOMAIN); ?></h2>
14
 
15
- <p><?php echo $settingsWithLock; ?></p>
16
- <p>There are elements that are enabled by default in many WordPress environments, but not necessary to be enabled. Cleanup the unnecessary code between <code>&lt;head&gt;</code> and <code>&lt;/head&gt;</code>.</p>
17
- <table class="wpacu-form-table">
18
- <!-- Remove "Really Simple Discovery (RSD)" link? -->
19
- <tr valign="top">
20
- <th scope="row">
21
- <label for="wpacu_remove_rsd_link">Remove "Really Simple Discovery (RSD)" link tag?</label>
22
- </th>
23
- <td>
24
- <?php echo $availableForPro; ?>
25
- <label class="wpacu_switch wpacu_locked_for_pro">
26
- <input id="wpacu_remove_rsd_link"
27
- type="checkbox"
28
- disabled="disabled"
29
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_rsd_link]"
30
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
31
- &nbsp;
32
- <code>&lt;link rel=&quot;EditURI&quot; type=&quot;application/rsd xml&quot; title=&quot;RSD&quot; href=&quot;http://yourwebsite.com/xmlrpc.php?rsd&quot; /&gt;</code>
33
- <p style="margin-top: 10px;">XML-RPC clients use this discover method. If you do not know what this is and don't use service integrations such as <a href="http://www.flickr.com/services/api/request.xmlrpc.html" target="_blank">Flickr</a> on your WordPress website, you can remove it.</p>
34
- </td>
35
- </tr>
36
 
37
- <!-- Remove "Windows Live Writer" link? -->
38
- <tr valign="top">
39
- <th scope="row">
40
- <label for="wpacu_remove_wlw_link">Remove "Windows Live Writer" link tag?</label>
41
- </th>
42
- <td>
43
- <?php echo $availableForPro; ?>
44
- <label class="wpacu_switch wpacu_locked_for_pro">
45
- <input id="wpacu_remove_wlw_link"
46
- type="checkbox"
47
- disabled="disabled"
48
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_wlw_link]"
49
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
50
- &nbsp;
51
- <code>&lt;link rel=&quot;wlwmanifest&quot; type=&quot;application/wlwmanifest xml&quot; href=&quot;https://yourwebsite.com/asset-optimizer/wp-includes/wlwmanifest.xml&quot; /&gt;</code>
52
- <p style="margin-top: 10px;">If you do not use Windows Live Writer to edit your blog contents, then it's safe to remove this.</p>
53
- </td>
54
- </tr>
55
 
56
- <!-- Remove "REST API" link tag? -->
57
- <tr valign="top">
58
- <th scope="row">
59
- <label for="wpacu_remove_rest_api_link">Remove "REST API" link tag?</label>
60
- </th>
61
- <td>
62
- <?php echo $availableForPro; ?>
63
- <label class="wpacu_switch wpacu_locked_for_pro">
64
- <input id="wpacu_remove_rest_api_link"
65
- type="checkbox"
66
- disabled="disabled"
67
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_rest_api_link]"
68
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
69
- &nbsp;
70
- <code>&lt;link rel=&#39;https://api.w.org/&#39; href=&#39;https://yourwebsite.com/wp-json/&#39; /&gt;</code>
71
- <p style="margin-top: 10px;">Are you accessing your content through endpoints (e.g. https://yourwebsite.com/wp-json/, https://yourwebsite.com/wp-json/wp/v2/posts/1 - <em>1</em> in this example is the POST ID)? If not, you can remove this.</p>
72
- </td>
73
- </tr>
74
 
75
- <!-- Remove Pages/Posts "Shortlink" tag? -->
76
- <tr valign="top">
77
- <th scope="row">
78
- <label for="wpacu_remove_shortlink">Remove Pages/Posts "Shortlink" tag?</label>
79
- </th>
80
- <td>
81
- <?php echo $availableForPro; ?>
82
- <label class="wpacu_switch wpacu_locked_for_pro">
83
- <input id="wpacu_remove_shortlink"
84
- type="checkbox"
85
- disabled="disabled"
86
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_shortlink]"
87
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
88
- &nbsp;
89
- <code>&lt;link rel=&#39;shortlink&#39; href=&quot;https://yourdomain.com/?p=1&quot;&gt;</code>
90
- <p style="margin-top: 10px;">Are you using SEO friendly URLs and do not need the default WordPress shortlink? You can just remove this as it bulks out the head section of your website.</p>
91
- </td>
92
- </tr>
93
 
94
- <!-- Remove "Post's Relational Links" tag? -->
95
- <tr valign="top">
96
- <th scope="row">
97
- <label for="wpacu_remove_posts_rel_links">Remove "Post's Relational Links" tag?</label>
98
- </th>
99
- <td>
100
- <?php echo $availableForPro; ?>
101
- <label class="wpacu_switch wpacu_locked_for_pro">
102
- <input id="wpacu_remove_posts_rel_links"
103
- type="checkbox"
104
- disabled="disabled"
105
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_posts_rel_links]"
106
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
107
- &nbsp;
108
- <code>&lt;link rel=&#39;prev&#39; title=&#39;Title of adjacent post&#39; href=&#39;https://yourdomain.com/adjacent-post-slug-here/&#39; /&gt;</code>
109
- <p style="margin-top: 10px;">This removes relational links for the posts adjacent to the current post for single post pages.</p>
110
- </td>
111
- </tr>
112
 
113
- <!-- Remove "WordPress version" meta tag? -->
114
- <tr valign="top">
115
- <th scope="row">
116
- <label for="wpacu_remove_wp_version">Remove "WordPress version" meta tag?</label>
117
- </th>
118
- <td>
119
- <?php echo $availableForPro; ?>
120
- <label class="wpacu_switch wpacu_locked_for_pro">
121
- <input id="wpacu_remove_wp_version"
122
- type="checkbox"
123
- disabled="disabled"
124
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_wp_version]"
125
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
126
- &nbsp;
127
- <code>&lt;meta name=&quot;generator&quot; content=&quot;WordPress 4.9.8&quot; /&gt;</code>
128
- <p style="margin-top: 10px;">This is good for security purposes as well, since it hides the WordPress version you're using (in case of hacking attempts).</p>
129
- </td>
130
- </tr>
131
 
132
- <!-- Remove "WordPress version" meta tag and all other tags? -->
133
- <tr valign="top">
134
- <th scope="row">
135
- <label for="wpacu_remove_generator_tag">Remove All "generator" meta tags?</label>
136
- </th>
137
- <td>
138
- <?php echo $availableForPro; ?>
139
- <label class="wpacu_switch wpacu_locked_for_pro">
140
- <input id="wpacu_remove_generator_tag"
141
- type="checkbox"
142
- disabled="disabled"
143
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_generator_tag]"
144
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
145
- &nbsp;
146
- <code>e.g. &lt;meta name=&quot;generator&quot; content=&quot;Easy Digital Downloads v2.9.8&quot; /&gt;</code>
147
- <p style="margin-top: 10px;">This will remove all meta tags with the "generator" name, including the WordPress version. You could use a plugin or a theme that has added a generator notice, but you do not need to have it there. Moreover, it will hide the version of the plugins and theme you're using which is good for security reasons.</p>
148
- </td>
149
- </tr>
150
 
151
- <!-- Remove Main RSS Feed Link -->
152
- <tr valign="top">
153
- <th scope="row">
154
- <label for="wpacu_remove_main_feed_link">Remove Main RSS Feed Link?</label>
155
- </th>
156
- <td>
157
- <?php echo $availableForPro; ?>
158
- <label class="wpacu_switch wpacu_locked_for_pro">
159
- <input id="wpacu_remove_main_feed_link"
160
- type="checkbox"
161
- disabled="disabled"
162
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_main_feed_link]"
163
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
164
- &nbsp;
165
- <code>&lt;link rel=&quot;alternate&quot; type=&quot;application/rss xml&quot; title=&quot;Your Site Title &amp;raquo; Feed&quot; href=&quot;https://www.yourwebsite.com/feed/&quot; /&gt;</code>
166
- <p style="margin-top: 10px;">If you do not use WordPress for blogging purposes at all, and it doesn't have any blog posts (apart from the main pages that you added), then you can remove the main feed link. It will also remove feeds for the following pages: categories, tags, custom taxonomies &amp; search results. Note that it will not remove comments RSS feeds which can be removed using the setting below. Some websites might have blog posts and would keep the main RSS feeds enabled, while removing the comments RSS feeds if they don't use the comments functionality.</p>
167
- </td>
168
- </tr>
169
 
170
- <!-- Remove Comment Feeds Link -->
171
- <tr valign="top">
172
- <th scope="row">
173
- <label for="wpacu_remove_comment_feed_link">Remove Comment RSS Feed Link?</label>
174
- </th>
175
- <td>
176
- <?php echo $availableForPro; ?>
177
- <label class="wpacu_switch wpacu_locked_for_pro">
178
- <input id="wpacu_remove_comment_feed_link"
179
- type="checkbox"
180
- disabled="disabled"
181
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_comment_feed_link]"
182
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
183
- &nbsp;
184
- <code>e.g. &lt;link rel=&quot;alternate&quot; type=&quot;application/rss xml&quot; title=&quot;Your Website Title &amp;raquo; Comments Feed&quot; href=&quot;https://www.yourdomain.com/comments/feed/&quot; /&gt;</code>
185
- <p style="margin-top: 10px;">If you do not use the comments functionality on your posts or do not use WordPress for blogging purposes at all, then you can remove the comments feed link.</p>
186
- </td>
187
- </tr>
188
- </table>
189
  </div>
10
  $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-cell;"' : '';
11
  ?>
12
  <div id="<?php echo $tabIdArea; ?>" class="wpacu-settings-tab-content" <?php echo $styleTabContent; ?>>
13
+ <h2><?php _e('Remove unused elements from the &lthead&gt; section', WPACU_PLUGIN_TEXT_DOMAIN); ?></h2>
14
 
15
+ <p>There are elements that are enabled by default in many WordPress environments, but not necessary to be enabled. Cleanup the unnecessary code between <code>&lt;head&gt;</code> and <code>&lt;/head&gt;</code>.</p>
16
+ <table class="wpacu-form-table">
17
+ <!-- Remove "Really Simple Discovery (RSD)" link? -->
18
+ <tr valign="top">
19
+ <th scope="row">
20
+ <label for="wpacu_remove_rsd_link">Remove "Really Simple Discovery (RSD)" link tag?</label>
21
+ </th>
22
+ <td>
23
+ <label class="wpacu_switch">
24
+ <input id="wpacu_remove_rsd_link" type="checkbox"
25
+ <?php echo (($data['remove_rsd_link'] == 1) ? 'checked="checked"' : ''); ?>
26
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_rsd_link]"
27
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
28
+ &nbsp;
29
+ <code>&lt;link rel=&quot;EditURI&quot; type=&quot;application/rsd xml&quot; title=&quot;RSD&quot; href=&quot;http://yourwebsite.com/xmlrpc.php?rsd&quot; /&gt;</code>
30
+ <p style="margin-top: 10px;">XML-RPC clients use this discover method. If you do not know what this is and don't use service integrations such as <a href="http://www.flickr.com/services/api/request.xmlrpc.html">Flickr</a> on your WordPress website, you can remove it.</p>
31
+ </td>
32
+ </tr>
 
 
 
33
 
34
+ <!-- Remove "Windows Live Writer" link? -->
35
+ <tr valign="top">
36
+ <th scope="row">
37
+ <label for="wpacu_remove_wlw_link">Remove "Windows Live Writer" link tag?</label>
38
+ </th>
39
+ <td>
40
+ <label class="wpacu_switch">
41
+ <input id="wpacu_remove_wlw_link" type="checkbox"
42
+ <?php echo (($data['remove_wlw_link'] == 1) ? 'checked="checked"' : ''); ?>
43
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_wlw_link]"
44
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
45
+ &nbsp;
46
+ <code>&lt;link rel=&quot;wlwmanifest&quot; type=&quot;application/wlwmanifest xml&quot; href=&quot;https://yourwebsite.com/wp-includes/wlwmanifest.xml&quot; /&gt;</code>
47
+ <p style="margin-top: 10px;">If you do not use Windows Live Writer to edit your blog contents, then it's safe to remove this.</p>
48
+ </td>
49
+ </tr>
 
 
50
 
51
+ <!-- Remove "REST API" link? -->
52
+ <tr valign="top">
53
+ <th scope="row">
54
+ <label for="wpacu_remove_rest_api_link">Remove "REST API" link tag?</label>
55
+ </th>
56
+ <td>
57
+ <label class="wpacu_switch">
58
+ <input id="wpacu_remove_rest_api_link" type="checkbox"
59
+ <?php echo (($data['remove_rest_api_link'] == 1) ? 'checked="checked"' : ''); ?>
60
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_rest_api_link]"
61
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
62
+ &nbsp;
63
+ <code>&lt;link rel=&#39;https://api.w.org/&#39; href=&#39;https://yourwebsite.com/wp-json/&#39; /&gt;</code>
64
+ <p style="margin-top: 10px;">Are you accessing your content through endpoints (e.g. https://yourwebsite.com/wp-json/, https://yourwebsite.com/wp-json/wp/v2/posts/1 - <em>1</em> in this example is the POST ID)? If not, you can remove this.</p>
65
+ </td>
66
+ </tr>
 
 
67
 
68
+ <!-- Remove "Shortlink"? -->
69
+ <tr valign="top">
70
+ <th scope="row">
71
+ <label for="wpacu_remove_shortlink">Remove Pages/Posts "Shortlink" tag?</label>
72
+ </th>
73
+ <td>
74
+ <label class="wpacu_switch">
75
+ <input id="wpacu_remove_shortlink" type="checkbox"
76
+ <?php echo (($data['remove_shortlink'] == 1) ? 'checked="checked"' : ''); ?>
77
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_shortlink]"
78
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
79
+ &nbsp;
80
+ <code>&lt;link rel=&#39;shortlink&#39; href=&quot;https://yourdomain.com/?p=1&quot;&gt;</code>
81
+ <p style="margin-top: 10px;">Are you using SEO friendly URLs and do not need the default WordPress shortlink? You can just remove this as it bulks out the head section of your website.</p>
82
+ </td>
83
+ </tr>
 
 
84
 
85
+ <!-- Remove "Post's Relational Links" tag? -->
86
+ <tr valign="top">
87
+ <th scope="row">
88
+ <label for="wpacu_remove_posts_rel_links">Remove "Post's Relational Links" tag?</label>
89
+ </th>
90
+ <td>
91
+ <label class="wpacu_switch">
92
+ <input id="wpacu_remove_posts_rel_links" type="checkbox"
93
+ <?php echo (($data['remove_posts_rel_links'] == 1) ? 'checked="checked"' : ''); ?>
94
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_posts_rel_links]"
95
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
96
+ &nbsp;
97
+ <code>&lt;link rel=&#39;prev&#39; title=&#39;Title of adjacent post&#39; href=&#39;https://yourdomain.com/adjacent-post-slug-here/&#39; /&gt;</code>
98
+ <p style="margin-top: 10px;">This removes relational links for the posts adjacent to the current post for single post pages.</p>
99
+ </td>
100
+ </tr>
 
 
101
 
102
+ <!-- Remove "WordPress version" meta tag? -->
103
+ <tr valign="top">
104
+ <th scope="row">
105
+ <label for="wpacu_remove_wp_version">Remove "WordPress version" meta tag?</label>
106
+ </th>
107
+ <td>
108
+ <label class="wpacu_switch">
109
+ <input id="wpacu_remove_wp_version" type="checkbox"
110
+ <?php echo (($data['remove_wp_version'] == 1) ? 'checked="checked"' : ''); ?>
111
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_wp_version]"
112
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
113
+ &nbsp;
114
+ <code>&lt;meta name=&quot;generator&quot; content=&quot;WordPress 4.9.8&quot; /&gt;</code>
115
+ <p style="margin-top: 10px;">This is good for security purposes as well, since it hides the WordPress version you're using (in case of hacking attempts).</p>
116
+ </td>
117
+ </tr>
 
 
118
 
119
+ <!-- Remove "WordPress version" meta tag and all other tags? -->
120
+ <tr valign="top">
121
+ <th scope="row">
122
+ <label for="wpacu_remove_generator_tag">Remove All "generator" meta tags?</label>
123
+ </th>
124
+ <td>
125
+ <label class="wpacu_switch">
126
+ <input id="wpacu_remove_generator_tag"
127
+ type="checkbox"
128
+ <?php echo (($data['remove_generator_tag'] == 1) ? 'checked="checked"' : ''); ?>
129
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_generator_tag]"
130
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
131
+ &nbsp;
132
+ <code>e.g. &lt;meta name=&quot;generator&quot; content=&quot;Easy Digital Downloads v2.9.8&quot; /&gt;</code>
133
+ <p style="margin-top: 10px;">This will remove all meta tags with the "generator" name, including the "WordPress version" meta tag. You could use a plugin or a theme that has added a generator notice, but you do not need to have it there. Moreover, it will hide the version of the plugins and theme you're using which is good for security reasons.</p>
134
+ </td>
135
+ </tr>
 
136
 
137
+ <!-- Remove Main RSS Feed Link -->
138
+ <tr valign="top">
139
+ <th scope="row">
140
+ <label for="wpacu_remove_main_feed_link">Remove Main RSS Feed Link?</label>
141
+ </th>
142
+ <td>
143
+ <label class="wpacu_switch">
144
+ <input id="wpacu_remove_main_feed_link"
145
+ type="checkbox"
146
+ <?php echo (($data['remove_main_feed_link'] == 1) ? 'checked="checked"' : ''); ?>
147
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_main_feed_link]"
148
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
149
+ &nbsp;
150
+ <code>&lt;link rel=&quot;alternate&quot; type=&quot;application/rss xml&quot; title=&quot;Your Site Title &amp;raquo; Feed&quot; href=&quot;https://www.yourwebsite.com/feed/&quot; /&gt;</code>
151
+ <p style="margin-top: 10px;">If you do not use WordPress for blogging purposes at all, and it doesn't have any blog posts (apart from the main pages that you added), then you can remove the main feed link. It will also remove feeds for the following pages: categories, tags, custom taxonomies &amp; search results. Note that it will not remove comments RSS feeds which can be removed using the setting below. Some websites might have blog posts and would keep the main RSS feeds enabled, while removing the comments RSS feeds if they don't use the comments functionality.</p>
152
+ </td>
153
+ </tr>
 
154
 
155
+ <!-- Remove Comment Feeds Link -->
156
+ <tr valign="top">
157
+ <th scope="row">
158
+ <label for="wpacu_remove_comment_feed_link">Remove Comment RSS Feed Link?</label>
159
+ </th>
160
+ <td>
161
+ <label class="wpacu_switch">
162
+ <input id="wpacu_remove_comment_feed_link"
163
+ type="checkbox"
164
+ <?php echo (($data['remove_comment_feed_link'] == 1) ? 'checked="checked"' : ''); ?>
165
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_comment_feed_link]"
166
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
167
+ &nbsp;
168
+ <code>e.g. &lt;link rel=&quot;alternate&quot; type=&quot;application/rss xml&quot; title=&quot;Your Website Title &amp;raquo; Comments Feed&quot; href=&quot;https://www.yourdomain.com/comments/feed/&quot; /&gt;</code>
169
+ <p style="margin-top: 10px;">If you do not use the comments functionality on your posts or do not use WordPress for blogging purposes at all, then you can remove the comments feed link.</p>
170
+ </td>
171
+ </tr>
172
+ </table>
 
173
  </div>
templates/_admin-page-settings-plugin-areas/_minify-loaded-files.php CHANGED
@@ -27,39 +27,54 @@ $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-ce
27
 
28
  &nbsp;This will take the remaining enqueued CSS files, minify them and load them from the cache.
29
 
30
- <?php
31
- ?>
 
32
 
33
- <div id="wpacu_minify_css_exceptions_area">
34
- <div style="margin: 0 0 6px;">Do not minify the CSS files matching the patterns below (one per line):</div>
35
- <label for="wpacu_minify_css_exceptions">
36
  <textarea style="width: 100%;"
37
- rows="5"
38
  id="wpacu_minify_css_exceptions"
39
  name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[minify_loaded_css_exceptions]"><?php echo $data['minify_loaded_css_exceptions']; ?></textarea>
40
- </label>
41
- <div style="margin-top: 15px; margin-bottom: 0;"><hr /></div>
42
- </div>
43
- </td>
44
- </tr>
45
 
46
- <tr valign="top">
47
- <th scope="row" class="setting_title" style="padding: 5px 20px 10px 0;">
48
- <label for="wpacu_minify_js_enable">JavaScript Files Minification</label>
49
- <p class="wpacu_subtitle"><small><em>Helps decrease the total page size even further</em></small></p>
50
- </th>
51
- <td>
52
- <?php echo $availableForPro; ?>
53
- <label class="wpacu_switch wpacu_locked_for_pro">
54
- <input id="wpacu_minify_js_enable"
55
- type="checkbox"
56
- disabled="disabled"
57
- name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[minify_loaded_js]"
58
- value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
59
- &nbsp;&nbsp;This will take the remaining enqueued JavaScript files, minify them and load them from the cache.
60
- </td>
61
- </tr>
62
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
  <hr />
65
 
27
 
28
  &nbsp;This will take the remaining enqueued CSS files, minify them and load them from the cache.
29
 
30
+ <?php
31
+ $minifyCssExceptionsAreaStyle = ($data['minify_loaded_css'] == 1) ? 'opacity: 1;' : 'opacity: 0.4;';
32
+ ?>
33
 
34
+ <div id="wpacu_minify_css_exceptions_area" style="<?php echo $minifyCssExceptionsAreaStyle; ?>">
35
+ <div style="margin: 0 0 6px;">Do not minify the CSS files matching the patterns below (one per line):</div>
36
+ <label for="wpacu_minify_css_exceptions">
37
  <textarea style="width: 100%;"
38
+ rows="4"
39
  id="wpacu_minify_css_exceptions"
40
  name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[minify_loaded_css_exceptions]"><?php echo $data['minify_loaded_css_exceptions']; ?></textarea>
41
+ </label>
42
+ <div style="margin-top: 15px; margin-bottom: 0;"><hr /></div>
43
+ </div>
44
+ </td>
45
+ </tr>
46
 
47
+ <tr valign="top">
48
+ <th scope="row" class="setting_title">
49
+ <label for="wpacu_minify_js_enable">JavaScript Files Minification</label>
50
+ <p class="wpacu_subtitle"><small><em>Helps decrease the total page size even further</em></small></p>
51
+ </th>
52
+ <td>
53
+ <label class="wpacu_switch">
54
+ <input id="wpacu_minify_js_enable"
55
+ type="checkbox"
56
+ <?php echo (($data['minify_loaded_js'] == 1) ? 'checked="checked"' : ''); ?>
57
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[minify_loaded_js]"
58
+ value="1" /> <span class="wpacu_slider wpacu_round"></span></label>
59
+ &nbsp;&nbsp;This will take the remaining enqueued JavaScript files, minify them and load them from the cache.
60
+
61
+ <?php
62
+ $minifyJsExceptionsAreaStyle = ($data['minify_loaded_js'] == 1) ? 'opacity: 1;' : 'opacity: 0.4;';
63
+ ?>
64
+
65
+ <div id="wpacu_minify_js_exceptions_area" style="<?php echo $minifyJsExceptionsAreaStyle; ?>">
66
+ <div style="margin: 0 0 6px;">Do not minify the JavaScript files matching the patterns below (one per line):</div>
67
+ <label for="wpacu_minify_js_exceptions">
68
+ <textarea style="width: 100%;"
69
+ rows="4"
70
+ id="wpacu_minify_js_exceptions"
71
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[minify_loaded_js_exceptions]"><?php echo $data['minify_loaded_js_exceptions']; ?></textarea>
72
+ </label>
73
+ <div style="margin-top: 15px; margin-bottom: 0;"><hr /></div>
74
+ </div>
75
+ </td>
76
+ </tr>
77
+ </table>
78
 
79
  <hr />
80
 
templates/_admin-page-settings-plugin-areas/_strip-the-fat.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * No direct access to this file
4
+ */
5
+ if (! isset($data)) {
6
+ exit;
7
+ }
8
+
9
+ $tabIdArea = 'wpacu-setting-strip-the-fat';
10
+ $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-cell;"' : '';
11
+ ?>
12
+ <div id="<?php echo $tabIdArea; ?>" class="wpacu-settings-tab-content" <?php echo $styleTabContent; ?>>
13
+ <h2><span class="dashicons dashicons-info"></span> <?php _e('Prevent useless and often large CSS &amp; JS files increasing your total page size', WPACU_PLUGIN_TEXT_DOMAIN); ?></h2>
14
+ <p class="wpacu-notice wpacu-warning" style="font-size: 13px;">Please read the following tips regarding the usage of <?php echo WPACU_PLUGIN_TITLE; ?> to avoid any inconveniences later on. This is useful if you haven't used a page speed booster plugin before or you're also using a caching plugin for the page caching feature. If you're already familiar with the plugin or read the explanations below, just mark this area as "read" using the slider button from the bottom of this page.</p>
15
+ <p>The core functionality of <?php echo WPACU_PLUGIN_TITLE; ?>, as its name suggests, is to help you unload CSS Stylesheets (.css) &amp; JavaScript (.js) files through the <a href="<?php echo admin_url('admin.php?page=wpassetcleanup_assets_manager'); ?>">CSS &amp; JavaScript load manager</a> wherever they are loading in excess. This has always been the main purpose of this page speed booster plugin.</p>
16
+ <p>It's recommended that you take this action first on whatever page you wish to optimize (e.g. homepage), before minification &amp; concatenation of the remaining loaded files (as you will eventually end up with less and smaller optimised files). They are extra features added to the plugin and are meant to further reduce the number of HTTP requests and also get a smaller page size as the minification will help with that.</p>
17
+ <p>If you're already using other plugin for minification and concatenation, and you're happy with its configuration and decide to keep it, you can just use <?php echo WPACU_PLUGIN_TITLE; ?> for stripping the "fat" and the other plugin such as WP Rocket or Autoptimize will take the remaining files and optimize them. Don't enable minification/concatenation on both <?php echo WPACU_PLUGIN_TITLE; ?> and other caching plugin at the same time as this could lead to extra resources loaded and can generate conflicts or even duplicated files that will end up increasing the total page size.</p>
18
+
19
+ <hr />
20
+ <div style="margin: 20px 0 10px;"><strong style="font-size: 15px; line-height: 17px;">How are plugins such as WP Rocket, WP Fastest Cache, Autoptimize or W3 Total Cache working together with <?php echo WPACU_PLUGIN_TITLE; ?>?</strong></div>
21
+ <p>Let's suppose you're optimising the homepage that has a total of 20 CSS/JS files loading and decided that 8 CSS &amp; JavaScript files are not needed there. Once they are prevented from loading (not deleted or altered in any way from their original source, this plugin doesn't do that), the remaining 12 files will be minified/combined (if you have this option enabled) by either <?php echo WPACU_PLUGIN_TITLE; ?>, WP Rocket or other plugin you decided to do this and saved into smaller and less files. This will end up in a decreased total page size, deferred unused CSS &amp; less HTTP requests resulting in a faster page load and a higher page speed performance score (via tools such as GTMetrix).</p>
22
+
23
+ <hr />
24
+ <div style="margin: 20px 0 10px;"><strong style="font-size: 15px; line-height: 17px;">Is a decrease in the total page size or a higher page speed score guaranteed?</strong></div>
25
+ <p>As long as you will prevent useless files from loading, then you will for sure have a lighter &amp; faster website. If anything changes in your hosting configuration, the size of your images or any external scripts etc. that you're website is loading, then you could end up with a slower website and that is not dependent on <?php echo WPACU_PLUGIN_TITLE; ?> nor any other WordPress performance plugin as there are external things which will never depend entirely on a plugin.</p>
26
+
27
+ <hr />
28
+ <div style="margin: 20px 0 10px;"><strong style="font-size: 15px; line-height: 17px;">Can this plugin make the pages load slower?</strong></div>
29
+ <p><?php echo WPACU_PLUGIN_TITLE; ?> doesn't add any extra files to load in the front-end view that will increase the number of HTTP requests in any way as it will defy its purpose. It's main task is to prevent other files from loading and cleaning up the HTML code. Moreover, by enabling concatenation (if your website is not using the HTTP/2 protocol), you will reduce the number of HTTP requests further. If you're using another plugin that also has an option for minification/concatenation and you have enabled the feature on both plugins (never do it), or haven't configured something the right way, you could end up with extra CSS/JS loaded that will eventually lead to a poorer page speed score and a slower website.</p>
30
+ <p><?php echo WPACU_PLUGIN_TITLE; ?> will never alter (in any way) or delete CSS &amp; JS files from their original source (e.g. plugins, themes). Files created through minification/concatenation are cached and stored in <em>/wp-content/cache/asset-cleanup/</em> directory.</p>
31
+ <hr />
32
+
33
+ <label class="wpacu_switch">
34
+ <input id="wpacu_wiki_read"
35
+ type="checkbox"
36
+ <?php echo (($data['wiki_read'] == 1) ? 'checked="checked"' : ''); ?>
37
+ name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[wiki_read]"
38
+ value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
39
+ I understand how the plugin works and I will make sure to make proper tests (via "Test Mode" if necessary) after the changes I'm making. I'm aware that unloading the wrong CSS/JS files can break the layout and front-end functionality of the pages I'm optimising.
40
+ </div>
templates/admin-page-child-settings-homepage.php CHANGED
@@ -53,6 +53,11 @@ if ($data['show_on_front'] === 'page') {
53
  <form id="wpacu_home_page_form" method="post" action="">
54
  <input type="hidden" name="wpacu_manage_home_page_assets" value="1" />
55
 
 
 
 
 
 
56
  <p><?php _e('Here you can unload files loaded on the home page. "Front page displays" (from "Settings" &#187; "Reading") is set to either "Your latest posts" (in "Settings" &#187; "Reading") OR a special layout (from a theme or plugin) was enabled.', WPACU_PLUGIN_TEXT_DOMAIN); ?> Changes will also apply to pages such as <code>/page/2</code> <code>page/3</code> etc. in case the latest blog posts are paginated.</p>
57
 
58
  <div id="wpacu_meta_box_content">
53
  <form id="wpacu_home_page_form" method="post" action="">
54
  <input type="hidden" name="wpacu_manage_home_page_assets" value="1" />
55
 
56
+ <input type="hidden"
57
+ id="wpacu_ajax_fetch_assets_list_dashboard_view"
58
+ name="wpacu_ajax_fetch_assets_list_dashboard_view"
59
+ value="1" />
60
+
61
  <p><?php _e('Here you can unload files loaded on the home page. "Front page displays" (from "Settings" &#187; "Reading") is set to either "Your latest posts" (in "Settings" &#187; "Reading") OR a special layout (from a theme or plugin) was enabled.', WPACU_PLUGIN_TEXT_DOMAIN); ?> Changes will also apply to pages such as <code>/page/2</code> <code>page/3</code> etc. in case the latest blog posts are paginated.</p>
62
 
63
  <div id="wpacu_meta_box_content">
templates/admin-page-settings-plugin.php CHANGED
@@ -15,20 +15,28 @@ $settingsWithLock = '<em><strong>Note:</strong> The settings that have a lock ar
15
 
16
  do_action('wpacu_admin_notices');
17
 
 
 
 
18
  $settingsTabs = array(
 
19
  'wpacu-setting-plugin-usage-settings' => __('General &amp; Files Management', WPACU_PLUGIN_TEXT_DOMAIN),
20
  'wpacu-setting-test-mode' => __('Test Mode', WPACU_PLUGIN_TEXT_DOMAIN),
21
  'wpacu-setting-minify-loaded-files' => __('Minify CSS &amp; JS Files', WPACU_PLUGIN_TEXT_DOMAIN),
22
  'wpacu-setting-combine-loaded-files' => __('Combine CSS &amp; JS Files', WPACU_PLUGIN_TEXT_DOMAIN),
23
- 'wpacu-setting-common-files-unload' => __('Common Elements Unload', WPACU_PLUGIN_TEXT_DOMAIN),
24
  'wpacu-setting-head-cleanup' => __('&lthead&gt; CleanUp', WPACU_PLUGIN_TEXT_DOMAIN),
25
  'wpacu-setting-disable-xml-rpc' => __('Disable XML-RPC', WPACU_PLUGIN_TEXT_DOMAIN),
26
  );
27
 
28
  $settingsTabActive = 'wpacu-setting-plugin-usage-settings';
 
 
 
 
29
  $selectedTabArea = isset($_POST['wpacu_selected_tab_area']) && array_key_exists($_POST['wpacu_selected_tab_area'], $settingsTabs) // the tab id area has to be one within the list above
30
  ? $_POST['wpacu_selected_tab_area'] // after update
31
- : 'wpacu-setting-plugin-usage-settings'; // default
32
 
33
  if ($selectedTabArea && array_key_exists($selectedTabArea, $settingsTabs)) {
34
  $settingsTabActive = $selectedTabArea;
@@ -51,6 +59,7 @@ if ($selectedTabArea && array_key_exists($selectedTabArea, $settingsTabs)) {
51
  </div>
52
 
53
  <?php
 
54
  include_once '_admin-page-settings-plugin-areas/_plugin-usage-settings.php';
55
  include_once '_admin-page-settings-plugin-areas/_test-mode.php';
56
  include_once '_admin-page-settings-plugin-areas/_minify-loaded-files.php';
15
 
16
  do_action('wpacu_admin_notices');
17
 
18
+ $wikiStatus = ($data['wiki_read'] == 1) ? '<small style="font-weight: 200; color: green;">* '.__('read', WPACU_PLUGIN_TEXT_DOMAIN).'</small>'
19
+ : '<small style="font-weight: 200; color: #cc0000;">* '.__('unread', WPACU_PLUGIN_TEXT_DOMAIN).'</small>';
20
+
21
  $settingsTabs = array(
22
+ 'wpacu-setting-strip-the-fat' => __('Stripping the "fat"', WPACU_PLUGIN_TEXT_DOMAIN) . ' '.$wikiStatus,
23
  'wpacu-setting-plugin-usage-settings' => __('General &amp; Files Management', WPACU_PLUGIN_TEXT_DOMAIN),
24
  'wpacu-setting-test-mode' => __('Test Mode', WPACU_PLUGIN_TEXT_DOMAIN),
25
  'wpacu-setting-minify-loaded-files' => __('Minify CSS &amp; JS Files', WPACU_PLUGIN_TEXT_DOMAIN),
26
  'wpacu-setting-combine-loaded-files' => __('Combine CSS &amp; JS Files', WPACU_PLUGIN_TEXT_DOMAIN),
27
+ 'wpacu-setting-common-files-unload' => __('Site-Wide Common Unloads', WPACU_PLUGIN_TEXT_DOMAIN),
28
  'wpacu-setting-head-cleanup' => __('&lthead&gt; CleanUp', WPACU_PLUGIN_TEXT_DOMAIN),
29
  'wpacu-setting-disable-xml-rpc' => __('Disable XML-RPC', WPACU_PLUGIN_TEXT_DOMAIN),
30
  );
31
 
32
  $settingsTabActive = 'wpacu-setting-plugin-usage-settings';
33
+
34
+ // Is 'Stripping the "fat"' marked as read? Mark the "General & Files Management" as the default tab
35
+ $defaultTabArea = ($data['wiki_read'] == 1) ? 'wpacu-setting-plugin-usage-settings' : 'wpacu-setting-strip-the-fat';
36
+
37
  $selectedTabArea = isset($_POST['wpacu_selected_tab_area']) && array_key_exists($_POST['wpacu_selected_tab_area'], $settingsTabs) // the tab id area has to be one within the list above
38
  ? $_POST['wpacu_selected_tab_area'] // after update
39
+ : $defaultTabArea; // default
40
 
41
  if ($selectedTabArea && array_key_exists($selectedTabArea, $settingsTabs)) {
42
  $settingsTabActive = $selectedTabArea;
59
  </div>
60
 
61
  <?php
62
+ include_once '_admin-page-settings-plugin-areas/_strip-the-fat.php';
63
  include_once '_admin-page-settings-plugin-areas/_plugin-usage-settings.php';
64
  include_once '_admin-page-settings-plugin-areas/_test-mode.php';
65
  include_once '_admin-page-settings-plugin-areas/_minify-loaded-files.php';
templates/meta-box-loaded-assets/_asset-script-single-row.php CHANGED
@@ -47,7 +47,7 @@ $isBulkUnloaded = ($data['row']['global_unloaded'] || $data['row']['is_post_ty
47
  }
48
 
49
  if (isset($data['row']['obj']->position) && $data['row']['obj']->position !== '') {
50
- $extraInfo[] = __('Position:', WPACU_PLUGIN_TEXT_DOMAIN) . ' ' . (( $data['row']['obj']->position === 'head') ? 'HEAD' : 'BODY');
51
  }
52
 
53
  // [wpacu_lite]
47
  }
48
 
49
  if (isset($data['row']['obj']->position) && $data['row']['obj']->position !== '') {
50
+ $extraInfo[] = __('Position:', WPACU_PLUGIN_TEXT_DOMAIN) . ' ' . (( $data['row']['obj']->position === 'head') ? 'HEAD' : 'BODY') . '<a class="go-pro-link-no-style" href="' . WPACU_PLUGIN_GO_PRO_URL . '?utm_source=manage_asset&utm_medium=change_js_position"><span class="wpacu-tooltip" style="width: 300px; margin-left: -146px;">Upgrade to Pro and change the location<br />of the JS file (e.g. to BODY to reduce render-blocking or to HEAD for very early triggering)</span><img width="20" height="20" src="' . WPACU_PLUGIN_URL . '/assets/icons/icon-lock.svg" valign="top" alt="" /> Change it?</a>';
51
  }
52
 
53
  // [wpacu_lite]
templates/meta-box-loaded-assets/_asset-style-single-row.php CHANGED
@@ -42,6 +42,10 @@ $isBulkUnloaded = ($data['row']['global_unloaded'] || $data['row']['is_post_ty
42
  $extraInfo[] = __('Version:', WPACU_PLUGIN_TEXT_DOMAIN) . ' ' . $data['row']['obj']->ver;
43
  }
44
 
 
 
 
 
45
  // [wpacu_lite]
46
  if (isset($data['row']['obj']->src) && $data['row']['obj']->src) {
47
  $extraInfo[] = __('File Size:', WPACU_PLUGIN_TEXT_DOMAIN) . ' <a href="' . WPACU_PLUGIN_GO_PRO_URL . '?utm_source=manage_asset&utm_medium=file_size" class="go-pro-link-no-style"><span class="wpacu-tooltip">Upgrade to Pro and unlock all features</span><img width="20" height="20" src="' . WPACU_PLUGIN_URL . '/assets/icons/icon-lock.svg" valign="top" alt="" /> Pro Version</a>';
42
  $extraInfo[] = __('Version:', WPACU_PLUGIN_TEXT_DOMAIN) . ' ' . $data['row']['obj']->ver;
43
  }
44
 
45
+ if (isset($data['row']['obj']->position) && $data['row']['obj']->position !== '') {
46
+ $extraInfo[] = __('Position:', WPACU_PLUGIN_TEXT_DOMAIN) . ' ' . (( $data['row']['obj']->position === 'head') ? 'HEAD' : 'BODY') . '<a class="go-pro-link-no-style" href="' . WPACU_PLUGIN_GO_PRO_URL . '?utm_source=manage_asset&utm_medium=change_css_position"><span class="wpacu-tooltip" style="width: 300px; margin-left: -146px;">Upgrade to Pro and change the location<br />of the CSS file (e.g. to BODY to reduce render-blocking or to HEAD for very early triggering)</span><img width="20" height="20" src="' . WPACU_PLUGIN_URL . '/assets/icons/icon-lock.svg" valign="top" alt="" /> Change it?</a>';
47
+ }
48
+
49
  // [wpacu_lite]
50
  if (isset($data['row']['obj']->src) && $data['row']['obj']->src) {
51
  $extraInfo[] = __('File Size:', WPACU_PLUGIN_TEXT_DOMAIN) . ' <a href="' . WPACU_PLUGIN_GO_PRO_URL . '?utm_source=manage_asset&utm_medium=file_size" class="go-pro-link-no-style"><span class="wpacu-tooltip">Upgrade to Pro and unlock all features</span><img width="20" height="20" src="' . WPACU_PLUGIN_URL . '/assets/icons/icon-lock.svg" valign="top" alt="" /> Pro Version</a>';
templates/meta-box-side-page-options.php CHANGED
@@ -3,54 +3,59 @@
3
  * No direct access to this file
4
  */
5
  if (! isset($data)) {
6
- exit;
7
  }
8
-
9
- $availableForPro = '<a style="color: rgba(51,51,51,.4);" href="'.WPACU_PLUGIN_GO_PRO_URL.'?utm_source=edit_page_side_meta_box" class="go-pro-link-no-style"><span class="wpacu-tooltip" style="width: auto; margin-left: -32px;">Upgrade</span> <img style="opacity: 0.4;" width="20" height="20" src="'.WPACU_PLUGIN_URL.'/assets/icons/icon-lock.svg" valign="top" alt="" /></a>';
10
  ?>
11
  <div id="wpacu_meta_box_page_options_content">
12
  <ul>
13
- <!--
14
- -->
15
-
 
 
 
 
 
 
16
  <li>
17
  <label for="wpacu_page_options_no_css_optimize">
18
  <input type="checkbox"
19
- <?php if (isset($data['page_options']['no_css_optimize']) && $data['page_options']['no_css_optimize']) { echo 'checked="checked"'; } ?>
20
  id="wpacu_page_options_no_css_optimize"
21
  name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_css_optimize]"
22
- value="1" />Do not combine CSS files on this page
23
  </label>
24
  </li>
25
 
26
- <!--
27
- -->
28
-
29
  <li>
30
- <label for="wpacu_page_options_no_js_optimize" style="color: rgba(51,51,51,.4);">
31
- <input disabled="disabled"
32
- type="checkbox"
 
 
 
 
 
 
 
 
 
33
  id="wpacu_page_options_no_js_optimize"
34
  name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_js_optimize]"
35
- value="1" />Do not combine JS files on this page (Pro version) <?php echo $availableForPro; ?></label>
 
36
  </li>
37
 
38
  <li>
39
  <label for="wpacu_page_options_no_assets_settings">
40
  <input type="checkbox"
41
- <?php if (isset($data['page_options']['no_assets_settings']) && $data['page_options']['no_assets_settings']) { echo 'checked="checked"'; } ?>
42
  id="wpacu_page_options_no_assets_settings"
43
  name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_assets_settings]"
44
- value="1" />Do not apply any CSS &amp; JS settings (including async, defer, load &amp; unload rules) on this page
45
  </label>
46
  </li>
47
  </ul>
48
- <!--
49
- -->
50
  <hr/>
51
- <p style="margin-top: 10px;">
52
- <strong><span style="color: #82878c;" class="dashicons dashicons-lightbulb"></span></strong> Use the "Preview" button if you wish to see how the options above, as well as the load/unload rules will apply before updating anything. It works like the "Test Mode" feature for this page only.
53
- </p>
54
- <!--
55
- -->
56
  </div>
3
  * No direct access to this file
4
  */
5
  if (! isset($data)) {
6
+ exit;
7
  }
 
 
8
  ?>
9
  <div id="wpacu_meta_box_page_options_content">
10
  <ul>
11
+ <li>
12
+ <label for="wpacu_page_options_no_css_minify">
13
+ <input type="checkbox"
14
+ <?php if (isset($data['page_options']['no_css_minify']) && $data['page_options']['no_css_minify']) { echo 'checked="checked"'; } ?>
15
+ id="wpacu_page_options_no_css_minify"
16
+ name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_css_minify]"
17
+ value="1" />Do not minify CSS on this page
18
+ </label>
19
+ </li>
20
  <li>
21
  <label for="wpacu_page_options_no_css_optimize">
22
  <input type="checkbox"
23
+ <?php if (isset($data['page_options']['no_css_optimize']) && $data['page_options']['no_css_optimize']) { echo 'checked="checked"'; } ?>
24
  id="wpacu_page_options_no_css_optimize"
25
  name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_css_optimize]"
26
+ value="1" />Do not combine CSS on this page
27
  </label>
28
  </li>
29
 
 
 
 
30
  <li>
31
+ <label for="wpacu_page_options_no_js_minify">
32
+ <input type="checkbox"
33
+ <?php if (isset($data['page_options']['no_js_minify']) && $data['page_options']['no_js_minify']) { echo 'checked="checked"'; } ?>
34
+ id="wpacu_page_options_no_js_minify"
35
+ name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_js_minify]"
36
+ value="1" />Do not minify JS files on this page
37
+ </label>
38
+ </li>
39
+ <li>
40
+ <label for="wpacu_page_options_no_js_optimize">
41
+ <input type="checkbox"
42
+ <?php if (isset($data['page_options']['no_js_optimize']) && $data['page_options']['no_js_optimize']) { echo 'checked="checked"'; } ?>
43
  id="wpacu_page_options_no_js_optimize"
44
  name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_js_optimize]"
45
+ value="1" />Do not combine JavaScript on this page
46
+ </label>
47
  </li>
48
 
49
  <li>
50
  <label for="wpacu_page_options_no_assets_settings">
51
  <input type="checkbox"
52
+ <?php if (isset($data['page_options']['no_assets_settings']) && $data['page_options']['no_assets_settings']) { echo 'checked="checked"'; } ?>
53
  id="wpacu_page_options_no_assets_settings"
54
  name="<?php echo WPACU_PLUGIN_ID; ?>_page_options[no_assets_settings]"
55
+ value="1" />Do not apply any CSS &amp; JavaScript settings (including async, defer, load &amp; unload rules) on this page
56
  </label>
57
  </li>
58
  </ul>
 
 
59
  <hr/>
60
+ <p style="margin-top: 10px;"><strong><span style="color: #82878c;" class="dashicons dashicons-lightbulb"></span></strong> Use the "Preview" button if you wish to see how the options above, as well as the load/unload rules will apply before updating anything. It works like the "Test Mode" feature for this page only.</p>
 
 
 
 
61
  </div>
templates/meta-box.php CHANGED
@@ -5,6 +5,15 @@
5
  if (! isset($data)) {
6
  exit;
7
  }
 
 
 
 
 
 
 
 
 
8
  ?>
9
  <div id="wpacu_meta_box_content">
10
  <?php
@@ -20,6 +29,9 @@ if (! isset($data)) {
20
  <?php
21
  } else {
22
  _e('The styles and scripts will be available for unload once this post/page is <strong>public</strong> and <strong>publish</strong>ed as the whole page needs to be scanned for all the loaded assets.', WPACU_PLUGIN_TEXT_DOMAIN);
 
 
 
23
  }
24
  ?>
25
  </div>
5
  if (! isset($data)) {
6
  exit;
7
  }
8
+
9
+ if ($data['get_assets']) {
10
+ ?>
11
+ <input type="hidden"
12
+ id="wpacu_ajax_fetch_assets_list_dashboard_view"
13
+ name="wpacu_ajax_fetch_assets_list_dashboard_view"
14
+ value="1" />
15
+ <?php
16
+ }
17
  ?>
18
  <div id="wpacu_meta_box_content">
19
  <?php
29
  <?php
30
  } else {
31
  _e('The styles and scripts will be available for unload once this post/page is <strong>public</strong> and <strong>publish</strong>ed as the whole page needs to be scanned for all the loaded assets.', WPACU_PLUGIN_TEXT_DOMAIN);
32
+ ?>
33
+ <p class="wpacu-warning" style="margin: 15px 0 0; padding: 10px; font-size: inherit;"><span class="dashicons dashicons-image-rotate" style="-webkit-transform: rotateY(180deg); transform: rotateY(180deg);"></span> &nbsp;<?php _e('If this post/page was meanwhile published (after you saw the above notice), just reload this edit page and you should see the list of CSS/JS files loaded in the page.', WPACU_PLUGIN_TEXT_DOMAIN); ?></p>
34
+ <?php
35
  }
36
  ?>
37
  </div>
wpacu-load.php CHANGED
@@ -62,9 +62,17 @@ $wpacuOptimizeCommon->init();
62
  // Combine/Minify CSS Files Setup
63
  $wpacuOptimizeCss = new \WpAssetCleanUp\OptimiseAssets\OptimizeCss();
64
  $wpacuOptimizeCss->init();
65
-
66
  new \WpAssetCleanUp\OptimiseAssets\MinifyCss();
67
 
 
 
 
 
 
 
 
 
 
68
  if (is_admin()) {
69
  new \WpAssetCleanUp\Plugin;
70
  new \WpAssetCleanUp\Tools();
62
  // Combine/Minify CSS Files Setup
63
  $wpacuOptimizeCss = new \WpAssetCleanUp\OptimiseAssets\OptimizeCss();
64
  $wpacuOptimizeCss->init();
 
65
  new \WpAssetCleanUp\OptimiseAssets\MinifyCss();
66
 
67
+ // Combine/Minify JS Files Setup
68
+ $wpacuOptimizeJs = new \WpAssetCleanUp\OptimiseAssets\OptimizeJs();
69
+ $wpacuOptimizeJs->init();
70
+ new \WpAssetCleanUp\OptimiseAssets\MinifyJs();
71
+
72
+ // <head> Clean up
73
+ $cleanUp = new \WpAssetCleanUp\CleanUp();
74
+ $cleanUp->init();
75
+
76
  if (is_admin()) {
77
  new \WpAssetCleanUp\Plugin;
78
  new \WpAssetCleanUp\Tools();
wpacu.php CHANGED
@@ -2,13 +2,13 @@
2
  /*
3
  * Plugin Name: Asset CleanUp: Page Speed Booster
4
  * Plugin URI: https://wordpress.org/plugins/wp-asset-clean-up/
5
- * Version: 1.3.1
6
- * Description: Prevent Chosen Scripts & Styles from loading in Posts/Pages to reduce HTTP Requests and have the website load faster
7
  * Author: Gabriel Livan
8
  * Author URI: http://gabelivan.com/
9
  */
10
 
11
- define('WPACU_PLUGIN_VERSION', '1.3.1');
12
 
13
  // Exit if accessed directly
14
  if (! defined('ABSPATH')) {
2
  /*
3
  * Plugin Name: Asset CleanUp: Page Speed Booster
4
  * Plugin URI: https://wordpress.org/plugins/wp-asset-clean-up/
5
+ * Version: 1.3.2
6
+ * Description: Unload Chosen Scripts & Styles from Posts/Pages to reduce HTTP Requests, Combine/Minify CSS/JS files
7
  * Author: Gabriel Livan
8
  * Author URI: http://gabelivan.com/
9
  */
10
 
11
+ define('WPACU_PLUGIN_VERSION', '1.3.2');
12
 
13
  // Exit if accessed directly
14
  if (! defined('ABSPATH')) {