forked from discourse/discourse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpost_merger.rb
66 lines (52 loc) · 1.56 KB
/
post_merger.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 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