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)