Completed
Push — master ( 0e3b51...8538b3 )
by frank
01:43
created

autoptimizeMain::notice_installed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
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
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 uninstall & deactivation hooks.
75
        register_uninstall_hook( $this->filepath, 'autoptimizeMain::on_uninstall' );
76
        register_deactivation_hook( $this->filepath, 'autoptimizeMain::on_deactivation' );
77
    }
78
79
    public function load_textdomain()
80
    {
81
        load_plugin_textdomain( 'autoptimize' );
82
    }
83
84
    public function setup()
85
    {
86
        // Do we gzip in php when caching or is the webserver doing it?
87
        define( 'AUTOPTIMIZE_CACHE_NOGZIP', (bool) autoptimizeOptionWrapper::get_option( 'autoptimize_cache_nogzip' ) );
88
89
        // These can be overridden by specifying them in wp-config.php or such.
90
        if ( ! defined( 'AUTOPTIMIZE_WP_CONTENT_NAME' ) ) {
91
            define( 'AUTOPTIMIZE_WP_CONTENT_NAME', '/' . wp_basename( WP_CONTENT_DIR ) );
92
        }
93
        if ( ! defined( 'AUTOPTIMIZE_CACHE_CHILD_DIR' ) ) {
94
            define( 'AUTOPTIMIZE_CACHE_CHILD_DIR', '/cache/autoptimize/' );
95
        }
96
        if ( ! defined( 'AUTOPTIMIZE_CACHEFILE_PREFIX' ) ) {
97
            define( 'AUTOPTIMIZE_CACHEFILE_PREFIX', 'autoptimize_' );
98
        }
99
        // Note: trailing slash is not optional!
100
        if ( ! defined( 'AUTOPTIMIZE_CACHE_DIR' ) ) {
101
            define( 'AUTOPTIMIZE_CACHE_DIR', autoptimizeCache::get_pathname() );
102
        }
103
104
        define( 'WP_ROOT_DIR', substr( WP_CONTENT_DIR, 0, strlen( WP_CONTENT_DIR ) - strlen( AUTOPTIMIZE_WP_CONTENT_NAME ) ) );
105
106
        if ( ! defined( 'AUTOPTIMIZE_WP_SITE_URL' ) ) {
107
            if ( function_exists( 'domain_mapping_siteurl' ) ) {
108
                define( 'AUTOPTIMIZE_WP_SITE_URL', domain_mapping_siteurl( get_current_blog_id() ) );
109
            } else {
110
                define( 'AUTOPTIMIZE_WP_SITE_URL', site_url() );
111
            }
112
        }
113
        if ( ! defined( 'AUTOPTIMIZE_WP_CONTENT_URL' ) ) {
114
            if ( function_exists( 'get_original_url' ) ) {
115
                define( 'AUTOPTIMIZE_WP_CONTENT_URL', str_replace( get_original_url( AUTOPTIMIZE_WP_SITE_URL ), AUTOPTIMIZE_WP_SITE_URL, content_url() ) );
116
            } else {
117
                define( 'AUTOPTIMIZE_WP_CONTENT_URL', content_url() );
118
            }
119
        }
120
        if ( ! defined( 'AUTOPTIMIZE_CACHE_URL' ) ) {
121
            if ( is_multisite() && apply_filters( 'autoptimize_separate_blog_caches', true ) ) {
122
                $blog_id = get_current_blog_id();
123
                define( 'AUTOPTIMIZE_CACHE_URL', AUTOPTIMIZE_WP_CONTENT_URL . AUTOPTIMIZE_CACHE_CHILD_DIR . $blog_id . '/' );
124
            } else {
125
                define( 'AUTOPTIMIZE_CACHE_URL', AUTOPTIMIZE_WP_CONTENT_URL . AUTOPTIMIZE_CACHE_CHILD_DIR );
126
            }
127
        }
128
        if ( ! defined( 'AUTOPTIMIZE_WP_ROOT_URL' ) ) {
129
            define( 'AUTOPTIMIZE_WP_ROOT_URL', str_replace( AUTOPTIMIZE_WP_CONTENT_NAME, '', AUTOPTIMIZE_WP_CONTENT_URL ) );
130
        }
131
        if ( ! defined( 'AUTOPTIMIZE_HASH' ) ) {
132
            define( 'AUTOPTIMIZE_HASH', wp_hash( AUTOPTIMIZE_CACHE_URL ) );
133
        }
134
        if ( ! defined( 'AUTOPTIMIZE_SITE_DOMAIN' ) ) {
135
            define( 'AUTOPTIMIZE_SITE_DOMAIN', parse_url( AUTOPTIMIZE_WP_SITE_URL, PHP_URL_HOST ) );
136
        }
137
138
        // Multibyte-capable string replacements are available with a filter.
139
        // Also requires 'mbstring' extension.
140
        $with_mbstring = apply_filters( 'autoptimize_filter_main_use_mbstring', false );
141
        if ( $with_mbstring ) {
142
            autoptimizeUtils::mbstring_available( \extension_loaded( 'mbstring' ) );
143
        } else {
144
            autoptimizeUtils::mbstring_available( false );
145
        }
146
147
        do_action( 'autoptimize_setup_done' );
148
    }
