diff --git a/lib/search.rb b/lib/search.rb index c52f7e28e08..80b0a62e1d7 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -95,6 +95,7 @@ class Search end def initialize(term, opts=nil) + term = process_advanced_search!(term) if term.present? @term = Search.prepare_data(term.to_s) @original_term = PG::Connection.escape_string(@term) @@ -140,6 +141,21 @@ class Search private + def process_advanced_search!(term) + term.to_s.split(/\s+/).map do |word| + if word == 'status:open' + @status = :open + nil + elsif word == 'status:closed' + @status = :closed + nil + else + word + end + end.compact.join(' ') + end + + def find_grouped_results if @results.type_filter.present? @@ -238,6 +254,12 @@ class Search posts = posts.where("post_search_data.search_data @@ #{ts_query}") end + if @status == :open + posts = posts.where('NOT topics.closed AND NOT topics.archived') + elsif @status == :closed + posts = posts.where('topics.closed OR topics.archived') + end + # If we have a search context, prioritize those posts first if @search_context.present? diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 68ac337ad62..dea92fa5579 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -301,5 +301,29 @@ describe Search do end end + describe 'Advanced search' do + it 'can find by status' do + post = Fabricate(:post, raw: 'hi this is a test 123 123') + topic = post.topic + + Search.execute('test status:closed').posts.length.should == 0 + Search.execute('test status:open').posts.length.should == 1 + + topic.closed = true + topic.save + + Search.execute('test status:closed').posts.length.should == 1 + Search.execute('test status:open').posts.length.should == 0 + + topic.archived = true + topic.closed = false + topic.save + + Search.execute('test status:closed').posts.length.should == 1 + Search.execute('test status:open').posts.length.should == 0 + + end + end + end