Completed
Push — master ( b4100c...ed2097 )
by frank
01:49
created

autoptimizeMain::maybe_run_criticalcss_tab()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 2
nop 0
dl 0
loc 7
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
        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();
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...
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
            // also honor PageSpeed=off parameter as used by mod_pagespeed, in use by some pagebuilders,
338
            // see https://www.modpagespeed.com/doc/experiment#ModPagespeed for info on that.
339 View Code Duplication
            if ( false === $ao_noptimize && array_key_exists( 'PageSpeed', $_GET ) && 'off' === $_GET['PageSpeed'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
340
                $ao_noptimize = true;
341
            }
342
343
            // and make sure Thrive editor doesn't get optimized HTML.
344 View Code Duplication
            if ( false === $ao_noptimize && array_key_exists( 'tve', $_GET ) && 'true' === $_GET['tve'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
                $ao_noptimize = true;
346
            }
347
348
            // If setting says not to optimize logged in user and user is logged in...
349
            if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_logged', 'on' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
350
                $ao_noptimize = true;
351
            }
352
353
            // If setting says not to optimize cart/checkout.
354
            if ( false === $ao_noptimize && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_optimize_checkout', 'off' ) ) {
355
                // Checking for woocommerce, easy digital downloads and wp ecommerce...
356
                foreach ( array( 'is_checkout', 'is_cart', 'is_account_page', 'edd_is_checkout', 'wpsc_is_cart', 'wpsc_is_checkout' ) as $func ) {
357
                    if ( function_exists( $func ) && $func() ) {
358
                        $ao_noptimize = true;
359
                        break;
360
                    }
361
                }
362
            }
363
364
            // Allows blocking of autoptimization on your own terms regardless of above decisions.
365
            $ao_noptimize = (bool) apply_filters( 'autoptimize_filter_noptimize', $ao_noptimize );
366
367
            // Check for site being previewed in the Customizer (available since WP 4.0).
368
            $is_customize_preview = false;
369
            if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
370
                $is_customize_preview = is_customize_preview();
371
            }
372
373
            /**
374
             * We only buffer the frontend requests (and then only if not a feed
375
             * and not turned off explicitly and not when being previewed in Customizer)!
376
             * NOTE: Tests throw a notice here due to is_feed() being called
377
             * while the main query hasn't been ran yet. Thats why we use
378
             * AUTOPTIMIZE_INIT_EARLIER in tests.
379
             */
380
            $do_buffering = ( ! is_admin() && ! is_feed() && ! is_embed() && ! $ao_noptimize && ! $is_customize_preview );
381
        }
382
383
        return $do_buffering;
384
    }
385
386
    /**
387
     * Returns true if given markup is considered valid/processable/optimizable.
388
     *
389
     * @param string $content Markup.
390
     *
391
     * @return bool
392
     */
393
    public function is_valid_buffer( $content )
394
    {
395
        // Defaults to true.
396
        $valid = true;
397
398
        $has_no_html_tag    = ( false === stripos( $content, '<html' ) );
399
        $has_xsl_stylesheet = ( false !== stripos( $content, '<xsl:stylesheet' ) || false !== stripos( $content, '<?xml-stylesheet' ) );
400
        $has_html5_doctype  = ( preg_match( '/^<!DOCTYPE.+html>/i', ltrim( $content ) ) > 0 );
401
        $has_noptimize_page = ( false !== stripos( $content, '<!-- noptimize-page -->' ) );
402
403
        if ( $has_no_html_tag ) {
404
            // Can't be valid amp markup without an html tag preceding it.
405
            $is_amp_markup = false;
406
        } else {
407
            $is_amp_markup = self::is_amp_markup( $content );
408
        }
409
410
        // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it.
411
        if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet || $has_noptimize_page ) {
412
            $valid = false;
413
        }
414
415
        return $valid;
416
    }
417
418
    /**
419
     * Returns true if given $content is considered to be AMP markup.
420
     * This is far from actual validation against AMP spec, but it'll do for now.
421
     *
422
     * @param string $content Markup to check.
423
     *
424
     * @return bool
425
     */
426
    public static function is_amp_markup( $content )
427
    {
428
        // Short-circuit when a function is available to determine whether the response is (or will be) an AMP page.
429
        if ( function_exists( 'is_amp_endpoint' ) ) {
430
            return is_amp_endpoint();
431
        }
432
433
        $is_amp_markup = preg_match( '/<html[^>]*(?:amp|⚡)/i', $content );
434
435
        return (bool) $is_amp_markup;
436
    }
437
438
    /**
439
     * Processes/optimizes the output-buffered content and returns it.
440
     * If the content is not processable, it is returned unmodified.
441
     *
442
     * @param string $content Buffered content.
443
     *
444
     * @return string
445
     */