149
150
    /**
151
     * Checks if there's a need to upgrade/update options and whatnot,
152
     * in which case we might need to do stuff and flush the cache
153
     * to avoid old versions of aggregated files lingering around.
154
     */
155
    public function version_upgrades_check()
156
    {
157
        autoptimizeVersionUpdatesHandler::check_installed_and_update( $this->version );
158
    }
159
160
    public function check_cache_and_run()
161
    {
162
        if ( autoptimizeCache::cacheavail() ) {
163
            $conf = autoptimizeConfig::instance();
164
            if ( $conf->get( 'autoptimize_html' ) || $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) || autoptimizeImages::imgopt_active() || autoptimizeImages::should_lazyload_wrapper() ) {
165
                if ( ! defined( 'AUTOPTIMIZE_NOBUFFER_OPTIMIZE' ) ) {
166
                    // Hook into WordPress frontend.
167
                    if ( defined( 'AUTOPTIMIZE_INIT_EARLIER' ) ) {
168
                        add_action(
169
                            'init',
170
                            array( $this, 'start_buffering' ),
171
                            self::INIT_EARLIER_PRIORITY
172
                        );
173
                    } else {
174
                        if ( ! defined( 'AUTOPTIMIZE_HOOK_INTO' ) ) {
175
                            define( 'AUTOPTIMIZE_HOOK_INTO', 'template_redirect' );
176
                        }
177
                        add_action(
178
                            constant( 'AUTOPTIMIZE_HOOK_INTO' ),
179
                            array( $this, 'start_buffering' ),
180
                            self::DEFAULT_HOOK_PRIORITY
181
                        );
182
                    }
183
                }
184
185
                // And disable Jetpack's site accelerator if JS or CSS opt. are active.
186
                if ( class_exists( 'Jetpack' ) && apply_filters( 'autoptimize_filter_main_disable_jetpack_cdn', true ) && ( $conf->get( 'autoptimize_js' ) || $conf->get( 'autoptimize_css' ) ) ) {
187
                    add_filter( 'jetpack_force_disable_site_accelerator', '__return_true' );
188
                }
189
            }
190
        } else {
191
            add_action( 'admin_notices', 'autoptimizeMain::notice_cache_unavailable' );
192
        }
193
    }
194
195
    public function maybe_run_ao_extra()
196
    {
197
        if ( apply_filters( 'autoptimize_filter_extra_activate', true ) ) {
198
            $ao_imgopt = new autoptimizeImages();
199
            $ao_imgopt->run();
200
            $ao_extra = new autoptimizeExtra();
201
            $ao_extra->run();
202
203
            // And show the imgopt notice.
204
            add_action( 'admin_notices', 'autoptimizeMain::notice_plug_imgopt' );
205
        }
206
    }
207
208
    public function maybe_run_partners_tab()
209
    {
210
        // Loads partners tab code if in admin (and not in admin-ajax.php)!
211
        if ( autoptimizeConfig::is_admin_and_not_ajax() ) {
212
            new autoptimizePartners();
213
        }
214
    }
215
216
    public function maybe_run_criticalcss()
217
    {
218
        // Loads criticalcss if the power-up is not active and if the filter returns true.
219
        if ( apply_filters( 'autoptimize_filter_criticalcss_active', true ) && ! autoptimizeUtils::is_plugin_active( 'autoptimize-criticalcss/ao_criticss_aas.php' ) ) {
220
            new autoptimizeCriticalCSSBase();
221
        }
222
    }
