setup(); } return $instance; } /** * Setup routine */ public function setup() { $this->settings = \PoweredCache\Utils\get_settings(); /** * Filters whether apply or not apply file optimizations on wp-admin. * * @hook powered_cache_fo_dashboard * * @param {boolean} true to enable optimizations for dashboard. * * @return {boolean} New value. * @since 2.0 */ $this->optimize_dashboard = apply_filters( 'powered_cache_fo_dashboard', false ); add_action( 'powered_cache_purge_all_cache', [ $this, 'maybe_purge_fo_cache' ] ); /** * Don't optimize wp-admin by default * This might worth to add as option? */ if ( is_admin() && ! $this->optimize_dashboard ) { return; } add_action( 'init', [ $this, 'setup_css_combine' ] ); add_action( 'init', [ $this, 'setup_js_combine' ] ); add_filter( 'script_loader_tag', [ $this, 'js_minify' ], 10, 3 ); add_filter( 'style_loader_tag', [ $this, 'css_minify' ], 10, 4 ); if ( ! $this->settings['combine_js'] ) { add_filter( 'powered_cache_fo_js_do_concat', '__return_false' ); } if ( ! $this->settings['combine_css'] ) { add_filter( 'powered_cache_fo_css_do_concat', '__return_false' ); } add_filter( 'powered_cache_fo_script_loader_tag', [ $this, 'change_js_execute_method' ] ); if ( ! $this->settings['js_execution_optimized_only'] ) { add_filter( 'script_loader_tag', [ $this, 'change_js_execute_method' ], 99 ); } add_action( 'after_setup_theme', [ $this, 'html_minify' ] ); if ( $this->settings['combine_google_fonts'] ) { add_action( 'wp_enqueue_scripts', [ $this, 'combine_google_fonts' ], 99 ); } add_action( 'template_redirect', [ $this, 'maybe_suppress_optimizations' ] ); } /** * Maybe suppress optimizations based on the post meta options * * @since 2.1 */ public function maybe_suppress_optimizations() { if ( is_singular() ) { $disable_css_optimization = (bool) get_post_meta( get_the_ID(), POST_META_DISABLE_CSS_OPTIMIZATION, true ); $disable_js_optimization = (bool) get_post_meta( get_the_ID(), POST_META_DISABLE_JS_OPTIMIZATION, true ); if ( $disable_css_optimization ) { add_filter( 'powered_cache_fo_css_do_concat', '__return_false' ); add_filter( 'powered_cache_fo_disable_css_minify', '__return_true' ); } if ( $disable_js_optimization ) { add_filter( 'powered_cache_fo_js_do_concat', '__return_false' ); add_filter( 'powered_cache_fo_disable_js_minify', '__return_true' ); } } } /** * Purge FO cache * * @since 2.0 */ public function maybe_purge_fo_cache() { if ( file_exists( POWERED_CACHE_FO_CACHE_DIR ) ) { remove_dir( POWERED_CACHE_FO_CACHE_DIR ); } } /** * Minify HTML output */ public function html_minify() { if ( ! $this->settings['minify_html'] ) { return; } /** * Filters whether disable or not disable HTML minification. * * @hook powered_cache_fo_disable_html_minify * * @param {boolean} true to disable html minify * * @return {boolean} New value. * @since 2.0 */ if ( apply_filters( 'powered_cache_fo_disable_html_minify', false ) ) { return; } ob_start( [ $this, 'run_html_minify' ] ); } /** * Minify given HTML output * * @param string $buffer HTML * * @return string|string[]|null */ public function run_html_minify( $buffer ) { $search = array( '/\>[^\S ]+/s', // strip whitespaces after tags, except space '/[^\S ]+\', '<', '\\1', ' ' ); $buffer = preg_replace( $search, $replace, $buffer ); return $buffer; } /** * Add JS execution method to script tag * * @param string $tag settings['js_execution_method']; if ( ! $js_execution ) { return $tag; } if ( 'blocking' === $js_execution ) { return $tag; } if ( 'async' === $js_execution ) { $js_attr = 'async="async"'; } elseif ( 'defer' === $js_execution ) { $js_attr = 'defer="defer"'; } if ( false === stripos( $tag, $js_attr ) ) { $search = '