##// END OF EJS Templates
Adds Redmine::Plugin.public_directory to be used instead of Engines.public_directory....
Jean-Philippe Lang -
r8945:c7b1a42d19f0
parent child
Show More
@@ -1,86 +1,86
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 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 AdminController < ApplicationController
18 class AdminController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20 menu_item :projects, :only => :projects
20 menu_item :projects, :only => :projects
21 menu_item :plugins, :only => :plugins
21 menu_item :plugins, :only => :plugins
22 menu_item :info, :only => :info
22 menu_item :info, :only => :info
23
23
24 before_filter :require_admin
24 before_filter :require_admin
25 helper :sort
25 helper :sort
26 include SortHelper
26 include SortHelper
27
27
28 def index
28 def index
29 @no_configuration_data = Redmine::DefaultData::Loader::no_data?
29 @no_configuration_data = Redmine::DefaultData::Loader::no_data?
30 end
30 end
31
31
32 def projects
32 def projects
33 @status = params[:status] || 1
33 @status = params[:status] || 1
34
34
35 scope = Project.status(@status)
35 scope = Project.status(@status)
36 scope = scope.like(params[:name]) if params[:name].present?
36 scope = scope.like(params[:name]) if params[:name].present?
37
37
38 @projects = scope.all(:order => 'lft')
38 @projects = scope.all(:order => 'lft')
39
39
40 render :action => "projects", :layout => false if request.xhr?
40 render :action => "projects", :layout => false if request.xhr?
41 end
41 end
42
42
43 def plugins
43 def plugins
44 @plugins = Redmine::Plugin.all
44 @plugins = Redmine::Plugin.all
45 end
45 end
46
46
47 # Loads the default configuration
47 # Loads the default configuration
48 # (roles, trackers, statuses, workflow, enumerations)
48 # (roles, trackers, statuses, workflow, enumerations)
49 def default_configuration
49 def default_configuration
50 if request.post?
50 if request.post?
51 begin
51 begin
52 Redmine::DefaultData::Loader::load(params[:lang])
52 Redmine::DefaultData::Loader::load(params[:lang])
53 flash[:notice] = l(:notice_default_data_loaded)
53 flash[:notice] = l(:notice_default_data_loaded)
54 rescue Exception => e
54 rescue Exception => e
55 flash[:error] = l(:error_can_t_load_default_data, e.message)
55 flash[:error] = l(:error_can_t_load_default_data, e.message)
56 end
56 end
57 end
57 end
58 redirect_to :action => 'index'
58 redirect_to :action => 'index'
59 end
59 end
60
60
61 def test_email
61 def test_email
62 raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
62 raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
63 # Force ActionMailer to raise delivery errors so we can catch it
63 # Force ActionMailer to raise delivery errors so we can catch it
64 ActionMailer::Base.raise_delivery_errors = true
64 ActionMailer::Base.raise_delivery_errors = true
65 begin
65 begin
66 @test = Mailer.deliver_test(User.current)
66 @test = Mailer.deliver_test(User.current)
67 flash[:notice] = l(:notice_email_sent, User.current.mail)
67 flash[:notice] = l(:notice_email_sent, User.current.mail)
68 rescue Exception => e
68 rescue Exception => e
69 flash[:error] = l(:notice_email_error, e.message)
69 flash[:error] = l(:notice_email_error, e.message)
70 end
70 end
71 ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
71 ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
72 redirect_to :controller => 'settings', :action => 'edit', :tab => 'notifications'
72 redirect_to :controller => 'settings', :action => 'edit', :tab => 'notifications'
73 end
73 end
74
74
75 def info
75 def info
76 @db_adapter_name = ActiveRecord::Base.connection.adapter_name
76 @db_adapter_name = ActiveRecord::Base.connection.adapter_name
77 @checklist = [
77 @checklist = [
78 [:text_default_administrator_account_changed,
78 [:text_default_administrator_account_changed,
79 User.find(:first,
79 User.find(:first,
80 :conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?],
80 :conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?],
81 [:text_file_repository_writable, File.writable?(Attachment.storage_path)],
81 [:text_file_repository_writable, File.writable?(Attachment.storage_path)],
82 [:text_plugin_assets_writable, File.writable?(Engines.public_directory)],
82 [:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)],
83 [:text_rmagick_available, Object.const_defined?(:Magick)]
83 [:text_rmagick_available, Object.const_defined?(:Magick)]
84 ]
84 ]
85 end
85 end
86 end
86 end
@@ -1,278 +1,281
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 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 #:nodoc:
18 module Redmine #:nodoc:
19
19
20 class PluginNotFound < StandardError; end
20 class PluginNotFound < StandardError; end
21 class PluginRequirementError < StandardError; end
21 class PluginRequirementError < StandardError; end
22
22
23 # Base class for Redmine plugins.
23 # Base class for Redmine plugins.
24 # Plugins are registered using the <tt>register</tt> class method that acts as the public constructor.
24 # Plugins are registered using the <tt>register</tt> class method that acts as the public constructor.
25 #
25 #
26 # Redmine::Plugin.register :example do
26 # Redmine::Plugin.register :example do
27 # name 'Example plugin'
27 # name 'Example plugin'
28 # author 'John Smith'
28 # author 'John Smith'
29 # description 'This is an example plugin for Redmine'
29 # description 'This is an example plugin for Redmine'
30 # version '0.0.1'
30 # version '0.0.1'
31 # settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
31 # settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
32 # end
32 # end
33 #
33 #
34 # === Plugin attributes
34 # === Plugin attributes
35 #
35 #
36 # +settings+ is an optional attribute that let the plugin be configurable.
36 # +settings+ is an optional attribute that let the plugin be configurable.
37 # It must be a hash with the following keys:
37 # It must be a hash with the following keys:
38 # * <tt>:default</tt>: default value for the plugin settings
38 # * <tt>:default</tt>: default value for the plugin settings
39 # * <tt>:partial</tt>: path of the configuration partial view, relative to the plugin <tt>app/views</tt> directory
39 # * <tt>:partial</tt>: path of the configuration partial view, relative to the plugin <tt>app/views</tt> directory
40 # Example:
40 # Example:
41 # settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
41 # settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
42 # In this example, the settings partial will be found here in the plugin directory: <tt>app/views/settings/_settings.rhtml</tt>.
42 # In this example, the settings partial will be found here in the plugin directory: <tt>app/views/settings/_settings.rhtml</tt>.
43 #
43 #
44 # When rendered, the plugin settings value is available as the local variable +settings+
44 # When rendered, the plugin settings value is available as the local variable +settings+
45 class Plugin
45 class Plugin
46 cattr_accessor :public_directory
47 self.public_directory = File.join(Rails.root, 'public', 'plugin_assets')
48
46 @registered_plugins = {}
49 @registered_plugins = {}
47 class << self
50 class << self
48 attr_reader :registered_plugins
51 attr_reader :registered_plugins
49 private :new
52 private :new
50
53
51 def def_field(*names)
54 def def_field(*names)
52 class_eval do
55 class_eval do
53 names.each do |name|
56 names.each do |name|
54 define_method(name) do |*args|
57 define_method(name) do |*args|
55 args.empty? ? instance_variable_get("@#{name}") : instance_variable_set("@#{name}", *args)
58 args.empty? ? instance_variable_get("@#{name}") : instance_variable_set("@#{name}", *args)
56 end
59 end
57 end
60 end
58 end
61 end
59 end
62 end
60 end
63 end
61 def_field :name, :description, :url, :author, :author_url, :version, :settings
64 def_field :name, :description, :url, :author, :author_url, :version, :settings
62 attr_reader :id
65 attr_reader :id
63
66
64 # Plugin constructor
67 # Plugin constructor
65 def self.register(id, &block)
68 def self.register(id, &block)
66 p = new(id)
69 p = new(id)
67 p.instance_eval(&block)
70 p.instance_eval(&block)
68 # Set a default name if it was not provided during registration
71 # Set a default name if it was not provided during registration
69 p.name(id.to_s.humanize) if p.name.nil?
72 p.name(id.to_s.humanize) if p.name.nil?
70 # Adds plugin locales if any
73 # Adds plugin locales if any
71 # YAML translation files should be found under <plugin>/config/locales/
74 # YAML translation files should be found under <plugin>/config/locales/
72 ::I18n.load_path += Dir.glob(File.join(Rails.root, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
75 ::I18n.load_path += Dir.glob(File.join(Rails.root, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
73 registered_plugins[id] = p
76 registered_plugins[id] = p
74 end
77 end
75
78
76 # Returns an array of all registered plugins
79 # Returns an array of all registered plugins
77 def self.all
80 def self.all
78 registered_plugins.values.sort
81 registered_plugins.values.sort
79 end
82 end
80
83
81 # Finds a plugin by its id
84 # Finds a plugin by its id
82 # Returns a PluginNotFound exception if the plugin doesn't exist
85 # Returns a PluginNotFound exception if the plugin doesn't exist
83 def self.find(id)
86 def self.find(id)
84 registered_plugins[id.to_sym] || raise(PluginNotFound)
87 registered_plugins[id.to_sym] || raise(PluginNotFound)
85 end
88 end
86
89
87 # Clears the registered plugins hash
90 # Clears the registered plugins hash
88 # It doesn't unload installed plugins
91 # It doesn't unload installed plugins
89 def self.clear
92 def self.clear
90 @registered_plugins = {}
93 @registered_plugins = {}
91 end
94 end
92
95
93 # Checks if a plugin is installed
96 # Checks if a plugin is installed
94 #
97 #
95 # @param [String] id name of the plugin
98 # @param [String] id name of the plugin
96 def self.installed?(id)
99 def self.installed?(id)
97 registered_plugins[id.to_sym].present?
100 registered_plugins[id.to_sym].present?
98 end
101 end
99
102
100 def initialize(id)
103 def initialize(id)
101 @id = id.to_sym
104 @id = id.to_sym
102 end
105 end
103
106
104 def <=>(plugin)
107 def <=>(plugin)
105 self.id.to_s <=> plugin.id.to_s
108 self.id.to_s <=> plugin.id.to_s
106 end
109 end
107
110
108 # Sets a requirement on Redmine version
111 # Sets a requirement on Redmine version
109 # Raises a PluginRequirementError exception if the requirement is not met
112 # Raises a PluginRequirementError exception if the requirement is not met
110 #
113 #
111 # Examples
114 # Examples
112 # # Requires Redmine 0.7.3 or higher
115 # # Requires Redmine 0.7.3 or higher
113 # requires_redmine :version_or_higher => '0.7.3'
116 # requires_redmine :version_or_higher => '0.7.3'
114 # requires_redmine '0.7.3'
117 # requires_redmine '0.7.3'
115 #
118 #
116 # # Requires a specific Redmine version
119 # # Requires a specific Redmine version
117 # requires_redmine :version => '0.7.3' # 0.7.3 only
120 # requires_redmine :version => '0.7.3' # 0.7.3 only
118 # requires_redmine :version => ['0.7.3', '0.8.0'] # 0.7.3 or 0.8.0
121 # requires_redmine :version => ['0.7.3', '0.8.0'] # 0.7.3 or 0.8.0
119 def requires_redmine(arg)
122 def requires_redmine(arg)
120 arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
123 arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
121 arg.assert_valid_keys(:version, :version_or_higher)
124 arg.assert_valid_keys(:version, :version_or_higher)
122
125
123 current = Redmine::VERSION.to_a
126 current = Redmine::VERSION.to_a
124 arg.each do |k, v|
127 arg.each do |k, v|
125 v = [] << v unless v.is_a?(Array)
128 v = [] << v unless v.is_a?(Array)
126 versions = v.collect {|s| s.split('.').collect(&:to_i)}
129 versions = v.collect {|s| s.split('.').collect(&:to_i)}
127 case k
130 case k
128 when :version_or_higher
131 when :version_or_higher
129 raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
132 raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
130 unless (current <=> versions.first) >= 0
133 unless (current <=> versions.first) >= 0
131 raise PluginRequirementError.new("#{id} plugin requires Redmine #{v} or higher but current is #{current.join('.')}")
134 raise PluginRequirementError.new("#{id} plugin requires Redmine #{v} or higher but current is #{current.join('.')}")
132 end
135 end
133 when :version
136 when :version
134 unless versions.include?(current.slice(0,3))
137 unless versions.include?(current.slice(0,3))
135 raise PluginRequirementError.new("#{id} plugin requires one the following Redmine versions: #{v.join(', ')} but current is #{current.join('.')}")
138 raise PluginRequirementError.new("#{id} plugin requires one the following Redmine versions: #{v.join(', ')} but current is #{current.join('.')}")
136 end
139 end
137 end
140 end
138 end
141 end
139 true
142 true
140 end
143 end
141
144
142 # Sets a requirement on a Redmine plugin version
145 # Sets a requirement on a Redmine plugin version
143 # Raises a PluginRequirementError exception if the requirement is not met
146 # Raises a PluginRequirementError exception if the requirement is not met
144 #
147 #
145 # Examples
148 # Examples
146 # # Requires a plugin named :foo version 0.7.3 or higher
149 # # Requires a plugin named :foo version 0.7.3 or higher
147 # requires_redmine_plugin :foo, :version_or_higher => '0.7.3'
150 # requires_redmine_plugin :foo, :version_or_higher => '0.7.3'
148 # requires_redmine_plugin :foo, '0.7.3'
151 # requires_redmine_plugin :foo, '0.7.3'
149 #
152 #
150 # # Requires a specific version of a Redmine plugin
153 # # Requires a specific version of a Redmine plugin
151 # requires_redmine_plugin :foo, :version => '0.7.3' # 0.7.3 only
154 # requires_redmine_plugin :foo, :version => '0.7.3' # 0.7.3 only
152 # requires_redmine_plugin :foo, :version => ['0.7.3', '0.8.0'] # 0.7.3 or 0.8.0
155 # requires_redmine_plugin :foo, :version => ['0.7.3', '0.8.0'] # 0.7.3 or 0.8.0
153 def requires_redmine_plugin(plugin_name, arg)
156 def requires_redmine_plugin(plugin_name, arg)
154 arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
157 arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
155 arg.assert_valid_keys(:version, :version_or_higher)
158 arg.assert_valid_keys(:version, :version_or_higher)
156
159
157 plugin = Plugin.find(plugin_name)
160 plugin = Plugin.find(plugin_name)
158 current = plugin.version.split('.').collect(&:to_i)
161 current = plugin.version.split('.').collect(&:to_i)
159
162
160 arg.each do |k, v|
163 arg.each do |k, v|
161 v = [] << v unless v.is_a?(Array)
164 v = [] << v unless v.is_a?(Array)
162 versions = v.collect {|s| s.split('.').collect(&:to_i)}
165 versions = v.collect {|s| s.split('.').collect(&:to_i)}
163 case k
166 case k
164 when :version_or_higher
167 when :version_or_higher
165 raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
168 raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
166 unless (current <=> versions.first) >= 0
169 unless (current <=> versions.first) >= 0
167 raise PluginRequirementError.new("#{id} plugin requires the #{plugin_name} plugin #{v} or higher but current is #{current.join('.')}")
170 raise PluginRequirementError.new("#{id} plugin requires the #{plugin_name} plugin #{v} or higher but current is #{current.join('.')}")
168 end
171 end
169 when :version
172 when :version
170 unless versions.include?(current.slice(0,3))
173 unless versions.include?(current.slice(0,3))
171 raise PluginRequirementError.new("#{id} plugin requires one the following versions of #{plugin_name}: #{v.join(', ')} but current is #{current.join('.')}")
174 raise PluginRequirementError.new("#{id} plugin requires one the following versions of #{plugin_name}: #{v.join(', ')} but current is #{current.join('.')}")
172 end
175 end
173 end
176 end
174 end
177 end
175 true
178 true
176 end
179 end
177
180
178 # Adds an item to the given +menu+.
181 # Adds an item to the given +menu+.
179 # The +id+ parameter (equals to the project id) is automatically added to the url.
182 # The +id+ parameter (equals to the project id) is automatically added to the url.
180 # menu :project_menu, :plugin_example, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'
183 # menu :project_menu, :plugin_example, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'
181 #
184 #
182 # +name+ parameter can be: :top_menu, :account_menu, :application_menu or :project_menu
185 # +name+ parameter can be: :top_menu, :account_menu, :application_menu or :project_menu
183 #
186 #
184 def menu(menu, item, url, options={})
187 def menu(menu, item, url, options={})
185 Redmine::MenuManager.map(menu).push(item, url, options)
188 Redmine::MenuManager.map(menu).push(item, url, options)
186 end
189 end
187 alias :add_menu_item :menu
190 alias :add_menu_item :menu
188
191
189 # Removes +item+ from the given +menu+.
192 # Removes +item+ from the given +menu+.
190 def delete_menu_item(menu, item)
193 def delete_menu_item(menu, item)
191 Redmine::MenuManager.map(menu).delete(item)
194 Redmine::MenuManager.map(menu).delete(item)
192 end
195 end
193
196
194 # Defines a permission called +name+ for the given +actions+.
197 # Defines a permission called +name+ for the given +actions+.
195 #
198 #
196 # The +actions+ argument is a hash with controllers as keys and actions as values (a single value or an array):
199 # The +actions+ argument is a hash with controllers as keys and actions as values (a single value or an array):
197 # permission :destroy_contacts, { :contacts => :destroy }
200 # permission :destroy_contacts, { :contacts => :destroy }
198 # permission :view_contacts, { :contacts => [:index, :show] }
201 # permission :view_contacts, { :contacts => [:index, :show] }
199 #
202 #
200 # The +options+ argument can be used to make the permission public (implicitly given to any user)
203 # The +options+ argument can be used to make the permission public (implicitly given to any user)
201 # or to restrict users the permission can be given to.
204 # or to restrict users the permission can be given to.
202 #
205 #
203 # Examples
206 # Examples
204 # # A permission that is implicitly given to any user
207 # # A permission that is implicitly given to any user
205 # # This permission won't appear on the Roles & Permissions setup screen
208 # # This permission won't appear on the Roles & Permissions setup screen
206 # permission :say_hello, { :example => :say_hello }, :public => true
209 # permission :say_hello, { :example => :say_hello }, :public => true
207 #
210 #
208 # # A permission that can be given to any user
211 # # A permission that can be given to any user
209 # permission :say_hello, { :example => :say_hello }
212 # permission :say_hello, { :example => :say_hello }
210 #
213 #
211 # # A permission that can be given to registered users only
214 # # A permission that can be given to registered users only
212 # permission :say_hello, { :example => :say_hello }, :require => :loggedin
215 # permission :say_hello, { :example => :say_hello }, :require => :loggedin
213 #
216 #
214 # # A permission that can be given to project members only
217 # # A permission that can be given to project members only
215 # permission :say_hello, { :example => :say_hello }, :require => :member
218 # permission :say_hello, { :example => :say_hello }, :require => :member
216 def permission(name, actions, options = {})
219 def permission(name, actions, options = {})
217 if @project_module
220 if @project_module
218 Redmine::AccessControl.map {|map| map.project_module(@project_module) {|map|map.permission(name, actions, options)}}
221 Redmine::AccessControl.map {|map| map.project_module(@project_module) {|map|map.permission(name, actions, options)}}
219 else
222 else
220 Redmine::AccessControl.map {|map| map.permission(name, actions, options)}
223 Redmine::AccessControl.map {|map| map.permission(name, actions, options)}
221 end
224 end
222 end
225 end
223
226
224 # Defines a project module, that can be enabled/disabled for each project.
227 # Defines a project module, that can be enabled/disabled for each project.
225 # Permissions defined inside +block+ will be bind to the module.
228 # Permissions defined inside +block+ will be bind to the module.
226 #
229 #
227 # project_module :things do
230 # project_module :things do
228 # permission :view_contacts, { :contacts => [:list, :show] }, :public => true
231 # permission :view_contacts, { :contacts => [:list, :show] }, :public => true
229 # permission :destroy_contacts, { :contacts => :destroy }
232 # permission :destroy_contacts, { :contacts => :destroy }
230 # end
233 # end
231 def project_module(name, &block)
234 def project_module(name, &block)
232 @project_module = name
235 @project_module = name
233 self.instance_eval(&block)
236 self.instance_eval(&block)
234 @project_module = nil
237 @project_module = nil
235 end
238 end
236
239
237 # Registers an activity provider.
240 # Registers an activity provider.
238 #
241 #
239 # Options:
242 # Options:
240 # * <tt>:class_name</tt> - one or more model(s) that provide these events (inferred from event_type by default)
243 # * <tt>:class_name</tt> - one or more model(s) that provide these events (inferred from event_type by default)
241 # * <tt>:default</tt> - setting this option to false will make the events not displayed by default
244 # * <tt>:default</tt> - setting this option to false will make the events not displayed by default
242 #
245 #
243 # A model can provide several activity event types.
246 # A model can provide several activity event types.
244 #
247 #
245 # Examples:
248 # Examples:
246 # register :news
249 # register :news
247 # register :scrums, :class_name => 'Meeting'
250 # register :scrums, :class_name => 'Meeting'
248 # register :issues, :class_name => ['Issue', 'Journal']
251 # register :issues, :class_name => ['Issue', 'Journal']
249 #
252 #
250 # Retrieving events:
253 # Retrieving events:
251 # Associated model(s) must implement the find_events class method.
254 # Associated model(s) must implement the find_events class method.
252 # ActiveRecord models can use acts_as_activity_provider as a way to implement this class method.
255 # ActiveRecord models can use acts_as_activity_provider as a way to implement this class method.
253 #
256 #
254 # The following call should return all the scrum events visible by current user that occured in the 5 last days:
257 # The following call should return all the scrum events visible by current user that occured in the 5 last days:
255 # Meeting.find_events('scrums', User.current, 5.days.ago, Date.today)
258 # Meeting.find_events('scrums', User.current, 5.days.ago, Date.today)
256 # Meeting.find_events('scrums', User.current, 5.days.ago, Date.today, :project => foo) # events for project foo only
259 # Meeting.find_events('scrums', User.current, 5.days.ago, Date.today, :project => foo) # events for project foo only
257 #
260 #
258 # Note that :view_scrums permission is required to view these events in the activity view.
261 # Note that :view_scrums permission is required to view these events in the activity view.
259 def activity_provider(*args)
262 def activity_provider(*args)
260 Redmine::Activity.register(*args)
263 Redmine::Activity.register(*args)
261 end
264 end
262
265
263 # Registers a wiki formatter.
266 # Registers a wiki formatter.
264 #
267 #
265 # Parameters:
268 # Parameters:
266 # * +name+ - human-readable name
269 # * +name+ - human-readable name
267 # * +formatter+ - formatter class, which should have an instance method +to_html+
270 # * +formatter+ - formatter class, which should have an instance method +to_html+
268 # * +helper+ - helper module, which will be included by wiki pages
271 # * +helper+ - helper module, which will be included by wiki pages
269 def wiki_format_provider(name, formatter, helper)
272 def wiki_format_provider(name, formatter, helper)
270 Redmine::WikiFormatting.register(name, formatter, helper)
273 Redmine::WikiFormatting.register(name, formatter, helper)
271 end
274 end
272
275
273 # Returns +true+ if the plugin can be configured.
276 # Returns +true+ if the plugin can be configured.
274 def configurable?
277 def configurable?
275 settings && settings.is_a?(Hash) && !settings[:partial].blank?
278 settings && settings.is_a?(Hash) && !settings[:partial].blank?
276 end
279 end
277 end
280 end
278 end
281 end
General Comments 0
You need to be logged in to leave comments. Login now