mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 11:03:44 +08:00
2215fa0c8e
This commit fixes a bug in theme settings migrations where values of `objects` typed theme settings aren't passed to migrations even when there are overriding values for those settings. What causes this bug is that, when creating the hash that contains all the overridden settings and will be passed to migrations, the values of `objects` typed settings are incorrectly retrieved from the `value` column (which is always nil for `objects` type) instead of `json_value`. `objects` settings are different from all other types in that they store their values in the `json_value` column and they need to be special-cased when retrieving their values.
106 lines
2.4 KiB
Ruby
106 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ThemeSettingsManager
|
|
attr_reader :name, :theme, :default
|
|
|
|
def self.types
|
|
ThemeSetting.types
|
|
end
|
|
|
|
def self.cast_row_value(row)
|
|
type_name = self.types.invert[row.data_type].downcase.capitalize
|
|
klass = "ThemeSettingsManager::#{type_name}".constantize
|
|
klass.cast(klass.extract_value_from_row(row))
|
|
end
|
|
|
|
def self.create(name, default, type, theme, opts = {})
|
|
type_name = self.types.invert[type].downcase.capitalize
|
|
klass = "ThemeSettingsManager::#{type_name}".constantize
|
|
klass.new(name, default, theme, opts)
|
|
end
|
|
|
|
def self.cast(value)
|
|
value
|
|
end
|
|
|
|
def self.extract_value_from_row(row)
|
|
row.value
|
|
end
|
|
|
|
def initialize(name, default, theme, opts = {})
|
|
@name = name.to_sym
|
|
@default = default
|
|
@theme = theme
|
|
@opts = opts
|
|
@types = self.class.types
|
|
end
|
|
|
|
def value
|
|
has_record? ? db_record.value : default
|
|
end
|
|
|
|
def type_name
|
|
self.class.name.demodulize.downcase.to_sym
|
|
end
|
|
|
|
def type
|
|
@types[type_name]
|
|
end
|
|
|
|
def description
|
|
@opts[:description] # Old method of specifying description. Is now overridden by locale file
|
|
end
|
|
|
|
def requests_refresh?
|
|
@opts[:refresh]
|
|
end
|
|
|
|
def value=(new_value)
|
|
ensure_is_valid_value!(new_value)
|
|
value = new_value.to_s
|
|
|
|
record = has_record? ? update_record!(value:) : create_record!(value:)
|
|
|
|
record.value
|
|
end
|
|
|
|
def db_record
|
|
# theme.theme_settings will already be preloaded, so it is better to use
|
|
# `find` on an array, rather than make a round trip to the database
|
|
theme.theme_settings.to_a.find do |i|
|
|
i.name.to_s == @name.to_s && i.data_type.to_s == type.to_s
|
|
end
|
|
end
|
|
|
|
def update_record!(args)
|
|
db_record.tap { |instance| instance.update!(args) }
|
|
end
|
|
|
|
def create_record!(args)
|
|
record = ThemeSetting.new(name: @name, data_type: type, theme: @theme, **args)
|
|
record.save!
|
|
record
|
|
end
|
|
|
|
def has_record?
|
|
db_record.present?
|
|
end
|
|
|
|
def ensure_is_valid_value!(new_value)
|
|
return if new_value.nil?
|
|
|
|
error_messages = ThemeSettingsValidator.validate_value(new_value, type, @opts)
|
|
raise Discourse::InvalidParameters.new error_messages.join(" ") if error_messages.present?
|
|
end
|
|
|
|
def has_min?
|
|
min = @opts[:min]
|
|
(min.is_a?(::Integer) || min.is_a?(::Float)) && min != -::Float::INFINITY
|
|
end
|
|
|
|
def has_max?
|
|
max = @opts[:max]
|
|
(max.is_a?(::Integer) || max.is_a?(::Float)) && max != ::Float::INFINITY
|
|
end
|
|
end
|