Autoptimize - Version 2.9.2

Version Description

  • New: page/ post settings now have a "Generate Critical CSS"-button (critical CSS needs to be active with valid API key)
  • Improvement: also check WP Rocket settings for possible conflicts
  • Improvement: Image optimization CDN updated to new Autoptimize-specific subdomain
  • Fix: "don't aggregate but defer" did not defer 3rd party hosted JS (can be disabled with a filter)
  • Fix: the metabox per page/post logic failed when all optimizations were off (hat tip to Valenki for reporting) resulting in PHP notices
Download this release

Release Info

Developer futtta
Plugin Icon 128x128 Autoptimize
Version 2.9.2
Comparing to
See all releases

Code changes from version 2.9.1 to 2.9.2

autoptimize.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Autoptimize
4
  * Plugin URI: https://autoptimize.com/
5
  * Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
6
- * Version: 2.9.1
7
  * Author: Frank Goossens (futtta)
8
  * Author URI: https://autoptimize.com/
9
  * Text Domain: autoptimize
@@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
21
  exit;
22
  }
23
 
24
- define( 'AUTOPTIMIZE_PLUGIN_VERSION', '2.9.1' );
25
 
26
  // plugin_dir_path() returns the trailing slash!
27
  define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
3
  * Plugin Name: Autoptimize
4
  * Plugin URI: https://autoptimize.com/
5
  * Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
6
+ * Version: 2.9.2
7
  * Author: Frank Goossens (futtta)
8
  * Author URI: https://autoptimize.com/
9
  * Text Domain: autoptimize
21
  exit;
22
  }
23
 
24
+ define( 'AUTOPTIMIZE_PLUGIN_VERSION', '2.9.2' );
25
 
26
  // plugin_dir_path() returns the trailing slash!
27
  define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
