annotate app/controllers/.svn/text-base/search_controller.rb.svn-base @ 8:0c83d98252d9 yuya

* Add custom repo prefix and proper auth realm, remove auth cache (seems like an unwise feature), pass DB handle around, various other bits of tidying
author Chris Cannam
date Thu, 12 Aug 2010 15:31:37 +0100
parents 513646585e45
children 0c939c159af4
rev   line source
Chris@0 1 # redMine - project management software
Chris@0 2 # Copyright (C) 2006 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 class SearchController < ApplicationController
Chris@0 19 before_filter :find_optional_project
Chris@0 20
Chris@0 21 helper :messages
Chris@0 22 include MessagesHelper
Chris@0 23
Chris@0 24 def index
Chris@0 25 @question = params[:q] || ""
Chris@0 26 @question.strip!
Chris@0 27 @all_words = params[:all_words] || (params[:submit] ? false : true)
Chris@0 28 @titles_only = !params[:titles_only].nil?
Chris@0 29
Chris@0 30 projects_to_search =
Chris@0 31 case params[:scope]
Chris@0 32 when 'all'
Chris@0 33 nil
Chris@0 34 when 'my_projects'
Chris@0 35 User.current.memberships.collect(&:project)
Chris@0 36 when 'subprojects'
Chris@0 37 @project ? (@project.self_and_descendants.active) : nil
Chris@0 38 else
Chris@0 39 @project
Chris@0 40 end
Chris@0 41
Chris@0 42 offset = nil
Chris@0 43 begin; offset = params[:offset].to_time if params[:offset]; rescue; end
Chris@0 44
Chris@0 45 # quick jump to an issue
Chris@0 46 if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1.to_i)
Chris@0 47 redirect_to :controller => "issues", :action => "show", :id => $1
Chris@0 48 return
Chris@0 49 end
Chris@0 50
Chris@0 51 @object_types = Redmine::Search.available_search_types.dup
Chris@0 52 if projects_to_search.is_a? Project
Chris@0 53 # don't search projects
Chris@0 54 @object_types.delete('projects')
Chris@0 55 # only show what the user is allowed to view
Chris@0 56 @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
Chris@0 57 end
Chris@0 58
Chris@0 59 @scope = @object_types.select {|t| params[t]}
Chris@0 60 @scope = @object_types if @scope.empty?
Chris@0 61
Chris@0 62 # extract tokens from the question
Chris@0 63 # eg. hello "bye bye" => ["hello", "bye bye"]
Chris@0 64 @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
Chris@0 65 # tokens must be at least 2 characters long
Chris@0 66 @tokens = @tokens.uniq.select {|w| w.length > 1 }
Chris@0 67
Chris@0 68 if !@tokens.empty?
Chris@0 69 # no more than 5 tokens to search for
Chris@0 70 @tokens.slice! 5..-1 if @tokens.size > 5
Chris@0 71
Chris@0 72 @results = []
Chris@0 73 @results_by_type = Hash.new {|h,k| h[k] = 0}
Chris@0 74
Chris@0 75 limit = 10
Chris@0 76 @scope.each do |s|
Chris@0 77 r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search,
Chris@0 78 :all_words => @all_words,
Chris@0 79 :titles_only => @titles_only,
Chris@0 80 :limit => (limit+1),
Chris@0 81 :offset => offset,
Chris@0 82 :before => params[:previous].nil?)
Chris@0 83 @results += r
Chris@0 84 @results_by_type[s] += c
Chris@0 85 end
Chris@0 86 @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
Chris@0 87 if params[:previous].nil?
Chris@0 88 @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
Chris@0 89 if @results.size > limit
Chris@0 90 @pagination_next_date = @results[limit-1].event_datetime
Chris@0 91 @results = @results[0, limit]
Chris@0 92 end
Chris@0 93 else
Chris@0 94 @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
Chris@0 95 if @results.size > limit
Chris@0 96 @pagination_previous_date = @results[-(limit)].event_datetime
Chris@0 97 @results = @results[-(limit), limit]
Chris@0 98 end
Chris@0 99 end
Chris@0 100 else
Chris@0 101 @question = ""
Chris@0 102 end
Chris@0 103 render :layout => false if request.xhr?
Chris@0 104 end
Chris@0 105
Chris@0 106 private
Chris@0 107 def find_optional_project
Chris@0 108 return true unless params[:id]
Chris@0 109 @project = Project.find(params[:id])
Chris@0 110 check_project_privacy
Chris@0 111 rescue ActiveRecord::RecordNotFound
Chris@0 112 render_404
Chris@0 113 end
Chris@0 114 end