PluginProbe
Autoptimize / 3.1.16
Autoptimize v3.1.16
3.1.16 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 All 108 releases
← All changes | classes/autoptimizeMain.php +337 -58 2.5.0 → 3.1.16 View file →
@@ -27,8 +27,15 @@
27 27 */
28 28 protected $filepath = null;
29 29
30 30 /**
31 + * Critical CSS base object
32 + *
33 + * @var object
34 + */
35 + protected $_criticalcss = null;
36 +
37 + /**
31 38 * Constructor.
32 39 *
33 40 * @param string $version Version.
34 41 * @param string $filepath Filepath. Needed for activation/deactivation/uninstall hooks.
@@ -58,20 +65,24 @@
58 65 add_action( AUTOPTIMIZE_SETUP_INITHOOK, array( $this, 'hook_page_cache_purge' ) );
59 66
60 67 add_action( 'autoptimize_setup_done', array( $this, 'version_upgrades_check' ) );
61 68 add_action( 'autoptimize_setup_done', array( $this, 'check_cache_and_run' ) );
62 - add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_ao_extra' ) );
63 - add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_partners_tab' ) );
69 + add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_ao_compat' ), 10 );
70 + add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_ao_extra' ), 15 );
71 + add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_admin_only_trinkets' ), 20 );
72 + add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_criticalcss' ), 11 );
73 + add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_notfound_fallback' ), 10 );
64 74
65 75 add_action( 'init', array( $this, 'load_textdomain' ) );
66 - add_action( 'admin_init', array( 'PAnD', 'init' ) );
67 76
68 - register_activation_hook( $this->filepath, array( $this, 'on_activate' ) );
69 - }
77 + if ( is_multisite() && is_admin() ) {
78 + // Only if multisite and if in admin we want to check if we need to save options on network level.
79 + add_action( 'init', 'autoptimizeOptionWrapper::check_multisite_on_saving_options' );
80 + }
70 81
71 - public function on_activate()
72 - {
82 + // register uninstall & deactivation hooks.
73 83 register_uninstall_hook( $this->filepath, 'autoptimizeMain::on_uninstall' );
84 + register_deactivation_hook( $this->filepath, 'autoptimizeMain::on_deactivation' );
74 85 }
75 86
76 87 public function load_textdomain()
77 88 {
@@ -80,9 +91,9 @@
80 91
81 92 public function setup()
82 93 {
83 94 // Do we gzip in php when caching or is the webserver doing it?
84 - define( 'AUTOPTIMIZE_CACHE_NOGZIP', (bool) get_option( 'autoptimize_cache_nogzip' ) );
95 + define( 'AUTOPTIMIZE_CACHE_NOGZIP', (bool) autoptimizeOptionWrapper::get_option( 'autoptimize_cache_nogzip' ) );
85 96
86 97 // These can be overridden by specifying them in wp-config.php or such.
87 98 if ( ! defined( 'AUTOPTIMIZE_WP_CONTENT_NAME' ) ) {
88 99 define( 'AUTOPTIMIZE_WP_CONTENT_NAME', '/' . wp_basename( WP_CONTENT_DIR ) );
@@ -107,9 +118,9 @@
107 118 define( 'AUTOPTIMIZE_WP_SITE_URL', site_url() );
108 119 }
109 120 }
110 121 if ( ! defined( 'AUTOPTIMIZE_WP_CONTENT_URL' ) ) {
111 - if ( function_exists( 'domain_mapping_siteurl' ) ) {
122 + if ( function_exists( 'get_original_url' ) ) {
112 123 define( 'AUTOPTIMIZE_WP_CONTENT_URL', str_replace( get_original_url( AUTOPTIMIZE_WP_SITE_URL ), AUTOPTIMIZE_WP_SITE_URL, content_url() ) );
113 124 } else {
114 125 define( 'AUTOPTIMIZE_WP_CONTENT_URL', content_url() );
115 126 }
@@ -135,9 +146,9 @@
135 146 // Multibyte-capable string replacements are available with a filter.
136 147 // Also requires 'mbstring' extension.
137 148 $with_mbstring = apply_filters( 'autoptimize_filter_main_use_mbstring', false );
138 149 if ( $with_mbstring ) {
139 - autoptimizeUtils::mbstring_available( \extensions_loaded( 'mbstring' ) );
150 + autoptimizeUtils::mbstring_available( \extension_loaded( 'mbstring' ) );
140 151 } else {
141 152 autoptimizeUtils::mbstring_available( false );
142 153 }
143 154
@@ -158,30 +169,40 @@
158 169 {
159 170 if ( autoptimizeCache::cacheavail() ) {
160 171 $conf = autoptimizeConfig::instance();
161 172 if ( $conf->get( 'autoptimize_html' ) || $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) || autoptimizeImages::imgopt_active() || autoptimizeImages::should_lazyload_wrapper() ) {
162 - // Hook into WordPress frontend.
163 - if ( defined( 'AUTOPTIMIZE_INIT_EARLIER' ) ) {
164 - add_action(
165 - 'init',
166 - array( $this, 'start_buffering' ),
167 - self::INIT_EARLIER_PRIORITY
168 - );
169 - } else {
170 - if ( ! defined( 'AUTOPTIMIZE_HOOK_INTO' ) ) {
171 - define( 'AUTOPTIMIZE_HOOK_INTO', 'template_redirect' );
173 + if ( ! defined( 'AUTOPTIMIZE_NOBUFFER_OPTIMIZE' ) ) {
174 + // Hook into WordPress frontend.
175 + if ( defined( 'AUTOPTIMIZE_INIT_EARLIER' ) ) {
176 + add_action(
177 + 'init',
178 + array( $this, 'start_buffering' ),
179 + self::INIT_EARLIER_PRIORITY
180 + );
181 + } else {
182 + if ( ! defined( 'AUTOPTIMIZE_HOOK_INTO' ) ) {
183 + define( 'AUTOPTIMIZE_HOOK_INTO', 'template_redirect' );
184 + }
185 + add_action(
186 + constant( 'AUTOPTIMIZE_HOOK_INTO' ),
187 + array( $this, 'start_buffering' ),
188 + self::DEFAULT_HOOK_PRIORITY
189 + );
172 190 }
173 - add_action(
174 - constant( 'AUTOPTIMIZE_HOOK_INTO' ),
175 - array( $this, 'start_buffering' ),
176 - self::DEFAULT_HOOK_PRIORITY
177 - );
178 191 }
179 192
180 193 // And disable Jetpack's site accelerator if JS or CSS opt. are active.
181 - if ( class_exists( 'Jetpack' ) && apply_filters( 'autoptimize_filter_main_disable_jetpack_cdn', true ) && ( $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) ) ) {
182 - add_filter( 'jetpack_force_disable_site_accelerator', '__return_true' );
194 + if ( class_exists( 'Jetpack' ) && apply_filters( 'autoptimize_filter_main_disable_jetpack_cdn', true ) && ( $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) || autoptimizeImages::imgopt_active() ) ) {
195 + add_filter( 'jetpack_force_disable_site_accelerator', '__return_true' ); // this does not seemt to work any more?
196 + if ( true === autoptimizeImages::imgopt_active() ) {
197 + // only disable photon if AO is optimizing images.
198 + add_filter( 'jetpack_photon_skip_for_url', '__return_true' );
199 + }
183 200 }
201 +
202 + // Add "no cache found" notice.
203 + add_action( 'admin_notices', 'autoptimizeMain::notice_nopagecache', 99 );
204 + add_action( 'admin_notices', 'autoptimizeMain::notice_potential_conflict', 99 );
184 205 }
185 206 } else {
186 207 add_action( 'admin_notices', 'autoptimizeMain::notice_cache_unavailable' );
187 208 }
@@ -196,19 +217,67 @@
196 217 $ao_extra->run();
197 218
198 219 // And show the imgopt notice.
199 220 add_action( 'admin_notices', 'autoptimizeMain::notice_plug_imgopt' );
221 + add_action( 'admin_notices', 'autoptimizeMain::notice_imgopt_issue' );
200 222 }
201 223 }
202 224
203 - public function maybe_run_partners_tab()
225 + public function maybe_run_admin_only_trinkets()
204 226 {
205 - // Loads partners tab code if in admin (and not in admin-ajax.php)!
227 + // Loads partners tab and exit survey code if in admin (and not in admin-ajax.php)!
206 228 if ( autoptimizeConfig::is_admin_and_not_ajax() ) {
207 229 new autoptimizePartners();
230 + new autoptimizeExitSurvey();
231 + new autoptimizeProTab();
208 232 }
209 233 }
210 234
235 + public function criticalcss()
236 + {
237 + if ( apply_filters( 'autoptimize_filter_criticalcss_active', true ) && ! autoptimizeUtils::is_plugin_active( 'autoptimize-criticalcss/ao_criticss_aas.php' ) ) {
238 + return $this->_criticalcss;
239 + } else {
240 + return false;
241 + }
242 + }
243 +
244 + public function maybe_run_criticalcss()
245 + {
246 + // Loads criticalcss if the filter returns true & old power-up is not active.
247 + if ( apply_filters( 'autoptimize_filter_criticalcss_active', true ) && ! autoptimizeUtils::is_plugin_active( 'autoptimize-criticalcss/ao_criticss_aas.php' ) ) {
248 + $this->_criticalcss = new autoptimizeCriticalCSSBase();
249 + $this->_criticalcss->setup();
250 + $this->_criticalcss->load_requires();
251 + }
252 + }
253 +
254 + public function maybe_run_notfound_fallback()
255 + {
256 + if ( autoptimizeCache::do_fallback() ) {
257 + add_action( 'template_redirect', array( 'autoptimizeCache', 'wordpress_notfound_fallback' ) );
258 + }
259 + }
260 +
261 + public function maybe_run_ao_compat()
262 + {
263 + $conf = autoptimizeConfig::instance();
264 +
265 + // Condtionally loads the compatibility-class to ensure more out-of-the-box compatibility with big players.
266 + $_run_compat = true;
267 +
268 + if ( 'on' === $conf->get( 'autoptimize_installed_before_compatibility' ) ) {
269 + // If AO was already running before Compatibility logic was added, don't run compat by default
270 + // because it can be assumed everything works and we want to avoid (perf) regressions that
271 + // could occur due to compatibility code.
272 + $_run_compat = false;
273 + }
274 +
275 + if ( apply_filters( 'autoptimize_filter_init_compatibility', $_run_compat ) ) {
276 + new autoptimizeCompatibility();
277 + }
278 + }
279 +
211 280 public function hook_page_cache_purge()
212 281 {
213 282 // hook into a collection of page cache purge actions if filter allows.
214 283 if ( apply_filters( 'autoptimize_filter_main_hookpagecachepurge', true ) ) {
@@ -217,12 +286,15 @@
217 286 'hyper_cache_purged', // Stefano confirmed this will be added.
218 287 'w3tc_flush_posts', // exits.
219 288 'w3tc_flush_all', // exists.
220 289 'ce_action_cache_cleared', // Sven confirmed this will be added.
290 + 'aoce_action_cache_cleared', // Some other cache enabler.
221 291 'comet_cache_wipe_cache', // still to be confirmed by Raam.
222 292 'wp_cache_cleared', // cfr. https://github.com/Automattic/wp-super-cache/pull/537.
223 293 'wpfc_delete_cache', // Emre confirmed this will be added this.
224 294 'swift_performance_after_clear_all_cache', // swift perf. yeah!
295 + 'wpo_cache_flush', // wp-optimize.
296 + 'rt_nginx_helper_after_fastcgi_purge_all', // nginx helper.
225 297 );
226 298 $page_cache_purge_actions = apply_filters( 'autoptimize_filter_main_pagecachepurgeactions', $page_cache_purge_actions );
227 299 foreach ( $page_cache_purge_actions as $purge_action ) {
228 300 add_action( $purge_action, 'autoptimizeCache::clearall_actionless' );
@@ -278,9 +350,9 @@
278 350 * @param bool $doing_tests Allows overriding the optimization of only
279 351 * deciding once per request (for use in tests).
280 352 * @return bool
281 353 */
282 - public function should_buffer( $doing_tests = false )
354 + public static function should_buffer( $doing_tests = false )
283 355 {
284 356 static $do_buffering = null;
285 357
286 358 // Only check once in case we're called multiple times by others but
@@ -310,16 +382,16 @@
310 382 }
311 383 }
312 384
313 385 // If setting says not to optimize logged in user and user is logged in...
314 - if ( 'on' !== get_option( 'autoptimize_optimize_logged', 'on' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
386 + if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_logged', 'on' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
315 387 $ao_noptimize = true;
316 388 }
317 389
318 390 // If setting says not to optimize cart/checkout.
319 - if ( 'on' !== get_option( 'autoptimize_optimize_checkout', 'on' ) ) {
391 + if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_checkout', 'off' ) ) {
320 392 // Checking for woocommerce, easy digital downloads and wp ecommerce...
321 - foreach ( array( 'is_checkout', 'is_cart', 'edd_is_checkout', 'wpsc_is_cart', 'wpsc_is_checkout' ) as $func ) {
393 + foreach ( array( 'is_checkout', 'is_cart', 'is_account_page', 'edd_is_checkout', 'wpsc_is_cart', 'wpsc_is_checkout' ) as $func ) {
322 394 if ( function_exists( $func ) && $func() ) {
323 395 $ao_noptimize = true;
324 396 break;
325 397 }
@@ -325,9 +397,38 @@
325 397 }
326 398 }
327 399 }
328 400
329 - // Allows blocking of autoptimization on your own terms regardless of above decisions.
401 + // Misc. querystring paramaters that will stop AO from doing optimizations (pagebuilders +
402 + // 2 generic parameters that could/ should become standard between optimization plugins?).
403 + if ( false === $ao_noptimize ) {
404 + $_qs_showstoppers = array( 'no_cache', 'no_optimize', 'tve', 'elementor-preview', 'fl_builder', 'vc_action', 'et_fb', 'bt-beaverbuildertheme', 'ct_builder', 'fb-edit', 'siteorigin_panels_live_editor', 'preview', 'td_action' );
405 +
406 + // doing Jonathan a quick favor to allow correct unused CSS generation ;-) .
407 + if ( apply_filters( 'autoptimize_filter_main_showstoppers_do_wp_rocket_a_favor', true ) ) {
408 + $_qs_showstoppers[] = 'nowprocket';
409 + }
410 +
411 + foreach ( $_qs_showstoppers as $_showstopper ) {
412 + if ( array_key_exists( $_showstopper, $_GET ) ) {
413 + $ao_noptimize = true;
414 + break;
415 + }
416 + }
417 + }
418 +
419 + // Also honor PageSpeed=off parameter as used by mod_pagespeed, in use by some pagebuilders,
420 + // see https://www.modpagespeed.com/doc/experiment#ModPagespeed for info on that.
421 + if ( false === $ao_noptimize && array_key_exists( 'PageSpeed', $_GET ) && 'off' === $_GET['PageSpeed'] ) {
422 + $ao_noptimize = true;
423 + }
424 +
425 + // If page/ post check post_meta to see if optimize is off.
426 + if ( false === autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_optimize' ) ) {
427 + $ao_noptimize = true;
428 + }
429 +
430 + // And finally allows blocking of autoptimization on your own terms regardless of above decisions.
330 431 $ao_noptimize = (bool) apply_filters( 'autoptimize_filter_noptimize', $ao_noptimize );
331 432
332 433 // Check for site being previewed in the Customizer (available since WP 4.0).
333 434 $is_customize_preview = false;
@@ -333,8 +434,14 @@
333 434 $is_customize_preview = false;
334 435 if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
335 436 $is_customize_preview = is_customize_preview();
336 437 }
438 +
439 + // explicitly disable when is_login exists and is true but don't use it direclty because older versions of WordPress don't have that yet.
440 + $is_login = false;
441 + if ( function_exists( 'is_login' ) && true === is_login() ) {
442 + $is_login = true;
443 + }
337 444
338 445 /**
339 446 * We only buffer the frontend requests (and then only if not a feed
340 447 * and not turned off explicitly and not when being previewed in Customizer)!
@@ -341,9 +448,9 @@
341 448 * NOTE: Tests throw a notice here due to is_feed() being called
342 449 * while the main query hasn't been ran yet. Thats why we use
343 450 * AUTOPTIMIZE_INIT_EARLIER in tests.
344 451 */
345 - $do_buffering = ( ! is_admin() && ! is_feed() && ! $ao_noptimize && ! $is_customize_preview );
452 + $do_buffering = ( ! is_admin() && ! is_feed() && ! is_embed() && ! $is_login && ! $is_customize_preview && ! $ao_noptimize );
346 453 }
347 454
348 455 return $do_buffering;
349 456 }
@@ -360,10 +467,11 @@
360 467 // Defaults to true.
361 468 $valid = true;
362 469
363 470 $has_no_html_tag = ( false === stripos( $content, '<html' ) );
364 - $has_xsl_stylesheet = ( false !== stripos( $content, '<xsl:stylesheet' ) );
471 + $has_xsl_stylesheet = ( false !== stripos( $content, '<xsl:stylesheet' ) || false !== stripos( $content, '<?xml-stylesheet' ) );
365 472 $has_html5_doctype = ( preg_match( '/^<!DOCTYPE.+html>/i', ltrim( $content ) ) > 0 );
473 + $has_noptimize_page = ( false !== stripos( $content, '<!-- noptimize-page -->' ) );
366 474
367 475 if ( $has_no_html_tag ) {
368 476 // Can't be valid amp markup without an html tag preceding it.
369 477 $is_amp_markup = false;
@@ -371,9 +479,9 @@
371 479 $is_amp_markup = self::is_amp_markup( $content );
372 480 }
373 481
374 482 // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it.
375 - if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet ) {
483 + if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet || $has_noptimize_page ) {
376 484 $valid = false;
377 485 }
378 486
379 487 return $valid;
@@ -388,16 +496,31 @@
388 496 * @return bool
389 497 */
390 498 public static function is_amp_markup( $content )
391 499 {
392 - // Short-circuit when a function is available to determine whether the response is (or will be) an AMP page.
393 - if ( function_exists( 'is_amp_endpoint' ) ) {
394 - return is_amp_endpoint();
500 + // Short-circuit if the page is already AMP from the start.
501 + if (
502 + preg_match(
503 + sprintf(
504 + '#^(?:<!.*?>|\s+)*+<html(?=\s)[^>]*?\s(%1$s|%2$s|%3$s)(\s|=|>)#is',
505 + 'amp',
506 + "\xE2\x9A\xA1", // From \AmpProject\Attribute::AMP_EMOJI.
507 + "\xE2\x9A\xA1\xEF\xB8\x8F" // From \AmpProject\Attribute::AMP_EMOJI_ALT, per https://github.com/ampproject/amphtml/issues/25990.
508 + ),
509 + $content
510 + )
511 + ) {
512 + return true;
395 513 }
396 514
397 - $is_amp_markup = preg_match( '/<html[^>]*(?:amp|âš¡)/i', $content );
515 + // Or else short-circuit if the AMP plugin will be processing the output to be an AMP page.
516 + if ( function_exists( 'amp_is_request' ) ) {
517 + return amp_is_request(); // For AMP plugin v2.0+.
518 + } elseif ( function_exists( 'is_amp_endpoint' ) ) {
519 + return is_amp_endpoint(); // For older/other AMP plugins (still supported in 2.0 as an alias).
520 + }
398 521
399 - return (bool) $is_amp_markup;
522 + return false;
400 523 }
401 524
402 525 /**
403 526 * Processes/optimizes the output-buffered content and returns it.
@@ -429,16 +552,18 @@
429 552 }
430 553
431 554 $classoptions = array(
432 555 'autoptimizeScripts' => array(
433 - 'aggregate' => $conf->get( 'autoptimize_js_aggregate' ),
434 - 'justhead' => $conf->get( 'autoptimize_js_justhead' ),
435 - 'forcehead' => $conf->get( 'autoptimize_js_forcehead' ),
436 - 'trycatch' => $conf->get( 'autoptimize_js_trycatch' ),
437 - 'js_exclude' => $conf->get( 'autoptimize_js_exclude' ),
438 - 'cdn_url' => $conf->get( 'autoptimize_cdn_url' ),
439 - 'include_inline' => $conf->get( 'autoptimize_js_include_inline' ),
440 - 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
556 + 'aggregate' => $conf->get( 'autoptimize_js_aggregate' ),
557 + 'defer_not_aggregate' => $conf->get( 'autoptimize_js_defer_not_aggregate' ),
558 + 'defer_inline' => $conf->get( 'autoptimize_js_defer_inline' ),
559 + 'justhead' => $conf->get( 'autoptimize_js_justhead' ),
560 + 'forcehead' => $conf->get( 'autoptimize_js_forcehead' ),
561 + 'trycatch' => $conf->get( 'autoptimize_js_trycatch' ),
562 + 'js_exclude' => $conf->get( 'autoptimize_js_exclude' ),
563 + 'cdn_url' => $conf->get( 'autoptimize_cdn_url' ),
564 + 'include_inline' => $conf->get( 'autoptimize_js_include_inline' ),
565 + 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
441 566 ),
442 567 'autoptimizeStyles' => array(
443 568 'aggregate' => $conf->get( 'autoptimize_css_aggregate' ),
444 569 'justhead' => $conf->get( 'autoptimize_css_justhead' ),
@@ -452,9 +577,10 @@
452 577 'nogooglefont' => $conf->get( 'autoptimize_css_nogooglefont' ),
453 578 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
454 579 ),
455 580 'autoptimizeHTML' => array(
456 - 'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ),
581 + 'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ),
582 + 'minify_inline' => $conf->get( 'autoptimize_html_minify_inline' ),
457 583 ),
458 584 );
459 585
460 586 $content = apply_filters( 'autoptimize_filter_html_before_minify', $content );
@@ -474,12 +600,33 @@
474 600
475 601 return $content;
476 602 }
477 603
604 + public static function autoptimize_nobuffer_optimize( $html_in ) {
605 + $html_out = $html_in;
606 +
607 + if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
608 + $ao_speedupper = new autoptimizeSpeedupper();
609 + }
610 +
611 + $self = new self( AUTOPTIMIZE_PLUGIN_VERSION, AUTOPTIMIZE_PLUGIN_FILE );
612 + if ( $self->should_buffer() ) {
613 + $html_out = $self->end_buffering( $html_in );
614 + }
615 + return $html_out;
616 + }
617 +
478 618 public static function on_uninstall()
479 619 {
620 + // clear the cache.
480 621 autoptimizeCache::clearall();
481 622
623 + // remove postmeta if active.
624 + if ( autoptimizeConfig::is_ao_meta_settings_active() ) {
625 + delete_post_meta_by_key( 'ao_post_optimize' );
626 + }
627 +
628 + // remove all options.
482 629 $delete_options = array(
483 630 'autoptimize_cache_clean',
484 631 'autoptimize_cache_nogzip',
485 632 'autoptimize_css',
@@ -491,10 +638,15 @@
491 638 'autoptimize_css_inline',
492 639 'autoptimize_css_exclude',
493 640 'autoptimize_html',
494 641 'autoptimize_html_keepcomments',
642 + 'autoptimize_html_minify_inline',
643 + 'autoptimize_enable_site_config',
644 + 'autoptimize_enable_meta_ao_settings',
495 645 'autoptimize_js',
496 646 'autoptimize_js_aggregate',
647 + 'autoptimize_js_defer_not_aggregate',
648 + 'autoptimize_js_defer_inline',
497 649 'autoptimize_js_exclude',
498 650 'autoptimize_js_forcehead',
499 651 'autoptimize_js_justhead',
500 652 'autoptimize_js_trycatch',
@@ -511,8 +663,27 @@
511 663 'autoptimize_imgopt_provider_stat',
512 664 'autoptimize_imgopt_launched',
513 665 'autoptimize_imgopt_settings',
514 666 'autoptimize_minify_excluded',
667 + 'autoptimize_cache_fallback',
668 + 'autoptimize_ccss_rules',
669 + 'autoptimize_ccss_additional',
670 + 'autoptimize_ccss_queue',
671 + 'autoptimize_ccss_viewport',
672 + 'autoptimize_ccss_finclude',
673 + 'autoptimize_ccss_rlimit',
674 + 'autoptimize_ccss_rtimelimit',
675 + 'autoptimize_ccss_noptimize',
676 + 'autoptimize_ccss_debug',
677 + 'autoptimize_ccss_key',
678 + 'autoptimize_ccss_keyst',
679 + 'autoptimize_ccss_version',
680 + 'autoptimize_ccss_loggedin',
681 + 'autoptimize_ccss_forcepath',
682 + 'autoptimize_ccss_deferjquery',
683 + 'autoptimize_ccss_domain',
684 + 'autoptimize_ccss_unloadccss',
685 + 'autoptimize_installed_before_compatibility',
515 686 );
516 687
517 688 if ( ! is_multisite() ) {
518 689 foreach ( $delete_options as $del_opt ) {
@@ -517,8 +688,9 @@
517 688 if ( ! is_multisite() ) {
518 689 foreach ( $delete_options as $del_opt ) {
519 690 delete_option( $del_opt );
520 691 }
692 + autoptimizeMain::remove_cronjobs();
521 693 } else {
522 694 global $wpdb;
523 695 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
524 696 $original_blog_id = get_current_blog_id();
@@ -526,22 +698,60 @@
526 698 switch_to_blog( $blog_id );
527 699 foreach ( $delete_options as $del_opt ) {
528 700 delete_option( $del_opt );
529 701 }
702 + autoptimizeMain::remove_cronjobs();
530 703 }
531 704 switch_to_blog( $original_blog_id );
532 705 }
533 706
534 - if ( wp_get_schedule( 'ao_cachechecker' ) ) {
535 - wp_clear_scheduled_hook( 'ao_cachechecker' );
707 + // Remove AO CCSS cached files and directory.
708 + $ao_ccss_dir = WP_CONTENT_DIR . '/uploads/ao_ccss/';
709 + if ( file_exists( $ao_ccss_dir ) && is_dir( $ao_ccss_dir ) && defined( 'GLOB_BRACE' ) ) {
710 + // fixme: should check for subdirs when in multisite and remove contents of those as well.
711 + // fixme: if GLOB_BRACE is not avaible we need to remove AO_CCSS_DIR differently?
712 + array_map( 'unlink', glob( $ao_ccss_dir . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) );
713 + rmdir( $ao_ccss_dir );
536 714 }
715 +
716 + // Remove 404-handler (although that should have been removed in clearall already).
717 + $_fallback_php = trailingslashit( WP_CONTENT_DIR ) . 'autoptimize_404_handler.php';
718 + if ( file_exists( $_fallback_php ) ) {
719 + unlink( $_fallback_php );
720 + }
537 721 }
538 722
723 + public static function on_deactivation()
724 + {
725 + if ( is_multisite() && is_network_admin() ) {
726 + global $wpdb;
727 + $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
728 + $original_blog_id = get_current_blog_id();
729 + foreach ( $blog_ids as $blog_id ) {
730 + switch_to_blog( $blog_id );
731 + autoptimizeMain::remove_cronjobs();
732 + }
733 + switch_to_blog( $original_blog_id );
734 + } else {
735 + autoptimizeMain::remove_cronjobs();
736 + }
737 + autoptimizeCache::clearall();
738 + }
739 +
740 + public static function remove_cronjobs() {
741 + // Remove scheduled events.
742 + foreach ( array( 'ao_cachechecker', 'ao_ccss_queue', 'ao_ccss_maintenance', 'ao_ccss_keychecker' ) as $_event ) {
743 + if ( wp_get_schedule( $_event ) ) {
744 + wp_clear_scheduled_hook( $_event );
745 + }
746 + }
747 + }
748 +
539 749 public static function notice_cache_unavailable()
540 750 {
541 751 echo '<div class="error"><p>';
542 752 // Translators: %s is the cache directory location.
543 - printf( __( 'Autoptimize cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'autoptimize' ), AUTOPTIMIZE_CACHE_DIR );
753 + printf( esc_html__( 'Autoptimize cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'autoptimize' ), AUTOPTIMIZE_CACHE_DIR );
544 754 echo '</p></div>';
545 755 }
546 756
547 757 public static function notice_installed()
@@ -546,9 +756,10 @@
546 756
547 757 public static function notice_installed()
548 758 {
549 759 echo '<div class="updated"><p>';
550 - _e( 'Thank you for installing and activating Autoptimize. Please configure it under "Settings" -> "Autoptimize" to start improving your site\'s performance.', 'autoptimize' );
760 + // translators: the variables contain opening and closing <a> tags to link to the settings page.
761 + printf( esc_html__( 'Thank you for installing and activating Autoptimize. Your site is being optimized immediately, please test the frontend to ensure everything still works as expected. If needed you can change JavaScript or CSS optimization settings under %1$sSettings -> Autoptimize%2$s .', 'autoptimize' ), '<a href="options-general.php?page=autoptimize">', '</a>' );
551 762 echo '</p></div>';
552 763 }
553 764
554 765 public static function notice_updated()
@@ -553,9 +764,9 @@
553 764
554 765 public static function notice_updated()
555 766 {
556 767 echo '<div class="updated"><p>';
557 - _e( 'Autoptimize has just been updated. Please <strong>test your site now</strong> and adapt Autoptimize config if needed.', 'autoptimize' );
768 + printf( esc_html__( 'Autoptimize has just been updated. Please %1$stest your site now%2$s and adapt Autoptimize config if needed.', 'autoptimize' ), '<strong>', '</strong>' );
558 769 echo '</p></div>';
559 770 }
560 771
561 772 public static function notice_plug_imgopt()
@@ -560,17 +771,85 @@
560 771
561 772 public static function notice_plug_imgopt()
562 773 {
563 774 // Translators: the URL added points to the Autopmize Extra settings.
564 - $_ao_imgopt_plug_notice = sprintf( __( 'Did you know Autoptimize includes on-the-fly image optimization (with support for WebP) and CDN via ShortPixel? Check out the %1$sAutoptimize Image settings%2$s to activate this option.', 'autoptimize' ), '<a href="options-general.php?page=autoptimize_imgopt">', '</a>' );
775 + $_ao_imgopt_plug_notice = sprintf( esc_html__( 'Did you know that Autoptimize offers on-the-fly image optimization (with support for WebP and AVIF) and CDN via ShortPixel? Check out the %1$sAutoptimize Image settings%2$s to enable this option.', 'autoptimize' ), '<a href="options-general.php?page=autoptimize_imgopt">', '</a>' );
565 776 $_ao_imgopt_plug_notice = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
566 777 $_ao_imgopt_launch_ok = autoptimizeImages::launch_ok_wrapper();
567 778 $_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
568 779 $_ao_imgopt_active = autoptimizeImages::imgopt_active();
780 + $_is_ao_settings_page = autoptimizeUtils::is_ao_settings();
569 781
570 - if ( current_user_can( 'manage_options' ) && '' !== $_ao_imgopt_plug_notice && ! $_ao_imgopt_active && $_ao_imgopt_launch_ok && PAnD::is_admin_notice_active( $_ao_imgopt_plug_dismissible ) ) {
782 + if ( current_user_can( 'manage_options' ) && ! defined( 'AO_PRO_VERSION' ) && $_is_ao_settings_page && '' !== $_ao_imgopt_plug_notice && ! $_ao_imgopt_active && $_ao_imgopt_launch_ok && PAnD::is_admin_notice_active( $_ao_imgopt_plug_dismissible ) ) {
571 783 echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
572 784 echo $_ao_imgopt_plug_notice;
573 785 echo '</p></div>';
786 + }
787 + }
788 +
789 + public static function notice_imgopt_issue()
790 + {
791 + // Translators: the URL added points to the Autopmize Extra settings.
792 + $_ao_imgopt_issue_notice = sprintf( esc_html__( 'Shortpixel reports it cannot always reach your site, which might mean some images are not optimized. You can %1$sread more about why this happens and how you can fix that problem here%2$s.', 'autoptimize' ), '<a href="https://shortpixel.com/knowledge-base/article/469-i-received-an-e-mail-that-says-some-of-my-images-are-not-accessible-what-should-i-do#fullarticle" target="_blank">', '</a>' );
793 + $_ao_imgopt_issue_notice = apply_filters( 'autoptimize_filter_main_imgopt_issue_notice', $_ao_imgopt_issue_notice );
794 + $_ao_imgopt_issue_dismissible = 'ao-img-opt-issue-14';
795 + $_ao_imgopt_active = autoptimizeImages::imgopt_active();
796 + $_ao_imgopt_status = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_provider_stat', '' );
797 +
798 + if ( is_array( $_ao_imgopt_status ) && array_key_exists( 'TemporaryRedirectOrigin', $_ao_imgopt_status ) && ( $_ao_imgopt_status['TemporaryRedirectOrigin'] === "true" || $_ao_imgopt_status['TemporaryRedirectOrigin'] === true ) ) {
799 + $_ao_imgopt_status_redirect_warning = true;
800 + } else {
801 + $_ao_imgopt_status_redirect_warning = false;
802 + }
803 +
804 + if ( current_user_can( 'manage_options' ) && $_ao_imgopt_active && $_ao_imgopt_status_redirect_warning && '' !== $_ao_imgopt_issue_notice && PAnD::is_admin_notice_active( $_ao_imgopt_issue_dismissible ) ) {
805 + echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_issue_dismissible . '"><p>';
806 + echo $_ao_imgopt_issue_notice;
807 + echo '</p></div>';
808 + }
809 + }
810 +
811 +
812 + public static function notice_nopagecache()
813 + {
814 + /*
815 + * Autoptimize does not do page caching (yet) but not everyone knows, so below logic tries to find out if page caching is available and if not show a notice on the AO Settings pages.
816 + *
817 + * uses helper function in autoptimizeUtils.php
818 + */
819 + // translators: strong tags and a break.
820 + $_ao_nopagecache_notice = sprintf( esc_html__( 'It looks like your site might not have %1$spage caching%2$s which is a %1$smust-have for performance%2$s. If you are sure you have a page cache, you can close this notice.%3$sWhen in doubt check with your host if they offer this or install a free page caching plugin like for example KeyCDN Cache Enabler', 'autoptimize' ), '<strong>', '</strong>', '<br />' );
821 + // translators: strong tags.
822 + $_ao_nopagecache_notice .= ' ' . esc_html__('or consider ', 'autoptimize') . '<strong><a href="https://autoptimize.com/pro/">Autoptimize Pro</a></strong>' . sprintf( esc_html__( ' which not only has page caching but also image optimization, critical CSS and advanced booster options %1$sto make your site significantly faster%2$s!', 'autoptimize' ), '<strong>', '</strong>' );
823 + $_ao_nopagecache_dismissible = 'ao-nopagecache-forever'; // the notice is only shown once and will not re-appear when dismissed.
824 + $_is_ao_settings_page = autoptimizeUtils::is_ao_settings();
825 +
826 + if ( current_user_can( 'manage_options' ) && $_is_ao_settings_page && PAnD::is_admin_notice_active( $_ao_nopagecache_dismissible ) && true === apply_filters( 'autoptimize_filter_main_show_pagecache_notice', true ) ) {
827 + if ( false === autoptimizeUtils::find_pagecache() ) {
828 + echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_nopagecache_dismissible . '"><p>';
829 + echo $_ao_nopagecache_notice;
830 + echo '</p></div>';
831 + }
832 + }
833 + }
834 +
835 + public static function notice_potential_conflict()
836 + {
837 + /*
838 + * Using other plugins to do CSS/ JS optimization can cause unexpected and hard to troubleshoot issues, warn users who seem to be in that situation.
839 + */
840 + // Translators: some strong tags + the sentence will be finished with the name of the offending plugin and a final stop.
841 + $_ao_potential_conflict_notice = sprintf( esc_html__( 'It looks like you have %1$sanother plugin also doing CSS and/ or JS optimization%2$s, which can result in hard to troubleshoot %1$sconflicts%2$s. For this reason it is recommended to disable this functionality in', 'autoptimize' ), '<strong>', '</strong>' ) . ' ';
842 + $_ao_potential_conflict_dismissible = 'ao-potential-conflict-forever'; // the notice is only shown once and will not re-appear when dismissed.
843 + $_is_ao_settings_page = autoptimizeUtils::is_ao_settings();
844 +
845 + if ( current_user_can( 'manage_options' ) && $_is_ao_settings_page && PAnD::is_admin_notice_active( $_ao_potential_conflict_dismissible ) && true === apply_filters( 'autoptimize_filter_main_show_potential_conclict_notice', true ) ) {
846 + $_potential_conflicts = autoptimizeUtils::find_potential_conflicts();
847 + if ( false !== $_potential_conflicts ) {
848 + $_ao_potential_conflict_notice .= '<strong>' . $_potential_conflicts . '</strong>.';
849 + echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_potential_conflict_dismissible . '"><p>';
850 + echo $_ao_potential_conflict_notice;
851 + echo '</p></div>';
852 + }
574 853 }
575 854 }
576 855 }