0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-25 02:30:28 +01:00
discourse-custom-wizard/lib/custom_wizard/template.rb

206 Zeilen
5,4 KiB
Ruby

# frozen_string_literal: true
2020-10-31 08:05:50 +01:00
class CustomWizard::Template
2020-11-03 01:24:20 +01:00
include HasErrors
2021-03-11 07:30:15 +01:00
AFTER_SIGNUP_CACHE_KEY ||= "after_signup_wizard_ids"
AFTER_TIME_CACHE_KEY ||= "after_time_wizard_ids"
2024-10-16 13:52:03 +02:00
attr_reader :data, :opts, :steps, :actions
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
def initialize(data)
@data = data
2024-10-16 13:52:03 +02:00
@steps = data["steps"] || []
@actions = data["actions"] || []
2020-10-31 08:05:50 +01:00
end
2021-03-11 07:30:15 +01:00
def save(opts = {})
2020-11-03 01:24:20 +01:00
@opts = opts
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
normalize_data
validate_data
prepare_data
return false if errors.any?
2021-03-11 07:30:15 +01:00
2020-10-31 08:05:50 +01:00
ActiveRecord::Base.transaction do
2020-11-03 01:24:20 +01:00
schedule_save_jobs unless opts[:skip_jobs]
PluginStore.set(CustomWizard::PLUGIN_NAME, @data[:id], @data)
ensure_wizard_upload_references!
2020-10-31 08:05:50 +01:00
end
2021-03-11 07:30:15 +01:00
self.class.clear_cache_keys
2020-11-03 01:24:20 +01:00
@data[:id]
end
2021-03-11 07:30:15 +01:00
def self.save(data, opts = {})
2020-11-03 01:24:20 +01:00
new(data).save(opts)
end
2021-03-11 07:30:15 +01:00
def self.create(wizard_id)
if data = find(wizard_id)
new(data)
else
nil
end
end
2020-11-03 01:24:20 +01:00
def self.find(wizard_id)
PluginStore.get(CustomWizard::PLUGIN_NAME, wizard_id)
2020-10-31 08:05:50 +01:00
end
2021-03-11 07:30:15 +01:00
def self.find_record(wizard_id)
PluginStoreRow.find_by(plugin_name: CustomWizard::PLUGIN_NAME, key: wizard_id)
end
2020-10-31 08:05:50 +01:00
def self.remove(wizard_id)
2020-11-03 01:24:20 +01:00
wizard = CustomWizard::Wizard.create(wizard_id)
return false if !wizard
2021-03-11 07:30:15 +01:00
ActiveRecord::Base.transaction do
ensure_wizard_upload_references!(wizard_id)
PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id)
clear_user_wizard_redirect(wizard_id, after_time: !!wizard.after_time)
2024-10-16 13:52:03 +02:00
related_custom_fields =
CategoryCustomField.where(
name: "create_topic_wizard",
value: wizard.name.parameterize(separator: "_"),
)
related_custom_fields.destroy_all
2020-10-31 08:05:50 +01:00
end
2021-03-11 07:30:15 +01:00
clear_cache_keys
true
2020-10-31 08:05:50 +01:00
end
2021-03-11 07:30:15 +01:00
2020-10-31 08:05:50 +01:00
def self.exists?(wizard_id)
2024-10-16 13:52:03 +02:00
PluginStoreRow.exists?(plugin_name: "custom_wizard", key: wizard_id)
2020-10-31 08:05:50 +01:00
end
2021-03-11 07:30:15 +01:00
def self.list(setting: nil, query_str: nil, order: :id)
2020-11-03 01:24:20 +01:00
query = "plugin_name = 'custom_wizard'"
query += " AND (value::json ->> '#{setting}')::boolean IS TRUE" if setting
query += " #{query_str}" if query_str
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
PluginStoreRow
.where(query)
.order(order)
2020-10-31 08:05:50 +01:00
.reduce([]) do |result, record|
attrs = JSON.parse(record.value)
2021-03-11 07:30:15 +01:00
2024-10-16 13:52:03 +02:00
if attrs.present? && attrs.is_a?(Hash) && attrs["id"].present? && attrs["name"].present?
2020-10-31 08:05:50 +01:00
result.push(attrs)
end
2021-03-11 07:30:15 +01:00
2020-10-31 08:05:50 +01:00
result
end
end
2021-03-11 07:30:15 +01:00
def self.clear_user_wizard_redirect(wizard_id, after_time: false)
2024-10-16 13:52:03 +02:00
UserCustomField.where(name: "redirect_to_wizard", value: wizard_id).destroy_all
2024-10-16 13:52:03 +02:00
Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id) if after_time
end
def self.after_signup_ids
::CustomWizard::Cache.wrap(AFTER_SIGNUP_CACHE_KEY) do
2024-10-16 13:52:03 +02:00
list(setting: "after_signup").map { |t| t["id"] }
end
end
def self.after_time_ids
::CustomWizard::Cache.wrap(AFTER_TIME_CACHE_KEY) do
list(
2024-10-16 13:52:03 +02:00
setting: "after_time",
query_str:
"AND (value::json ->> 'after_time_scheduled')::timestamp < '#{Time.now}'::timestamp",
).map { |t| t["id"] }
end
end
def self.can_redirect_users?(wizard_id)
after_signup_ids.include?(wizard_id) || after_time_ids.include?(wizard_id)
end
def self.clear_cache_keys
CustomWizard::Cache.new(AFTER_SIGNUP_CACHE_KEY).delete
CustomWizard::Cache.new(AFTER_TIME_CACHE_KEY).delete
end
def self.ensure_wizard_upload_references!(wizard_id, wizard_upload_ids = [])
wizard_record = find_record(wizard_id)
if wizard_record
UploadReference.ensure_exist!(
upload_ids: wizard_upload_ids,
target_type: "PluginStoreRow",
2024-10-16 13:52:03 +02:00
target_id: wizard_record.id,
)
end
end
2020-11-03 01:24:20 +01:00
private
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
def normalize_data
@data = ::JSON.parse(@data) if @data.is_a?(String)
@data = @data.with_indifferent_access
end
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
def prepare_data
@data[:steps].each do |step|
2024-10-16 13:52:03 +02:00
step[:description] = step[:raw_description] if step[:raw_description]
remove_non_mapped_index(step)
2024-10-16 13:52:03 +02:00
step[:fields].each { |field| remove_non_mapped_index(field) }
2020-11-03 01:24:20 +01:00
end
end
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
def validate_data
validator = CustomWizard::TemplateValidator.new(@data, @opts)
2020-11-03 01:24:20 +01:00
validator.perform
add_errors_from(validator)
end
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
def schedule_save_jobs
if @data[:after_time] && @data[:after_time_scheduled]
wizard_id = @data[:id]
old_data = CustomWizard::Template.find(data[:id])
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
begin
enqueue_wizard_at = Time.parse(@data[:after_time_scheduled]).utc
rescue ArgumentError
errors.add :validation, I18n.t("wizard.validation.after_time")
raise ActiveRecord::Rollback.new
end
2021-03-11 07:30:15 +01:00
2020-11-03 01:24:20 +01:00
if enqueue_wizard_at
2024-10-17 16:15:25 +02:00
self.class.clear_user_wizard_redirect(wizard_id, after_time: true)
2020-11-03 01:24:20 +01:00
Jobs.enqueue_at(enqueue_wizard_at, :set_after_time_wizard, wizard_id: wizard_id)
elsif old_data && old_data[:after_time]
2024-10-17 16:15:25 +02:00
self.class.clear_user_wizard_redirect(wizard_id, after_time: true)
2020-11-03 01:24:20 +01:00
end
end
2020-10-31 08:05:50 +01:00
end
def remove_non_mapped_index(object)
2024-10-16 13:52:03 +02:00
object.delete(:index) if !object[:index].is_a?(Array)
end
2022-08-02 13:39:56 +02:00
def ensure_wizard_upload_references!
2022-08-02 13:39:56 +02:00
upload_ids = []
@data[:steps].each do |step|
upload_ids << step[:banner_upload_id] if step[:banner_upload_id]
step[:fields].each do |field|
upload_ids << field[:image_upload_id] if field[:image_upload_id]
end
end
upload_ids = upload_ids.select { |upload_id| Upload.exists?(upload_id) }
self.class.ensure_wizard_upload_references!(@data[:id], upload_ids)
2022-08-02 13:39:56 +02:00
end
2021-03-11 07:30:15 +01:00
end