diff --git a/app/assets/javascripts/discourse/components/choose-topic.js.es6 b/app/assets/javascripts/discourse/components/choose-topic.js.es6 index 4f35e90e203..3d787d58431 100644 --- a/app/assets/javascripts/discourse/components/choose-topic.js.es6 +++ b/app/assets/javascripts/discourse/components/choose-topic.js.es6 @@ -32,20 +32,22 @@ export default Ember.Component.extend({ return; } - searchForTerm(title, { typeFilter: "topic", searchForId: true }).then( - function(results) { - if (results && results.posts && results.posts.length > 0) { - self.set( - "topics", - results.posts - .mapBy("topic") - .filter(t => t.get("id") !== currentTopicId) - ); - } else { - self.setProperties({ topics: null, loading: false }); - } + searchForTerm(title, { + typeFilter: "topic", + searchForId: true, + restrictToArchetype: "regular" + }).then(function(results) { + if (results && results.posts && results.posts.length > 0) { + self.set( + "topics", + results.posts + .mapBy("topic") + .filter(t => t.get("id") !== currentTopicId) + ); + } else { + self.setProperties({ topics: null, loading: false }); } - ); + }); }, 300), actions: { diff --git a/app/assets/javascripts/discourse/lib/search.js.es6 b/app/assets/javascripts/discourse/lib/search.js.es6 index 752776a9353..8fab105cfe1 100644 --- a/app/assets/javascripts/discourse/lib/search.js.es6 +++ b/app/assets/javascripts/discourse/lib/search.js.es6 @@ -107,6 +107,8 @@ export function searchForTerm(term, opts) { const data = { term: term, include_blurbs: "true" }; if (opts.typeFilter) data.type_filter = opts.typeFilter; if (opts.searchForId) data.search_for_id = true; + if (opts.restrictToArchetype) + data.restrict_to_archetype = opts.restrictToArchetype; if (opts.searchContext) { data.search_context = { diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index b1fc8b0f5a2..621788f7ecd 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -68,6 +68,7 @@ class SearchController < ApplicationController search_args[:search_type] = :header search_args[:ip_address] = request.remote_ip search_args[:user_id] = current_user.id if current_user.present? + search_args[:restrict_to_archetype] = params[:restrict_to_archetype] if params[:restrict_to_archetype].present? search = Search.new(params[:term], search_args) result = search.execute diff --git a/lib/search.rb b/lib/search.rb index e26f8c29f15..61ccf79d91d 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -227,7 +227,7 @@ class Search end # If the term is a number or url to a topic, just include that topic - if @opts[:search_for_id] && @results.type_filter == 'topic' + if @opts[:search_for_id] && (@results.type_filter == 'topic' || @results.type_filter == 'private_messages') if @term =~ /^\d+$/ single_topic(@term.to_i) else @@ -629,7 +629,14 @@ class Search # If we're searching for a single topic def single_topic(id) - post = Post.find_by(topic_id: id, post_number: 1) + if @opts[:restrict_to_archetype].present? + archetype = @opts[:restrict_to_archetype] == Archetype.default ? Archetype.default : Archetype.private_message + post = Post.joins(:topic) + .where("topics.id = :id AND topics.archetype = :archetype AND posts.post_number = 1", id: id, archetype: archetype) + .first + else + post = Post.find_by(topic_id: id, post_number: 1) + end return nil unless @guardian.can_see?(post) @results.add(post) diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 877812d9d2e..ce6088a0a99 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -341,12 +341,32 @@ describe Search do end context "search for a topic by url" do - let(:result) { Search.execute(topic.relative_url, search_for_id: true, type_filter: 'topic') } - it 'returns the topic' do + result = Search.execute(topic.relative_url, search_for_id: true, type_filter: 'topic') expect(result.posts.length).to eq(1) expect(result.posts.first.id).to eq(post.id) end + + context 'restrict_to_archetype' do + let(:personal_message) { Fabricate(:private_message_topic) } + let!(:p1) { Fabricate(:post, topic: personal_message, post_number: 1) } + + it 'restricts result to topics' do + result = Search.execute(personal_message.relative_url, search_for_id: true, type_filter: 'topic', restrict_to_archetype: Archetype.default) + expect(result.posts.length).to eq(0) + + result = Search.execute(topic.relative_url, search_for_id: true, type_filter: 'topic', restrict_to_archetype: Archetype.default) + expect(result.posts.length).to eq(1) + end + + it 'restricts result to messages' do + result = Search.execute(topic.relative_url, search_for_id: true, type_filter: 'private_messages', guardian: Guardian.new(Fabricate(:admin)), restrict_to_archetype: Archetype.private_message) + expect(result.posts.length).to eq(0) + + result = Search.execute(personal_message.relative_url, search_for_id: true, type_filter: 'private_messages', guardian: Guardian.new(Fabricate(:admin)), restrict_to_archetype: Archetype.private_message) + expect(result.posts.length).to eq(1) + end + end end context 'security' do