223
224
    public function maybe_run_notfound_fallback()
225
    {
226
        if ( autoptimizeCache::do_fallback() ) {
227
            add_action( 'template_redirect', array( 'autoptimizeCache', 'wordpress_notfound_fallback' ) );
228
        }
229
    }
230
231
    public function hook_page_cache_purge()
232
    {
233
        // hook into a collection of page cache purge actions if filter allows.
234
        if ( apply_filters( 'autoptimize_filter_main_hookpagecachepurge', true ) ) {
235
            $page_cache_purge_actions = array(
236
                'after_rocket_clean_domain', // exists.
237
                'hyper_cache_purged', // Stefano confirmed this will be added.
238
                'w3tc_flush_posts', // exits.
239
                'w3tc_flush_all', // exists.
240
                'ce_action_cache_cleared', // Sven confirmed this will be added.
241
                'aoce_action_cache_cleared', // Some other cache enabler.
242
                'comet_cache_wipe_cache', // still to be confirmed by Raam.
243
                'wp_cache_cleared', // cfr. https://github.com/Automattic/wp-super-cache/pull/537.
244
                'wpfc_delete_cache', // Emre confirmed this will be added this.
245
                'swift_performance_after_clear_all_cache', // swift perf. yeah!
246
                'wpo_cache_flush', // wp-optimize.
247
                'rt_nginx_helper_after_fastcgi_purge_all', // nginx helper.
248
            );
249
            $page_cache_purge_actions = apply_filters( 'autoptimize_filter_main_pagecachepurgeactions', $page_cache_purge_actions );
250
            foreach ( $page_cache_purge_actions as $purge_action ) {
251
                add_action( $purge_action, 'autoptimizeCache::clearall_actionless' );
252
            }
253
        }
254
    }
255
256
    /**
257
     * Setup output buffering if needed.
258
     *
259
     * @return void
260
     */
261
    public function start_buffering()
262
    {
263
        if ( $this->should_buffer() ) {
264
265
            // Load speedupper conditionally (true by default).
266
            if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
267
                $ao_speedupper = new autoptimizeSpeedupper();
0 ignored issues
show
Unused Code introduced by
$ao_speedupper is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
268
            }
269
270
            $conf = autoptimizeConfig::instance();
271
272
            if ( $conf->get( 'autoptimize_js' ) ) {
273
                if ( ! defined( 'CONCATENATE_SCRIPTS' ) ) {
274
                    define( 'CONCATENATE_SCRIPTS', false );
275
                }
276
                if ( ! defined( 'COMPRESS_SCRIPTS' ) ) {
277
                    define( 'COMPRESS_SCRIPTS', false );
278
                }
279
            }
280
281
            if ( $conf->get( 'autoptimize_css' ) ) {
282
                if ( ! defined( 'COMPRESS_CSS' ) ) {
283
                    define( 'COMPRESS_CSS', false );
284
                }
285
            }
286
287
            if ( apply_filters( 'autoptimize_filter_obkiller', false ) ) {
288
                while ( ob_get_level() > 0 ) {
289
                    ob_end_clean();
290
                }
291
            }
292
293
            // Now, start the real thing!
294
            ob_start( array( $this, 'end_buffering' ) );
295
        }
296
    }
297
298
    /**
299
     * Returns true if all the conditions to start output buffering are satisfied.
300
     *
301
     * @param bool $doing_tests Allows overriding the optimization of only
302
     *                          deciding once per request (for use in tests).
303
     * @return bool
304
     */
305
    public static function should_buffer( $doing_tests = false )
