diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb
index 9f0fd9e6082..daaa144b367 100644
--- a/lib/discourse_plugin_registry.rb
+++ b/lib/discourse_plugin_registry.rb
@@ -106,6 +106,8 @@ class DiscoursePluginRegistry
define_filtered_register :hashtag_autocomplete_data_sources
define_filtered_register :hashtag_autocomplete_contextual_type_priorities
+ define_filtered_register :search_groups_set_query_callbacks
+
def self.register_auth_provider(auth_provider)
self.auth_providers << auth_provider
end
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index fc69c104760..743f35283e5 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -1292,6 +1292,10 @@ class Plugin::Instance
DiscoursePluginRegistry.register_topic_preloader_association(fields, self)
end
+ def register_search_group_query_callback(callback)
+ DiscoursePluginRegistry.register_search_groups_set_query_callback(callback, self)
+ end
+
private
def validate_directory_column_name(column_name)
diff --git a/lib/search.rb b/lib/search.rb
index e81b7ab0d93..77748100573 100644
--- a/lib/search.rb
+++ b/lib/search.rb
@@ -615,12 +615,17 @@ class Search
end
advanced_filter(/^group:(.+)$/i) do |posts, match|
- group_id =
+ group_query =
Group
.visible_groups(@guardian.user)
.members_visible_groups(@guardian.user)
- .where("name ilike ? OR (id = ? AND id > 0)", match, match.to_i)
- .pluck_first(:id)
+ .where("groups.name ILIKE ? OR (id = ? AND id > 0)", match, match.to_i)
+
+ DiscoursePluginRegistry.search_groups_set_query_callbacks.each do |cb|
+ group_query = cb.call(group_query, @term, @guardian)
+ end
+
+ group_id = group_query.pluck_first(:id)
if group_id
posts.where(
@@ -944,11 +949,17 @@ class Search
end
def groups_search
- groups =
- Group
- .visible_groups(@guardian.user, "name ASC", include_everyone: false)
- .where("name ILIKE :term OR full_name ILIKE :term", term: "%#{@term}%")
- .limit(limit)
+ group_query =
+ Group.visible_groups(@guardian.user, "groups.name ASC", include_everyone: false).where(
+ "groups.name ILIKE :term OR groups.full_name ILIKE :term",
+ term: "%#{@term}%",
+ )
+
+ DiscoursePluginRegistry.search_groups_set_query_callbacks.each do |cb|
+ group_query = cb.call(group_query, @term, @guardian)
+ end
+
+ groups = group_query.limit(limit)
groups.each { |group| @results.add(group) }
end
diff --git a/spec/lib/search_spec.rb b/spec/lib/search_spec.rb
index 01640a5f99b..4388a13ebde 100644
--- a/spec/lib/search_spec.rb
+++ b/spec/lib/search_spec.rb
@@ -897,7 +897,7 @@ RSpec.describe Search do
result = Search.execute("search term")
expect(result.posts.first.topic_title_headline).to eq(<<~HTML.chomp)
- Very very very very very very very long topic title with our search term in the middle of the title
+ Very very very very very very very long topic title with our search term in the middle of the title
HTML
end
@@ -1316,7 +1316,28 @@ RSpec.describe Search do
context "with non staff logged in" do
it "shows doesn’t show group" do
- expect(search.groups.map(&:name)).to be_empty
+ end
+ end
+ end
+
+ context "with registered plugin callbacks" do
+ let!(:group) { Fabricate(:group, name: "plugin-special") }
+
+ context "when :search_groups_set_query_callback is registered" do
+ it "changes the search results" do
+ # initial result (without applying the plugin callback )
+ expect(search.groups.map(&:name).include?("plugin-special")).to eq(true)
+
+ DiscoursePluginRegistry.register_search_groups_set_query_callback(
+ Proc.new { |query, term, guardian| query.where.not(name: "plugin-special") },
+ Plugin::Instance.new,
+ )
+
+ # after using the callback we expect the search result to be changed because the
+ # query was altered
+ expect(search.groups.map(&:name).include?("plugin-special")).to eq(false)
+
+ DiscoursePluginRegistry.reset_register!(:search_groups_set_query_callbacks)
end
end
end
@@ -1780,6 +1801,31 @@ RSpec.describe Search do
Search.execute("group:#{group.id}", guardian: Guardian.new(user)).posts,
).to contain_exactly(post)
end
+
+ context "with registered plugin callbacks" do
+ context "when :search_groups_set_query_callback is registered" do
+ it "changes the search results" do
+ group.update!(
+ visibility_level: Group.visibility_levels[:public],
+ members_visibility_level: Group.visibility_levels[:public],
+ )
+
+ # initial result (without applying the plugin callback )
+ expect(Search.execute("group:like_a_boss").posts).to contain_exactly(post)
+
+ DiscoursePluginRegistry.register_search_groups_set_query_callback(
+ Proc.new { |query, term, guardian| query.where.not(name: "Like_a_Boss") },
+ Plugin::Instance.new,
+ )
+
+ # after using the callback we expect the search result to be changed because the
+ # query was altered
+ expect(Search.execute("group:like_a_boss").posts).to be_blank
+
+ DiscoursePluginRegistry.reset_register!(:search_groups_set_query_callbacks)
+ end
+ end
+ end
end
it "supports badge" do
@@ -2356,7 +2402,7 @@ RSpec.describe Search do
expect(results.posts.length).to eq(1)
# TODO: this is a test we need to fix!
- #expect(results.blurb(results.posts.first)).to include('Rágis')
+ # expect(results.blurb(results.posts.first)).to include('Rágis')
results = Search.execute("สวัสดี", type_filter: "topic")
expect(results.posts.length).to eq(1)