67 lines
1.6 KiB
Ruby
67 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class PostMerger
|
|
class CannotMergeError < StandardError
|
|
end
|
|
|
|
def initialize(user, posts)
|
|
@user = user
|
|
@posts = posts
|
|
end
|
|
|
|
def merge
|
|
return if @posts.count < 2
|
|
|
|
ensure_same_topic!
|
|
ensure_same_user!
|
|
|
|
guardian = Guardian.new(@user)
|
|
ensure_can_merge!(guardian)
|
|
|
|
posts =
|
|
@posts.sort_by do |post|
|
|
guardian.ensure_can_delete!(post)
|
|
post.post_number
|
|
end
|
|
|
|
post_content = posts.map(&:raw)
|
|
post = posts.pop
|
|
|
|
merged_post_raw = post_content.join("\n\n")
|
|
changes = {
|
|
raw: merged_post_raw,
|
|
edit_reason: I18n.t("merge_posts.edit_reason", count: posts.length, username: @user.username),
|
|
}
|
|
|
|
ensure_max_post_length!(merged_post_raw)
|
|
PostRevisor
|
|
.new(post, post.topic)
|
|
.revise!(@user, changes) { posts.each { |p| PostDestroyer.new(@user, p).destroy } }
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_same_topic!
|
|
if @posts.map(&:topic_id).uniq.size != 1
|
|
raise CannotMergeError.new(I18n.t("merge_posts.errors.different_topics"))
|
|
end
|
|
end
|
|
|
|
def ensure_same_user!
|
|
if @posts.map(&:user_id).uniq.size != 1
|
|
raise CannotMergeError.new(I18n.t("merge_posts.errors.different_users"))
|
|
end
|
|
end
|
|
|
|
def ensure_can_merge!(guardian)
|
|
raise Discourse::InvalidAccess unless guardian.can_moderate_topic?(@posts[0].topic)
|
|
end
|
|
|
|
def ensure_max_post_length!(raw)
|
|
value = StrippedLengthValidator.get_sanitized_value(raw)
|
|
if value.size > SiteSetting.max_post_length
|
|
raise CannotMergeError.new(I18n.t("merge_posts.errors.max_post_length"))
|
|
end
|
|
end
|
|
end
|