Class: Redmine::Plugin

Inherits:
Object
  • Object
show all
Defined in:
lib/redmine/plugin.rb

Overview

Base class for Redmine plugins. Plugins are registered using the register class method that acts as the public constructor.

Redmine::Plugin.register :example do
  name 'Example plugin'
  author 'John Smith'
  description 'This is an example plugin for Redmine'
  version '0.0.1'
  settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
end

Plugin attributes

settings is an optional attribute that let the plugin be configurable. It must be a hash with the following keys:

  • :default: default value for the plugin settings

  • :partial: path of the configuration partial view, relative to the plugin app/views directory

Example:

settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'

In this example, the settings partial will be found here in the plugin directory: app/views/settings/_settings.rhtml.

When rendered, the plugin settings value is available as the local variable settings

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id) ⇒ Plugin

Returns a new instance of Plugin.



100
101
102
# File 'lib/redmine/plugin.rb', line 100

def initialize(id)
  @id = id.to_sym
end

Class Attribute Details

.registered_pluginsObject (readonly)

Returns the value of attribute registered_plugins.



48
49
50
# File 'lib/redmine/plugin.rb', line 48

def registered_plugins
  @registered_plugins
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



62
63
64
# File 'lib/redmine/plugin.rb', line 62

def id
  @id
end

Class Method Details

.allObject

Returns an array off all registered plugins



77
78
79
# File 'lib/redmine/plugin.rb', line 77

def self.all
  registered_plugins.values.sort
end

.clearObject

Clears the registered plugins hash It doesn’t unload installed plugins



89
90
91
# File 'lib/redmine/plugin.rb', line 89

def self.clear
  @registered_plugins = {}
end

.def_field(*names) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/redmine/plugin.rb', line 51

def def_field(*names)
  class_eval do 
    names.each do |name|
      define_method(name) do |*args| 
        args.empty? ? instance_variable_get("@#{name}") : instance_variable_set("@#{name}", *args)
      end
    end
  end
end

.find(id) ⇒ Object

Finds a plugin by its id Returns a PluginNotFound exception if the plugin doesn’t exist



83
84
85
# File 'lib/redmine/plugin.rb', line 83

def self.find(id)
  registered_plugins[id.to_sym] || raise(PluginNotFound)
end

.installed?(id) ⇒ Boolean

Checks if a plugin is installed

Parameters:

  • id (String)

    name of the plugin

Returns:

  • (Boolean)


96
97
98
# File 'lib/redmine/plugin.rb', line 96

def self.installed?(id)
  registered_plugins[id.to_sym].present?
end

.register(id, &block) ⇒ Object

Plugin constructor



65
66
67
68
69
70
71
72
73
74
# File 'lib/redmine/plugin.rb', line 65

def self.register(id, &block)
  p = new(id)
  p.instance_eval(&block)
  # Set a default name if it was not provided during registration
  p.name(id.to_s.humanize) if p.name.nil?
  # Adds plugin locales if any
  # YAML translation files should be found under <plugin>/config/locales/
  ::I18n.load_path += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
  registered_plugins[id] = p
end

Instance Method Details

#<=>(plugin) ⇒ Object



104
105
106
# File 'lib/redmine/plugin.rb', line 104

def <=>(plugin)
  self.id.to_s <=> plugin.id.to_s
end

#activity_provider(*args) ⇒ Object

Registers an activity provider.

Options:

  • :class_name - one or more model(s) that provide these events (inferred from event_type by default)

  • :default - setting this option to false will make the events not displayed by default

A model can provide several activity event types.

Examples:

register :news
register :scrums, :class_name => 'Meeting'
register :issues, :class_name => ['Issue', 'Journal']

Retrieving events: Associated model(s) must implement the find_events class method. ActiveRecord models can use acts_as_activity_provider as a way to implement this class method.

The following call should return all the scrum events visible by current user that occured in the 5 last days:

Meeting.find_events('scrums', User.current, 5.days.ago, Date.today)
Meeting.find_events('scrums', User.current, 5.days.ago, Date.today, :project => foo) # events for project foo only

Note that :view_scrums permission is required to view these events in the activity view.



259
260
261
# File 'lib/redmine/plugin.rb', line 259

def activity_provider(*args)
  Redmine::Activity.register(*args)
end

#configurable?Boolean

Returns true if the plugin can be configured.

Returns:

  • (Boolean)


274
275
276
# File 'lib/redmine/plugin.rb', line 274

def configurable?
  settings && settings.is_a?(Hash) && !settings[:partial].blank?
end

#delete_menu_item(menu, item) ⇒ Object

Removes item from the given menu.



190
191
192
# File 'lib/redmine/plugin.rb', line 190

def delete_menu_item(menu, item)
  Redmine::MenuManager.map(menu).delete(item)
end

Adds an item to the given menu. The id parameter (equals to the project id) is automatically added to the url.

menu :project_menu, :plugin_example, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'

name parameter can be: :top_menu, :account_menu, :application_menu or :project_menu