306
    {
307
        static $do_buffering = null;
308
309
        // Only check once in case we're called multiple times by others but
310
        // still allows multiple calls when doing tests.
311
        if ( null === $do_buffering || $doing_tests ) {
312
313
            $ao_noptimize = false;
314
315
            // Checking for DONOTMINIFY constant as used by e.g. WooCommerce POS.
316
            if ( defined( 'DONOTMINIFY' ) && ( constant( 'DONOTMINIFY' ) === true || constant( 'DONOTMINIFY' ) === 'true' ) ) {
317
                $ao_noptimize = true;
318
            }
319
320
            // Skip checking query strings if they're disabled.
321
            if ( apply_filters( 'autoptimize_filter_honor_qs_noptimize', true ) ) {
322
                // Check for `ao_noptimize` (and other) keys in the query string
323
                // to get non-optimized page for debugging.
324
                $keys = array(
325
                    'ao_noptimize',
326
                    'ao_noptirocket',
327
                );
328
                foreach ( $keys as $key ) {
329
                    if ( array_key_exists( $key, $_GET ) && '1' === $_GET[ $key ] ) {
330
                        $ao_noptimize = true;
331
                        break;
332
                    }
333
                }
334
            }
335
336
            // If setting says not to optimize logged in user and user is logged in...
337
            if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_logged', 'on' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
338
                $ao_noptimize = true;
339
            }
340
341
            // If setting says not to optimize cart/checkout.
342
            if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_checkout', 'off' ) ) {
343
                // Checking for woocommerce, easy digital downloads and wp ecommerce...
344
                foreach ( array( 'is_checkout', 'is_cart', 'is_account_page', 'edd_is_checkout', 'wpsc_is_cart', 'wpsc_is_checkout' ) as $func ) {
345
                    if ( function_exists( $func ) && $func() ) {
346
                        $ao_noptimize = true;
347
                        break;
348
                    }
349
                }
350
            }
351
352
            // And make sure pagebuilder previews don't get optimized HTML/ JS/ CSS/ ...
353
            if ( false === $ao_noptimize ) {
354
                $_qs_pagebuilders = array( 'tve', 'elementor-preview', 'fl_builder', 'vc_action', 'et_fb', 'bt-beaverbuildertheme', 'ct_builder', 'fb-edit', 'siteorigin_panels_live_editor' );
355
                foreach ( $_qs_pagebuilders as $_pagebuilder ) {
356
                    if ( array_key_exists( $_pagebuilder, $_GET ) ) {
357
                        $ao_noptimize = true;
358
                        break;
359
                    }
360
                }
361
            }
362
363
            // Also honor PageSpeed=off parameter as used by mod_pagespeed, in use by some pagebuilders,
364
            // see https://www.modpagespeed.com/doc/experiment#ModPagespeed for info on that.
365
            if ( false === $ao_noptimize && array_key_exists( 'PageSpeed', $_GET ) && 'off' === $_GET['PageSpeed'] ) {
366
                $ao_noptimize = true;
367
            }
368
369
            // And finally allows blocking of autoptimization on your own terms regardless of above decisions.
370
            $ao_noptimize = (bool) apply_filters( 'autoptimize_filter_noptimize', $ao_noptimize );
371
372
            // Check for site being previewed in the Customizer (available since WP 4.0).
373
            $is_customize_preview = false;
374
            if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
375
                $is_customize_preview = is_customize_preview();
376
            }
377
378
            /**
379
             * We only buffer the frontend requests (and then only if not a feed
380
             * and not turned off explicitly and not when being previewed in Customizer)!
381
             * NOTE: Tests throw a notice here due to is_feed() being called
382
             * while the main query hasn't been ran yet. Thats why we use
383
             * AUTOPTIMIZE_INIT_EARLIER in tests.
384
             */
385
            $do_buffering = ( ! is_admin() && ! is_feed() && ! is_embed() && ! $ao_noptimize && ! $is_customize_preview );
386
        }
387
388
        return $do_buffering;
389
    }
390
391
    /**
392
     * Returns true if given markup is considered valid/processable/optimizable.
393
     *
394
     * @param string $content Markup.
395
     *
396
     * @return bool
397
     */
398
    public function is_valid_buffer( $content )
399
    {
400
        // Defaults to true.
401
        $valid = true;
402
403
        $has_no_html_tag    = ( false === stripos( $content, '<html' ) );
404
        $has_xsl_stylesheet = ( false !== stripos( $content, '<xsl:stylesheet' ) || false !== stripos( $content, '<?xml-stylesheet' ) );
405
        $has_html5_doctype  = ( preg_match( '/^<!DOCTYPE.+html>/i', ltrim( $content ) ) > 0 );
406
        $has_noptimize_page = ( false !== stripos( $content, '<!-- noptimize-page -->' ) );
407
408
        if ( $has_no_html_tag ) {
409
            // Can't be valid amp markup without an html tag preceding it.
410
            $is_amp_markup = false;
411
        } else {
412
            $is_amp_markup = self::is_amp_markup( $content );
413
        }
414
415
        // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it.
416
        if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet || $has_noptimize_page ) {
417
            $valid = false;
418
        }
