| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  | # redMine - project management software | 
					
						
							|  |  |  | # Copyright (C) 2006  Jean-Philippe Lang | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							|  |  |  | #  | 
					
						
							|  |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							|  |  |  | #  | 
					
						
							|  |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SearchController < ApplicationController | 
					
						
							| 
									
										
										
										
											2008-03-12 20:50:48 +00:00
										 |  |  |   before_filter :find_optional_project | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-14 17:46:58 +00:00
										 |  |  |   helper :messages | 
					
						
							|  |  |  |   include MessagesHelper | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |   def index | 
					
						
							|  |  |  |     @question = params[:q] || "" | 
					
						
							|  |  |  |     @question.strip! | 
					
						
							|  |  |  |     @all_words = params[:all_words] || (params[:submit] ? false : true) | 
					
						
							| 
									
										
										
										
											2007-10-15 16:53:39 +00:00
										 |  |  |     @titles_only = !params[:titles_only].nil? | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |     projects_to_search = | 
					
						
							| 
									
										
										
										
											2008-05-20 20:31:04 +00:00
										 |  |  |       case params[:scope] | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |       when 'all' | 
					
						
							|  |  |  |         nil | 
					
						
							|  |  |  |       when 'my_projects' | 
					
						
							|  |  |  |         User.current.memberships.collect(&:project) | 
					
						
							| 
									
										
										
										
											2008-05-20 20:31:04 +00:00
										 |  |  |       when 'subprojects' | 
					
						
							| 
									
										
										
										
											2009-01-24 11:31:15 +00:00
										 |  |  |         @project ? (@project.self_and_descendants.active) : nil | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |       else | 
					
						
							|  |  |  |         @project | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |            | 
					
						
							| 
									
										
										
										
											2007-09-27 17:28:22 +00:00
										 |  |  |     offset = nil | 
					
						
							|  |  |  |     begin; offset = params[:offset].to_time if params[:offset]; rescue; end | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |     # quick jump to an issue | 
					
						
							| 
									
										
										
										
											2009-11-14 12:08:47 +00:00
										 |  |  |     if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1) | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |       redirect_to :controller => "issues", :action => "show", :id => $1 | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2010-02-17 20:05:51 +00:00
										 |  |  |     @object_types = Redmine::Search.available_search_types.dup | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |     if projects_to_search.is_a? Project | 
					
						
							|  |  |  |       # don't search projects | 
					
						
							|  |  |  |       @object_types.delete('projects') | 
					
						
							| 
									
										
										
										
											2007-09-24 17:46:25 +00:00
										 |  |  |       # only show what the user is allowed to view | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |       @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)} | 
					
						
							| 
									
										
										
										
											2007-09-24 17:46:25 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |        | 
					
						
							|  |  |  |     @scope = @object_types.select {|t| params[t]} | 
					
						
							|  |  |  |     @scope = @object_types if @scope.empty? | 
					
						
							| 
									
										
										
										
											2007-09-24 17:46:25 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2007-11-29 18:33:42 +00:00
										 |  |  |     # extract tokens from the question | 
					
						
							|  |  |  |     # eg. hello "bye bye" => ["hello", "bye bye"] | 
					
						
							|  |  |  |     @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')} | 
					
						
							| 
									
										
										
										
											2010-01-10 14:15:12 +00:00
										 |  |  |     # tokens must be at least 2 characters long | 
					
						
							|  |  |  |     @tokens = @tokens.uniq.select {|w| w.length > 1 } | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     if !@tokens.empty? | 
					
						
							|  |  |  |       # no more than 5 tokens to search for | 
					
						
							|  |  |  |       @tokens.slice! 5..-1 if @tokens.size > 5
 | 
					
						
							|  |  |  |       # strings used in sql like statement | 
					
						
							| 
									
										
										
										
											2007-10-15 16:53:39 +00:00
										 |  |  |       like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}       | 
					
						
							| 
									
										
										
										
											2008-07-20 17:26:07 +00:00
										 |  |  |        | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |       @results = [] | 
					
						
							| 
									
										
										
										
											2008-07-20 17:26:07 +00:00
										 |  |  |       @results_by_type = Hash.new {|h,k| h[k] = 0} | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2007-09-27 17:28:22 +00:00
										 |  |  |       limit = 10
 | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |       @scope.each do |s| | 
					
						
							| 
									
										
										
										
											2008-07-20 17:26:07 +00:00
										 |  |  |         r, c = s.singularize.camelcase.constantize.search(like_tokens, projects_to_search, | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |           :all_words => @all_words, | 
					
						
							|  |  |  |           :titles_only => @titles_only, | 
					
						
							|  |  |  |           :limit => (limit+1), | 
					
						
							|  |  |  |           :offset => offset, | 
					
						
							|  |  |  |           :before => params[:previous].nil?) | 
					
						
							| 
									
										
										
										
											2008-07-20 17:26:07 +00:00
										 |  |  |         @results += r | 
					
						
							|  |  |  |         @results_by_type[s] += c | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |       @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime} | 
					
						
							|  |  |  |       if params[:previous].nil? | 
					
						
							|  |  |  |         @pagination_previous_date = @results[0].event_datetime if offset && @results[0] | 
					
						
							|  |  |  |         if @results.size > limit | 
					
						
							|  |  |  |           @pagination_next_date = @results[limit-1].event_datetime  | 
					
						
							|  |  |  |           @results = @results[0, limit] | 
					
						
							| 
									
										
										
										
											2007-05-14 17:46:58 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2008-05-18 16:15:22 +00:00
										 |  |  |         @pagination_next_date = @results[-1].event_datetime if offset && @results[-1] | 
					
						
							|  |  |  |         if @results.size > limit | 
					
						
							|  |  |  |           @pagination_previous_date = @results[-(limit)].event_datetime  | 
					
						
							|  |  |  |           @results = @results[-(limit), limit] | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       @question = "" | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2007-09-27 17:28:22 +00:00
										 |  |  |     render :layout => false if request.xhr? | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private   | 
					
						
							| 
									
										
										
										
											2008-03-12 20:50:48 +00:00
										 |  |  |   def find_optional_project | 
					
						
							|  |  |  |     return true unless params[:id] | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |     @project = Project.find(params[:id]) | 
					
						
							| 
									
										
										
										
											2008-03-12 20:50:48 +00:00
										 |  |  |     check_project_privacy | 
					
						
							| 
									
										
										
										
											2007-04-30 08:52:39 +00:00
										 |  |  |   rescue ActiveRecord::RecordNotFound | 
					
						
							|  |  |  |     render_404 | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |