0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 07:23:30 +08:00
discourse/plugins/discourse-calendar/lib/calendar_custom_fields_validator.rb
Régis Hanol 5cf6b4a29c
FIX: Support uppercase and separators in event custom field names (#40995)
Previously, event custom fields whose names contained uppercase letters,
dashes, or dots either crashed the event builder's advanced settings
dialog or were silently dropped on save, so the feature effectively only
worked with plain lowercase names.

This change normalizes custom field names consistently across the
composer, server parser, and rich-text editor so they round-trip
regardless of case or separator, and validates the
`discourse_post_event_allowed_custom_fields` site setting to reject
malformed, colliding, or reserved names up front.

Meta:
https://meta.discourse.org/t/event-custom-fields-can-only-be-lowercase/405386
2026-06-24 17:02:32 +02:00

48 lines
1.2 KiB
Ruby
Vendored

# frozen_string_literal: true
class CalendarCustomFieldsValidator
NAME_FORMAT = /\A[a-z0-9]+([_.-][a-z0-9]+)*\z/i
def initialize(opts = {})
@opts = opts
end
def valid_value?(val)
@error_message = nil
return true if val.blank?
names = val.split("|").reject(&:blank?)
attributes =
names.index_with { |name| DiscoursePostEvent::EventParser.custom_field_data_attribute(name) }
errors = []
malformed = names.reject { |name| name.match?(NAME_FORMAT) }
errors << error(:invalid, malformed) if malformed.any?
colliding =
names.group_by { |name| attributes[name] }.values.select { |group| group.size > 1 }.flatten
errors << error(:collision, colliding) if colliding.any?
reserved = DiscoursePostEvent::EventParser.valid_option_attributes
reserved_names = names.select { |name| reserved.include?(attributes[name]) }
errors << error(:reserved, reserved_names) if reserved_names.any?
return true if errors.empty?
@error_message = errors.join(" ")
false
end
def error_message
@error_message
end
private
def error(key, names)
I18n.t(
"site_settings.discourse_post_event_allowed_custom_fields_#{key}",
names: names.join(", "),
)
end
end