false, 'provider' => 'simulated', 'model' => '', 'api_base_url' => '', 'api_token' => '', ]; $stored = get_option( self::OPTION, [] ); if ( ! is_array( $stored ) ) $stored = []; return wp_parse_args( $stored, $defaults ); } /** * Save settings. Token field preserves the existing value when input is empty. */ public static function save( array $input ): void { $current = self::get(); $new = [ 'enabled' => ! empty( $input['enabled'] ), 'provider' => sanitize_key( $input['provider'] ?? 'simulated' ), 'model' => sanitize_text_field( $input['model'] ?? '' ), 'api_base_url' => esc_url_raw( $input['api_base_url'] ?? '' ), 'api_token' => ! empty( $input['api_token'] ) ? (string) $input['api_token'] : (string) $current['api_token'], ]; update_option( self::OPTION, $new ); } public static function has_token(): bool { $s = self::get(); return ! empty( $s['api_token'] ); } /** * Public-facing label for the saved-token state. Never returns the value itself. */ public static function token_status_label(): string { return self::has_token() ? '[token is set; leave blank to preserve, enter a new value to update]' : '[no token saved]'; } }