446
    public function end_buffering( $content )
447
    {
448
        // Bail early without modifying anything if we can't handle the content.
449
        if ( ! $this->is_valid_buffer( $content ) ) {
450
            return $content;
451
        }
452
453
        $conf = autoptimizeConfig::instance();
454
455
        // Determine what needs to be ran.
456
        $classes = array();
457
        if ( $conf->get( 'autoptimize_js' ) ) {
458
            $classes[] = 'autoptimizeScripts';
459
        }
460
        if ( $conf->get( 'autoptimize_css' ) ) {
461
            $classes[] = 'autoptimizeStyles';
462
        }
463
        if ( $conf->get( 'autoptimize_html' ) ) {
464
            $classes[] = 'autoptimizeHTML';
465
        }
466
467
        $classoptions = array(
468
            'autoptimizeScripts' => array(
469
                'aggregate'       => $conf->get( 'autoptimize_js_aggregate' ),
470
                'justhead'        => $conf->get( 'autoptimize_js_justhead' ),
471
                'forcehead'       => $conf->get( 'autoptimize_js_forcehead' ),
472
                'trycatch'        => $conf->get( 'autoptimize_js_trycatch' ),
473
                'js_exclude'      => $conf->get( 'autoptimize_js_exclude' ),
474
                'cdn_url'         => $conf->get( 'autoptimize_cdn_url' ),
475
                'include_inline'  => $conf->get( 'autoptimize_js_include_inline' ),
476
                'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
477
            ),
478
            'autoptimizeStyles'  => array(
479
                'aggregate'       => $conf->get( 'autoptimize_css_aggregate' ),
480
                'justhead'        => $conf->get( 'autoptimize_css_justhead' ),
481
                'datauris'        => $conf->get( 'autoptimize_css_datauris' ),
482
                'defer'           => $conf->get( 'autoptimize_css_defer' ),
483
                'defer_inline'    => $conf->get( 'autoptimize_css_defer_inline' ),
484
                'inline'          => $conf->get( 'autoptimize_css_inline' ),
485
                'css_exclude'     => $conf->get( 'autoptimize_css_exclude' ),
486
                'cdn_url'         => $conf->get( 'autoptimize_cdn_url' ),
487
                'include_inline'  => $conf->get( 'autoptimize_css_include_inline' ),
488
                'nogooglefont'    => $conf->get( 'autoptimize_css_nogooglefont' ),
489
                'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
490
            ),
491
            'autoptimizeHTML'    => array(
492
                'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ),
493
            ),
494
        );
495
496
        $content = apply_filters( 'autoptimize_filter_html_before_minify', $content );
497
498
        // Run the classes!
499
        foreach ( $classes as $name ) {
500
            $instance = new $name( $content );
501
            if ( $instance->read( $classoptions[ $name ] ) ) {
502
                $instance->minify();
503
                $instance->cache();
504
                $content = $instance->getcontent();
505
            }
506
            unset( $instance );
507
        }
508
509
        $content = apply_filters( 'autoptimize_html_after_minify', $content );
510
511
        return $content;
512
    }
513
514
    public static function autoptimize_nobuffer_optimize( $html_in ) {
515
        $html_out = $html_in;
516
517
        if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
518
            $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...
519
        }
520
521
        $self = new self( AUTOPTIMIZE_PLUGIN_VERSION, AUTOPTIMIZE_PLUGIN_FILE );
522
        if ( $self->should_buffer() ) {
523
            $html_out = $self->end_buffering( $html_in );
524
        }
525
        return $html_out;
526
    }
527
528
    public static function on_uninstall()