classes/autoptimizeConfig.php CHANGED
@@ -254,7 +254,7 @@ if ( is_network_admin() && autoptimizeOptionWrapper::is_ao_active_for_network()
254
  <?php _e( 'Individual JS-files will be minified and deferred, making them non-render-blocking.', 'autoptimize' ); ?></label></td>
255
  </tr>
256
  <tr valign="top" id="js_defer_inline" class="js_sub js_not_aggregate hidden">
257
- <th scope="row">&emsp;<?php _e( 'Also defer inline JS?', 'autoptimize' ); ?> (beta)</th>
258
  <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_defer_inline" <?php echo autoptimizeOptionWrapper::get_option( 'autoptimize_js_defer_inline' ) ? 'checked="checked" ' : ''; ?>/>
259
  <?php _e( 'Also defer inline JS. Generally this will allow all JS to be deferred, so you should remove default exclusions, test and only exclude specific items if still needed.', 'autoptimize' ); ?></label></td>
260
  </tr>
@@ -1001,7 +1001,8 @@ $_rapidload_link = 'https://misc.optimizingmatters.com/partners/?from=csssetting
1001
 
1002
  static $_meta_value = null;
1003
  if ( null === $_meta_value ) {
1004
- if ( is_page() || is_single() ) {
 
1005
  $_meta_value = get_post_meta( get_the_ID(), 'ao_post_optimize', true );
1006
  } else {
1007
  $_meta_value = false;
254
  <?php _e( 'Individual JS-files will be minified and deferred, making them non-render-blocking.', 'autoptimize' ); ?></label></td>
255
  </tr>
256
  <tr valign="top" id="js_defer_inline" class="js_sub js_not_aggregate hidden">
257
+ <th scope="row">&emsp;<?php _e( 'Also defer inline JS?', 'autoptimize' ); ?></th>
258
  <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_defer_inline" <?php echo autoptimizeOptionWrapper::get_option( 'autoptimize_js_defer_inline' ) ? 'checked="checked" ' : ''; ?>/>
259
  <?php _e( 'Also defer inline JS. Generally this will allow all JS to be deferred, so you should remove default exclusions, test and only exclude specific items if still needed.', 'autoptimize' ); ?></label></td>
260
  </tr>
1001
 
1002
  static $_meta_value = null;
1003
  if ( null === $_meta_value ) {
1004
+ global $wp_query;
1005
+ if ( isset( $wp_query ) && ( is_page() || is_single() ) ) {
1006
  $_meta_value = get_post_meta( get_the_ID(), 'ao_post_optimize', true );
1007
  } else {
1008
  $_meta_value = false;
classes/autoptimizeCriticalCSSCron.php CHANGED
@@ -408,6 +408,12 @@ class autoptimizeCriticalCSSCron {
408
  // Prepare rule variables.
409
  $trule = explode( '|', $rule );
410
  $srule = $ao_ccss_rules[ $trule[0] ][ $trule[1] ];
 
 
 
 
 
 
411
 
412
  // Check if a MANUAL rule exist and return false.
413
  if ( ! empty( $srule ) && ( 0 == $srule['hash'] && 0 != $srule['file'] ) ) {
@@ -425,7 +431,7 @@ class autoptimizeCriticalCSSCron {
425
  return $hash;
426
  }
427
  } else {
428
- // Or just return the hash if no rule exist yet.
429
  autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> with hash <' . $hash . '> has no rule yet', 3 );
430
  return $hash;
431
  }
408
  // Prepare rule variables.
409
  $trule = explode( '|', $rule );
410
  $srule = $ao_ccss_rules[ $trule[0] ][ $trule[1] ];
411
+
412
+ // If hash is empty, set it to now for a "forced job".
413
+ if ( empty( $hash ) ) {
414
+ $hash = 'new';
415
+ autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> had no hash, assuming forced job so setting hash to new', 3 );
416
+ }
417
 
418
  // Check if a MANUAL rule exist and return false.
419
  if ( ! empty( $srule ) && ( 0 == $srule['hash'] && 0 != $srule['file'] ) ) {
431
  return $hash;
432
  }
433
  } else {
434
+ // Return the hash for a job that has no rule yet.
435
  autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> with hash <' . $hash . '> has no rule yet', 3 );
436
  return $hash;
437
  }
classes/autoptimizeCriticalCSSEnqueue.php CHANGED
@@ -18,7 +18,7 @@ class autoptimizeCriticalCSSEnqueue {
18
  }
19
  }
20
 
21
- public static function ao_ccss_enqueue( $hash ) {
22
  $self = new self();
23
  // Get key status.
24
  $key = autoptimizeCriticalCSSCore::ao_ccss_key_status( false );
@@ -27,9 +27,15 @@ class autoptimizeCriticalCSSEnqueue {
27
  $enqueue = true;
28
 
29
  // ... which are not the ones below.
30
- if ( is_user_logged_in() || is_feed() || is_404() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || $self->ao_ccss_ua() || 'nokey' == $key['status'] || 'invalid' == $key['status'] || false === apply_filters( 'autoptimize_filter_ccss_enqueue_should_enqueue', true ) ) {
31
  $enqueue = false;
32
- autoptimizeCriticalCSSCore::ao_ccss_log( "Job queuing is not available for WordPress's logged in users, feeds, error pages, ajax calls, to criticalcss.com itself or when a valid API key is not found", 3 );
 
 
 
 
 
 
33
  }
34
 
35
  if ( $enqueue ) {
@@ -41,8 +47,18 @@ class autoptimizeCriticalCSSEnqueue {
41
  global $ao_ccss_forcepath;
42
 
43
  // Get request path and page type, and initialize the queue update flag.
44
- $req_orig = $_SERVER['REQUEST_URI'];
45
- $req_path = strtok( $req_orig, '?' );
 
 
 
 
 
 
 
 
 
 
46
 
47
  // Check if we have a lang param. we need to keep as WPML can switch languages based on that
48
  // and that includes RTL -> LTR so diff. structure, so rules would be RTL vs LTR
@@ -56,7 +72,6 @@ class autoptimizeCriticalCSSEnqueue {
56
  }
57
  }
58
 
59
- $req_type = $self->ao_ccss_get_type();
60
  $job_qualify = false;
61
  $target_rule = false;
62
  $rule_properties = false;
@@ -85,7 +100,7 @@ class autoptimizeCriticalCSSEnqueue {
85
  }
86
 
87
  // Match for types in rules if no path rule matches and if we're not enforcing paths.
88
- if ( ! $job_qualify && ( ! $ao_ccss_forcepath || ! in_array( $req_type, apply_filters( 'autoptimize_filter_ccss_coreenqueue_forcepathfortype', array( 'is_page' ) ) ) || ! apply_filters( 'autoptimize_filter_ccss_coreenqueue_ignorealltypes', false ) ) ) {
89
  foreach ( $ao_ccss_rules['types'] as $type => $props ) {
90
 
91
  // Prepare rule target and log.
@@ -117,7 +132,7 @@ class autoptimizeCriticalCSSEnqueue {
117
  // Should we switch to path-base AUTO-rules? Conditions:
118
  // 1. forcepath option has to be enabled (off by default)
119
  // 2. request type should be (by default, but filterable) one of is_page (removed for now: woo_is_product or woo_is_product_category).
120
- if ( ( $ao_ccss_forcepath && in_array( $req_type, apply_filters( 'autoptimize_filter_ccss_coreenqueue_forcepathfortype', array( 'is_page' ) ) ) ) || apply_filters( 'autoptimize_filter_ccss_coreenqueue_ignorealltypes', false ) ) {
121
  if ( '/' !== $req_path ) {
122
  $target_rule = 'paths|' . $req_path;
123
  } else {
18
  }
19
  }
20
 
21
+ public static function ao_ccss_enqueue( $hash = '', $path = '', $type = 'is_page' ) {
22
  $self = new self();
23
  // Get key status.
24
  $key = autoptimizeCriticalCSSCore::ao_ccss_key_status( false );
27
  $enqueue = true;
28
 
29
  // ... which are not the ones below.
30
+ if ( 'nokey' == $key['status'] || 'invalid' == $key['status'] ) {
31
  $enqueue = false;
32
+ autoptimizeCriticalCSSCore::ao_ccss_log( "Job queuing is not available: no valid API key found.", 3 );
33
+ } elseif ( ! empty( $hash ) && ( is_user_logged_in() || is_feed() || is_404() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || $self->ao_ccss_ua() || false === apply_filters( 'autoptimize_filter_ccss_enqueue_should_enqueue', true ) ) ) {
34
+ $enqueue = false;
35
+ autoptimizeCriticalCSSCore::ao_ccss_log( "Job queuing is not available for WordPress's logged in users, feeds, error pages, ajax calls or calls from criticalcss.com itself.", 3 );
36
+ } elseif ( empty( $hash ) && empty( $path ) || ( ( 'is_single' !== $type ) && ( 'is_page' !== $type ) ) ) {
37
+ $enqueue = false;
38
+ autoptimizeCriticalCSSCore::ao_ccss_log( "Forced job queuing failed, no path or not right type", 3 );
39
  }
40
 
41
  if ( $enqueue ) {
47
  global $ao_ccss_forcepath;
48
 
49
  // Get request path and page type, and initialize the queue update flag.
50
+ if ( ! empty( $hash ) ) {
51
+ $req_orig = $_SERVER['REQUEST_URI'];
52
+ $req_type = $self->ao_ccss_get_type();
53
+ } elseif ( ! empty( $path ) ) {
54
+ $req_orig = $path;
55
+ if ( $path === '/' ) {
56
+ $req_type = 'is_front_page';
57
+ } else {
58
+ $req_type = $type;
59
+ }
60
+ }
61
+ $req_path = strtok( $req_orig, '?' );
62
 
63
  // Check if we have a lang param. we need to keep as WPML can switch languages based on that
64
  // and that includes RTL -> LTR so diff. structure, so rules would be RTL vs LTR
72
  }
73
  }
74
 
 
75
  $job_qualify = false;
76
  $target_rule = false;
77
  $rule_properties = false;
100
  }
101
 
102
  // Match for types in rules if no path rule matches and if we're not enforcing paths.
103
+ if ( '' !== $hash && ! $job_qualify && ( ! $ao_ccss_forcepath || ! in_array( $req_type, apply_filters( 'autoptimize_filter_ccss_coreenqueue_forcepathfortype', array( 'is_page' ) ) ) || ! apply_filters( 'autoptimize_filter_ccss_coreenqueue_ignorealltypes', false ) ) ) {
104
  foreach ( $ao_ccss_rules['types'] as $type => $props ) {
105
 
106
  // Prepare rule target and log.
132
  // Should we switch to path-base AUTO-rules? Conditions:
133
  // 1. forcepath option has to be enabled (off by default)
134
  // 2. request type should be (by default, but filterable) one of is_page (removed for now: woo_is_product or woo_is_product_category).
135
+ if ( ( $ao_ccss_forcepath && in_array( $req_type, apply_filters( 'autoptimize_filter_ccss_coreenqueue_forcepathfortype', array( 'is_page' ) ) ) ) || apply_filters( 'autoptimize_filter_ccss_coreenqueue_ignorealltypes', false ) || empty( $hash )) {
136
  if ( '/' !== $req_path ) {
137
  $target_rule = 'paths|' . $req_path;
138
  } else {
classes/autoptimizeCriticalCSSSettings.php CHANGED
@@ -151,16 +151,16 @@ class autoptimizeCriticalCSSSettings {
151
  ?>
152
  <div class="notice-info notice"><p>
153
  <?php
154
- _e( "The \"Inline and Defer CSS\" option was activated to allow critical CSS to be used.", 'autoptimize' );
155
  ?>
156
  </p></div>
157
  <?php
158
  } else {
159
- // we have keystate, so "inline & defer CSS" was probably disable for troubleshooting, warn but let users continue.
160
  ?>
161
  <div class="notice-warning notice"><p>
162
  <?php
163
- _e( "Oops! Please <strong>activate the \"Inline and Defer CSS\" option</strong> on Autoptimize's main settings page to ensure critical CSS is used on the front-end.", 'autoptimize' );
164
  ?>
165
  </p></div>
166
  <?php
151
  ?>
152
  <div class="notice-info notice"><p>
153
  <?php
154
+ _e( "The \"Eliminate render-blocking CSS\" option was activated to allow critical CSS to be used.", 'autoptimize' );
155
  ?>
156
  </p></div>
157
  <?php
158
  } else {
159
+ // we have keystate, so "inline & defer CSS" was probably disabled for troubleshooting, warn but let users continue.
160
  ?>
161
  <div class="notice-warning notice"><p>
162
  <?php
163
+ _e( "Please <strong>activate the \"Eliminate render-blocking CSS\" option</strong> on Autoptimize's main settings page to ensure critical CSS is used on the front-end.", 'autoptimize' );
164
  ?>
165
  </p></div>
166
  <?php
classes/autoptimizeImages.php CHANGED
@@ -227,7 +227,7 @@ class autoptimizeImages
227
  static $imgopt_host = null;
228
 
229
  if ( null === $imgopt_host ) {
230
- $imgopt_host = 'https://cdn.shortpixel.ai/';
231
  $avail_imgopt = $this->options['availabilities']['extra_imgopt'];
232
  if ( ! empty( $avail_imgopt ) && array_key_exists( 'hosts', $avail_imgopt ) && is_array( $avail_imgopt['hosts'] ) ) {
233
  $imgopt_host = array_rand( array_flip( $avail_imgopt['hosts'] ) );
227
  static $imgopt_host = null;
228
 
229
  if ( null === $imgopt_host ) {
230
+ $imgopt_host = 'https://sp-ao.shortpixel.ai/';
231
  $avail_imgopt = $this->options['availabilities']['extra_imgopt'];
232
  if ( ! empty( $avail_imgopt ) && array_key_exists( 'hosts', $avail_imgopt ) && is_array( $avail_imgopt['hosts'] ) ) {
233
  $imgopt_host = array_rand( array_flip( $avail_imgopt['hosts'] ) );
classes/autoptimizeMain.php CHANGED
@@ -643,6 +643,12 @@ class autoptimizeMain
643
  array_map( 'unlink', glob( $ao_ccss_dir . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) );
644
  rmdir( $ao_ccss_dir );
645
  }
 
 
 
 
 
 
646
  }
647
 
648
  public static function on_deactivation()
643
  array_map( 'unlink', glob( $ao_ccss_dir . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) );
644
  rmdir( $ao_ccss_dir );
645
  }
646
+
647
+ // Remove 404-handler (although that should have been removed in clearall already).
648
+ $_fallback_php = trailingslashit( WP_CONTENT_DIR ) . 'autoptimize_404_handler.php';
649
+ if ( file_exists( $_fallback_php ) ) {
650
+ unlink( $_fallback_php );
651
+ }
652
  }
653
 
654
  public static function on_deactivation()
classes/autoptimizeMetabox.php CHANGED
@@ -18,6 +18,7 @@ class autoptimizeMetabox
18
  {
19
  add_action( 'add_meta_boxes', array( $this, 'ao_metabox_add_box' ) );
20
  add_action( 'save_post', array( $this, 'ao_metabox_save' ) );
 
21
  }
22
 
23
  public function ao_metabox_add_box()
@@ -44,14 +45,11 @@ class autoptimizeMetabox
44
  *
45
  * @param WP_Post $post The object for the current post/page.
46
  */
47
- function ao_metabox_content( $post ) {
 
48
  wp_nonce_field( 'ao_metabox', 'ao_metabox_nonce' );
49
 
50
- $ao_opt_value = get_post_meta( $post->ID, 'ao_post_optimize', true );
51
-
52
- if ( empty( $ao_opt_value ) ) {
53
- $ao_opt_value = $this->get_metabox_default_values();
54
- }
55
 
56
  $_ao_meta_sub_opacity = '';
57
  if ( 'on' !== $ao_opt_value['ao_post_optimize'] ) {
@@ -115,8 +113,33 @@ class autoptimizeMetabox
115
  <?php _e( 'Lazyload images?', 'autoptimize' ); ?>
116
  </label>
117
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  <script>
119
- if ( typeof jQuery !== 'undefined' ) {
120
  jQuery( "#autoptimize_post_optimize" ).change(function() {
121
  if (this.checked) {
122
  jQuery(".ao_meta_sub:visible").fadeTo("fast",1);
@@ -131,7 +154,41 @@ class autoptimizeMetabox
131
  jQuery(".ao_meta_sub_css:visible").fadeTo("fast",.33);
132
  }
133
  });
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  </script>
136
  <?php
137
  }
@@ -141,7 +198,8 @@ class autoptimizeMetabox
141
  *
142
  * @param int $post_id The ID of the post being saved.
143
  */
144
- public function ao_metabox_save( $post_id ) {
 
145
  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
146
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
147
  return $post_id;
@@ -183,14 +241,65 @@ class autoptimizeMetabox
183
  update_post_meta( $post_id, 'ao_post_optimize', $ao_meta_result );
184
  }
185
 
186
- public function get_metabox_default_values() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  $ao_metabox_defaults = array(
188
  'ao_post_optimize' => 'on',
189
  'ao_post_js_optimize' => 'on',
190
- 'ao_post_css_optimize' => 'on',
191
  'ao_post_ccss' => 'on',
192
  'ao_post_lazyload' => 'on',
193
  );
194
  return $ao_metabox_defaults;
195
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
18
  {
19
  add_action( 'add_meta_boxes', array( $this, 'ao_metabox_add_box' ) );
20
  add_action( 'save_post', array( $this, 'ao_metabox_save' ) );
21
+ add_action( 'wp_ajax_ao_metabox_ccss_addjob', array( $this, 'ao_metabox_generateccss_callback' ) );
22
  }
23
 
24
  public function ao_metabox_add_box()
45
  *
46
  * @param WP_Post $post The object for the current post/page.
47
  */
48
+ function ao_metabox_content( $post )
49
+ {
50
  wp_nonce_field( 'ao_metabox', 'ao_metabox_nonce' );
51
 
52
+ $ao_opt_value = $this->check_ao_opt_sanity( get_post_meta( $post->ID, 'ao_post_optimize', true ) );
 
 
 
 
53
 
54
  $_ao_meta_sub_opacity = '';
55
  if ( 'on' !== $ao_opt_value['ao_post_optimize'] ) {
113
  <?php _e( 'Lazyload images?', 'autoptimize' ); ?>
114
  </label>
115
  </p>
116
+ <p>
117
+ <?php
118
+ // Get path + check if button should be enabled or disabled.
119
+ $_generate_disabled = true;
120
+ $_slug = false;
121
+ $_type = 'is_single';
122
+
123
+ // harvest post ID from URL, get permalink from that and extract path from that.
124
+ if ( array_key_exists( 'post', $_GET ) ) {
125
+ $_slug = str_replace( AUTOPTIMIZE_WP_SITE_URL, '', get_permalink( $_GET['post'] ) );
126
+ }
127
+
128
+ // override the default 'is_single' if post.
129
+ global $post;
130
+ if ( 'page' === $post->post_type ) {
131
+ $_type = 'is_page';
132
+ }
133
+
134
+ // if CSS opt and inline & defer are on and if we have a slug, the button can be active.
135
+ if ( false !== $_slug && 'on' === get_option( 'autoptimize_css', false ) && 'on' === get_option( 'autoptimize_css_defer', false ) && ! empty( get_option( 'autoptimize_ccss_key', false ) ) && '2' === get_option( 'autoptimize_ccss_keyst', false ) ) {
136
+ $_generate_disabled = false;
137
+ }
138
+ ?>
139
+ <button class="button ao_meta_sub ao_meta_sub_css" id="generateccss" style="<?php echo $_ao_meta_sub_opacity . $_ao_meta_ccss_style; ?>" <?php if ( true === $_generate_disabled ) { echo 'disabled'; } ?>><?php _e( 'Generate Critical CSS', 'autoptimize' ); ?></button>
140
+ </p>
141
  <script>
142
+ jQuery(document).ready(function() {
143
  jQuery( "#autoptimize_post_optimize" ).change(function() {
144
  if (this.checked) {
145
  jQuery(".ao_meta_sub:visible").fadeTo("fast",1);
154
  jQuery(".ao_meta_sub_css:visible").fadeTo("fast",.33);
155
  }
156
  });
157
+ jQuery( "#autoptimize_post_ccss" ).change(function() {
158
+ if (this.checked) {
159
+ jQuery("#generateccss:visible").fadeTo("fast",1);
160
+ } else {
161
+ jQuery("#generateccss:visible").fadeTo("fast",.33);
162
+ }
163
+ });
164
+ jQuery("#generateccss").click(function(e){
165
+ e.preventDefault();
166
+ // disable button to avoid it being clicked several times.
167
+ jQuery("#generateccss").prop('disabled', true);
168
+ var data = {
169
+ 'action': 'ao_metabox_ccss_addjob',
170
+ 'path' : '<?php echo $_slug; ?>',
171
+ 'type' : '<?php echo $_type; ?>',
172
+ 'ao_ccss_addjob_nonce': '<?php echo wp_create_nonce( 'ao_ccss_addjob_nonce' ); ?>',
173
+ };
174
+
175
+ jQuery.post(ajaxurl, data, function(response) {
176
+ response_array=JSON.parse(response);
177
+ if (response_array['code'] == 200) {
178
+ setCritCSSbutton("<?php _e('Added to CCSS job queue.', 'autoptimize' ); ?>", "green");
179
+ } else {
180
+ setCritCSSbutton("<?php _e('Could not add to CCSS job queue.', 'autoptimize' ); ?>", "orange");
181
+ }
182
+ }).fail(function() {
183
+ setCritCSSbutton("<?php _e('Sorry, something went wrong.', 'autoptimize' ); ?>", "orange");
184
+ });
185
+ });
186
+ });
187
+
188
+ function setCritCSSbutton( message, color) {
189
+ jQuery("#generateccss").html(message);
190
+ jQuery("#generateccss").prop("style","border-color:" + color + "!important; color:" + color + "!important");
191
+ }
192
  </script>
193
  <?php
194
  }
198
  *
199
  * @param int $post_id The ID of the post being saved.
200
  */
201
+ public function ao_metabox_save( $post_id )
202
+ {
203
  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
204
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
205
  return $post_id;
241
  update_post_meta( $post_id, 'ao_post_optimize', $ao_meta_result );
242
  }
243
 
244
+ public function ao_metabox_generateccss_callback()
245
+ {
246
+ check_ajax_referer( 'ao_ccss_addjob_nonce', 'ao_ccss_addjob_nonce' );
247
+
248
+ if ( current_user_can( 'manage_options' ) && array_key_exists( 'path', $_POST ) && ! empty( $_POST['path'] ) ) {
249
+ if ( array_key_exists( 'type', $_POST ) && 'is_page' === $_POST['type'] ) {
250
+ $type = 'is_page';
251
+ } else {
252
+ $type = 'is_single';
253
+ }
254
+
255
+ $path = wp_strip_all_tags( $_POST['path'] );
256
+ $criticalcss_core = new autoptimizeCriticalCSSCore();
257
+ $criticalcss_base = new autoptimizeCriticalCSSBase();
258
+ $criticalcss_enqueue = new autoptimizeCriticalCSSEnqueue();
259
+ $_result = $criticalcss_enqueue->ao_ccss_enqueue( '', $path, $type );
260
+
261
+ if ( $_result ) {
262
+ $response['code'] = '200';
263
+ $response['string'] = $path . ' added to job queue.';
264
+ } else {
265
+ $response['code'] = '404';
266
+ $response['string'] = 'could not add ' . $path . ' to job queue.';
267
+ }
268
+ } else {
269
+ $response['code'] = '500';
270
+ $response['string'] = 'nok';
271
+ }
272
+
273
+ // Dispatch respose.
274
+ echo json_encode( $response );
275
+
276
+ // Close ajax request.
277
+ wp_die();
278
+ }
279
+
280
+ public function get_metabox_default_values()
281
+ {
282
  $ao_metabox_defaults = array(
283
  'ao_post_optimize' => 'on',
284
  'ao_post_js_optimize' => 'on',
285
+ 'ao_post_css_optimize' => 'on',
286
  'ao_post_ccss' => 'on',
287
  'ao_post_lazyload' => 'on',
288
  );
289
  return $ao_metabox_defaults;
290
  }
291
+
292
+ public function check_ao_opt_sanity( $ao_opt_val ) {
293
+ if ( empty( $ao_opt_val ) ) {
294
+ $ao_opt_val = $this->get_metabox_default_values();
295
+ } else {
296
+ foreach ( array( 'ao_post_optimize', 'ao_post_js_optimize', 'ao_post_css_optimize', 'ao_post_ccss', 'ao_post_lazyload' ) as $key ) {
297
+ if ( ! array_key_exists( $key, $ao_opt_val ) ) {
298
+ $ao_opt_val[$key] = 'off';
299
+ }
300
+ }
301
+ }
302
+
303
+ return $ao_opt_val;
304
+ }
305
  }
classes/autoptimizeScripts.php CHANGED
@@ -268,7 +268,7 @@ class autoptimizeScripts extends autoptimizeBase
268
  }
269
 
270
  // Defer inline JS?
271
- if ( true === $this->defer_not_aggregate && apply_filters( 'autoptimize_js_filter_defer_inline', $options['defer_inline'] ) ) {
272
  $this->defer_inline = true;
273
  }
274
 
@@ -373,9 +373,9 @@ class autoptimizeScripts extends autoptimizeBase
373
  }
374
  }
375
  }
376
-
377
  // not aggregating but deferring?
378
- if ( $this->defer_not_aggregate && false === $this->aggregate && str_replace( $this->dontmove, '', $path ) === $path && strpos( $new_tag, ' defer' ) === false && strpos( $new_tag, ' async' ) === false ) {
379
  $new_tag = str_replace( '<script ', '<script defer ', $new_tag );
380
  }
381
 
@@ -446,7 +446,7 @@ class autoptimizeScripts extends autoptimizeBase
446
  } else {
447
  $tag = '';
448
  }
449
- } else if ( str_replace( $this->dontmove, '', $tag ) === $tag ) {
450
  // defer inline JS by base64 encoding it.
451
  preg_match( '#<script.*>(.*)</script>#Usmi', $tag, $match );
452
  $new_tag = '<script defer src="data:text/javascript;base64,' . base64_encode( $match[1] ) . '"></script>';
268
  }
269
 
270
  // Defer inline JS?
271
+ if ( ( true === $this->defer_not_aggregate && apply_filters( 'autoptimize_js_filter_defer_inline', $options['defer_inline'] ) ) || apply_filters( 'autoptimize_js_filter_force_defer_inline', false ) ) {
272
  $this->defer_inline = true;
273
  }
274
 
373
  }
374
  }
375
  }
376
+
377
  // not aggregating but deferring?
378
+ if ( $this->defer_not_aggregate && false === $this->aggregate && ( str_replace( $this->dontmove, '', $path ) === $path || ( apply_filters( 'autoptimize_filter_js_defer_external', true ) && str_replace( $this->dontmove, '', $url ) === $url ) ) && strpos( $new_tag, ' defer' ) === false && strpos( $new_tag, ' async' ) === false ) {
379
  $new_tag = str_replace( '<script ', '<script defer ', $new_tag );
380
  }
381
 
446
  } else {
447
  $tag = '';
448
  }
449
+ } elseif ( str_replace( $this->dontmove, '', $tag ) === $tag ) {
450
  // defer inline JS by base64 encoding it.
451
  preg_match( '#<script.*>(.*)</script>#Usmi', $tag, $match );
452
  $new_tag = '<script defer src="data:text/javascript;base64,' . base64_encode( $match[1] ) . '"></script>';
classes/autoptimizeUtils.php CHANGED
@@ -472,29 +472,33 @@ class autoptimizeUtils
472
  return 'WP Fastest Cache';
473
  }
474
  }
475
- } else if ( defined( 'W3TC_VERSION' ) ) {
476
  $w3tcConfig = file_get_contents( WP_CONTENT_DIR . '/w3tc-config/master.php' );
477
  $w3tc_minify_on = strpos( $w3tcConfig, '"minify.enabled": true' );
478
  if ( $w3tc_minify ) {
479
  return 'W3 Total Cache';
480
  }
481
- } else if ( defined('SiteGround_Optimizer\VERSION') ) {
482
  if ( get_option('siteground_optimizer_optimize_css') == 1 || get_option('siteground_optimizer_optimize_javascript') == 1 || get_option('siteground_optimizer_combine_javascript') == 1 || get_option('siteground_optimizer_combine_css') == 1 ) {
483
  return 'Siteground Optimizer';
484
  }
485
- } else if ( defined( 'WPO_VERSION' ) ) {
486
  $_wpo_options = get_site_option( 'wpo_minify_config' );
487
  if ( is_array( $_wpo_options ) && $_wpo_options['enabled'] == 1 && ( $_wpo_options['enable_css'] == 1 || $_wpo_options['enable_js'] == 1 ) ) {
488
  return 'WP Optimize';
489
  }
490
- } else if ( defined( 'WPACU_PLUGIN_VERSION' ) || defined( 'WPACU_PRO_PLUGIN_VERSION' ) ) {
491
  $wpacuSettingsClass = new \WpAssetCleanUp\Settings();
492
  $wpacuSettings = $wpacuSettingsClass->getAll();
493
 
494
  if ( $wpacuSettings['minify_loaded_css'] || $wpacuSettings['minify_loaded_js'] || $wpacuSettings['combine_loaded_js'] || $wpacuSettings['combine_loaded_css'] ) {
495
  return 'Asset Cleanup';
496
  }
497
- } else if ( function_exists( 'fvm_get_settings' ) ) {
 
 
 
 
498
  return 'Fast Velocity Minify';
499
  }
500
 
472
  return 'WP Fastest Cache';
473
  }
474
  }
475
+ } elseif ( defined( 'W3TC_VERSION' ) ) {
476
  $w3tcConfig = file_get_contents( WP_CONTENT_DIR . '/w3tc-config/master.php' );
477
  $w3tc_minify_on = strpos( $w3tcConfig, '"minify.enabled": true' );
478
  if ( $w3tc_minify ) {
479
  return 'W3 Total Cache';
480
  }
481
+ } elseif ( defined('SiteGround_Optimizer\VERSION') ) {
482
  if ( get_option('siteground_optimizer_optimize_css') == 1 || get_option('siteground_optimizer_optimize_javascript') == 1 || get_option('siteground_optimizer_combine_javascript') == 1 || get_option('siteground_optimizer_combine_css') == 1 ) {
483
  return 'Siteground Optimizer';
484
  }
485
+ } elseif ( defined( 'WPO_VERSION' ) ) {
486
  $_wpo_options = get_site_option( 'wpo_minify_config' );
487
  if ( is_array( $_wpo_options ) && $_wpo_options['enabled'] == 1 && ( $_wpo_options['enable_css'] == 1 || $_wpo_options['enable_js'] == 1 ) ) {
488
  return 'WP Optimize';
489
  }
490
+ } elseif ( defined( 'WPACU_PLUGIN_VERSION' ) || defined( 'WPACU_PRO_PLUGIN_VERSION' ) ) {
491
  $wpacuSettingsClass = new \WpAssetCleanUp\Settings();
492
  $wpacuSettings = $wpacuSettingsClass->getAll();
493
 
494
  if ( $wpacuSettings['minify_loaded_css'] || $wpacuSettings['minify_loaded_js'] || $wpacuSettings['combine_loaded_js'] || $wpacuSettings['combine_loaded_css'] ) {
495
  return 'Asset Cleanup';
496
  }
497
+ } elseif ( defined( 'WP_ROCKET_VERSION' ) && function_exists( 'get_rocket_option' ) ) {
498
+ if ( get_rocket_option( 'minify_js' ) || get_rocket_option( 'minify_concatenate_js' ) || get_rocket_option( 'minify_css' ) || get_rocket_option( 'minify_concatenate_css' ) || get_rocket_option('async_css' ) ) {
499
+ return 'WP Rocket';
500
+ }
501
+ } elseif ( function_exists( 'fvm_get_settings' ) ) {
502
  return 'Fast Velocity Minify';
503
  }