419
420
        return $valid;
421
    }
422
423
    /**
424
     * Returns true if given $content is considered to be AMP markup.
425
     * This is far from actual validation against AMP spec, but it'll do for now.
426
     *
427
     * @param string $content Markup to check.
428
     *
429
     * @return bool
430
     */
431
    public static function is_amp_markup( $content )
432
    {
433
        // Short-circuit if the page is already AMP from the start.
434
        if (
435
            preg_match(
436
                sprintf(
437
                    '#^(?:<!.*?>|\s+)*+<html(?=\s)[^>]*?\s(%1$s|%2$s|%3$s)(\s|=|>)#is',
438
                    'amp',
439
                    "\xE2\x9A\xA1", // From \AmpProject\Attribute::AMP_EMOJI.
440
                    "\xE2\x9A\xA1\xEF\xB8\x8F" // From \AmpProject\Attribute::AMP_EMOJI_ALT, per https://github.com/ampproject/amphtml/issues/25990.
441
                ),
442
                $content
443
            )
444
        ) {
445
            return true;
446
        }
447
448
        // Or else short-circuit if the AMP plugin will be processing the output to be an AMP page.
449
        if ( function_exists( 'amp_is_request' ) ) {
450
            return amp_is_request(); // For AMP plugin v2.0+.
451
        } elseif ( function_exists( 'is_amp_endpoint' ) ) {
452
            return is_amp_endpoint(); // For older/other AMP plugins (still supported in 2.0 as an alias).
453
        }
454
455
        return false;
456
    }
457
458
    /**
459
     * Processes/optimizes the output-buffered content and returns it.
460
     * If the content is not processable, it is returned unmodified.
461
     *
462
     * @param string $content Buffered content.
463
     *
464
     * @return string
465
     */
466
    public function end_buffering( $content )
467
    {
468
        // Bail early without modifying anything if we can't handle the content.
469
        if ( ! $this->is_valid_buffer( $content ) ) {
470
            return $content;
471
        }
472
473
        $conf = autoptimizeConfig::instance();
474
475
        // Determine what needs to be ran.
476
        $classes = array();
477
        if ( $conf->get( 'autoptimize_js' ) ) {
478
            $classes[] = 'autoptimizeScripts';
479
        }
480
        if ( $conf->get( 'autoptimize_css' ) ) {
481
            $classes[] = 'autoptimizeStyles';
482
        }
483
        if ( $conf->get( 'autoptimize_html' ) ) {
484
            $classes[] = 'autoptimizeHTML';
485
        }
486
487
        $classoptions = array(
488
            'autoptimizeScripts' => array(
489
                'aggregate'           => $conf->get( 'autoptimize_js_aggregate' ),
490
                'defer_not_aggregate' => $conf->get( 'autoptimize_js_defer_not_aggregate' ),
491
                'justhead'            => $conf->get( 'autoptimize_js_justhead' ),
492
                'forcehead'           => $conf->get( 'autoptimize_js_forcehead' ),
493
                'trycatch'            => $conf->get( 'autoptimize_js_trycatch' ),
494
                'js_exclude'          => $conf->get( 'autoptimize_js_exclude' ),
495
                'cdn_url'             => $conf->get( 'autoptimize_cdn_url' ),
496
                'include_inline'      => $conf->get( 'autoptimize_js_include_inline' ),
497
                'minify_excluded'     => $conf->get( 'autoptimize_minify_excluded' ),
498
            ),
499
            'autoptimizeStyles'  => array(
500
                'aggregate'       => $conf->get( 'autoptimize_css_aggregate' ),
501
                'justhead'        => $conf->get( 'autoptimize_css_justhead' ),
502
                'datauris'        => $conf->get( 'autoptimize_css_datauris' ),
503
                'defer'           => $conf->get( 'autoptimize_css_defer' ),
504
                'defer_inline'    => $conf->get( 'autoptimize_css_defer_inline' ),
505
                'inline'          => $conf->get( 'autoptimize_css_inline' ),
506
                'css_exclude'     => $conf->get( 'autoptimize_css_exclude' ),
507
                'cdn_url'         => $conf->get( 'autoptimize_cdn_url' ),
508
                'include_inline'  => $conf->get( 'autoptimize_css_include_inline' ),
509
                'nogooglefont'    => $conf->get( 'autoptimize_css_nogooglefont' ),
510
                'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
511
            ),
512
            'autoptimizeHTML'    => array(
513
                'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ),
514
            ),
515
        );
516
517
        $content = apply_filters( 'autoptimize_filter_html_before_minify', $content );
518
519
        // Run the classes!
520
        foreach ( $classes as $name ) {
521
            $instance = new $name( $content );
522
            if ( $instance->read( $classoptions[ $name ] ) ) {
523
                $instance->minify();
524
                $instance->cache();
525
                $content = $instance->getcontent();
526
            }
527
            unset( $instance );
528
        }
529
530
        $content = apply_filters( 'autoptimize_html_after_minify', $content );
531
532
        return $content;
533
    }
