# 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