184
185
186
# File 'lib/redmine/plugin.rb', line 184

def menu(menu, item, url, options={})
  Redmine::MenuManager.map(menu).push(item, url, options)
end

#permission(name, actions, options = {}) ⇒ Object

Defines a permission called name for the given actions.

The actions argument is a hash with controllers as keys and actions as values (a single value or an array):

permission :destroy_contacts, { :contacts => :destroy }
permission :view_contacts, { :contacts => [:index, :show] }

The options argument can be used to make the permission public (implicitly given to any user) or to restrict users the permission can be given to.

Examples

# A permission that is implicitly given to any user
# This permission won't appear on the Roles & Permissions setup screen
permission :say_hello, { :example => :say_hello }, :public => true

# A permission that can be given to any user
permission :say_hello, { :example => :say_hello }

# A permission that can be given to registered users only
permission :say_hello, { :example => :say_hello }, :require => :loggedin

# A permission that can be given to project members only
permission :say_hello, { :example => :say_hello }, :require => :member


216
217
218
219
220
221
222
# File 'lib/redmine/plugin.rb', line 216

def permission(name, actions, options = {})
  if @project_module
    Redmine::AccessControl.map {|map| map.project_module(@project_module) {|map|map.permission(name, actions, options)}}
  else
    Redmine::AccessControl.map {|map| map.permission(name, actions, options)}
  end
end

#project_module(name, &block) ⇒ Object

Defines a project module, that can be enabled/disabled for each project. Permissions defined inside block will be bind to the module.

project_module :things do
  permission :view_contacts, { :contacts => [:list, :show] }, :public => true
  permission :destroy_contacts, { :contacts => :destroy }
end


231
232
233
234
235
# File 'lib/redmine/plugin.rb', line 231

def project_module(name, &block)
  @project_module = name
  self.instance_eval(&block)
  @project_module = nil
end

#requires_redmine(arg) ⇒ Object

Sets a requirement on Redmine version Raises a PluginRequirementError exception if the requirement is not met

Examples

# Requires Redmine 0.7.3 or higher
requires_redmine :version_or_higher => '0.7.3'
requires_redmine '0.7.3'

# Requires a specific Redmine version
requires_redmine :version => '0.7.3'              # 0.7.3 only
requires_redmine :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/redmine/plugin.rb', line 119

def requires_redmine(arg)
  arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
  arg.assert_valid_keys(:version, :version_or_higher)
  
  current = Redmine::VERSION.to_a
  arg.each do |k, v|
    v = [] << v unless v.is_a?(Array)
    versions = v.collect {|s| s.split('.').collect(&:to_i)}
    case k
    when :version_or_higher
      raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
      unless (current <=> versions.first) >= 0
        raise PluginRequirementError.new("#{id} plugin requires Redmine #{v} or higher but current is #{current.join('.')}")
      end
    when :version
      unless versions.include?(current.slice(0,3))
        raise PluginRequirementError.new("#{id} plugin requires one the following Redmine versions: #{v.join(', ')} but current is #{current.join('.')}")
      end
    end
  end
  true
end

#requires_redmine_plugin(plugin_name, arg) ⇒ Object

Sets a requirement on a Redmine plugin version Raises a PluginRequirementError exception if the requirement is not met

Examples

# Requires a plugin named :foo version 0.7.3 or higher
requires_redmine_plugin :foo, :version_or_higher => '0.7.3'
requires_redmine_plugin :foo, '0.7.3'

# Requires a specific version of a Redmine plugin
requires_redmine_plugin :foo, :version => '0.7.3'              # 0.7.3 only
requires_redmine_plugin :foo, :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/redmine/plugin.rb', line 153

def requires_redmine_plugin(plugin_name, arg)
  arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
  arg.assert_valid_keys(:version, :version_or_higher)

  plugin = Plugin.find(plugin_name)
  current = plugin.version.split('.').collect(&:to_i)

  arg.each do |k, v|
    v = [] << v unless v.is_a?(Array)
    versions = v.collect {|s| s.split('.').collect(&:to_i)}
    case k
    when :version_or_higher
      raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
      unless (current <=> versions.first) >= 0
        raise PluginRequirementError.new("#{id} plugin requires the #{plugin_name} plugin #{v} or higher but current is #{current.join('.')}")
      end
    when :version
      unless versions.include?(current.slice(0,3))
        raise PluginRequirementError.new("#{id} plugin requires one the following versions of #{plugin_name}: #{v.join(', ')} but current is #{current.join('.')}")
      end
    end
  end
  true
end

#wiki_format_provider(name, formatter, helper) ⇒ Object

Registers a wiki formatter.

Parameters:

  • name - human-readable name

  • formatter - formatter class, which should have an instance method to_html

  • helper - helper module, which will be included by wiki pages



269
270
271
# File 'lib/redmine/plugin.rb', line 269

def wiki_format_provider(name, formatter, helper)
  Redmine::WikiFormatting.register(name, formatter, helper)
end