server = $server; $this->conflicts = $conflicts; $this->metrics = $metrics; $this->recommendations = $recommendations; } /** Build a safe, explainable plan. */ public function build( $mode = 'balanced' ) { $mode = sanitize_key( (string) $mode ); if ( ! in_array( $mode, array( 'safe', 'balanced', 'maximum' ), true ) ) { $mode = 'balanced'; } $server = $this->server->report(); $conflicts = $this->conflicts->diagnose(); $metrics = $this->metrics->snapshot(); $woocommerce = class_exists( 'WooCommerce' ) || defined( 'WC_VERSION' ); $constrained = isset( $server['hosting']['tier'] ) && 'constrained' === $server['hosting']['tier']; $image_ready = function_exists( 'wp_get_image_editor' ); $blockers = array(); $warnings = array(); foreach ( (array) $conflicts as $issue ) { $severity = isset( $issue['severity'] ) ? sanitize_key( $issue['severity'] ) : 'info'; $item = array( 'id' => isset( $issue['id'] ) ? sanitize_key( $issue['id'] ) : 'compatibility', 'message' => isset( $issue['message'] ) ? sanitize_text_field( $issue['message'] ) : __( 'A compatibility issue needs review.', 'nbh-performance' ), 'owner' => 'compatibility', ); if ( 'critical' === $severity ) { $blockers[] = $item; } elseif ( 'warning' === $severity ) { $warnings[] = $item; } } $environment = function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production'; if ( ! is_ssl() && ! in_array( $environment, array( 'local', 'development' ), true ) ) { $blockers[] = array( 'id' => 'https', 'message' => __( 'HTTPS must be enabled before automatic optimization.', 'nbh-performance' ), 'owner' => 'hosting', ); } if ( $constrained ) { $warnings[] = array( 'id' => 'constrained-hosting', 'message' => __( 'Background concurrency will be reduced for this hosting environment.', 'nbh-performance' ), 'owner' => 'hosting', ); } if ( ! $image_ready ) { $warnings[] = array( 'id' => 'image-editor', 'message' => __( 'WordPress did not expose an image editor, so image conversion will remain disabled.', 'nbh-performance' ), 'owner' => 'hosting', ); } $features = array( 'nbh_performance_cache_enabled' => 1, 'nbh_performance_sitemap_preload_enabled' => 1, 'nbh_performance_css_minify_enabled' => 1, 'nbh_performance_js_minify_enabled' => 1, 'nbh_performance_lazy_load_enabled' => 1, 'nbh_performance_responsive_images_enabled' => 1, 'nbh_performance_font_preload_enabled' => 1, 'nbh_performance_heartbeat_control_enabled' => 1, 'nbh_performance_speculation_rules_enabled' => 1, 'nbh_performance_resource_priority_enabled' => 1, ); $settings = array( 'nbh_performance_cache_ttl' => $woocommerce ? 3600 : 43200, 'nbh_performance_preload_batch_size' => $constrained ? 1 : ( 'maximum' === $mode ? 6 : 3 ), 'nbh_performance_preload_request_timeout' => $constrained ? 8 : 12, 'nbh_performance_webp_quality' => 82, 'nbh_performance_avif_quality' => 68, 'nbh_performance_font_preload_limit' => 2, 'nbh_performance_lcp_preload_limit' => 1, 'nbh_performance_lazyload_eager_images' => $woocommerce ? 3 : 2, 'nbh_performance_speculation_mode' => 'prefetch', 'nbh_performance_asset_inventory_enabled' => 1, 'nbh_performance_performance_budgets_enabled' => 1, 'nbh_performance_smart_rollback_enabled' => 1, ); if ( 'safe' !== $mode ) { $features['nbh_performance_defer_js_enabled'] = 1; $features['nbh_performance_youtube_facade_enabled'] = 1; if ( $image_ready ) { $features['nbh_performance_image_conversion_enabled'] = 1; $features['nbh_performance_nextgen_image_serving_enabled'] = 1; } } if ( 'maximum' === $mode ) { $features['nbh_performance_delay_js_enabled'] = 1; } if ( $woocommerce && 'maximum' !== $mode ) { $features['nbh_performance_delay_js_enabled'] = 0; } // A plan may only advertise options that persistence can actually apply. // Legacy/retired settings are deliberately omitted rather than silently ignored. $allowed_features = array(); foreach ( ( new FeatureToggleManager() )->groups() as $group ) { $allowed_features = array_merge( $allowed_features, array_keys( $group['features'] ) ); } $features = array_intersect_key( $features, array_fill_keys( $allowed_features, true ) ); $allowed_settings = array(); foreach ( ( new AdvancedSettingsManager() )->schema() as $section ) { $allowed_settings = array_merge( $allowed_settings, array_keys( $section['fields'] ) ); } $settings = array_intersect_key( $settings, array_fill_keys( $allowed_settings, true ) ); if ( ! defined( 'WP_CACHE' ) || ! WP_CACHE ) { $blockers[] = array( 'id' => 'wp-cache-setup', 'message' => __( 'Page caching requires WP_CACHE enabled by your hosting provider or in wp-config.php. Smart Optimize will not modify server configuration.', 'nbh-performance' ), 'owner' => 'hosting', ); } $steps = array( array( 'id' => 'baseline', 'title' => __( 'Capture current performance evidence', 'nbh-performance' ), 'status' => 'planned', ), array( 'id' => 'configure', 'title' => __( 'Apply environment-safe optimization settings', 'nbh-performance' ), 'status' => 'planned', ), array( 'id' => 'purge', 'title' => __( 'Purge and warm important page cache entries', 'nbh-performance' ), 'status' => 'planned', ), array( 'id' => 'validate', 'title' => __( 'Validate public and WooCommerce routes', 'nbh-performance' ), 'status' => 'planned', ), array( 'id' => 'measure', 'title' => __( 'Review local configuration and cache evidence', 'nbh-performance' ), 'status' => 'planned', ), array( 'id' => 'protect', 'title' => __( 'Protect the site with validation and reversible settings', 'nbh-performance' ), 'status' => 'planned', ), ); return array( 'mode' => $mode, 'eligible' => empty( $blockers ), 'generated_at' => time(), 'site_type' => $woocommerce ? 'woocommerce' : 'wordpress', 'hosting_tier' => isset( $server['hosting']['tier'] ) ? sanitize_key( $server['hosting']['tier'] ) : 'unknown', 'features' => $features, 'settings' => $settings, 'blockers' => $blockers, 'warnings' => $warnings, 'steps' => $steps, 'before' => $metrics, 'recommendations' => array_slice( $this->recommendations->recommendations(), 0, 8 ), 'safeguards' => array( 'configuration_snapshot' => true, 'frontend_validation' => true, 'woocommerce_protection' => $woocommerce, 'automatic_rollback' => true, ), ); } }