2020-03-30 08:16:03 +02:00
|
|
|
class CustomWizard::Action
|
|
|
|
attr_accessor :data,
|
|
|
|
:action,
|
|
|
|
:user,
|
|
|
|
:updater
|
|
|
|
|
|
|
|
def initialize(params)
|
|
|
|
@action = params[:action]
|
|
|
|
@user = params[:user]
|
|
|
|
@data = params[:data]
|
|
|
|
@updater = params[:updater]
|
|
|
|
end
|
|
|
|
|
|
|
|
def perform
|
|
|
|
ActiveRecord::Base.transaction { self.send(action['type'].to_sym) }
|
|
|
|
end
|
|
|
|
|
|
|
|
def mapper
|
|
|
|
@mapper ||= CustomWizard::Mapper.new(user: user, data: data)
|
|
|
|
end
|
|
|
|
|
2020-03-31 08:29:59 +02:00
|
|
|
def create_topic
|
2020-04-02 07:21:57 +02:00
|
|
|
params = basic_topic_params
|
2020-04-02 10:21:03 +02:00
|
|
|
|
2020-04-02 07:21:57 +02:00
|
|
|
if params[:title] && params[:raw]
|
|
|
|
params[:category] = action_category
|
|
|
|
params[:tags] = action_tags
|
2020-03-30 08:16:03 +02:00
|
|
|
|
|
|
|
creator = PostCreator.new(user, params)
|
|
|
|
post = creator.create
|
2020-04-07 13:17:20 +02:00
|
|
|
|
2020-03-30 08:16:03 +02:00
|
|
|
if creator.errors.present?
|
|
|
|
updater.errors.add(:create_topic, creator.errors.full_messages.join(" "))
|
2020-04-02 07:21:57 +02:00
|
|
|
elsif action['skip_redirect'].blank?
|
|
|
|
data['redirect_on_complete'] = post.topic.url
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_message
|
2020-04-02 07:21:57 +02:00
|
|
|
return if action['required'].present? && data[action['required']].blank?
|
2020-03-30 08:16:03 +02:00
|
|
|
|
2020-04-02 07:21:57 +02:00
|
|
|
params = basic_topic_params
|
|
|
|
params[:target_usernames] = CustomWizard::Mapper.new(
|
|
|
|
inputs: action['recipient'],
|
|
|
|
data: data,
|
2020-04-02 10:21:03 +02:00
|
|
|
user: user
|
2020-04-06 10:36:38 +02:00
|
|
|
).perform
|
2020-04-02 10:21:03 +02:00
|
|
|
|
2020-04-02 07:21:57 +02:00
|
|
|
if params[:title] && params[:raw]
|
|
|
|
params[:archetype] = Archetype.private_message
|
|
|
|
|
|
|
|
creator = PostCreator.new(user, params)
|
2020-03-30 08:16:03 +02:00
|
|
|
post = creator.create
|
|
|
|
|
|
|
|
if creator.errors.present?
|
|
|
|
updater.errors.add(:send_message, creator.errors.full_messages.join(" "))
|
2020-04-02 07:21:57 +02:00
|
|
|
elsif action['skip_redirect'].blank?
|
|
|
|
data['redirect_on_complete'] = post.topic.url
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_profile
|
2020-04-02 07:21:57 +02:00
|
|
|
return unless (profile_updates = action['profile_updates']).length
|
2020-04-07 15:33:11 +02:00
|
|
|
params = {}
|
|
|
|
|
|
|
|
profile_updates.first[:pairs].each do |pair|
|
2020-04-07 16:18:12 +02:00
|
|
|
if allowed_profile_fields.include?(pair['key'])
|
|
|
|
key = cast_profile_key(pair['key']).to_sym
|
|
|
|
value = mapper.map_field(pair['value'], pair['value_type'])
|
|
|
|
params[key] = cast_profile_value(value, pair['key'])
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-04-07 15:33:11 +02:00
|
|
|
params = add_custom_fields(params)
|
|
|
|
|
|
|
|
if params.present?
|
|
|
|
UserUpdater.new(Discourse.system_user, user).update(params)
|
|
|
|
|
|
|
|
if params[:avatar].present?
|
|
|
|
update_avatar(params[:avatar])
|
|
|
|
end
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_to_api
|
|
|
|
api_body = nil
|
|
|
|
|
|
|
|
if action['api_body'] != ""
|
|
|
|
begin
|
|
|
|
api_body_parsed = JSON.parse(action['api_body'])
|
|
|
|
rescue JSON::ParserError
|
|
|
|
raise Discourse::InvalidParameters, "Invalid API body definition: #{action['api_body']} for #{action['title']}"
|
|
|
|
end
|
|
|
|
api_body = JSON.parse(mapper.interpolate(JSON.generate(api_body_parsed)))
|
|
|
|
end
|
|
|
|
|
|
|
|
result = CustomWizard::Api::Endpoint.request(user, action['api'], action['api_endpoint'], api_body)
|
|
|
|
|
|
|
|
if error = result['error'] || (result[0] && result[0]['error'])
|
|
|
|
error = error['message'] || error
|
|
|
|
updater.errors.add(:send_to_api, error)
|
|
|
|
else
|
|
|
|
## add validation callback
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def open_composer
|
|
|
|
if action['custom_title_enabled']
|
|
|
|
title = mapper.interpolate(action['custom_title'])
|
|
|
|
else
|
|
|
|
title = data[action['title']]
|
|
|
|
end
|
|
|
|
|
|
|
|
url = "/new-topic?title=#{title}"
|
|
|
|
|
|
|
|
if action['post_builder']
|
|
|
|
post = mapper.interpolate(action['post_template'])
|
|
|
|
else
|
|
|
|
post = data[action['post']]
|
|
|
|
end
|
|
|
|
|
|
|
|
url += "&body=#{post}"
|
|
|
|
|
2020-04-02 07:21:57 +02:00
|
|
|
if category_id = action_category
|
2020-03-30 08:16:03 +02:00
|
|
|
if category = Category.find(category_id)
|
|
|
|
url += "&category=#{category.full_slug('/')}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-03-31 08:29:59 +02:00
|
|
|
if tags = action_tags
|
2020-03-30 08:16:03 +02:00
|
|
|
url += "&tags=#{tags.join(',')}"
|
|
|
|
end
|
|
|
|
|
|
|
|
data['redirect_on_complete'] = Discourse.base_uri + URI.encode(url)
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_to_group
|
|
|
|
groups = CustomWizard::Mapper.new(
|
|
|
|
inputs: action['inputs'],
|
|
|
|
data: data,
|
|
|
|
user: user,
|
|
|
|
opts: {
|
|
|
|
multiple: true
|
|
|
|
}
|
2020-04-06 10:36:38 +02:00
|
|
|
).perform
|
2020-03-30 08:16:03 +02:00
|
|
|
|
|
|
|
groups = groups.flatten.reduce([]) do |result, g|
|
|
|
|
begin
|
|
|
|
result.push(Integer(g))
|
|
|
|
rescue ArgumentError
|
|
|
|
group = Group.find_by(name: g)
|
|
|
|
result.push(group.id) if group
|
|
|
|
end
|
|
|
|
|
|
|
|
result
|
|
|
|
end
|
|
|
|
|
|
|
|
if groups.present?
|
|
|
|
groups.each do |group_id|
|
|
|
|
group = Group.find(group_id) if group_id
|
|
|
|
group.add(user) if group
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def route_to
|
|
|
|
url = mapper.interpolate(action['url'])
|
2020-04-02 07:21:57 +02:00
|
|
|
|
2020-03-30 08:16:03 +02:00
|
|
|
if action['code']
|
|
|
|
data[action['code']] = SecureRandom.hex(8)
|
|
|
|
url += "&#{action['code']}=#{data[action['code']]}"
|
|
|
|
end
|
2020-04-02 07:21:57 +02:00
|
|
|
|
2020-03-30 08:16:03 +02:00
|
|
|
data['route_to'] = URI.encode(url)
|
|
|
|
end
|
|
|
|
|
2020-04-02 07:21:57 +02:00
|
|
|
private
|
|
|
|
|
|
|
|
def action_category
|
|
|
|
output = CustomWizard::Mapper.new(
|
|
|
|
inputs: action['category'],
|
|
|
|
data: data,
|
|
|
|
user: user
|
2020-04-06 10:36:38 +02:00
|
|
|
).perform
|
2020-04-02 07:21:57 +02:00
|
|
|
|
|
|
|
if output.is_a?(Array)
|
|
|
|
output.first
|
|
|
|
elsif output.is_a?(Integer)
|
|
|
|
output
|
|
|
|
elsif output.is_a?(String)
|
|
|
|
output.to_i
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def action_tags
|
2020-04-02 07:21:57 +02:00
|
|
|
output = CustomWizard::Mapper.new(
|
|
|
|
inputs: action['tags'],
|
|
|
|
data: data,
|
|
|
|
user: user,
|
2020-04-06 10:36:38 +02:00
|
|
|
).perform
|
2020-04-07 13:17:20 +02:00
|
|
|
|
2020-04-02 07:21:57 +02:00
|
|
|
if output.is_a?(Array)
|
|
|
|
output.flatten
|
2020-04-07 13:17:20 +02:00
|
|
|
else output.is_a?(String)
|
2020-04-02 07:21:57 +02:00
|
|
|
[*output]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_custom_fields(params = {})
|
|
|
|
if (custom_fields = action['custom_fields']).present?
|
2020-04-06 10:36:38 +02:00
|
|
|
field_map = CustomWizard::Mapper.new(
|
|
|
|
inputs: custom_fields,
|
|
|
|
data: data,
|
|
|
|
user: user
|
|
|
|
).perform
|
|
|
|
|
|
|
|
field_map.each do |field|
|
|
|
|
keyArr = field[:key].split('.')
|
|
|
|
value = field[:value]
|
2020-04-02 07:21:57 +02:00
|
|
|
|
2020-04-07 15:33:11 +02:00
|
|
|
if keyArr.first === 'topic'
|
2020-04-06 10:36:38 +02:00
|
|
|
params[:topic_opts] ||= {}
|
|
|
|
params[:topic_opts][:custom_fields] ||= {}
|
|
|
|
params[:topic_opts][:custom_fields][keyArr.last] = value
|
2020-04-07 15:33:11 +02:00
|
|
|
else
|
2020-04-06 10:36:38 +02:00
|
|
|
params[:custom_fields] ||= {}
|
|
|
|
params[:custom_fields][keyArr.last.to_sym] = value
|
2020-04-02 07:21:57 +02:00
|
|
|
end
|
|
|
|
end
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
2020-04-02 07:21:57 +02:00
|
|
|
|
|
|
|
params
|
|
|
|
end
|
|
|
|
|
|
|
|
def basic_topic_params
|
|
|
|
params = {
|
|
|
|
skip_validations: true
|
|
|
|
}
|
|
|
|
|
|
|
|
params[:title] = CustomWizard::Mapper.new(
|
|
|
|
inputs: action['title'],
|
|
|
|
data: data,
|
|
|
|
user: user
|
2020-04-06 10:36:38 +02:00
|
|
|
).perform
|
2020-04-02 07:21:57 +02:00
|
|
|
|
|
|
|
params[:raw] = action['post_builder'] ?
|
|
|
|
mapper.interpolate(action['post_template']) :
|
|
|
|
data[action['post']]
|
|
|
|
|
2020-04-07 15:33:11 +02:00
|
|
|
add_custom_fields(params)
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|
2020-04-07 16:18:12 +02:00
|
|
|
|
|
|
|
def profile_url_fields
|
|
|
|
['profile_background', 'card_background']
|
|
|
|
end
|
|
|
|
|
|
|
|
def cast_profile_key(key)
|
|
|
|
if profile_url_fields.include?(key)
|
|
|
|
"#{key}_upload_url"
|
|
|
|
else
|
|
|
|
key
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def cast_profile_value(value, key)
|
|
|
|
if profile_url_fields.include?(key)
|
|
|
|
value['url']
|
|
|
|
elsif key === 'avatar'
|
|
|
|
value['id']
|
|
|
|
else
|
|
|
|
value
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def allowed_profile_fields
|
|
|
|
CustomWizard::Mapper.user_fields +
|
|
|
|
profile_url_fields +
|
|
|
|
['avatar']
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_avatar(upload_id)
|
|
|
|
user.create_user_avatar unless user.user_avatar
|
|
|
|
user.user_avatar.custom_upload_id = upload_id
|
|
|
|
user.uploaded_avatar_id = upload_id
|
|
|
|
user.save!
|
|
|
|
user.user_avatar.save!
|
|
|
|
end
|
2020-03-30 08:16:03 +02:00
|
|
|
end
|