Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-12-01 13:01:10 +01:00
522d4e9489
* Add test of redirect_to_wizard when wizard is removed * Make clear_user_wizard_redirect a synchronous operation
146 Zeilen
3,4 KiB
Ruby
146 Zeilen
3,4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class CustomWizard::Template
|
|
include HasErrors
|
|
|
|
attr_reader :data,
|
|
:opts,
|
|
:steps,
|
|
:actions
|
|
|
|
def initialize(data)
|
|
@data = data
|
|
@steps = data['steps'] || []
|
|
@actions = data['actions'] || []
|
|
end
|
|
|
|
def save(opts = {})
|
|
@opts = opts
|
|
|
|
normalize_data
|
|
validate_data
|
|
prepare_data
|
|
|
|
return false if errors.any?
|
|
|
|
ActiveRecord::Base.transaction do
|
|
schedule_save_jobs unless opts[:skip_jobs]
|
|
PluginStore.set(CustomWizard::PLUGIN_NAME, @data[:id], @data)
|
|
end
|
|
|
|
@data[:id]
|
|
end
|
|
|
|
def self.save(data, opts = {})
|
|
new(data).save(opts)
|
|
end
|
|
|
|
def self.create(wizard_id)
|
|
if data = find(wizard_id)
|
|
new(data)
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
def self.find(wizard_id)
|
|
PluginStore.get(CustomWizard::PLUGIN_NAME, wizard_id)
|
|
end
|
|
|
|
def self.remove(wizard_id)
|
|
wizard = CustomWizard::Wizard.create(wizard_id)
|
|
return false if !wizard
|
|
|
|
ActiveRecord::Base.transaction do
|
|
PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id)
|
|
clear_user_wizard_redirect(wizard_id)
|
|
end
|
|
|
|
Jobs.cancel_scheduled_job(:set_after_time_wizard) if wizard.after_time
|
|
|
|
true
|
|
end
|
|
|
|
def self.exists?(wizard_id)
|
|
PluginStoreRow.exists?(plugin_name: 'custom_wizard', key: wizard_id)
|
|
end
|
|
|
|
def self.list(setting: nil, order: :id)
|
|
query = "plugin_name = 'custom_wizard'"
|
|
query += "AND (value::json ->> '#{setting}')::boolean IS TRUE" if setting
|
|
|
|
PluginStoreRow.where(query).order(order)
|
|
.reduce([]) do |result, record|
|
|
attrs = JSON.parse(record.value)
|
|
|
|
if attrs.present? &&
|
|
attrs.is_a?(Hash) &&
|
|
attrs['id'].present? &&
|
|
attrs['name'].present?
|
|
|
|
result.push(attrs)
|
|
end
|
|
|
|
result
|
|
end
|
|
end
|
|
|
|
def self.clear_user_wizard_redirect(wizard_id)
|
|
UserCustomField.where(name: 'redirect_to_wizard', value: wizard_id).destroy_all
|
|
end
|
|
|
|
private
|
|
|
|
def normalize_data
|
|
@data = ::JSON.parse(@data) if @data.is_a?(String)
|
|
@data = @data.with_indifferent_access
|
|
end
|
|
|
|
def prepare_data
|
|
@data[:steps].each do |step|
|
|
if step[:raw_description]
|
|
step[:description] = step[:raw_description]
|
|
end
|
|
|
|
remove_non_mapped_index(step)
|
|
|
|
step[:fields].each do |field|
|
|
remove_non_mapped_index(field)
|
|
end
|
|
end
|
|
end
|
|
|
|
def validate_data
|
|
validator = CustomWizard::TemplateValidator.new(@data, @opts)
|
|
validator.perform
|
|
add_errors_from(validator)
|
|
end
|
|
|
|
def schedule_save_jobs
|
|
if @data[:after_time] && @data[:after_time_scheduled]
|
|
wizard_id = @data[:id]
|
|
old_data = CustomWizard::Template.find(data[:id])
|
|
|
|
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
|
|
|
|
if enqueue_wizard_at
|
|
Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id)
|
|
Jobs.enqueue_at(enqueue_wizard_at, :set_after_time_wizard, wizard_id: wizard_id)
|
|
elsif old_data && old_data[:after_time]
|
|
Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard_id)
|
|
self.class.clear_user_wizard_redirect(wizard_id)
|
|
end
|
|
end
|
|
end
|
|
|
|
def remove_non_mapped_index(object)
|
|
if !object[:index].is_a?(Array)
|
|
object.delete(:index)
|
|
end
|
|
end
|
|
end
|