FEATURE: Add new setting to force user edit last post. (#6571)
This commit is contained in:
parent
d003ae45f9
commit
b6576d9473
|
@ -218,6 +218,10 @@ en:
|
||||||
one: "We're sorry, but new users are temporarily limited to 1 reply in the same topic."
|
one: "We're sorry, but new users are temporarily limited to 1 reply in the same topic."
|
||||||
other: "We're sorry, but new users are temporarily limited to %{count} replies in the same topic."
|
other: "We're sorry, but new users are temporarily limited to %{count} replies in the same topic."
|
||||||
|
|
||||||
|
max_consecutive_replies:
|
||||||
|
one: "No more than 1 reply is allowed. Please edit your previous reply instead, or wait for someone to reply to you."
|
||||||
|
other: "No more than %{count} consecutive replies are allowed. Please edit your previous reply instead, or wait for someone to reply to you."
|
||||||
|
|
||||||
embed:
|
embed:
|
||||||
start_discussion: "Start Discussion"
|
start_discussion: "Start Discussion"
|
||||||
continue: "Continue Discussion"
|
continue: "Continue Discussion"
|
||||||
|
@ -1536,6 +1540,7 @@ en:
|
||||||
title_min_entropy: "The minimum entropy (unique characters, non-english count for more) required for a topic title."
|
title_min_entropy: "The minimum entropy (unique characters, non-english count for more) required for a topic title."
|
||||||
body_min_entropy: "The minimum entropy (unique characters, non-english count for more) required for a post body."
|
body_min_entropy: "The minimum entropy (unique characters, non-english count for more) required for a post body."
|
||||||
allow_uppercase_posts: "Allow all caps in a topic title or a post body."
|
allow_uppercase_posts: "Allow all caps in a topic title or a post body."
|
||||||
|
max_consecutive_replies: "Force users to edit their last post instead of replying"
|
||||||
|
|
||||||
title_fancy_entities: "Convert common ASCII characters to fancy HTML entities in topic titles, ala SmartyPants <a href='https://daringfireball.net/projects/smartypants/' target='_blank'>https://daringfireball.net/projects/smartypants/</a>"
|
title_fancy_entities: "Convert common ASCII characters to fancy HTML entities in topic titles, ala SmartyPants <a href='https://daringfireball.net/projects/smartypants/' target='_blank'>https://daringfireball.net/projects/smartypants/</a>"
|
||||||
|
|
||||||
|
|
|
@ -594,6 +594,8 @@ posting:
|
||||||
default: false
|
default: false
|
||||||
locale_default:
|
locale_default:
|
||||||
ja: true
|
ja: true
|
||||||
|
max_consecutive_replies:
|
||||||
|
default: 0
|
||||||
title_prettify:
|
title_prettify:
|
||||||
default: true
|
default: true
|
||||||
locale_default:
|
locale_default:
|
||||||
|
|
|
@ -17,6 +17,7 @@ class Validators::PostValidator < ActiveModel::Validator
|
||||||
max_attachments_validator(record)
|
max_attachments_validator(record)
|
||||||
can_post_links_validator(record)
|
can_post_links_validator(record)
|
||||||
unique_post_validator(record)
|
unique_post_validator(record)
|
||||||
|
force_edit_last_validator(record)
|
||||||
end
|
end
|
||||||
|
|
||||||
def presence(post)
|
def presence(post)
|
||||||
|
@ -141,6 +142,32 @@ class Validators::PostValidator < ActiveModel::Validator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def force_edit_last_validator(post)
|
||||||
|
return if SiteSetting.max_consecutive_replies == 0 || post.id || post.acting_user&.staff? || private_message?(post)
|
||||||
|
|
||||||
|
topic = post.topic
|
||||||
|
|
||||||
|
last_posts_count = DB.query_single(<<~SQL, topic_id: post.topic_id, user_id: post.acting_user.id, max_replies: SiteSetting.max_consecutive_replies).first
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM (
|
||||||
|
SELECT user_id
|
||||||
|
FROM posts
|
||||||
|
WHERE deleted_at IS NULL
|
||||||
|
AND NOT hidden
|
||||||
|
AND topic_id = :topic_id
|
||||||
|
ORDER BY post_number DESC
|
||||||
|
LIMIT :max_replies
|
||||||
|
) c
|
||||||
|
WHERE c.user_id = :user_id
|
||||||
|
SQL
|
||||||
|
return if last_posts_count < SiteSetting.max_consecutive_replies
|
||||||
|
|
||||||
|
guardian = Guardian.new(post.acting_user)
|
||||||
|
if guardian.can_edit?(topic.posts.last)
|
||||||
|
post.errors.add(:base, I18n.t(:max_consecutive_replies, count: SiteSetting.max_consecutive_replies))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def acting_user_is_trusted?(post, level = 1)
|
def acting_user_is_trusted?(post, level = 1)
|
||||||
|
|
|
@ -219,6 +219,43 @@ describe Validators::PostValidator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "force_edit_last_validator" do
|
||||||
|
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:other_user) { Fabricate(:user) }
|
||||||
|
let(:topic) { Fabricate(:topic) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.max_consecutive_replies = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow posting more than 2 consecutive replies" do
|
||||||
|
1.upto(3).each do |i|
|
||||||
|
post = Post.new(user: user, topic: topic, raw: "post number #{i}")
|
||||||
|
validator.force_edit_last_validator(post)
|
||||||
|
expect(post.errors.count).to eq(i > SiteSetting.max_consecutive_replies ? 1 : 0)
|
||||||
|
post.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should always allow editing" do
|
||||||
|
post = Fabricate(:post, user: user, topic: topic)
|
||||||
|
post = Fabricate(:post, user: user, topic: topic)
|
||||||
|
|
||||||
|
revisor = PostRevisor.new(post)
|
||||||
|
revisor.revise!(post.user, raw: 'hello world123456789')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow posting more than 2 replies" do
|
||||||
|
3.times do
|
||||||
|
post = Fabricate(:post, user: user, topic: topic)
|
||||||
|
Fabricate(:post, user: other_user, topic: topic)
|
||||||
|
validator.force_edit_last_validator(post)
|
||||||
|
expect(post.errors.count).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
shared_examples "almost no validations" do
|
shared_examples "almost no validations" do
|
||||||
it "skips most validations" do
|
it "skips most validations" do
|
||||||
validator.expects(:stripped_length).never
|
validator.expects(:stripped_length).never
|
||||||
|
@ -229,6 +266,7 @@ describe Validators::PostValidator do
|
||||||
validator.expects(:max_attachments_validator).never
|
validator.expects(:max_attachments_validator).never
|
||||||
validator.expects(:newuser_links_validator).never
|
validator.expects(:newuser_links_validator).never
|
||||||
validator.expects(:unique_post_validator).never
|
validator.expects(:unique_post_validator).never
|
||||||
|
validator.expects(:force_edit_last_validator).never
|
||||||
validator.validate(post)
|
validator.validate(post)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue