$is_amp_markup = false; } else { $is_amp_markup = self::is_amp_markup( $content ); } // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it. if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet || $has_noptimize_page ) { $valid = false; } return $valid; } /** * Returns true if given $content is considered to be AMP markup. * This is far from actual validation against AMP spec, but it'll do for now. * * @param string $content Markup to check. * * @return bool */ public static function is_amp_markup( $content ) { // Short-circuit if the page is already AMP from the start. if ( preg_match( sprintf( '#^(?:|\s+)*+]*?\s(%1$s|%2$s|%3$s)(\s|=|>)#is', 'amp', "\xE2\x9A\xA1", // From \AmpProject\Attribute::AMP_EMOJI. "\xE2\x9A\xA1\xEF\xB8\x8F" // From \AmpProject\Attribute::AMP_EMOJI_ALT, per https://github.com/ampproject/amphtml/issues/25990. ), $content ) ) { return true; } // Or else short-circuit if the AMP plugin will be processing the output to be an AMP page. if ( function_exists( 'amp_is_request' ) ) { return amp_is_request(); // For AMP plugin v2.0+. } elseif ( function_exists( 'is_amp_endpoint' ) ) { return is_amp_endpoint(); // For older/other AMP plugins (still supported in 2.0 as an alias). } return false; } /** * Processes/optimizes the output-buffered content and returns it. * If the content is not processable, it is returned unmodified. * * @param string $content Buffered content. * * @return string */ public function end_buffering( $content ) { // Bail early without modifying anything if we can't handle the content. if ( ! $this->is_valid_buffer( $content ) ) { return $content; } $conf = autoptimizeConfig::instance(); // Determine what needs to be ran. $classes = array(); if ( $conf->get( 'autoptimize_js' ) ) { $classes[] = 'autoptimizeScripts'; } if ( $conf->get( 'autoptimize_css' ) ) { $classes[] = 'autoptimizeStyles'; } if ( $conf->get( 'autoptimize_html' ) ) { $classes[] = 'autoptimizeHTML'; } $classoptions = array( 'autoptimizeScripts' => array( 'aggregate' => $conf->get( 'autoptimize_js_aggregate' ), 'defer_not_aggregate' => $conf->get( 'autoptimize_js_defer_not_aggregate' ), 'defer_inline' => $conf->get( 'autoptimize_js_defer_inline' ), 'justhead' => $conf->get( 'autoptimize_js_justhead' ), 'forcehead' => $conf->get( 'autoptimize_js_forcehead' ), 'trycatch' => $conf->get( 'autoptimize_js_trycatch' ), 'js_exclude' => $conf->get( 'autoptimize_js_exclude' ), 'cdn_url' => $conf->get( 'autoptimize_cdn_url' ), 'include_inline' => $conf->get( 'autoptimize_js_include_inline' ), 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ), ), 'autoptimizeStyles' => array( 'aggregate' => $conf->get( 'autoptimize_css_aggregate' ), 'justhead' => $conf->get( 'autoptimize_css_justhead' ), 'datauris' => $conf->get( 'autoptimize_css_datauris' ), 'defer' => $conf->get( 'autoptimize_css_defer' ), 'defer_inline' => $conf->get( 'autoptimize_css_defer_inline' ), 'inline' => $conf->get( 'autoptimize_css_inline' ), 'css_exclude' => $conf->get( 'autoptimize_css_exclude' ), 'cdn_url' => $conf->get( 'autoptimize_cdn_url' ), 'include_inline' => $conf->get( 'autoptimize_css_include_inline' ), 'nogooglefont' => $conf->get( 'autoptimize_css_nogooglefont' ), 'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ), ), 'autoptimizeHTML' => array( 'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ), 'minify_inline' => $conf->get( 'autoptimize_html_minify_inline' ), ), ); $content = apply_filters( 'autoptimize_filter_html_before_minify', $content ); // Run the classes! foreach ( $classes as $name ) { $instance = new $name( $content ); if ( $instance->read( $classoptions[ $name ] ) ) { $instance->minify(); $instance->cache(); $content = $instance->getcontent(); } unset( $instance ); } $content = apply_filters( 'autoptimize_html_after_minify', $content ); return $content; } public static function autoptimize_nobuffer_optimize( $html_in ) { $html_out = $html_in; if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) { $ao_speedupper = new autoptimizeSpeedupper(); } $self = new self( AUTOPTIMIZE_PLUGIN_VERSION, AUTOPTIMIZE_PLUGIN_FILE ); if ( $self->should_buffer() ) { $html_out = $self->end_buffering( $html_in ); } return $html_out; } public static function on_uninstall() { // clear the cache. autoptimizeCache::clearall(); // remove postmeta if active. if ( autoptimizeConfig::is_ao_meta_settings_active() ) { delete_post_meta_by_key( 'ao_post_optimize' ); } // remove all options. $delete_options = array( 'autoptimize_cache_clean', 'autoptimize_cache_nogzip', 'autoptimize_css', 'autoptimize_css_aggregate', 'autoptimize_css_datauris', 'autoptimize_css_justhead', 'autoptimize_css_defer', 'autoptimize_css_defer_inline', 'autoptimize_css_inline', 'autoptimize_css_exclude', 'autoptimize_html', 'autoptimize_html_keepcomments', 'autoptimize_html_minify_inline', 'autoptimize_enable_site_config', 'autoptimize_enable_meta_ao_settings', 'autoptimize_js', 'autoptimize_js_aggregate', 'autoptimize_js_defer_not_aggregate', 'autoptimize_js_defer_inline', 'autoptimize_js_exclude', 'autoptimize_js_forcehead', 'autoptimize_js_justhead', 'autoptimize_js_trycatch', 'autoptimize_version', 'autoptimize_show_adv', 'autoptimize_cdn_url', 'autoptimize_cachesize_notice', 'autoptimize_css_include_inline', 'autoptimize_js_include_inline', 'autoptimize_optimize_logged', 'autoptimize_optimize_checkout', 'autoptimize_extra_settings', 'autoptimize_service_availablity', 'autoptimize_imgopt_provider_stat', 'autoptimize_imgopt_launched', 'autoptimize_imgopt_settings', 'autoptimize_minify_excluded', 'autoptimize_cache_fallback', 'autoptimize_ccss_rules', 'autoptimize_ccss_additional', 'autoptimize_ccss_queue', 'autoptimize_ccss_viewport', 'autoptimize_ccss_finclude', 'autoptimize_ccss_rlimit', 'autoptimize_ccss_rtimelimit', 'autoptimize_ccss_noptimize', 'autoptimize_ccss_debug', 'autoptimize_ccss_key', 'autoptimize_ccss_keyst', 'autoptimize_ccss_version', 'autoptimize_ccss_loggedin', 'autoptimize_ccss_forcepath', 'autoptimize_ccss_deferjquery', 'autoptimize_ccss_domain', 'autoptimize_ccss_unloadccss', 'autoptimize_installed_before_compatibility', ); if ( ! is_multisite() ) { foreach ( $delete_options as $del_opt ) { delete_option( $del_opt ); } autoptimizeMain::remove_cronjobs(); } else { global $wpdb; $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ); $original_blog_id = get_current_blog_id(); foreach ( $blog_ids as $blog_id ) { switch_to_blog( $blog_id ); foreach ( $delete_options as $del_opt ) { delete_option( $del_opt ); } autoptimizeMain::remove_cronjobs(); } switch_to_blog( $original_blog_id ); } // Remove AO CCSS cached files and directory. $ao_ccss_dir = WP_CONTENT_DIR . '/uploads/ao_ccss/'; if ( file_exists( $ao_ccss_dir ) && is_dir( $ao_ccss_dir ) && defined( 'GLOB_BRACE' ) ) { // fixme: should check for subdirs when in multisite and remove contents of those as well. // fixme: if GLOB_BRACE is not avaible we need to remove AO_CCSS_DIR differently? array_map( 'unlink', glob( $ao_ccss_dir . '*.{css,html,json,log,zip,lock}', GLOB_BRACE ) ); rmdir( $ao_ccss_dir ); } // Remove 404-handler (although that should have been removed in clearall already). $_fallback_php = trailingslashit( WP_CONTENT_DIR ) . 'autoptimize_404_handler.php'; if ( file_exists( $_fallback_php ) ) { unlink( $_fallback_php ); } } public static function on_deactivation() { if ( is_multisite() && is_network_admin() ) { global $wpdb; $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ); $original_blog_id = get_current_blog_id(); foreach ( $blog_ids as $blog_id ) { switch_to_blog( $blog_id ); autoptimizeMain::remove_cronjobs(); } switch_to_blog( $original_blog_id ); } else { autoptimizeMain::remove_cronjobs(); } autoptimizeCache::clearall(); } public static function remove_cronjobs() { // Remove scheduled events. foreach ( array( 'ao_cachechecker', 'ao_ccss_queue', 'ao_ccss_maintenance', 'ao_ccss_keychecker' ) as $_event ) { if ( wp_get_schedule( $_event ) ) { wp_clear_scheduled_hook( $_event ); } } } public static function notice_cache_unavailable() { echo '
'; // Translators: %s is the cache directory location. printf( esc_html__( 'Autoptimize cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'autoptimize' ), AUTOPTIMIZE_CACHE_DIR ); echo '
'; // translators: the variables contain opening and closing tags to link to the settings page. printf( esc_html__( 'Thank you for installing and activating Autoptimize. Your site is being optimized immediately, please test the frontend to ensure everything still works as expected. If needed you can change JavaScript or CSS optimization settings under %1$sSettings -> Autoptimize%2$s .', 'autoptimize' ), '', '' ); echo '
'; printf( esc_html_e( 'Autoptimize has just been updated. Please %1$stest your site now%2$s and adapt Autoptimize config if needed.', 'autoptimize' ), '', '' ); echo '
'; echo $_ao_imgopt_plug_notice; echo '
'; echo $_ao_imgopt_issue_notice; echo '
'; echo $_ao_nopagecache_notice; echo '
'; echo $_ao_potential_conflict_notice; echo '