2019-05-02 18:17:27 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-04 19:04:23 -05:00
|
|
|
class ThemeSettingsParser
|
|
|
|
class InvalidYaml < StandardError
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(setting_field)
|
|
|
|
@setting_field = setting_field
|
|
|
|
@types = ThemeSetting.types
|
|
|
|
end
|
|
|
|
|
|
|
|
def extract_description(desc)
|
|
|
|
return desc if desc.is_a?(String)
|
|
|
|
|
|
|
|
if desc.is_a?(Hash)
|
|
|
|
default_locale = SiteSetting.default_locale.to_sym
|
|
|
|
fallback_locale = desc.keys.find { |key| I18n.locale_available?(key) }
|
|
|
|
locale = desc[I18n.locale] || desc[default_locale] || desc[:en] || desc[fallback_locale]
|
|
|
|
|
|
|
|
locale if locale.is_a?(String)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_opts(default, type, raw_opts = {})
|
|
|
|
opts = {}
|
|
|
|
opts[:description] = extract_description(raw_opts[:description])
|
|
|
|
|
|
|
|
if type == @types[:enum]
|
|
|
|
choices = raw_opts[:choices]
|
|
|
|
choices = [] unless choices.is_a?(Array)
|
2024-05-27 06:27:13 -04:00
|
|
|
choices << default if choices.exclude?(default)
|
2018-03-04 19:04:23 -05:00
|
|
|
opts[:choices] = choices
|
|
|
|
end
|
|
|
|
|
|
|
|
if [@types[:integer], @types[:string], @types[:float]].include?(type)
|
|
|
|
opts[:max] = raw_opts[:max].is_a?(Numeric) ? raw_opts[:max] : Float::INFINITY
|
|
|
|
opts[:min] = raw_opts[:min].is_a?(Numeric) ? raw_opts[:min] : -Float::INFINITY
|
|
|
|
end
|
2018-08-03 16:41:37 -04:00
|
|
|
|
|
|
|
opts[:list_type] = raw_opts[:list_type] if raw_opts[:list_type]
|
|
|
|
|
2019-02-05 09:14:53 -05:00
|
|
|
opts[:textarea] = !!raw_opts[:textarea]
|
2021-03-10 20:15:04 -05:00
|
|
|
opts[:json_schema] = raw_opts[:json_schema]
|
2024-02-07 21:20:59 -05:00
|
|
|
opts[:schema] = raw_opts[:schema]
|
2019-02-05 09:14:53 -05:00
|
|
|
|
2021-11-22 07:16:56 -05:00
|
|
|
opts[:refresh] = !!raw_opts[:refresh]
|
|
|
|
|
2018-03-04 19:04:23 -05:00
|
|
|
opts
|
|
|
|
end
|
|
|
|
|
|
|
|
def load
|
|
|
|
return if @setting_field.value.blank?
|
|
|
|
|
|
|
|
begin
|
|
|
|
parsed = YAML.safe_load(@setting_field.value)
|
|
|
|
rescue Psych::SyntaxError, Psych::DisallowedClass => e
|
|
|
|
raise InvalidYaml.new(e.message)
|
|
|
|
end
|
|
|
|
raise InvalidYaml.new(I18n.t("themes.settings_errors.invalid_yaml")) unless parsed.is_a?(Hash)
|
|
|
|
|
|
|
|
parsed.deep_symbolize_keys!
|
|
|
|
|
|
|
|
parsed.each_pair do |setting, value|
|
|
|
|
if (type = ThemeSetting.guess_type(value)).present?
|
|
|
|
result = [setting, value, type, create_opts(value, type)]
|
|
|
|
elsif (hash = value).is_a?(Hash)
|
|
|
|
default = hash[:default]
|
|
|
|
type = hash.key?(:type) ? @types[hash[:type]&.to_sym] : ThemeSetting.guess_type(default)
|
|
|
|
|
|
|
|
result = [setting, default, type, create_opts(default, type, hash)]
|
|
|
|
else
|
|
|
|
result = [setting, value, nil, {}]
|
|
|
|
end
|
|
|
|
|
|
|
|
yield(*result)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|