534
535
    public static function autoptimize_nobuffer_optimize( $html_in ) {
536
        $html_out = $html_in;
537
538
        if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
539
            $ao_speedupper = new autoptimizeSpeedupper();
0 ignored issues
show
Unused Code introduced by
$ao_speedupper is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
540
        }
541
542
        $self = new self( AUTOPTIMIZE_PLUGIN_VERSION, AUTOPTIMIZE_PLUGIN_FILE );
543
        if ( $self->should_buffer() ) {
544
            $html_out = $self->end_buffering( $html_in );
545
        }
546
        return $html_out;
547
    }
548
549
    public static function on_uninstall()
550
    {
551
        autoptimizeCache::clearall();
552
553
        $delete_options = array(
554
            'autoptimize_cache_clean',
555
            'autoptimize_cache_nogzip',
556
            'autoptimize_css',
557
            'autoptimize_css_aggregate',
558
            'autoptimize_css_datauris',
559
            'autoptimize_css_justhead',
560
            'autoptimize_css_defer',
561
            'autoptimize_css_defer_inline',
562
            'autoptimize_css_inline',
563
            'autoptimize_css_exclude',
564
            'autoptimize_html',
565
            'autoptimize_html_keepcomments',
566
            'autoptimize_enable_site_config',
567
            'autoptimize_js',
568
            'autoptimize_js_aggregate',
569
            'autoptimize_js_defer_not_aggregate',
570
            'autoptimize_js_exclude',
571
            'autoptimize_js_forcehead',
572
            'autoptimize_js_justhead',
573
            'autoptimize_js_trycatch',
574
            'autoptimize_version',
575
            'autoptimize_show_adv',
576
            'autoptimize_cdn_url',
577
            'autoptimize_cachesize_notice',
578
            'autoptimize_css_include_inline',
579
            'autoptimize_js_include_inline',
580
            'autoptimize_optimize_logged',
581
            'autoptimize_optimize_checkout',
582
            'autoptimize_extra_settings',
583
            'autoptimize_service_availablity',
584
            'autoptimize_imgopt_provider_stat',
585
            'autoptimize_imgopt_launched',
586
            'autoptimize_imgopt_settings',
587
            'autoptimize_minify_excluded',
588
            'autoptimize_cache_fallback',
589
            'autoptimize_ccss_rules',
590
            'autoptimize_ccss_additional',
591
            'autoptimize_ccss_queue',
592
            'autoptimize_ccss_viewport',
593
            'autoptimize_ccss_finclude',
594
            'autoptimize_ccss_rlimit',
595
            'autoptimize_ccss_rtimelimit',
596
            'autoptimize_ccss_noptimize',
597
            'autoptimize_ccss_debug',
598
            'autoptimize_ccss_key',
599
            'autoptimize_ccss_keyst',
600
            'autoptimize_ccss_version',
601
            'autoptimize_ccss_loggedin',
602
            'autoptimize_ccss_forcepath',
603
            'autoptimize_ccss_deferjquery',
604
            'autoptimize_ccss_domain',
605
            'autoptimize_ccss_unloadccss',
606
        );
607
608
        if ( ! is_multisite() ) {
609
            foreach ( $delete_options as $del_opt ) {
610
                delete_option( $del_opt );
611
            }
612
            autoptimizeMain::remove_cronjobs();
613
        } else {
614
            global $wpdb;
615
            $blog_ids         = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
616
            $original_blog_id = get_current_blog_id();
617
            foreach ( $blog_ids as $blog_id ) {
618
                switch_to_blog( $blog_id );
619
                foreach ( $delete_options as $del_opt ) {
620
                    delete_option( $del_opt );
621
                }
622
                autoptimizeMain::remove_cronjobs();
623
            }
624
            switch_to_blog( $original_blog_id );
625
        }
626
627
        // Remove AO CCSS cached files and directory.
628
        $ao_ccss_dir = WP_CONTENT_DIR . '/uploads/ao_ccss/';
629
        if ( file_exists( $ao_ccss_dir ) && is_dir( $ao_ccss_dir ) ) {
630
            // fixme: should check for subdirs when in multisite and remove contents of those as well.
631
            array_map( 'unlink', glob( $ao_ccss_dir . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) );
632
            rmdir( $ao_ccss_dir );
633
        }
634
    }
