0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-14 22:02:53 +01:00
discourse-custom-wizard/lib/custom_wizard/custom_field.rb

250 Zeilen
5,7 KiB
Ruby

# frozen_string_literal: true
2020-10-20 07:40:23 +02:00
class ::CustomWizard::CustomField
2020-10-17 03:31:07 +02:00
include HasErrors
include ActiveModel::Serialization
2021-03-11 07:30:15 +01:00
attr_reader :id
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
ATTRS ||= %w[name klass type serializers]
REQUIRED ||= %w[name klass type]
NAMESPACE ||= "custom_wizard_custom_fields"
NAME_MIN_LENGTH ||= 3
2021-03-11 07:30:15 +01:00
CLASSES ||= {
2024-10-16 13:52:03 +02:00
topic: %w[topic_view topic_list_item],
group: ["basic_group"],
category: ["basic_category"],
2024-10-16 13:52:03 +02:00
post: ["post"],
}
2024-10-16 13:52:03 +02:00
TYPES ||= %w[string boolean integer json]
LIST_CACHE_KEY ||= "custom_field_list"
2021-03-11 07:30:15 +01:00
def self.serializers
CLASSES.values.flatten.uniq
end
2021-03-11 07:30:15 +01:00
def initialize(id, data)
@id = id
2020-10-17 03:31:07 +02:00
data = data.with_indifferent_access
2021-03-11 07:30:15 +01:00
2020-10-17 03:31:07 +02:00
ATTRS.each do |attr|
self.class.class_eval { attr_accessor attr }
2021-03-11 07:30:15 +01:00
value = data[attr]
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
send("#{attr}=", value) if value.present?
2020-10-17 03:31:07 +02:00
end
2021-09-01 04:19:00 +02:00
2021-09-24 11:58:42 +02:00
@subscription = CustomWizard::Subscription.new
2020-10-17 03:31:07 +02:00
end
def save
validate
if valid?
data = {}
key = name
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
(ATTRS - ["name"]).each { |attr| data[attr] = send(attr) }
2021-03-11 07:30:15 +01:00
if self.class.save_to_store(id, key, data)
2020-11-09 11:44:32 +01:00
self.class.invalidate_cache
true
else
false
end
2020-10-17 03:31:07 +02:00
else
false
end
end
2021-03-11 07:30:15 +01:00
2020-10-17 03:31:07 +02:00
def validate
ATTRS.each do |attr|
value = send(attr)
i18n_key = "wizard.custom_field.error"
2021-03-11 07:30:15 +01:00
if value.blank? && REQUIRED.include?(attr)
add_error(I18n.t("#{i18n_key}.required_attribute", attr: attr))
break
end
2024-10-16 13:52:03 +02:00
next if attr == "serializers" && !value.is_a?(Array)
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
if (attr == "klass" && CLASSES.keys.exclude?(value.to_sym)) ||
(attr == "serializers" && CLASSES[klass.to_sym].blank?)
add_error(I18n.t("#{i18n_key}.unsupported_class", class: value))
next
2020-10-20 07:40:23 +02:00
end
2021-11-10 15:25:42 +01:00
2024-10-16 13:52:03 +02:00
if attr == "klass" && !@subscription.includes?(:custom_field, :klass, value)
2021-09-24 11:58:42 +02:00
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
2021-09-03 10:46:32 +02:00
end
2024-10-16 13:52:03 +02:00
if attr == "serializers" && (unsupported = value - CLASSES[klass.to_sym]).length > 0
add_error(
I18n.t(
"#{i18n_key}.unsupported_serializers",
class: klass,
serializers: unsupported.join(", "),
),
)
2020-10-20 07:40:23 +02:00
end
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
if attr == "type" && TYPES.exclude?(value)
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
2020-10-20 07:40:23 +02:00
end
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
if attr == "type" && !@subscription.includes?(:custom_field, :type, value)
2021-09-24 11:58:42 +02:00
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
2021-09-01 04:19:00 +02:00
end
2024-10-16 13:52:03 +02:00
if attr == "name"
add_error(I18n.t("#{i18n_key}.name_invalid", name: value)) unless value.is_a?(String)
2021-03-11 07:30:15 +01:00
if value.length < NAME_MIN_LENGTH
add_error(I18n.t("#{i18n_key}.name_too_short", name: value, min_length: NAME_MIN_LENGTH))
end
2021-03-11 07:30:15 +01:00
if new? && self.class.exists?(name)
add_error(I18n.t("#{i18n_key}.name_already_taken", name: value))
end
2021-03-11 07:30:15 +01:00
begin
2024-10-16 13:52:03 +02:00
@name = value.parameterize(separator: "_")
rescue StandardError
add_error(I18n.t("#{i18n_key}.name_invalid", name: value))
end
2020-10-20 07:40:23 +02:00
end
2020-10-17 03:31:07 +02:00
end
end
2021-03-11 07:30:15 +01:00
def new?
id.blank?
end
2021-03-11 07:30:15 +01:00
2020-10-17 03:31:07 +02:00
def valid?
errors.blank?
end
2021-03-11 07:30:15 +01:00
def self.list
2024-10-16 13:52:03 +02:00
PluginStoreRow.where(plugin_name: NAMESPACE).map { |record| create_from_store(record) }
end
2021-03-11 07:30:15 +01:00
def self.cached_list
2024-10-16 13:52:03 +02:00
@custom_wizard_cached_fields ||=
::CustomWizard::Cache.wrap(LIST_CACHE_KEY) do
PluginStoreRow
.where(plugin_name: NAMESPACE)
.map { |record| create_from_store(record).as_json.with_indifferent_access }
end
2020-10-17 03:31:07 +02:00
end
2021-03-11 07:30:15 +01:00
def self.list_by(attr, value, cached: true)
attr = attr.to_sym
fields = cached ? cached_list : list
2021-03-11 07:30:15 +01:00
fields.select do |cf|
if attr == :serializers
cf[attr] && cf[attr].include?(value)
else
cf[attr] == value
end
end
end
2021-03-11 07:30:15 +01:00
def self.exists?(name)
PluginStoreRow.where(plugin_name: NAMESPACE, key: name).exists?
end
2021-03-11 07:30:15 +01:00
2020-11-10 01:56:11 +01:00
def self.find(field_id)
record = PluginStoreRow.find_by(id: field_id, plugin_name: NAMESPACE)
2021-03-11 07:30:15 +01:00
2020-11-10 01:56:11 +01:00
if record
create_from_store(record)
else
false
end
end
2021-03-11 07:30:15 +01:00
2020-11-10 01:56:11 +01:00
def self.find_by_name(name)
record = PluginStoreRow.find_by(key: name, plugin_name: NAMESPACE)
2021-03-11 07:30:15 +01:00
2020-11-10 01:56:11 +01:00
if record
create_from_store(record)
else
false
end
end
2021-03-11 07:30:15 +01:00
def self.create_from_store(record)
data = JSON.parse(record.value)
data[:name] = record.key
new(record.id, data)
end
2021-03-11 07:30:15 +01:00
def self.save_to_store(id = nil, key, data)
if id
2020-11-10 01:56:11 +01:00
record = PluginStoreRow.find_by(id: id, plugin_name: NAMESPACE)
return false if !record
2020-11-10 01:56:11 +01:00
record.key = key
record.value = data.to_json
record.save
else
record = PluginStoreRow.new(plugin_name: NAMESPACE, key: key)
record.type_name = "JSON"
record.value = data.to_json
record.save
end
end
2021-03-11 07:30:15 +01:00
2020-11-09 11:44:32 +01:00
def self.destroy(name)
if exists?(name)
PluginStoreRow.where(plugin_name: NAMESPACE, key: name).destroy_all
invalidate_cache
true
else
false
end
end
2021-03-11 07:30:15 +01:00
2020-11-09 11:44:32 +01:00
def self.invalidate_cache
@custom_wizard_cached_fields = nil
CustomWizard::Cache.new(LIST_CACHE_KEY).delete
2020-11-09 11:44:32 +01:00
Discourse.clear_readonly!
Discourse.request_refresh!
end
2021-03-11 07:30:15 +01:00
def self.any?
cached_list.length > 0
end
2021-03-11 07:30:15 +01:00
def self.enabled?
any?
end
def self.external_list
external = []
CLASSES.keys.each do |klass|
2024-10-16 13:52:03 +02:00
meta_data = klass.to_s.classify.constantize.send("custom_field_meta_data")
if meta_data.present?
meta_data.each do |name, data|
unless list.any? { |field| field.name === name }
2024-10-16 13:52:03 +02:00
field = new("external", name: name, klass: klass, type: data.type)
external.push(field)
end
end
end
end
external
end
def self.full_list
(list + external_list).uniq
end
2021-03-11 07:30:15 +01:00
end