discourse/app/services/user_action_manager.rb
Sam Saffron 30990006a9 DEV: enable frozen string literal on all files
This reduces chances of errors where consumers of strings mutate inputs
and reduces memory usage of the app.

Test suite passes now, but there may be some stuff left, so we will run
a few sites on a branch prior to merging
2019-05-13 09:31:32 +08:00

133 lines
3.4 KiB
Ruby

# frozen_string_literal: true
class UserActionManager
def self.disable
@disabled = true
end
def self.enable
@disabled = false
end
[:notification, :post, :topic, :post_action].each do |type|
self.class_eval(<<~METHODS)
def self.#{type}_created(*args)
return if @disabled
#{type}_rows(*args).each { |row| UserAction.log_action!(row) }
end
def self.#{type}_destroyed(*args)
return if @disabled
#{type}_rows(*args).each { |row| UserAction.remove_action!(row) }
end
METHODS
end
private
def self.topic_rows(topic)
# no action to log here, this can happen if a user is deleted
# then topic has no user_id
return [] unless topic.user_id
row = {
action_type: topic.private_message? ? UserAction::NEW_PRIVATE_MESSAGE : UserAction::NEW_TOPIC,
user_id: topic.user_id,
acting_user_id: topic.user_id,
target_topic_id: topic.id,
target_post_id: -1,
created_at: topic.created_at
}
UserAction.remove_action!(row.merge(
action_type: topic.private_message? ? UserAction::NEW_TOPIC : UserAction::NEW_PRIVATE_MESSAGE
))
rows = [row]
if topic.private_message?
topic.topic_allowed_users.reject { |a| a.user_id == topic.user_id }.each do |ta|
row = row.dup
row[:user_id] = ta.user_id
row[:action_type] = UserAction::GOT_PRIVATE_MESSAGE
rows << row
end
end
rows
end
def self.post_rows(post)
# first post gets nada
return [] if post.is_first_post? || post.topic.blank?
row = {
action_type: UserAction::REPLY,
user_id: post.user_id,
acting_user_id: post.user_id,
target_post_id: post.id,
target_topic_id: post.topic_id,
created_at: post.created_at
}
rows = [row]
if post.topic.private_message?
rows = []
post.topic.topic_allowed_users.each do |ta|
row = row.dup
row[:user_id] = ta.user_id
row[:action_type] = ta.user_id == post.user_id ? UserAction::NEW_PRIVATE_MESSAGE : UserAction::GOT_PRIVATE_MESSAGE
rows << row
end
end
rows
end
def self.notification_rows(post, user, notification_type, acting_user_id)
action =
case notification_type
when Notification.types[:quoted]
UserAction::QUOTE
when Notification.types[:replied]
UserAction::RESPONSE
when Notification.types[:mentioned]
UserAction::MENTION
when Notification.types[:edited]
UserAction::EDIT
end
# skip any invalid items, eg failed to save post and so on
return [] unless action && post && user && post.id
[{
action_type: action,
user_id: user.id,
acting_user_id: acting_user_id || post.user_id,
target_topic_id: post.topic_id,
target_post_id: post.id
}]
end
def self.post_action_rows(post_action)
action = UserAction::BOOKMARK if post_action.is_bookmark?
action = UserAction::LIKE if post_action.is_like?
return [] unless action
post = Post.with_deleted.where(id: post_action.post_id).first
row = {
action_type: action,
user_id: post_action.user_id,
acting_user_id: post_action.user_id,
target_post_id: post_action.post_id,
target_topic_id: post.topic_id,
created_at: post_action.created_at
}
post_action.is_like? ?
[row, row.merge(action_type: UserAction::WAS_LIKED, user_id: post.user_id)] :
[row]
end
end