mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 23:07:28 +08:00
DEV: Allow default scope to be configurable per topic. (#15018)
Not exposing this as a plugin API yet as we're testing it out with a plugin.
This commit is contained in:

committed by
GitHub

parent
057ef55684
commit
a6aff40e4b
@ -79,6 +79,25 @@ class TopicView
|
|||||||
@custom_filters || {}
|
@custom_filters || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Configure a default scope to be applied to @filtered_posts.
|
||||||
|
# The registered block is called with @filtered_posts and an instance of
|
||||||
|
# `TopicView`.
|
||||||
|
#
|
||||||
|
# This API should be considered experimental until it is exposed in
|
||||||
|
# `Plugin::Instance`.
|
||||||
|
def self.apply_custom_default_scope(&block)
|
||||||
|
custom_default_scopes << block
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.custom_default_scopes
|
||||||
|
@custom_default_scopes ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
# For testing
|
||||||
|
def self.reset_custom_default_scopes
|
||||||
|
@custom_default_scopes = nil
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(topic_or_topic_id, user = nil, options = {})
|
def initialize(topic_or_topic_id, user = nil, options = {})
|
||||||
@topic = find_topic(topic_or_topic_id)
|
@topic = find_topic(topic_or_topic_id)
|
||||||
@user = user
|
@user = user
|
||||||
@ -108,7 +127,7 @@ class TopicView
|
|||||||
@page = @page.to_i > 1 ? @page.to_i : calculate_page
|
@page = @page.to_i > 1 ? @page.to_i : calculate_page
|
||||||
|
|
||||||
setup_filtered_posts
|
setup_filtered_posts
|
||||||
@filtered_posts = apply_default_order(@filtered_posts)
|
@filtered_posts = apply_default_scope(@filtered_posts)
|
||||||
filter_posts(options)
|
filter_posts(options)
|
||||||
|
|
||||||
if @posts && !@skip_custom_fields
|
if @posts && !@skip_custom_fields
|
||||||
@ -160,7 +179,7 @@ class TopicView
|
|||||||
if is_mega_topic?
|
if is_mega_topic?
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
Gaps.new(filtered_post_ids, apply_default_order(unfiltered_posts).pluck(:id))
|
Gaps.new(filtered_post_ids, apply_default_scope(unfiltered_posts).pluck(:id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -287,8 +306,10 @@ class TopicView
|
|||||||
elsif opts[:post_ids].present?
|
elsif opts[:post_ids].present?
|
||||||
filter_posts_by_ids(opts[:post_ids])
|
filter_posts_by_ids(opts[:post_ids])
|
||||||
elsif opts[:filter_post_number].present?
|
elsif opts[:filter_post_number].present?
|
||||||
|
# Only used for megatopics where we do not load the entire post stream
|
||||||
filter_posts_by_post_number(opts[:filter_post_number], opts[:asc])
|
filter_posts_by_post_number(opts[:filter_post_number], opts[:asc])
|
||||||
elsif opts[:best].present?
|
elsif opts[:best].present?
|
||||||
|
# Only used for wordpress
|
||||||
filter_best(opts[:best], opts)
|
filter_best(opts[:best], opts)
|
||||||
else
|
else
|
||||||
filter_posts_paged(@page)
|
filter_posts_paged(@page)
|
||||||
@ -738,7 +759,7 @@ class TopicView
|
|||||||
:image_upload
|
:image_upload
|
||||||
)
|
)
|
||||||
|
|
||||||
@posts = apply_default_order(@posts)
|
@posts = apply_default_scope(@posts)
|
||||||
@posts = filter_post_types(@posts)
|
@posts = filter_post_types(@posts)
|
||||||
@posts = @posts.with_deleted if @guardian.can_see_deleted_posts?(@topic.category)
|
@posts = @posts.with_deleted if @guardian.can_see_deleted_posts?(@topic.category)
|
||||||
@posts
|
@posts
|
||||||
@ -762,8 +783,14 @@ class TopicView
|
|||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_default_order(scope)
|
def apply_default_scope(scope)
|
||||||
scope.order(sort_order: :asc)
|
scope = scope.order(sort_order: :asc)
|
||||||
|
|
||||||
|
self.class.custom_default_scopes.each do |block|
|
||||||
|
scope = block.call(scope, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
scope
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_filtered_posts
|
def setup_filtered_posts
|
||||||
|
@ -968,4 +968,27 @@ describe TopicView do
|
|||||||
expect(topic_view.reviewable_counts.keys).to contain_exactly(reviewable.target_id)
|
expect(topic_view.reviewable_counts.keys).to contain_exactly(reviewable.target_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.apply_custom_default_scope' do
|
||||||
|
fab!(:post) { Fabricate(:post, topic: topic, created_at: 2.hours.ago) }
|
||||||
|
fab!(:post_2) { Fabricate(:post, topic: topic, created_at: 1.hour.ago) }
|
||||||
|
|
||||||
|
after do
|
||||||
|
TopicView.reset_custom_default_scopes
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows a custom default scope to be configured' do
|
||||||
|
topic_view = TopicView.new(topic, admin)
|
||||||
|
|
||||||
|
expect(topic_view.filtered_post_ids).to eq([post.id, post_2.id])
|
||||||
|
|
||||||
|
TopicView.apply_custom_default_scope do |scope, _|
|
||||||
|
scope.unscope(:order).order("posts.created_at DESC")
|
||||||
|
end
|
||||||
|
|
||||||
|
topic_view = TopicView.new(topic, admin)
|
||||||
|
|
||||||
|
expect(topic_view.filtered_post_ids).to eq([post_2.id, post.id])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user