PluginProbe
Autoptimize / 2.7.6
Autoptimize v2.7.6
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 2.7.8 All 107 releases
autoptimize / classes / autoptimizeMain.php

autoptimizeMain.php in Autoptimize 2.7.6, at classes/autoptimizeMain.php

683 lines 27.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Wraps base plugin logic/hooks and handles activation/deactivation/uninstall.
4 */
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 class autoptimizeMain
11 {
12 const INIT_EARLIER_PRIORITY = -1;
13 const DEFAULT_HOOK_PRIORITY = 2;
14
15 /**
16 * Version string.
17 *
18 * @var string
19 */
20 protected $version = null;
21
22 /**
23 * Main plugin filepath.
24 * Used for activation/deactivation/uninstall hooks.
25 *
26 * @var string
27 */
28 protected $filepath = null;
29
30 /**
31 * Constructor.
32 *
33 * @param string $version Version.
34 * @param string $filepath Filepath. Needed for activation/deactivation/uninstall hooks.
35 */
36 public function __construct( $version, $filepath )
37 {
38 $this->version = $version;
39 $this->filepath = $filepath;
40 }
41
42 public function run()
43 {
44 $this->add_hooks();
45
46 // Runs cache size checker.
47 $checker = new autoptimizeCacheChecker();
48 $checker->run();
49 }
50
51 protected function add_hooks()
52 {
53 if ( ! defined( 'AUTOPTIMIZE_SETUP_INITHOOK' ) ) {
54 define( 'AUTOPTIMIZE_SETUP_INITHOOK', 'plugins_loaded' );
55 }
56
57 add_action( AUTOPTIMIZE_SETUP_INITHOOK, array( $this, 'setup' ) );
58 add_action( AUTOPTIMIZE_SETUP_INITHOOK, array( $this, 'hook_page_cache_purge' ) );
59
60 add_action( 'autoptimize_setup_done', array( $this, 'version_upgrades_check' ) );
61 add_action( 'autoptimize_setup_done', array( $this, 'check_cache_and_run' ) );
62 add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_ao_extra' ), 15 );
63 add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_partners_tab' ), 20 );
64 add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_criticalcss' ), 11 );
65 add_action( 'autoptimize_setup_done', array( $this, 'maybe_run_notfound_fallback' ), 10 );
66
67 add_action( 'init', array( $this, 'load_textdomain' ) );
68 add_action( 'admin_init', array( 'PAnD', 'init' ) );
69
70 if ( is_multisite() && is_admin() ) {
71 // Only if multisite and if in admin we want to check if we need to save options on network level.
72 add_action( 'init', 'autoptimizeOptionWrapper::check_multisite_on_saving_options' );
73 }
74
75 // register uninstall & deactivation hooks.
76 register_uninstall_hook( $this->filepath, 'autoptimizeMain::on_uninstall' );
77 register_deactivation_hook( $this->filepath, 'autoptimizeMain::on_deactivation' );
78 }
79
80 public function load_textdomain()
81 {
82 load_plugin_textdomain( 'autoptimize' );
83 }
84
85 public function setup()
86 {
87 // Do we gzip in php when caching or is the webserver doing it?
88 define( 'AUTOPTIMIZE_CACHE_NOGZIP', (bool) autoptimizeOptionWrapper::get_option( 'autoptimize_cache_nogzip' ) );
89
90 // These can be overridden by specifying them in wp-config.php or such.
91 if ( ! defined( 'AUTOPTIMIZE_WP_CONTENT_NAME' ) ) {
92 define( 'AUTOPTIMIZE_WP_CONTENT_NAME', '/' . wp_basename( WP_CONTENT_DIR ) );
93 }
94 if ( ! defined( 'AUTOPTIMIZE_CACHE_CHILD_DIR' ) ) {
95 define( 'AUTOPTIMIZE_CACHE_CHILD_DIR', '/cache/autoptimize/' );
96 }
97 if ( ! defined( 'AUTOPTIMIZE_CACHEFILE_PREFIX' ) ) {
98 define( 'AUTOPTIMIZE_CACHEFILE_PREFIX', 'autoptimize_' );
99 }
100 // Note: trailing slash is not optional!
101 if ( ! defined( 'AUTOPTIMIZE_CACHE_DIR' ) ) {
102 define( 'AUTOPTIMIZE_CACHE_DIR', autoptimizeCache::get_pathname() );
103 }
104
105 define( 'WP_ROOT_DIR', substr( WP_CONTENT_DIR, 0, strlen( WP_CONTENT_DIR ) - strlen( AUTOPTIMIZE_WP_CONTENT_NAME ) ) );
106
107 if ( ! defined( 'AUTOPTIMIZE_WP_SITE_URL' ) ) {
108 if ( function_exists( 'domain_mapping_siteurl' ) ) {
109 define( 'AUTOPTIMIZE_WP_SITE_URL', domain_mapping_siteurl( get_current_blog_id() ) );
110 } else {
111 define( 'AUTOPTIMIZE_WP_SITE_URL', site_url() );
112 }
113 }
114 if ( ! defined( 'AUTOPTIMIZE_WP_CONTENT_URL' ) ) {
115 if ( function_exists( 'get_original_url' ) ) {
116 define( 'AUTOPTIMIZE_WP_CONTENT_URL', str_replace( get_original_url( AUTOPTIMIZE_WP_SITE_URL ), AUTOPTIMIZE_WP_SITE_URL, content_url() ) );
117 } else {
118 define( 'AUTOPTIMIZE_WP_CONTENT_URL', content_url() );
119 }
120 }
121 if ( ! defined( 'AUTOPTIMIZE_CACHE_URL' ) ) {
122 if ( is_multisite() && apply_filters( 'autoptimize_separate_blog_caches', true ) ) {
123 $blog_id = get_current_blog_id();
124 define( 'AUTOPTIMIZE_CACHE_URL', AUTOPTIMIZE_WP_CONTENT_URL . AUTOPTIMIZE_CACHE_CHILD_DIR . $blog_id . '/' );
125 } else {
126 define( 'AUTOPTIMIZE_CACHE_URL', AUTOPTIMIZE_WP_CONTENT_URL . AUTOPTIMIZE_CACHE_CHILD_DIR );
127 }
128 }
129 if ( ! defined( 'AUTOPTIMIZE_WP_ROOT_URL' ) ) {
130 define( 'AUTOPTIMIZE_WP_ROOT_URL', str_replace( AUTOPTIMIZE_WP_CONTENT_NAME, '', AUTOPTIMIZE_WP_CONTENT_URL ) );
131 }
132 if ( ! defined( 'AUTOPTIMIZE_HASH' ) ) {
133 define( 'AUTOPTIMIZE_HASH', wp_hash( AUTOPTIMIZE_CACHE_URL ) );
134 }
135 if ( ! defined( 'AUTOPTIMIZE_SITE_DOMAIN' ) ) {
136 define( 'AUTOPTIMIZE_SITE_DOMAIN', parse_url( AUTOPTIMIZE_WP_SITE_URL, PHP_URL_HOST ) );
137 }
138
139 // Multibyte-capable string replacements are available with a filter.
140 // Also requires 'mbstring' extension.
141 $with_mbstring = apply_filters( 'autoptimize_filter_main_use_mbstring', false );
142 if ( $with_mbstring ) {
143 autoptimizeUtils::mbstring_available( \extension_loaded( 'mbstring' ) );
144 } else {
145 autoptimizeUtils::mbstring_available( false );
146 }
147
148 do_action( 'autoptimize_setup_done' );
149 }
150
151 /**
152 * Checks if there's a need to upgrade/update options and whatnot,
153 * in which case we might need to do stuff and flush the cache
154 * to avoid old versions of aggregated files lingering around.
155 */
156 public function version_upgrades_check()
157 {
158 autoptimizeVersionUpdatesHandler::check_installed_and_update( $this->version );
159 }
160
161 public function check_cache_and_run()
162 {
163 if ( autoptimizeCache::cacheavail() ) {
164 $conf = autoptimizeConfig::instance();
165 if ( $conf->get( 'autoptimize_html' ) || $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) || autoptimizeImages::imgopt_active() || autoptimizeImages::should_lazyload_wrapper() ) {
166 if ( ! defined( 'AUTOPTIMIZE_NOBUFFER_OPTIMIZE' ) ) {
167 // Hook into WordPress frontend.
168 if ( defined( 'AUTOPTIMIZE_INIT_EARLIER' ) ) {
169 add_action(
170 'init',
171 array( $this, 'start_buffering' ),
172 self::INIT_EARLIER_PRIORITY
173 );
174 } else {
175 if ( ! defined( 'AUTOPTIMIZE_HOOK_INTO' ) ) {
176 define( 'AUTOPTIMIZE_HOOK_INTO', 'template_redirect' );
177 }
178 add_action(
179 constant( 'AUTOPTIMIZE_HOOK_INTO' ),
180 array( $this, 'start_buffering' ),
181 self::DEFAULT_HOOK_PRIORITY
182 );
183 }
184 }
185
186 // And disable Jetpack's site accelerator if JS or CSS opt. are active.
187 if ( class_exists( 'Jetpack' ) && apply_filters( 'autoptimize_filter_main_disable_jetpack_cdn', true ) && ( $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) ) ) {
188 add_filter( 'jetpack_force_disable_site_accelerator', '__return_true' );
189 }
190 }
191 } else {
192 add_action( 'admin_notices', 'autoptimizeMain::notice_cache_unavailable' );
193 }
194 }
195
196 public function maybe_run_ao_extra()
197 {
198 if ( apply_filters( 'autoptimize_filter_extra_activate', true ) ) {
199 $ao_imgopt = new autoptimizeImages();
200 $ao_imgopt->run();
201 $ao_extra = new autoptimizeExtra();
202 $ao_extra->run();
203
204 // And show the imgopt notice.
205 add_action( 'admin_notices', 'autoptimizeMain::notice_plug_imgopt' );
206 }
207 }
208
209 public function maybe_run_partners_tab()
210 {
211 // Loads partners tab code if in admin (and not in admin-ajax.php)!
212 if ( autoptimizeConfig::is_admin_and_not_ajax() ) {
213 new autoptimizePartners();
214 }
215 }
216
217 public function maybe_run_criticalcss()
218 {
219 // Loads criticalcss if the power-up is not active and if the filter returns true.
220 if ( apply_filters( 'autoptimize_filter_criticalcss_active', true ) && ! autoptimizeUtils::is_plugin_active( 'autoptimize-criticalcss/ao_criticss_aas.php' ) ) {
221 new autoptimizeCriticalCSSBase();
222 }
223 }
224
225 public function maybe_run_notfound_fallback()
226 {
227 if ( autoptimizeCache::do_fallback() ) {
228 add_action( 'template_redirect', array( 'autoptimizeCache', 'wordpress_notfound_fallback' ) );
229 }
230 }
231
232 public function hook_page_cache_purge()
233 {
234 // hook into a collection of page cache purge actions if filter allows.
235 if ( apply_filters( 'autoptimize_filter_main_hookpagecachepurge', true ) ) {
236 $page_cache_purge_actions = array(
237 'after_rocket_clean_domain', // exists.
238 'hyper_cache_purged', // Stefano confirmed this will be added.
239 'w3tc_flush_posts', // exits.
240 'w3tc_flush_all', // exists.
241 'ce_action_cache_cleared', // Sven confirmed this will be added.
242 'aoce_action_cache_cleared', // Some other cache enabler.
243 'comet_cache_wipe_cache', // still to be confirmed by Raam.
244 'wp_cache_cleared', // cfr. https://github.com/Automattic/wp-super-cache/pull/537.
245 'wpfc_delete_cache', // Emre confirmed this will be added this.
246 'swift_performance_after_clear_all_cache', // swift perf. yeah!
247 'wpo_cache_flush', // wp-optimize.
248 'rt_nginx_helper_after_fastcgi_purge_all', // nginx helper.
249 );
250 $page_cache_purge_actions = apply_filters( 'autoptimize_filter_main_pagecachepurgeactions', $page_cache_purge_actions );
251 foreach ( $page_cache_purge_actions as $purge_action ) {
252 add_action( $purge_action, 'autoptimizeCache::clearall_actionless' );
253 }
254 }
255 }
256
257 /**
258 * Setup output buffering if needed.
259 *
260 * @return void
261 */
262 public function start_buffering()
263 {
264 if ( $this->should_buffer() ) {
265
266 // Load speedupper conditionally (true by default).
267 if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
268 $ao_speedupper = new autoptimizeSpeedupper();
269 }
270
271 $conf = autoptimizeConfig::instance();
272
273 if ( $conf->get( 'autoptimize_js' ) ) {
274 if ( ! defined( 'CONCATENATE_SCRIPTS' ) ) {
275 define( 'CONCATENATE_SCRIPTS', false );
276 }
277 if ( ! defined( 'COMPRESS_SCRIPTS' ) ) {
278 define( 'COMPRESS_SCRIPTS', false );
279 }
280 }
281
282 if ( $conf->get( 'autoptimize_css' ) ) {
283 if ( ! defined( 'COMPRESS_CSS' ) ) {
284 define( 'COMPRESS_CSS', false );
285 }
286 }
287
288 if ( apply_filters( 'autoptimize_filter_obkiller', false ) ) {
289 while ( ob_get_level() > 0 ) {
290 ob_end_clean();
291 }
292 }
293
294 // Now, start the real thing!
295 ob_start( array( $this, 'end_buffering' ) );
296 }
297 }
298
299 /**
300 * Returns true if all the conditions to start output buffering are satisfied.
301 *
302 * @param bool $doing_tests Allows overriding the optimization of only
303 * deciding once per request (for use in tests).
304 * @return bool
305 */
306 public static function should_buffer( $doing_tests = false )
307 {
308 static $do_buffering = null;
309
310 // Only check once in case we're called multiple times by others but
311 // still allows multiple calls when doing tests.
312 if ( null === $do_buffering || $doing_tests ) {
313
314 $ao_noptimize = false;
315
316 // Checking for DONOTMINIFY constant as used by e.g. WooCommerce POS.
317 if ( defined( 'DONOTMINIFY' ) && ( constant( 'DONOTMINIFY' ) === true || constant( 'DONOTMINIFY' ) === 'true' ) ) {
318 $ao_noptimize = true;
319 }
320
321 // Skip checking query strings if they're disabled.
322 if ( apply_filters( 'autoptimize_filter_honor_qs_noptimize', true ) ) {
323 // Check for `ao_noptimize` (and other) keys in the query string
324 // to get non-optimized page for debugging.
325 $keys = array(
326 'ao_noptimize',
327 'ao_noptirocket',
328 );
329 foreach ( $keys as $key ) {
330 if ( array_key_exists( $key, $_GET ) && '1' === $_GET[ $key ] ) {
331 $ao_noptimize = true;
332 break;
333 }
334 }
335 }
336
337 // If setting says not to optimize logged in user and user is logged in...
338 if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_logged', 'on' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
339 $ao_noptimize = true;
340 }
341
342 // If setting says not to optimize cart/checkout.
343 if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_checkout', 'off' ) ) {
344 // Checking for woocommerce, easy digital downloads and wp ecommerce...
345 foreach ( array( 'is_checkout', 'is_cart', 'is_account_page', 'edd_is_checkout', 'wpsc_is_cart', 'wpsc_is_checkout' ) as $func ) {
346 if ( function_exists( $func ) && $func() ) {
347 $ao_noptimize = true;
348 break;
349 }
350 }
351 }
352
353 // And make sure pagebuilder previews don't get optimized HTML/ JS/ CSS/ ...
354 if ( false === $ao_noptimize ) {
355 $_qs_pagebuilders = array( 'tve', 'elementor-preview', 'fl_builder', 'vc_action', 'et_fb', 'bt-beaverbuildertheme', 'ct_builder', 'fb-edit', 'siteorigin_panels_live_editor' );
356 foreach ( $_qs_pagebuilders as $_pagebuilder ) {
357 if ( array_key_exists( $_pagebuilder, $_GET ) ) {
358 $ao_noptimize = true;
359 break;
360 }
361 }
362 }
363
364 // Also honor PageSpeed=off parameter as used by mod_pagespeed, in use by some pagebuilders,
365 // see https://www.modpagespeed.com/doc/experiment#ModPagespeed for info on that.
366 if ( false === $ao_noptimize && array_key_exists( 'PageSpeed', $_GET ) && 'off' === $_GET['PageSpeed'] ) {
367 $ao_noptimize = true;
368 }
369
370 // And finally allows blocking of autoptimization on your own terms regardless of above decisions.
371 $ao_noptimize = (bool) apply_filters( 'autoptimize_filter_noptimize', $ao_noptimize );
372
373 // Check for site being previewed in the Customizer (available since WP 4.0).
374 $is_customize_preview = false;
375 if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
376 $is_customize_preview = is_customize_preview();
377 }
378
379 /**
380 * We only buffer the frontend requests (and then only if not a feed
381 * and not turned off explicitly and not when being previewed in Customizer)!
382 * NOTE: Tests throw a notice here due to is_feed() being called
383 * while the main query hasn't been ran yet. Thats why we use
384 * AUTOPTIMIZE_INIT_EARLIER in tests.
385 */
386 $do_buffering = ( ! is_admin() && ! is_feed() && ! is_embed() && ! $ao_noptimize && ! $is_customize_preview );
387 }
388
389 return $do_buffering;
390 }
391
392 /**
393 * Returns true if given markup is considered valid/processable/optimizable.
394 *
395 * @param string $content Markup.
396 *
397 * @return bool
398 */
399 public function is_valid_buffer( $content )
400 {
401 // Defaults to true.
402 $valid = true;
403
404 $has_no_html_tag = ( false === stripos( $content, '<html' ) );
405 $has_xsl_stylesheet = ( false !== stripos( $content, '<xsl:stylesheet' ) || false !== stripos( $content, '<?xml-stylesheet' ) );
406 $has_html5_doctype = ( preg_match( '/^<!DOCTYPE.+html>/i', ltrim( $content ) ) > 0 );
407 $has_noptimize_page = ( false !== stripos( $content, '<!-- noptimize-page -->' ) );
408
409 if ( $has_no_html_tag ) {
410 // Can't be valid amp markup without an html tag preceding it.
411 $is_amp_markup = false;
412 } else {
413 $is_amp_markup = self::is_amp_markup( $content );
414 }
415
416 // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it.
417 if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet || $has_noptimize_page ) {
418 $valid = false;
419 }
420
421 return $valid;
422 }
423
424 /**
425 * Returns true if given $content is considered to be AMP markup.
426 * This is far from actual validation against AMP spec, but it'll do for now.
427 *
428 * @param string $content Markup to check.
429 *
430 * @return bool
431 */
432 public static function is_amp_markup( $content )
433 {
434 // Short-circuit when a function is available to determine whether the response is (or will be) an AMP page.
435 if ( function_exists( 'is_amp_endpoint' ) ) {
436 return is_amp_endpoint();
437 }
438
439 $is_amp_markup = preg_match( '/<html[^>]*(?:amp|âš¡)/i', $content );
440
441 return (bool) $is_amp_markup;
442 }
443
444 /**
445 * Processes/optimizes the output-buffered content and returns it.
446 * If the content is not processable, it is returned unmodified.
447 *
448 * @param string $content Buffered content.
449 *
450 * @return string
451 */
452 public function end_buffering( $content )
453 {
454 // Bail early without modifying anything if we can't handle the content.
455 if ( ! $this->is_valid_buffer( $content ) ) {
456 return $content;
457 }
458
459 $conf = autoptimizeConfig::instance();
460
461 // Determine what needs to be ran.
462 $classes = array();
463 if ( $conf->get( 'autoptimize_js' ) ) {
464 $classes[] = 'autoptimizeScripts';
465 }
466 if ( $conf->get( 'autoptimize_css' ) ) {
467 $classes[] = 'autoptimizeStyles';
468 }
469 if ( $conf->get( 'autoptimize_html' ) ) {
470 $classes[] = 'autoptimizeHTML';
471 }
472
473 $classoptions = array(
474 'autoptimizeScripts' => array(
475 'aggregate' => $conf->get( 'autoptimize_js_aggregate' ),
476 'justhead' => $conf->get( 'autoptimize_js_justhead' ),
477 'forcehead' => $conf->get( 'autoptimize_js_forcehead' ),
478 'trycatch' => $conf->get( 'autoptimize_js_trycatch' ),
479 'js_exclude' => $conf->get( 'autoptimize_js_exclude' ),
480 'cdn_url' => $conf->get( 'autoptimize_cdn_url' ),
481 'include_inline' => $conf->get( 'autoptimize_js_include_inline' ),
482 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
483 ),
484 'autoptimizeStyles' => array(
485 'aggregate' => $conf->get( 'autoptimize_css_aggregate' ),
486 'justhead' => $conf->get( 'autoptimize_css_justhead' ),
487 'datauris' => $conf->get( 'autoptimize_css_datauris' ),
488 'defer' => $conf->get( 'autoptimize_css_defer' ),
489 'defer_inline' => $conf->get( 'autoptimize_css_defer_inline' ),
490 'inline' => $conf->get( 'autoptimize_css_inline' ),
491 'css_exclude' => $conf->get( 'autoptimize_css_exclude' ),
492 'cdn_url' => $conf->get( 'autoptimize_cdn_url' ),
493 'include_inline' => $conf->get( 'autoptimize_css_include_inline' ),
494 'nogooglefont' => $conf->get( 'autoptimize_css_nogooglefont' ),
495 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
496 ),
497 'autoptimizeHTML' => array(
498 'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ),
499 ),
500 );
501
502 $content = apply_filters( 'autoptimize_filter_html_before_minify', $content );
503
504 // Run the classes!
505 foreach ( $classes as $name ) {
506 $instance = new $name( $content );
507 if ( $instance->read( $classoptions[ $name ] ) ) {
508 $instance->minify();
509 $instance->cache();
510 $content = $instance->getcontent();
511 }
512 unset( $instance );
513 }
514
515 $content = apply_filters( 'autoptimize_html_after_minify', $content );
516
517 return $content;
518 }
519
520 public static function autoptimize_nobuffer_optimize( $html_in ) {
521 $html_out = $html_in;
522
523 if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
524 $ao_speedupper = new autoptimizeSpeedupper();
525 }
526
527 $self = new self( AUTOPTIMIZE_PLUGIN_VERSION, AUTOPTIMIZE_PLUGIN_FILE );
528 if ( $self->should_buffer() ) {
529 $html_out = $self->end_buffering( $html_in );
530 }
531 return $html_out;
532 }
533
534 public static function on_uninstall()
535 {
536 autoptimizeCache::clearall();
537
538 $delete_options = array(
539 'autoptimize_cache_clean',
540 'autoptimize_cache_nogzip',
541 'autoptimize_css',
542 'autoptimize_css_aggregate',
543 'autoptimize_css_datauris',
544 'autoptimize_css_justhead',
545 'autoptimize_css_defer',
546 'autoptimize_css_defer_inline',
547 'autoptimize_css_inline',
548 'autoptimize_css_exclude',
549 'autoptimize_html',
550 'autoptimize_html_keepcomments',
551 'autoptimize_enable_site_config',
552 'autoptimize_js',
553 'autoptimize_js_aggregate',
554 'autoptimize_js_exclude',
555 'autoptimize_js_forcehead',
556 'autoptimize_js_justhead',
557 'autoptimize_js_trycatch',
558 'autoptimize_version',
559 'autoptimize_show_adv',
560 'autoptimize_cdn_url',
561 'autoptimize_cachesize_notice',
562 'autoptimize_css_include_inline',
563 'autoptimize_js_include_inline',
564 'autoptimize_optimize_logged',
565 'autoptimize_optimize_checkout',
566 'autoptimize_extra_settings',
567 'autoptimize_service_availablity',
568 'autoptimize_imgopt_provider_stat',
569 'autoptimize_imgopt_launched',
570 'autoptimize_imgopt_settings',
571 'autoptimize_minify_excluded',
572 'autoptimize_cache_fallback',
573 'autoptimize_ccss_rules',
574 'autoptimize_ccss_additional',
575 'autoptimize_ccss_queue',
576 'autoptimize_ccss_viewport',
577 'autoptimize_ccss_finclude',
578 'autoptimize_ccss_rlimit',
579 'autoptimize_ccss_noptimize',
580 'autoptimize_ccss_debug',
581 'autoptimize_ccss_key',
582 'autoptimize_ccss_keyst',
583 'autoptimize_ccss_version',
584 'autoptimize_ccss_loggedin',
585 'autoptimize_ccss_forcepath',
586 'autoptimize_ccss_deferjquery',
587 'autoptimize_ccss_domain',
588 'autoptimize_ccss_unloadccss',
589 );
590
591 if ( ! is_multisite() ) {
592 foreach ( $delete_options as $del_opt ) {
593 delete_option( $del_opt );
594 }
595 autoptimizeMain::remove_cronjobs();
596 } else {
597 global $wpdb;
598 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
599 $original_blog_id = get_current_blog_id();
600 foreach ( $blog_ids as $blog_id ) {
601 switch_to_blog( $blog_id );
602 foreach ( $delete_options as $del_opt ) {
603 delete_option( $del_opt );
604 }
605 autoptimizeMain::remove_cronjobs();
606 }
607 switch_to_blog( $original_blog_id );
608 }
609
610 // Remove AO CCSS cached files and directory.
611 $ao_ccss_dir = WP_CONTENT_DIR . '/uploads/ao_ccss/';
612 if ( file_exists( $ao_ccss_dir ) && is_dir( $ao_ccss_dir ) ) {
613 // fixme: should check for subdirs when in multisite and remove contents of those as well.
614 array_map( 'unlink', glob( AO_CCSS_DIR . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) );
615 rmdir( AO_CCSS_DIR );
616 }
617 }
618
619 public static function on_deactivation()
620 {
621 if ( is_multisite() && is_network_admin() ) {
622 global $wpdb;
623 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
624 $original_blog_id = get_current_blog_id();
625 foreach ( $blog_ids as $blog_id ) {
626 switch_to_blog( $blog_id );
627 autoptimizeMain::remove_cronjobs();
628 }
629 switch_to_blog( $original_blog_id );
630 } else {
631 autoptimizeMain::remove_cronjobs();
632 }
633 autoptimizeCache::clearall();
634 }
635
636 public static function remove_cronjobs() {
637 // Remove scheduled events.
638 foreach ( array( 'ao_cachechecker', 'ao_ccss_queue', 'ao_ccss_maintenance' ) as $_event ) {
639 if ( wp_get_schedule( $_event ) ) {
640 wp_clear_scheduled_hook( $_event );
641 }
642 }
643 }
644
645 public static function notice_cache_unavailable()
646 {
647 echo '<div class="error"><p>';
648 // Translators: %s is the cache directory location.
649 printf( __( 'Autoptimize cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'autoptimize' ), AUTOPTIMIZE_CACHE_DIR );
650 echo '</p></div>';
651 }
652
653 public static function notice_installed()
654 {
655 echo '<div class="updated"><p>';
656 _e( 'Thank you for installing and activating Autoptimize. Please configure it under "Settings" -> "Autoptimize" to start improving your site\'s performance.', 'autoptimize' );
657 echo '</p></div>';
658 }
659
660 public static function notice_updated()
661 {
662 echo '<div class="updated"><p>';
663 _e( 'Autoptimize has just been updated. Please <strong>test your site now</strong> and adapt Autoptimize config if needed.', 'autoptimize' );
664 echo '</p></div>';
665 }
666
667 public static function notice_plug_imgopt()
668 {
669 // Translators: the URL added points to the Autopmize Extra settings.
670 $_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>' );
671 $_ao_imgopt_plug_notice = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
672 $_ao_imgopt_launch_ok = autoptimizeImages::launch_ok_wrapper();
673 $_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
674 $_ao_imgopt_active = autoptimizeImages::imgopt_active();
675
676 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 ) ) {
677 echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
678 echo $_ao_imgopt_plug_notice;
679 echo '</p></div>';
680 }
681 }
682 }
683