##// END OF EJS Templates
Makes search providers extensible (#3936)....
Jean-Philippe Lang -
r3330:c11d30ebc9f5
parent child
Show More
@@ -1,116 +1,116
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class SearchController < ApplicationController
18 class SearchController < ApplicationController
19 before_filter :find_optional_project
19 before_filter :find_optional_project
20
20
21 helper :messages
21 helper :messages
22 include MessagesHelper
22 include MessagesHelper
23
23
24 def index
24 def index
25 @question = params[:q] || ""
25 @question = params[:q] || ""
26 @question.strip!
26 @question.strip!
27 @all_words = params[:all_words] || (params[:submit] ? false : true)
27 @all_words = params[:all_words] || (params[:submit] ? false : true)
28 @titles_only = !params[:titles_only].nil?
28 @titles_only = !params[:titles_only].nil?
29
29
30 projects_to_search =
30 projects_to_search =
31 case params[:scope]
31 case params[:scope]
32 when 'all'
32 when 'all'
33 nil
33 nil
34 when 'my_projects'
34 when 'my_projects'
35 User.current.memberships.collect(&:project)
35 User.current.memberships.collect(&:project)
36 when 'subprojects'
36 when 'subprojects'
37 @project ? (@project.self_and_descendants.active) : nil
37 @project ? (@project.self_and_descendants.active) : nil
38 else
38 else
39 @project
39 @project
40 end
40 end
41
41
42 offset = nil
42 offset = nil
43 begin; offset = params[:offset].to_time if params[:offset]; rescue; end
43 begin; offset = params[:offset].to_time if params[:offset]; rescue; end
44
44
45 # quick jump to an issue
45 # quick jump to an issue
46 if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1)
46 if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1)
47 redirect_to :controller => "issues", :action => "show", :id => $1
47 redirect_to :controller => "issues", :action => "show", :id => $1
48 return
48 return
49 end
49 end
50
50
51 @object_types = %w(issues news documents changesets wiki_pages messages projects)
51 @object_types = Redmine::Search.available_search_types.dup
52 if projects_to_search.is_a? Project
52 if projects_to_search.is_a? Project
53 # don't search projects
53 # don't search projects
54 @object_types.delete('projects')
54 @object_types.delete('projects')
55 # only show what the user is allowed to view
55 # only show what the user is allowed to view
56 @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
56 @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
57 end
57 end
58
58
59 @scope = @object_types.select {|t| params[t]}
59 @scope = @object_types.select {|t| params[t]}
60 @scope = @object_types if @scope.empty?
60 @scope = @object_types if @scope.empty?
61
61
62 # extract tokens from the question
62 # extract tokens from the question
63 # eg. hello "bye bye" => ["hello", "bye bye"]
63 # eg. hello "bye bye" => ["hello", "bye bye"]
64 @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
64 @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
65 # tokens must be at least 2 characters long
65 # tokens must be at least 2 characters long
66 @tokens = @tokens.uniq.select {|w| w.length > 1 }
66 @tokens = @tokens.uniq.select {|w| w.length > 1 }
67
67
68 if !@tokens.empty?
68 if !@tokens.empty?
69 # no more than 5 tokens to search for
69 # no more than 5 tokens to search for
70 @tokens.slice! 5..-1 if @tokens.size > 5
70 @tokens.slice! 5..-1 if @tokens.size > 5
71 # strings used in sql like statement
71 # strings used in sql like statement
72 like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}
72 like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}
73
73
74 @results = []
74 @results = []
75 @results_by_type = Hash.new {|h,k| h[k] = 0}
75 @results_by_type = Hash.new {|h,k| h[k] = 0}
76
76
77 limit = 10
77 limit = 10
78 @scope.each do |s|
78 @scope.each do |s|
79 r, c = s.singularize.camelcase.constantize.search(like_tokens, projects_to_search,
79 r, c = s.singularize.camelcase.constantize.search(like_tokens, projects_to_search,
80 :all_words => @all_words,
80 :all_words => @all_words,
81 :titles_only => @titles_only,
81 :titles_only => @titles_only,
82 :limit => (limit+1),
82 :limit => (limit+1),
83 :offset => offset,
83 :offset => offset,
84 :before => params[:previous].nil?)
84 :before => params[:previous].nil?)
85 @results += r
85 @results += r
86 @results_by_type[s] += c
86 @results_by_type[s] += c
87 end
87 end
88 @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
88 @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
89 if params[:previous].nil?
89 if params[:previous].nil?
90 @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
90 @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
91 if @results.size > limit
91 if @results.size > limit
92 @pagination_next_date = @results[limit-1].event_datetime
92 @pagination_next_date = @results[limit-1].event_datetime
93 @results = @results[0, limit]
93 @results = @results[0, limit]
94 end
94 end
95 else
95 else
96 @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
96 @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
97 if @results.size > limit
97 if @results.size > limit
98 @pagination_previous_date = @results[-(limit)].event_datetime
98 @pagination_previous_date = @results[-(limit)].event_datetime
99 @results = @results[-(limit), limit]
99 @results = @results[-(limit), limit]
100 end
100 end
101 end
101 end
102 else
102 else
103 @question = ""
103 @question = ""
104 end
104 end
105 render :layout => false if request.xhr?
105 render :layout => false if request.xhr?
106 end
106 end
107
107
108 private
108 private
109 def find_optional_project
109 def find_optional_project
110 return true unless params[:id]
110 return true unless params[:id]
111 @project = Project.find(params[:id])
111 @project = Project.find(params[:id])
112 check_project_privacy
112 check_project_privacy
113 rescue ActiveRecord::RecordNotFound
113 rescue ActiveRecord::RecordNotFound
114 render_404
114 render_404
115 end
115 end
116 end
116 end
@@ -1,183 +1,194
1 require 'redmine/access_control'
1 require 'redmine/access_control'
2 require 'redmine/menu_manager'
2 require 'redmine/menu_manager'
3 require 'redmine/activity'
3 require 'redmine/activity'
4 require 'redmine/search'
4 require 'redmine/mime_type'
5 require 'redmine/mime_type'
5 require 'redmine/core_ext'
6 require 'redmine/core_ext'
6 require 'redmine/themes'
7 require 'redmine/themes'
7 require 'redmine/hook'
8 require 'redmine/hook'
8 require 'redmine/plugin'
9 require 'redmine/plugin'
9 require 'redmine/wiki_formatting'
10 require 'redmine/wiki_formatting'
10 require 'redmine/scm/base'
11 require 'redmine/scm/base'
11
12
12 begin
13 begin
13 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
14 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
14 rescue LoadError
15 rescue LoadError
15 # RMagick is not available
16 # RMagick is not available
16 end
17 end
17
18
18 if RUBY_VERSION < '1.9'
19 if RUBY_VERSION < '1.9'
19 require 'faster_csv'
20 require 'faster_csv'
20 else
21 else
21 require 'csv'
22 require 'csv'
22 FCSV = CSV
23 FCSV = CSV
23 end
24 end
24
25
25 Redmine::Scm::Base.add "Subversion"
26 Redmine::Scm::Base.add "Subversion"
26 Redmine::Scm::Base.add "Darcs"
27 Redmine::Scm::Base.add "Darcs"
27 Redmine::Scm::Base.add "Mercurial"
28 Redmine::Scm::Base.add "Mercurial"
28 Redmine::Scm::Base.add "Cvs"
29 Redmine::Scm::Base.add "Cvs"
29 Redmine::Scm::Base.add "Bazaar"
30 Redmine::Scm::Base.add "Bazaar"
30 Redmine::Scm::Base.add "Git"
31 Redmine::Scm::Base.add "Git"
31 Redmine::Scm::Base.add "Filesystem"
32 Redmine::Scm::Base.add "Filesystem"
32
33
33 # Permissions
34 # Permissions
34 Redmine::AccessControl.map do |map|
35 Redmine::AccessControl.map do |map|
35 map.permission :view_project, {:projects => [:show, :activity]}, :public => true
36 map.permission :view_project, {:projects => [:show, :activity]}, :public => true
36 map.permission :search_project, {:search => :index}, :public => true
37 map.permission :search_project, {:search => :index}, :public => true
37 map.permission :add_project, {:projects => :add}, :require => :loggedin
38 map.permission :add_project, {:projects => :add}, :require => :loggedin
38 map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member
39 map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member
39 map.permission :select_project_modules, {:projects => :modules}, :require => :member
40 map.permission :select_project_modules, {:projects => :modules}, :require => :member
40 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
41 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
41 map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :close_completed, :destroy]}, :require => :member
42 map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :close_completed, :destroy]}, :require => :member
42 map.permission :add_subprojects, {:projects => :add}, :require => :member
43 map.permission :add_subprojects, {:projects => :add}, :require => :member
43
44
44 map.project_module :issue_tracking do |map|
45 map.project_module :issue_tracking do |map|
45 # Issue categories
46 # Issue categories
46 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
47 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
47 # Issues
48 # Issues
48 map.permission :view_issues, {:projects => :roadmap,
49 map.permission :view_issues, {:projects => :roadmap,
49 :issues => [:index, :changes, :show, :context_menu],
50 :issues => [:index, :changes, :show, :context_menu],
50 :versions => [:show, :status_by],
51 :versions => [:show, :status_by],
51 :queries => :index,
52 :queries => :index,
52 :reports => [:issue_report, :issue_report_details]}
53 :reports => [:issue_report, :issue_report_details]}
53 map.permission :add_issues, {:issues => [:new, :update_form]}
54 map.permission :add_issues, {:issues => [:new, :update_form]}
54 map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :update_form]}
55 map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :update_form]}
55 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
56 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
56 map.permission :add_issue_notes, {:issues => [:edit, :reply]}
57 map.permission :add_issue_notes, {:issues => [:edit, :reply]}
57 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
58 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
58 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
59 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
59 map.permission :move_issues, {:issues => :move}, :require => :loggedin
60 map.permission :move_issues, {:issues => :move}, :require => :loggedin
60 map.permission :delete_issues, {:issues => :destroy}, :require => :member
61 map.permission :delete_issues, {:issues => :destroy}, :require => :member
61 # Queries
62 # Queries
62 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
63 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
63 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
64 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
64 # Gantt & calendar
65 # Gantt & calendar
65 map.permission :view_gantt, :issues => :gantt
66 map.permission :view_gantt, :issues => :gantt
66 map.permission :view_calendar, :issues => :calendar
67 map.permission :view_calendar, :issues => :calendar
67 # Watchers
68 # Watchers
68 map.permission :view_issue_watchers, {}
69 map.permission :view_issue_watchers, {}
69 map.permission :add_issue_watchers, {:watchers => :new}
70 map.permission :add_issue_watchers, {:watchers => :new}
70 map.permission :delete_issue_watchers, {:watchers => :destroy}
71 map.permission :delete_issue_watchers, {:watchers => :destroy}
71 end
72 end
72
73
73 map.project_module :time_tracking do |map|
74 map.project_module :time_tracking do |map|
74 map.permission :log_time, {:timelog => :edit}, :require => :loggedin
75 map.permission :log_time, {:timelog => :edit}, :require => :loggedin
75 map.permission :view_time_entries, :timelog => [:details, :report]
76 map.permission :view_time_entries, :timelog => [:details, :report]
76 map.permission :edit_time_entries, {:timelog => [:edit, :destroy]}, :require => :member
77 map.permission :edit_time_entries, {:timelog => [:edit, :destroy]}, :require => :member
77 map.permission :edit_own_time_entries, {:timelog => [:edit, :destroy]}, :require => :loggedin
78 map.permission :edit_own_time_entries, {:timelog => [:edit, :destroy]}, :require => :loggedin
78 map.permission :manage_project_activities, {:projects => [:save_activities, :reset_activities]}, :require => :member
79 map.permission :manage_project_activities, {:projects => [:save_activities, :reset_activities]}, :require => :member
79 end
80 end
80
81
81 map.project_module :news do |map|
82 map.project_module :news do |map|
82 map.permission :manage_news, {:news => [:new, :edit, :destroy, :destroy_comment]}, :require => :member
83 map.permission :manage_news, {:news => [:new, :edit, :destroy, :destroy_comment]}, :require => :member
83 map.permission :view_news, {:news => [:index, :show]}, :public => true
84 map.permission :view_news, {:news => [:index, :show]}, :public => true
84 map.permission :comment_news, {:news => :add_comment}
85 map.permission :comment_news, {:news => :add_comment}
85 end
86 end
86
87
87 map.project_module :documents do |map|
88 map.project_module :documents do |map|
88 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment]}, :require => :loggedin
89 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment]}, :require => :loggedin
89 map.permission :view_documents, :documents => [:index, :show, :download]
90 map.permission :view_documents, :documents => [:index, :show, :download]
90 end
91 end
91
92
92 map.project_module :files do |map|
93 map.project_module :files do |map|
93 map.permission :manage_files, {:projects => :add_file}, :require => :loggedin
94 map.permission :manage_files, {:projects => :add_file}, :require => :loggedin
94 map.permission :view_files, :projects => :list_files, :versions => :download
95 map.permission :view_files, :projects => :list_files, :versions => :download
95 end
96 end
96
97
97 map.project_module :wiki do |map|
98 map.project_module :wiki do |map|
98 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
99 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
99 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
100 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
100 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
101 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
101 map.permission :view_wiki_pages, :wiki => [:index, :special]
102 map.permission :view_wiki_pages, :wiki => [:index, :special]
102 map.permission :export_wiki_pages, {}
103 map.permission :export_wiki_pages, {}
103 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
104 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
104 map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment]
105 map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment]
105 map.permission :delete_wiki_pages_attachments, {}
106 map.permission :delete_wiki_pages_attachments, {}
106 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
107 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
107 end
108 end
108
109
109 map.project_module :repository do |map|
110 map.project_module :repository do |map|
110 map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
111 map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
111 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
112 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
112 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
113 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
113 map.permission :commit_access, {}
114 map.permission :commit_access, {}
114 end
115 end
115
116
116 map.project_module :boards do |map|
117 map.project_module :boards do |map|
117 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
118 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
118 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
119 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
119 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
120 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
120 map.permission :edit_messages, {:messages => :edit}, :require => :member
121 map.permission :edit_messages, {:messages => :edit}, :require => :member
121 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
122 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
122 map.permission :delete_messages, {:messages => :destroy}, :require => :member
123 map.permission :delete_messages, {:messages => :destroy}, :require => :member
123 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
124 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
124 end
125 end
125 end
126 end
126
127
127 Redmine::MenuManager.map :top_menu do |menu|
128 Redmine::MenuManager.map :top_menu do |menu|
128 menu.push :home, :home_path
129 menu.push :home, :home_path
129 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
130 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
130 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
131 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
131 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
132 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
132 menu.push :help, Redmine::Info.help_url, :last => true
133 menu.push :help, Redmine::Info.help_url, :last => true
133 end
134 end
134
135
135 Redmine::MenuManager.map :account_menu do |menu|
136 Redmine::MenuManager.map :account_menu do |menu|
136 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
137 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
137 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
138 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
138 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
139 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
139 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
140 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
140 end
141 end
141
142
142 Redmine::MenuManager.map :application_menu do |menu|
143 Redmine::MenuManager.map :application_menu do |menu|
143 # Empty
144 # Empty
144 end
145 end
145
146
146 Redmine::MenuManager.map :admin_menu do |menu|
147 Redmine::MenuManager.map :admin_menu do |menu|
147 # Empty
148 # Empty
148 end
149 end
149
150
150 Redmine::MenuManager.map :project_menu do |menu|
151 Redmine::MenuManager.map :project_menu do |menu|
151 menu.push :overview, { :controller => 'projects', :action => 'show' }
152 menu.push :overview, { :controller => 'projects', :action => 'show' }
152 menu.push :activity, { :controller => 'projects', :action => 'activity' }
153 menu.push :activity, { :controller => 'projects', :action => 'activity' }
153 menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' },
154 menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' },
154 :if => Proc.new { |p| p.shared_versions.any? }
155 :if => Proc.new { |p| p.shared_versions.any? }
155 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
156 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
156 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
157 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
157 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
158 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
158 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
159 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
159 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
160 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
160 menu.push :wiki, { :controller => 'wiki', :action => 'index', :page => nil },
161 menu.push :wiki, { :controller => 'wiki', :action => 'index', :page => nil },
161 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
162 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
162 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
163 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
163 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
164 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
164 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_file_plural
165 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_file_plural
165 menu.push :repository, { :controller => 'repositories', :action => 'show' },
166 menu.push :repository, { :controller => 'repositories', :action => 'show' },
166 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
167 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
167 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
168 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
168 end
169 end
169
170
170 Redmine::Activity.map do |activity|
171 Redmine::Activity.map do |activity|
171 activity.register :issues, :class_name => %w(Issue Journal)
172 activity.register :issues, :class_name => %w(Issue Journal)
172 activity.register :changesets
173 activity.register :changesets
173 activity.register :news
174 activity.register :news
174 activity.register :documents, :class_name => %w(Document Attachment)
175 activity.register :documents, :class_name => %w(Document Attachment)
175 activity.register :files, :class_name => 'Attachment'
176 activity.register :files, :class_name => 'Attachment'
176 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
177 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
177 activity.register :messages, :default => false
178 activity.register :messages, :default => false
178 activity.register :time_entries, :default => false
179 activity.register :time_entries, :default => false
179 end
180 end
180
181
182 Redmine::Search.map do |search|
183 search.register :issues
184 search.register :news
185 search.register :documents
186 search.register :changesets
187 search.register :wiki_pages
188 search.register :messages
189 search.register :projects
190 end
191
181 Redmine::WikiFormatting.map do |format|
192 Redmine::WikiFormatting.map do |format|
182 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
193 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
183 end
194 end
@@ -1,55 +1,72
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module Search
19 module Search
20
21 mattr_accessor :available_search_types
22
23 @@available_search_types = []
24
25 class << self
26 def map(&block)
27 yield self
28 end
29
30 # Registers a search provider
31 def register(search_type, options={})
32 search_type = search_type.to_s
33 @@available_search_types << search_type unless @@available_search_types.include?(search_type)
34 end
35 end
36
20 module Controller
37 module Controller
21 def self.included(base)
38 def self.included(base)
22 base.extend(ClassMethods)
39 base.extend(ClassMethods)
23 end
40 end
24
41
25 module ClassMethods
42 module ClassMethods
26 @@default_search_scopes = Hash.new {|hash, key| hash[key] = {:default => nil, :actions => {}}}
43 @@default_search_scopes = Hash.new {|hash, key| hash[key] = {:default => nil, :actions => {}}}
27 mattr_accessor :default_search_scopes
44 mattr_accessor :default_search_scopes
28
45
29 # Set the default search scope for a controller or specific actions
46 # Set the default search scope for a controller or specific actions
30 # Examples:
47 # Examples:
31 # * search_scope :issues # => sets the search scope to :issues for the whole controller
48 # * search_scope :issues # => sets the search scope to :issues for the whole controller
32 # * search_scope :issues, :only => :index
49 # * search_scope :issues, :only => :index
33 # * search_scope :issues, :only => [:index, :show]
50 # * search_scope :issues, :only => [:index, :show]
34 def default_search_scope(id, options = {})
51 def default_search_scope(id, options = {})
35 if actions = options[:only]
52 if actions = options[:only]
36 actions = [] << actions unless actions.is_a?(Array)
53 actions = [] << actions unless actions.is_a?(Array)
37 actions.each {|a| default_search_scopes[controller_name.to_sym][:actions][a.to_sym] = id.to_s}
54 actions.each {|a| default_search_scopes[controller_name.to_sym][:actions][a.to_sym] = id.to_s}
38 else
55 else
39 default_search_scopes[controller_name.to_sym][:default] = id.to_s
56 default_search_scopes[controller_name.to_sym][:default] = id.to_s
40 end
57 end
41 end
58 end
42 end
59 end
43
60
44 def default_search_scopes
61 def default_search_scopes
45 self.class.default_search_scopes
62 self.class.default_search_scopes
46 end
63 end
47
64
48 # Returns the default search scope according to the current action
65 # Returns the default search scope according to the current action
49 def default_search_scope
66 def default_search_scope
50 @default_search_scope ||= default_search_scopes[controller_name.to_sym][:actions][action_name.to_sym] ||
67 @default_search_scope ||= default_search_scopes[controller_name.to_sym][:actions][action_name.to_sym] ||
51 default_search_scopes[controller_name.to_sym][:default]
68 default_search_scopes[controller_name.to_sym][:default]
52 end
69 end
53 end
70 end
54 end
71 end
55 end
72 end
General Comments 0
You need to be logged in to leave comments. Login now