504
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Donate link: http://blog.futtta.be/2013/10/21/do-not-donate-to-me/
5
  Requires at least: 4.9
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
- Stable tag: 2.9.1
9
 
10
  Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-load), HTML and Google Fonts, asyncing JS, removing emoji cruft and more.
11
 
@@ -14,9 +14,6 @@ Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-loa
14
  Autoptimize makes optimizing your site really easy. It can aggregate, minify and cache scripts and styles, injects CSS in the page head by default but can also inline critical CSS and defer the aggregated full CSS, moves and defers scripts to the footer and minifies HTML. You can optimize and lazy-load images (with support for WebP and AVIF formats), optimize Google Fonts, async non-aggregated JavaScript, remove WordPress core emoji cruft and more. As such it can improve your site's performance even when already on HTTP/2! There is extensive API available to enable you to tailor Autoptimize to each and every site's specific needs.
15
  If you consider performance important, you really should use one of the many caching plugins to do page caching. Some good candidates to complement Autoptimize that way are e.g. [Speed Booster pack](https://wordpress.org/plugins/speed-booster-pack/), [KeyCDN's Cache Enabler](https://wordpress.org/plugins/cache-enabler), [WP Super Cache](http://wordpress.org/plugins/wp-super-cache/) or if you use Cloudflare [WP Cloudflare Super Page Cache](https://wordpress.org/plugins/wp-cloudflare-page-cache/).
16
 
17
- > <strong>Premium Support</strong><br>
18
- > We provide great [Autoptimize Pro Support and Web Performance Optimization services](https://autoptimize.com/), check out our offering on [https://autoptimize.com/](https://autoptimize.com/)!
19
-
20
  (Speed-surfing image under creative commons [by LL Twistiti](https://www.flickr.com/photos/twistiti/818552808/))
21
 
22
  == Installation ==
@@ -328,6 +325,13 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
328
 
329
  == Changelog ==
330
 
 
 
 
 
 
 
 
331
  = 2.9.1 =
332
  * New: logic to detect possibly conflicting plugins, with notification if found.
333
  * Improvement: to be reviewed critical css rules UI change.
5
  Requires at least: 4.9
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
+ Stable tag: 2.9.2
9
 
10
  Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-load), HTML and Google Fonts, asyncing JS, removing emoji cruft and more.
11
 
14
  Autoptimize makes optimizing your site really easy. It can aggregate, minify and cache scripts and styles, injects CSS in the page head by default but can also inline critical CSS and defer the aggregated full CSS, moves and defers scripts to the footer and minifies HTML. You can optimize and lazy-load images (with support for WebP and AVIF formats), optimize Google Fonts, async non-aggregated JavaScript, remove WordPress core emoji cruft and more. As such it can improve your site's performance even when already on HTTP/2! There is extensive API available to enable you to tailor Autoptimize to each and every site's specific needs.
15
  If you consider performance important, you really should use one of the many caching plugins to do page caching. Some good candidates to complement Autoptimize that way are e.g. [Speed Booster pack](https://wordpress.org/plugins/speed-booster-pack/), [KeyCDN's Cache Enabler](https://wordpress.org/plugins/cache-enabler), [WP Super Cache](http://wordpress.org/plugins/wp-super-cache/) or if you use Cloudflare [WP Cloudflare Super Page Cache](https://wordpress.org/plugins/wp-cloudflare-page-cache/).
16
 
 
 
 
17
  (Speed-surfing image under creative commons [by LL Twistiti](https://www.flickr.com/photos/twistiti/818552808/))
18
 
19
  == Installation ==
325
 
326
  == Changelog ==
327
 
328
+ = 2.9.2 =
329
+ * New: page/ post settings now have a "Generate Critical CSS"-button (critical CSS needs to be active with valid API key)
330
+ * Improvement: also check WP Rocket settings for possible conflicts
331
+ * Improvement: Image optimization CDN updated to new Autoptimize-specific subdomain
332
+ * Fix: "don't aggregate but defer" did not defer 3rd party hosted JS (can be disabled with a filter)
333
+ * Fix: the metabox per page/post logic failed when all optimizations were off (hat tip to Valenki for reporting) resulting in PHP notices
334
+
335
  = 2.9.1 =
336
  * New: logic to detect possibly conflicting plugins, with notification if found.
337
  * Improvement: to be reviewed critical css rules UI change.