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  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  layout  'base' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-20 15:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @question . match ( / ^ # ?( \ d+)$ / )  &&  Issue . find_by_id ( $1 ,  :include  = >  :project ,  :conditions  = >  Project . visible_by ( User . current ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-30 08:52:39 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      redirect_to  :controller  = >  " issues " ,  :action  = >  " show " ,  :id  = >  $1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  params [ :id ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      find_project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  unless  check_project_privacy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
									
										
										
										
											2007-09-24 17:46:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # only show what the user is allowed to view 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-27 17:28:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @object_types  =  %w( issues news documents changesets wiki_pages messages ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-24 17:46:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @object_types  =  @object_types . select  { | o |  User . current . allowed_to? ( " view_ #{ o } " . to_sym ,  @project ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @scope  =  @object_types . select  { | t |  params [ t ] } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @scope  =  @object_types  if  @scope . empty? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-24 18:08:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @object_types  =  @scope  =  %w( projects ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-24 17:46:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
									
										
										
										
											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*$) } ,  '' ) } 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-30 08:52:39 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    # tokens must be at least 3 character long 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-29 18:33:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @tokens  =  @tokens . uniq . select  { | w |  w . length  >  2  } 
							 
						 
					
						
							
								
									
										
										
										
											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 } % " }       
							 
						 
					
						
							
								
									
										
										
										
											2007-04-30 08:52:39 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      @results  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-27 17:28:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      limit  =  10 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-24 17:46:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  @project         
							 
						 
					
						
							
								
									
										
										
										
											2007-09-27 17:28:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @scope . each  do  | s | 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 16:53:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          @results  +=  s . singularize . camelcase . constantize . search ( like_tokens ,  @project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :all_words  = >  @all_words , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :titles_only  = >  @titles_only , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :limit  = >  ( limit + 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :offset  = >  offset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            :before  = >  params [ :previous ] . nil? ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 19:37:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-27 17:28:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @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 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          @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-05-14 17:46:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-30 08:52:39 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 16:53:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        operator  =  @all_words  ?  ' AND '  :  ' OR ' 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-10 17:58:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @results  +=  Project . find ( :all ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 :limit  = >  limit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 :conditions  = >  [  ( [ " ( #{ Project . visible_by ( User . current ) } ) AND (LOWER(name) like ? OR LOWER(description) like ?) " ]  *  like_tokens . size ) . join ( operator ) ,  *  ( like_tokens  *  2 ) . sort ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 )  if  @scope . include?  'projects' 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-30 08:52:39 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # if only one project is found, user is redirected to its overview 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        redirect_to  :controller  = >  'projects' ,  :action  = >  'show' ,  :id  = >  @results . first  and  return  if  @results . size  ==  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      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    
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  find_project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @project  =  Project . find ( params [ :id ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  rescue  ActiveRecord :: RecordNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    render_404 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								end