PluginProbe
Autoptimize / 2.6.1
Autoptimize v2.6.1
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.6.1, at classes/autoptimizeMain.php

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