529
    {
530
        autoptimizeCache::clearall();
531
532
        $delete_options = array(
533
            'autoptimize_cache_clean',
534
            'autoptimize_cache_nogzip',
535
            'autoptimize_css',
536
            'autoptimize_css_aggregate',
537
            'autoptimize_css_datauris',
538
            'autoptimize_css_justhead',
539
            'autoptimize_css_defer',
540
            'autoptimize_css_defer_inline',
541
            'autoptimize_css_inline',
542
            'autoptimize_css_exclude',
543
            'autoptimize_html',
544
            'autoptimize_html_keepcomments',
545
            'autoptimize_enable_site_config',
546
            'autoptimize_js',
547
            'autoptimize_js_aggregate',
548
            'autoptimize_js_exclude',
549
            'autoptimize_js_forcehead',
550
            'autoptimize_js_justhead',
551
            'autoptimize_js_trycatch',
552
            'autoptimize_version',
553
            'autoptimize_show_adv',
554
            'autoptimize_cdn_url',
555
            'autoptimize_cachesize_notice',
556
            'autoptimize_css_include_inline',
557
            'autoptimize_js_include_inline',
558
            'autoptimize_optimize_logged',
559
            'autoptimize_optimize_checkout',
560
            'autoptimize_extra_settings',
561
            'autoptimize_service_availablity',
562
            'autoptimize_imgopt_provider_stat',
563
            'autoptimize_imgopt_launched',
564
            'autoptimize_imgopt_settings',
565
            'autoptimize_minify_excluded',
566
            'autoptimize_cache_fallback',
567
            'autoptimize_ccss_rules',
568
            'autoptimize_ccss_additional',
569
            'autoptimize_ccss_queue',
570
            'autoptimize_ccss_viewport',
571
            'autoptimize_ccss_finclude',
572
            'autoptimize_ccss_rlimit',
573
            'autoptimize_ccss_noptimize',
574
            'autoptimize_ccss_debug',
575
            'autoptimize_ccss_key',
576
            'autoptimize_ccss_keyst',
577
            'autoptimize_ccss_version',
578
            'autoptimize_ccss_loggedin',
579
            'autoptimize_ccss_forcepath',
580
            'autoptimize_ccss_deferjquery',
581
            'autoptimize_ccss_domain',
582
        );
583
584
        if ( ! is_multisite() ) {
585
            foreach ( $delete_options as $del_opt ) {
586
                delete_option( $del_opt );
587
            }
588
            autoptimizeMain::remove_cronjobs();
589
        } else {
590
            global $wpdb;
591
            $blog_ids         = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
592
            $original_blog_id = get_current_blog_id();
593
            foreach ( $blog_ids as $blog_id ) {
594
                switch_to_blog( $blog_id );
595
                foreach ( $delete_options as $del_opt ) {
596
                    delete_option( $del_opt );
597
                }
598
                autoptimizeMain::remove_cronjobs();
599
            }
600
            switch_to_blog( $original_blog_id );
601
        }
602
603
        // Remove AO CCSS cached files and directory.
604
        $ao_ccss_dir = WP_CONTENT_DIR . '/uploads/ao_ccss/';
605
        if ( file_exists( $ao_ccss_dir ) && is_dir( $ao_ccss_dir ) ) {
606
            // fixme: should check for subdirs when in multisite and remove contents of those as well.
607
            array_map( 'unlink', glob( AO_CCSS_DIR . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) );
608
            rmdir( AO_CCSS_DIR );
609
        }
610
    }
611
612
    public static function on_deactivation()
613
    {
614
        if ( is_multisite() && is_network_admin() ) {
615
            global $wpdb;
616
            $blog_ids         = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
617
            $original_blog_id = get_current_blog_id();
618
            foreach ( $blog_ids as $blog_id ) {
619
                switch_to_blog( $blog_id );
620
                autoptimizeMain::remove_cronjobs();
621
            }
622
            switch_to_blog( $original_blog_id );
623
        } else {
624
            autoptimizeMain::remove_cronjobs();
625
        }
626
        autoptimizeCache::clearall();
627
    }
628
629
    public static function remove_cronjobs() {
630
        // Remove scheduled events.
631
        foreach ( array( 'ao_cachechecker', 'ao_ccss_queue', 'ao_ccss_maintenance' ) as $_event ) {
632
            if ( wp_get_schedule( $_event ) ) {
633
                wp_clear_scheduled_hook( $_event );
634
            }
635
        }
636
    }
637
638
    public static function notice_cache_unavailable()
639
    {
640
        echo '<div class="error"><p>';
641
        // Translators: %s is the cache directory location.
642
        printf( __( 'Autoptimize cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'autoptimize' ), AUTOPTIMIZE_CACHE_DIR );
643
        echo '</p></div>';
644
    }
645
646
    public static function notice_installed()
647
    {
648
        echo '<div class="updated"><p>';
649
        _e( 'Thank you for installing and activating Autoptimize. Please configure it under "Settings" -> "Autoptimize" to start improving your site\'s performance.', 'autoptimize' );
650
        echo '</p></div>';
651
    }
652
653
    public static function notice_updated()
654
    {
655
        echo '<div class="updated"><p>';
656
        _e( 'Autoptimize has just been updated. Please <strong>test your site now</strong> and adapt Autoptimize config if needed.', 'autoptimize' );
657
        echo '</p></div>';
658
    }
659
660
    public static function notice_plug_imgopt()
661
    {
662
        // Translators: the URL added points to the Autopmize Extra settings.
663
        $_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>' );
664
        $_ao_imgopt_plug_notice      = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
665
        $_ao_imgopt_launch_ok        = autoptimizeImages::launch_ok_wrapper();
666
        $_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
667
        $_ao_imgopt_active           = autoptimizeImages::imgopt_active();
668
669
        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 ) ) {
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...
670
            echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
671
            echo $_ao_imgopt_plug_notice;
672
            echo '</p></div>';
673
        }
674
    }
675
}
676