discourse/lib/post_merger.rb
2016-07-27 12:04:14 +08:00

59 lines
1.3 KiB
Ruby

class PostMerger
class CannotMergeError < StandardError; end
def initialize(user, posts)
@user = user
@posts = posts
end
def merge
return unless ensure_at_least_two_posts
ensure_same_topic!
ensure_same_user!
guardian = Guardian.new(@user)
ensure_staff_user!(guardian)
posts = @posts.sort_by do |post|
guardian.ensure_can_delete!(post)
post.post_number
end
post_content = posts.map(&:raw)
post = posts.pop
changes = {
raw: post_content.join("\n\n"),
edit_reason: I18n.t("merge_posts.edit_reason", count: posts.length, username: @user.username)
}
Post.transaction do
revisor = PostRevisor.new(post, post.topic)
revisor.revise!(@user, changes, {})
posts.each { |p| PostDestroyer.new(@user, p).destroy }
end
end
private
def ensure_at_least_two_posts
@posts.count >= 2
end
def ensure_same_topic!
unless @posts.map(&:topic_id).uniq.length == 1
raise CannotMergeError.new(I18n.t("merge_posts.errors.different_topics"))
end
end
def ensure_same_user!
unless @posts.map(&:user_id).uniq.length == 1
raise CannotMergeError.new(I18n.t("merge_posts.errors.different_users"))
end
end
def ensure_staff_user!(guardian)
raise Discourse::InvalidAccess unless guardian.is_staff?
end
end