635
636
    public static function on_deactivation()
637
    {
638
        if ( is_multisite() && is_network_admin() ) {
639
            global $wpdb;
640
            $blog_ids         = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
641
            $original_blog_id = get_current_blog_id();
642
            foreach ( $blog_ids as $blog_id ) {
643
                switch_to_blog( $blog_id );
644
                autoptimizeMain::remove_cronjobs();
645
            }
646
            switch_to_blog( $original_blog_id );
647
        } else {
648
            autoptimizeMain::remove_cronjobs();
649
        }
650
        autoptimizeCache::clearall();
651
    }
652
653
    public static function remove_cronjobs() {
654
        // Remove scheduled events.
655
        foreach ( array( 'ao_cachechecker', 'ao_ccss_queue', 'ao_ccss_maintenance' ) as $_event ) {
656
            if ( wp_get_schedule( $_event ) ) {
657
                wp_clear_scheduled_hook( $_event );
658
            }
659
        }
660
    }
661
662
    public static function notice_cache_unavailable()
663
    {
664
        echo '<div class="error"><p>';
665
        // Translators: %s is the cache directory location.
666
        printf( __( 'Autoptimize cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'autoptimize' ), AUTOPTIMIZE_CACHE_DIR );
667
        echo '</p></div>';
668
    }
669
670
    public static function notice_installed()
671
    {
672
        echo '<div class="updated"><p>';
673
        _e( 'Thank you for installing and activating Autoptimize. Please configure it under "Settings" -> "Autoptimize" to start improving your site\'s performance.', 'autoptimize' );
674
        echo '</p></div>';
675
    }
676
677
    public static function notice_updated()
678
    {
679
        echo '<div class="updated"><p>';
680
        _e( 'Autoptimize has just been updated. Please <strong>test your site now</strong> and adapt Autoptimize config if needed.', 'autoptimize' );
681
        echo '</p></div>';
682
    }
683
684
    public static function notice_plug_imgopt()
685
    {
686
        // Translators: the URL added points to the Autopmize Extra settings.
687
        $_ao_imgopt_plug_notice      = sprintf( __( 'Did you know Autoptimize includes 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 activate this option.', 'autoptimize' ), '<a href="options-general.php?page=autoptimize_imgopt">', '</a>' );
688
        $_ao_imgopt_plug_notice      = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
689
        $_ao_imgopt_launch_ok        = autoptimizeImages::launch_ok_wrapper();
690
        $_ao_imgopt_plug_dismissible = 'boe-ao-img-opt-plug-123';
691
        $_ao_imgopt_active           = autoptimizeImages::imgopt_active();
692
        $_is_ao_settings_page        = true;//( str_replace( array( 'autoptimize', 'autoptimize_imgopt', 'ao_critcss', 'autoptimize_extra', 'ao_partners' ), '', $_SERVER['REQUEST_URI'] ) !== $_SERVER['REQUEST_URI'] ? true : false );
693
694
        if ( current_user_can( 'manage_options' ) && $_is_ao_settings_page && '' !== $_ao_imgopt_plug_notice && ! $_ao_imgopt_active && $_ao_imgopt_launch_ok && PAnD::is_admin_notice_active( $_ao_imgopt_plug_dismissible ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $_ao_imgopt_active of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
695
            echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
696
            echo $_ao_imgopt_plug_notice;
697
            echo '</p></div>';
698
        }
699
    }
700
}
701