Skip to content

Commit

Permalink
DEV: add support for adding custom status filter
Browse files Browse the repository at this point in the history
Those can be used in the /filter routes.
  • Loading branch information
ZogStriP committed Apr 26, 2024
1 parent 351d212 commit 803c275
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
8 changes: 8 additions & 0 deletions lib/plugin/instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ def register_editable_group_custom_field(field)
DiscoursePluginRegistry.register_editable_group_custom_field(field, self)
end

# Allows to define custom "status:" filter. Example usage:
# register_custom_filter_by_status("foobar") do |scope|
# scope.where("word_count = 42")
# end
def register_custom_filter_by_status(status, &block)
TopicsFilter.add_filter_by_status(status, &block)
end

# Allows to define custom search order. Example usage:
# Search.advanced_order(:chars) do |posts|
# posts.reorder("(SELECT LENGTH(raw) FROM posts WHERE posts.topic_id = subquery.topic_id) DESC")
Expand Down
12 changes: 12 additions & 0 deletions lib/topics_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ def filter_from_query_string(query_string)
@scope
end

def self.add_filter_by_status(status, &blk)
(@custom_status_filters ||= {})[status] = blk
end

def self.custom_status_filters
@custom_status_filters || {}
end

def filter_status(status:, category_id: nil)
case status
when "open"
Expand All @@ -106,6 +114,10 @@ def filter_status(status:, category_id: nil)
end
when "public"
@scope = @scope.joins(:category).where("NOT categories.read_restricted")
else
if custom_filter = TopicsFilter.custom_status_filters[status]
@scope = custom_filter.call(@scope)
end
end

@scope
Expand Down
14 changes: 13 additions & 1 deletion spec/lib/topics_filter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,18 @@
fab!(:closed_topic) { Fabricate(:topic, closed: true) }
fab!(:archived_topic) { Fabricate(:topic, archived: true) }
fab!(:deleted_topic_id) { Fabricate(:topic, deleted_at: Time.zone.now).id }
fab!(:foobar_topic) { Fabricate(:topic, closed: true, word_count: 42) }

it "supports custom status filters" do
TopicsFilter.add_filter_by_status("foobar") { |scope| scope.where("word_count = 42") }

expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("status:foobar")
.pluck(:id),
).to contain_exactly(foobar_topic.id)
end

it "should only return topics that have not been closed or archived when query string is `status:open`" do
expect(
Expand All @@ -642,7 +654,7 @@
.new(guardian: Guardian.new)
.filter_from_query_string("status:deleted")
.pluck(:id),
).to contain_exactly(topic.id, closed_topic.id, archived_topic.id)
).to contain_exactly(topic.id, closed_topic.id, archived_topic.id, foobar_topic.id)
end

it "should only return topics that have been archived when query string is `status:archived`" do
Expand Down

0 comments on commit 803c275

Please sign in to comment.