30, 'retention_days' => 90, 'capture_fatal_errors'=> 1, 'store_error_message' => 0, 'show_noops' => 1, 'visual_intelligence' => 1, 'visual_mode' => 'hybrid', 'interface_theme' => 'commander_gold', 'interface_language' => 'auto', 'notice_bay' => 0, 'sensor_deployment' => 1, 'sensor_identity' => 1, 'sensor_configuration'=> 1, 'sensor_drift' => 1, 'flood_guard' => 1, 'flood_window' => 300, 'suppression_patterns'=> "", 'remove_on_uninstall' => 1, ); } public static function all() { return wp_parse_args( get_option( 'edrad_settings', array() ), self::defaults() ); } public static function get( $key ) { $options = self::all(); return $options[ $key ] ?? null; } public static function register() { add_action( 'admin_init', array( __CLASS__, 'register_setting' ) ); } public static function register_setting() { register_setting( 'edrad_settings_group', 'edrad_settings', array( 'type' => 'array', 'sanitize_callback' => array( __CLASS__, 'sanitize' ), 'default' => self::defaults() ) ); } public static function sanitize( $input ) { $input = is_array( $input ) ? $input : array(); $windows = array( 5, 15, 30, 60, 120 ); $retention = array( 7, 30, 90, 180, 365 ); return array( 'window_minutes' => in_array( absint( $input['window_minutes'] ?? 30 ), $windows, true ) ? absint( $input['window_minutes'] ) : 30, 'retention_days' => in_array( absint( $input['retention_days'] ?? 90 ), $retention, true ) ? absint( $input['retention_days'] ) : 90, 'capture_fatal_errors' => empty( $input['capture_fatal_errors'] ) ? 0 : 1, 'store_error_message' => empty( $input['store_error_message'] ) ? 0 : 1, 'show_noops' => empty( $input['show_noops'] ) ? 0 : 1, 'visual_intelligence' => empty( $input['visual_intelligence'] ) ? 0 : 1, 'visual_mode' => in_array( sanitize_key( $input['visual_mode'] ?? 'hybrid' ), array( 'hybrid', 'graph', 'statistics' ), true ) ? sanitize_key( $input['visual_mode'] ) : 'hybrid', 'interface_theme' => in_array( self::get( 'interface_theme' ), array( 'commander_gold', 'sensor_tactical', 'tactical_light' ), true ) ? self::get( 'interface_theme' ) : 'commander_gold', // Legacy site-wide fallback retained; theme selections use user meta. 'interface_language' => in_array( sanitize_key( $input['interface_language'] ?? 'auto' ), array( 'auto', 'en', 'de', 'es', 'fr', 'pt', 'it', 'tr', 'ru' ), true ) ? sanitize_key( $input['interface_language'] ) : 'auto', 'notice_bay' => empty( $input['notice_bay'] ) ? 0 : 1, 'sensor_deployment' => empty( $input['sensor_deployment'] ) ? 0 : 1, 'sensor_identity' => empty( $input['sensor_identity'] ) ? 0 : 1, 'sensor_configuration' => empty( $input['sensor_configuration'] ) ? 0 : 1, 'sensor_drift' => empty( $input['sensor_drift'] ) ? 0 : 1, 'flood_guard' => empty( $input['flood_guard'] ) ? 0 : 1, 'flood_window' => in_array( absint( $input['flood_window'] ?? 300 ), array( 60, 300, 900, 3600 ), true ) ? absint( $input['flood_window'] ) : 300, 'suppression_patterns' => self::sanitize_patterns( $input['suppression_patterns'] ?? '' ), 'remove_on_uninstall' => empty( $input['remove_on_uninstall'] ) ? 0 : 1, ); } private static function sanitize_patterns( $value ) { $lines = preg_split( '/\R/', (string) $value ); $clean = array(); foreach ( array_slice( is_array( $lines ) ? $lines : array(), 0, 100 ) as $line ) { $line = trim( sanitize_text_field( $line ) ); if ( '' !== $line && 0 !== strpos( $line, '#' ) ) { $clean[] = substr( $line, 0, 191 ); } } return implode( "\n", array_values( array_unique( $clean ) ) ); } }