create_tables(); // Initialize default settings $settings = new Vigilante_Settings(); $current_options = get_option( Vigilante_Settings::OPTION_NAME ); if ( false === $current_options ) { // First installation - set defaults update_option( Vigilante_Settings::OPTION_NAME, $settings->get_default_options() ); // Refresh settings instance to get new values $settings->clear_cache(); $settings = new Vigilante_Settings(); } else { // Existing installation - run idempotent migrations if ( self::run_migrations( $current_options ) ) { $settings->clear_cache(); $settings = new Vigilante_Settings(); } } // Create backup of current files FIRST (before any modifications) self::create_activation_backup( $settings ); // Apply htaccess protection (part of firewall module) if ( $settings->is_module_enabled( 'firewall' ) ) { self::apply_htaccess_protection( $settings ); } // Apply security headers to htaccess if ( $settings->is_module_enabled( 'security_headers' ) ) { self::apply_security_headers( $settings ); } // Apply wp-config security (part of wp_hardening module) if ( $settings->is_module_enabled( 'wp_hardening' ) ) { self::apply_wpconfig_security( $settings ); } // Update WordPress options for HTTPS (part of security_headers module) if ( $settings->is_module_enabled( 'security_headers' ) ) { self::enforce_https( $settings ); } // Apply comment security settings (part of wp_hardening module) if ( $settings->is_module_enabled( 'wp_hardening' ) ) { self::apply_comment_security( $settings ); } // Remove sensitive files self::remove_sensitive_files( $settings ); // Generate critical config files baseline (after all Vigilante writes above) self::generate_critical_baseline( $settings ); // Schedule cron events self::schedule_events(); // Set activation transient for admin notice set_transient( 'vigilante_activated', true, 30 ); // Store activation time update_option( 'vigilante_activated_time', time() ); // Send activation email if enabled self::send_activation_email( $settings ); // Flush rewrite rules flush_rewrite_rules(); // Clean any output that may have been generated ob_end_clean(); } /** * Idempotent migrations for existing installations. * * @param array $current_options Current vigilante_options array. * @return bool True if any migration changed the stored option. */ private static function run_migrations( $current_options ) { $changed = false; // Migration: rest_api_security.mode legacy value 'authenticated' // (UI bug shipped a