1
0
Fork 0
discourse-custom-wizard-unl.../lib/custom_wizard/mapper.rb

125 Zeilen
2,9 KiB
Ruby

2020-03-30 08:16:03 +02:00
class CustomWizard::Mapper
attr_accessor :inputs, :data, :user
USER_FIELDS = ['name', 'username', 'email', 'date_of_birth', 'title', 'locale', 'trust_level']
PROFILE_FIELDS = ['location', 'website', 'bio_raw']
2020-04-01 07:03:26 +02:00
OPERATORS = {
equal: '=',
greater: '>',
less: '<',
greater_or_equal: '>=',
less_or_equal: '<='
}
2020-03-30 08:16:03 +02:00
def initialize(params)
@inputs = params[:inputs] || {}
@data = params[:data] || {}
@user = params[:user]
@opts = params[:opts] || {}
end
def output
multiple = @opts[:multiple]
output = multiple ? [] : nil
inputs.each do |input|
if input['type'] === 'conditional' && validate_pairs(input['pairs'])
if multiple
output.push(map_field(input['output'], input['output_type']))
else
output = map_field(input['output'], input['output_type'])
break
end
end
if input['type'] === 'assignment'
value = map_field(input['output'], input['output_type'])
if @opts[:multiple]
output.push(value)
else
output = value
break
end
end
end
output
end
def validate_pairs(pairs)
failed = false
pairs.each do |pair|
key = map_field(pair['key'], pair['key_type'])
value = map_field(pair['value'], pair['value_type'])
2020-04-01 07:03:26 +02:00
begin
failed = true unless key.public_send(operator(pair['connector']), value)
rescue => e
byebug
end
2020-03-30 08:16:03 +02:00
end
!failed
end
def operator(connector)
2020-04-01 07:03:26 +02:00
OPERATORS[connector.to_sym] || '=='
2020-03-30 08:16:03 +02:00
end
def map_field(value, type)
method = "#{type}_field"
if self.respond_to?(method)
self.send(method, value)
else
value
end
end
def wizard_field(value)
data && !data.key?("submitted_at") && data[value]
end
def user_field(value)
if value.include?('user_field_')
UserCustomField.where(user_id: user.id, name: value).pluck(:value).first
elsif PROFILE_FIELDS.include?(value)
UserProfile.find_by(user_id: user.id).send(value)
elsif USER_FIELDS.include?(value)
User.find(user.id).send(value)
end
end
def interpolate(string)
result = string.gsub(/u\{(.*?)\}/) do |match|
result = ''
result = user.send($1) if USER_FIELDS.include?($1)
result = user.user_profile.send($1) if PROFILE_FIELDS.include?($1)
result
end
result = result.gsub(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split('.')]) }
result.gsub(/v\{(.*?)\}/) do |match|
attrs = $1.split(':')
key = attrs.first
format = attrs.length > 1 ? attrs.last : nil
val = nil
if key == 'time'
time_format = format.present? ? format : "%B %-d, %Y"
val = Time.now.strftime(time_format)
end
val
end
end
def recurse(data, keys)
k = keys.shift
result = data[k]
keys.empty? ? result : self.recurse(result, keys)
end
end