*/ public static function builtins() { return array( 'safe' => array( 'label' => __( 'Safe Start', 'qw-optimize' ), 'tagline' => __( 'Best first click for a new site', 'qw-optimize' ), 'description' => __( 'Turns on the safest high-value caching and front-end optimizations without aggressive CSS/JS behavior.', 'qw-optimize' ), 'risk' => 'safe', 'badge' => __( 'Beginner', 'qw-optimize' ), 'pro' => false, 'features' => array( __( 'Page + browser cache', 'qw-optimize' ), __( 'Compression', 'qw-optimize' ), __( 'HTML/CSS/JS minify', 'qw-optimize' ), __( 'Lazy-load + image dimensions', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'cache_mobile' => 1, 'browser_cache_enabled'=> 1, 'gzip_enabled' => 1, 'minify_html' => 1, 'minify_css' => 1, 'minify_js' => 1, 'combine_css' => 0, 'combine_js' => 0, 'defer_js' => 0, 'delay_js' => 0, 'js_safe_mode' => 1, 'builder_compat' => 1, 'lazyload_images' => 1, 'lazyload_iframes' => 1, 'image_dimensions' => 1, 'preload_critical_images' => 1, 'remove_unused_css' => 0, 'critical_css_enabled' => 0, 'test_mode' => 0, ), ), 'balanced' => array( 'label' => __( 'Balanced', 'qw-optimize' ), 'tagline' => __( 'Recommended for most WordPress sites', 'qw-optimize' ), 'description' => __( 'Adds safe JavaScript defer, hover prefetch and sensible cleanup while keeping compatibility safeguards enabled.', 'qw-optimize' ), 'risk' => 'balanced', 'badge' => __( 'Recommended', 'qw-optimize' ), 'pro' => false, 'features' => array( __( 'Everything in Safe Start', 'qw-optimize' ), __( 'Defer JavaScript', 'qw-optimize' ), __( 'Hover prefetch', 'qw-optimize' ), __( 'Heartbeat optimization', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'cache_mobile' => 1, 'browser_cache_enabled'=> 1, 'gzip_enabled' => 1, 'lazyload_images' => 1, 'lazyload_iframes' => 1, 'image_dimensions' => 1, 'preload_critical_images' => 1, 'critical_images_max' => 1, 'browser_cache_font_cors' => 1, 'google_fonts_optimize' => 1, 'font_display_sitewide' => 1, 'font_display' => 'swap', 'defer_js' => 1, 'js_safe_mode' => 1, 'builder_compat' => 1, 'minify_html' => 1, 'minify_css' => 1, 'minify_js' => 1, 'combine_js' => 0, 'combine_css' => 0, 'hover_prefetch_enabled' => 1, 'heartbeat_control' => 1, 'heartbeat_disable_front' => 1, 'hosting_purge_auto' => 1, 'delay_js' => 0, 'remove_unused_css' => 0, 'critical_css_enabled' => 0, 'test_mode' => 0, ), ), 'maximum' => array( 'label' => __( 'Maximum Performance', 'qw-optimize' ), 'tagline' => __( 'Push hard for the highest scores', 'qw-optimize' ), 'description' => __( 'Enables aggressive caching and optimization. Pro adds Delay JS, Critical CSS, Remove Unused CSS, INP optimization and smart preload.', 'qw-optimize' ), 'risk' => 'aggressive', 'badge' => __( 'PRO-heavy', 'qw-optimize' ), 'pro' => true, 'features' => array( __( 'Aggressive minification', 'qw-optimize' ), __( 'Delay JS (Pro)', 'qw-optimize' ), __( 'Critical CSS + RUCSS (Pro)', 'qw-optimize' ), __( 'INP + smart preload (Pro)', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'cache_mobile' => 1, 'browser_cache_enabled' => 1, 'gzip_enabled' => 1, 'lazyload_images' => 1, 'lazyload_iframes' => 1, 'image_dimensions' => 1, 'preload_critical_images' => 1, 'defer_js' => 1, 'js_safe_mode' => 1, 'builder_compat' => 1, 'minify_html' => 1, 'minify_css' => 1, 'minify_js' => 1, 'combine_css' => 0, 'combine_js' => 0, 'hover_prefetch_enabled' => 1, 'heartbeat_control' => 1, 'heartbeat_disable_front' => 1, 'delay_js' => 1, 'remove_unused_css' => 1, 'critical_css_enabled' => 1, 'critical_css_auto' => 1, 'async_css_enabled' => 1, 'smart_third_party' => 1, 'inp_optimizer_enabled' => 1, 'inp_scheduler_yield' => 1, 'preload_links' => 1, 'preload_after_purge' => 1, 'test_mode' => 0, ), ), 'ecommerce' => array( 'label' => __( 'WooCommerce / Store', 'qw-optimize' ), 'tagline' => __( 'Performance without breaking carts or checkout', 'qw-optimize' ), 'description' => __( 'Protects WooCommerce sessions, payment flows and builders while enabling safe caching, minification and store-specific optimizations.', 'qw-optimize' ), 'risk' => 'safe', 'badge' => __( 'Store Safe', 'qw-optimize' ), 'pro' => false, 'features' => array( __( 'Checkout/cart safeguards', 'qw-optimize' ), __( 'Safe JS mode', 'qw-optimize' ), __( 'Empty-cart caching', 'qw-optimize' ), __( 'WooCommerce asset cleanup', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'cache_mobile' => 1, 'cache_logged_in' => 0, 'browser_cache_enabled' => 1, 'gzip_enabled' => 1, 'lazyload_images' => 1, 'lazyload_iframes' => 1, 'image_dimensions' => 1, 'defer_js' => 1, 'delay_js' => 0, 'js_safe_mode' => 1, 'builder_compat' => 1, 'minify_html' => 1, 'minify_css' => 1, 'minify_js' => 1, 'combine_js' => 0, 'combine_css' => 0, 'remove_unused_css' => 0, 'critical_css_enabled' => 0, 'woo_disable_cart_fragments' => 1, 'woo_dequeue_outside_shop' => 1, 'woo_cache_empty_cart' => 1, 'woo_disable_password_strength' => 1, 'woo_disable_scripts_outside_checkout' => 1, 'hosting_purge_auto' => 1, 'test_mode' => 0, ), ), 'builder' => array( 'label' => __( 'Elementor / Builder Safe', 'qw-optimize' ), 'tagline' => __( 'Compatibility-first for visual builders', 'qw-optimize' ), 'description' => __( 'Uses caching, minification and media optimization while avoiding aggressive CSS/JS transformations that commonly break builder sites.', 'qw-optimize' ), 'risk' => 'safe', 'badge' => __( 'Builder Safe', 'qw-optimize' ), 'pro' => false, 'features' => array( __( 'Builder compatibility', 'qw-optimize' ), __( 'JS Safe Mode', 'qw-optimize' ), __( 'No combine', 'qw-optimize' ), __( 'Conservative defer', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'cache_mobile' => 1, 'browser_cache_enabled' => 1, 'gzip_enabled' => 1, 'lazyload_images' => 1, 'lazyload_iframes' => 1, 'image_dimensions' => 1, 'minify_html' => 1, 'minify_css' => 1, 'minify_js' => 1, 'defer_js' => 1, 'delay_js' => 0, 'combine_css' => 0, 'combine_js' => 0, 'remove_unused_css' => 0, 'critical_css_enabled' => 0, 'js_safe_mode' => 1, 'builder_compat' => 1, 'test_mode' => 0, ), ), 'developer' => array( 'label' => __( 'Developer Mode', 'qw-optimize' ), 'tagline' => __( 'Predictable behavior while actively building', 'qw-optimize' ), 'description' => __( 'Keeps risky transformations off, enables safe testing behavior and makes cache changes easier to reason about during development.', 'qw-optimize' ), 'risk' => 'safe', 'badge' => __( 'Development', 'qw-optimize' ), 'pro' => false, 'features' => array( __( 'Test mode', 'qw-optimize' ), __( 'No CSS/JS combine', 'qw-optimize' ), __( 'No Delay JS/RUCSS', 'qw-optimize' ), __( 'Builder + JS safeguards', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'cache_logged_in' => 0, 'browser_cache_enabled' => 0, 'minify_html' => 0, 'minify_css' => 0, 'minify_js' => 0, 'combine_css' => 0, 'combine_js' => 0, 'defer_js' => 0, 'delay_js' => 0, 'remove_unused_css' => 0, 'critical_css_enabled' => 0, 'js_safe_mode' => 1, 'builder_compat' => 1, 'test_mode' => 1, ), ), 'cwv' => array( 'label' => __( 'Core Web Vitals', 'qw-optimize' ), 'tagline' => __( 'Target LCP, INP and rendering bottlenecks', 'qw-optimize' ), 'description' => __( 'Focuses on above-the-fold rendering, JavaScript interaction cost, critical images and high-impact Core Web Vitals improvements.', 'qw-optimize' ), 'risk' => 'balanced', 'badge' => __( 'PRO-heavy', 'qw-optimize' ), 'pro' => true, 'features' => array( __( 'Critical image preload', 'qw-optimize' ), __( 'Delay JS (Pro)', 'qw-optimize' ), __( 'Critical CSS + RUCSS (Pro)', 'qw-optimize' ), __( 'INP optimizer (Pro)', 'qw-optimize' ) ), 'settings' => array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'browser_cache_enabled' => 1, 'gzip_enabled' => 1, 'lazyload_images' => 1, 'lazyload_iframes' => 1, 'image_dimensions' => 1, 'preload_critical_images' => 1, 'critical_images_max' => 1, 'browser_cache_font_cors' => 1, 'google_fonts_optimize' => 1, 'font_display_sitewide' => 1, 'font_display' => 'swap', 'defer_js' => 1, 'js_safe_mode' => 1, 'builder_compat' => 1, 'minify_html' => 1, 'minify_css' => 1, 'minify_js' => 1, 'combine_css' => 0, 'combine_js' => 0, 'hover_prefetch_enabled' => 1, 'delay_js' => 1, 'remove_unused_css' => 1, 'critical_css_enabled' => 1, 'critical_css_auto' => 1, 'inp_optimizer_enabled' => 1, 'inp_scheduler_yield' => 1, 'smart_third_party' => 1, 'preload_links' => 1, 'preload_after_purge' => 1, 'test_mode' => 0, ), ), ); } /** * Overlay used for emergency recovery. * * @return array */ public static function safe_defaults_overlay() { return array( 'page_cache_enabled' => 1, 'cache_enabled' => 1, 'minify_css' => 0, 'minify_js' => 0, 'minify_html' => 0, 'combine_css' => 0, 'combine_js' => 0, 'delay_js' => 0, 'defer_js' => 0, 'remove_unused_css' => 0, 'critical_css_auto' => 0, 'critical_css_enabled'=> 0, 'test_mode' => 0, 'js_safe_mode' => 1, 'builder_compat' => 1, 'emergency_safe_mode' => 0, ); } /** @return string[] */ public static function list_presets() { return array_keys( self::builtins() ); } /** * Translate retired preset IDs so old links/suggestions keep working. * * @param string $preset_id Preset id. * @return string */ public static function normalize_id( $preset_id ) { $aliases = array( 'aggressive' => 'maximum', 'compatibility' => 'builder', 'blog' => 'balanced', 'brochure' => 'balanced', ); return isset( $aliases[ $preset_id ] ) ? $aliases[ $preset_id ] : $preset_id; } /** * Apply preset keys onto current stored settings. * * @param string $preset_id Preset id. * @return bool */ public static function apply( $preset_id ) { $preset_id = self::normalize_id( sanitize_key( $preset_id ) ); $builtins = self::builtins(); if ( ! isset( $builtins[ $preset_id ] ) ) { return false; } $current = get_option( 'qwsc_settings', array() ); if ( ! is_array( $current ) ) { $current = array(); } // Presets are useful without Pro. Only a separately installed and // active extension may provide premium-only preset behavior. $premium = array_fill_keys( \QWSpeedCache\Free\FeatureCatalog::keys(), true ); $provided = array_fill_keys( \QWSpeedCache\Free\Extensions::available_pro_keys(), true ); foreach ( $builtins[ $preset_id ]['settings'] as $k => $v ) { if ( isset( $premium[ $k ] ) && ! isset( $provided[ $k ] ) ) { continue; } $sanitized = \QWSpeedCache\Settings\Schema::sanitize_value( $k, $v ); if ( null !== $sanitized ) { $current[ $k ] = $sanitized; } } update_option( 'qwsc_settings', $current ); if ( class_exists( '\\QWSpeedCache\\Plugin' ) ) { \QWSpeedCache\Plugin::instance()->reload_settings(); } if ( class_exists( '\\QWSpeedCache\\Stats\\Logger' ) ) { \QWSpeedCache\Stats\Logger::log( 'preset', 'Applied preset: ' . $preset_id ); } return true; } /** * Save named profile snapshot (non-secret exportable keys). * * @param string $name Name. * @return bool */ public static function save_profile( $name ) { $name = sanitize_text_field( $name ); if ( '' === $name || strlen( $name ) > 60 ) { return false; } $ie = new ImportExport(); $data = $ie->build_export_data(); $profiles = get_option( self::PROFILES_OPTION, array() ); if ( ! is_array( $profiles ) ) { $profiles = array(); } $profiles[ $name ] = array( 'time' => time(), 'settings' => isset( $data['settings'] ) ? $data['settings'] : array(), ); if ( count( $profiles ) > 20 ) { $profiles = array_slice( $profiles, -20, null, true ); } update_option( self::PROFILES_OPTION, $profiles, false ); return true; } /** * @param string $name Profile name. * @return bool */ public static function load_profile( $name ) { $profiles = get_option( self::PROFILES_OPTION, array() ); if ( ! is_array( $profiles ) || empty( $profiles[ $name ]['settings'] ) ) { return false; } $ie = new ImportExport(); $ie->apply_import_data( array( 'settings' => $profiles[ $name ]['settings'] ) ); if ( class_exists( '\\QWSpeedCache\\Stats\\Logger' ) ) { \QWSpeedCache\Stats\Logger::log( 'profile', 'Loaded profile: ' . $name ); } return true; } }