Compare commits
17 Commits
0.8.0
...
plugin-hoo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99ea01ec93 | ||
|
|
e87140a719 | ||
|
|
ca8fb4026e | ||
|
|
e14b86453e | ||
|
|
cb485c92ef | ||
|
|
e7309d8c57 | ||
|
|
d6808130dc | ||
|
|
c5242b4386 | ||
|
|
6615002df2 | ||
|
|
08058e6a02 | ||
|
|
8995245a0c | ||
|
|
04434cd6ef | ||
|
|
fe22ef95a8 | ||
|
|
355143ca18 | ||
|
|
5e1bcc6b24 | ||
|
|
00659ab8c5 | ||
|
|
404e6164cb |
@@ -223,7 +223,6 @@ class IssuesController < ApplicationController
|
||||
assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
|
||||
category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
|
||||
fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
|
||||
|
||||
unsaved_issue_ids = []
|
||||
@issues.each do |issue|
|
||||
journal = issue.init_journal(User.current, params[:notes])
|
||||
@@ -234,6 +233,9 @@ class IssuesController < ApplicationController
|
||||
issue.start_date = params[:start_date] unless params[:start_date].blank?
|
||||
issue.due_date = params[:due_date] unless params[:due_date].blank?
|
||||
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
|
||||
|
||||
Redmine::Plugin::Hook::Manager.call_hook(:issue_bulk_edit_save, {:params => params, :issue => issue })
|
||||
|
||||
# Don't save any change to the issue if the user is not authorized to apply the requested status
|
||||
if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
|
||||
# Send notification for each issue (if changed)
|
||||
|
||||
@@ -86,7 +86,9 @@ module IssuesHelper
|
||||
when 'attachment'
|
||||
label = l(:label_attachment)
|
||||
end
|
||||
|
||||
|
||||
Redmine::Plugin::Hook::Manager.call_hook(:issues_helper_show_details, {:detail => detail, :label => label, :value => value, :old_value => old_value })
|
||||
|
||||
label ||= detail.prop_key
|
||||
value ||= detail.value
|
||||
old_value ||= detail.old_value
|
||||
|
||||
@@ -48,4 +48,6 @@
|
||||
<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
|
||||
<% end %>
|
||||
|
||||
<%= Redmine::Plugin::Hook::Manager.call_hook(:issue_edit, {:project => @project, :issue => @issue, :form => f }) %>
|
||||
|
||||
<%= wikitoolbar_for 'issue_description' %>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<label><%= l(:field_done_ratio) %>:
|
||||
<%= select_tag 'done_ratio', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></label>
|
||||
</p>
|
||||
<%= Redmine::Plugin::Hook::Manager.call_hook(:issue_bulk_edit, {:project => @project, :issue => @issues }) %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset><legend><%= l(:field_notes) %></legend>
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
<%end
|
||||
end %>
|
||||
</tr>
|
||||
<%= Redmine::Plugin::Hook::Manager.call_hook(:issue_show, {:project => @project, :issue => @issue}) %>
|
||||
|
||||
</table>
|
||||
<hr />
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<thead>
|
||||
<th><%= l(:label_user) %></th>
|
||||
<th><%= l(:label_role) %></th>
|
||||
<%= Redmine::Plugin::Hook::Manager.call_hook(:project_member_list_header, {:project => @project }) %>
|
||||
<th style="width:15%"></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -24,6 +25,8 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
<%= Redmine::Plugin::Hook::Manager.call_hook(:project_member_list_column_three, {:project => @project, :member => member }) %>
|
||||
|
||||
<td align="center">
|
||||
<%= link_to_remote l(:button_delete), { :url => {:controller => 'members', :action => 'destroy', :id => member},
|
||||
:method => :post
|
||||
|
||||
@@ -117,6 +117,18 @@ module Redmine #:nodoc:
|
||||
@project_module = nil
|
||||
end
|
||||
|
||||
# Registers a +method+ to be called when Redmine runs a hook called
|
||||
# +hook_name+
|
||||
#
|
||||
# # Run puts whenever the issue_show hook is called
|
||||
# add_hook :issue_show, Proc.new { puts 'Hello' }
|
||||
#
|
||||
# # Call the class method +my_method+ passing in all the context
|
||||
# add_hook :issue_show, Proc.new {|context| MyPlugin.my_method(context)}
|
||||
def add_hook(hook_name, method)
|
||||
Redmine::Plugin::Hook::Manager.add_listener(hook_name, method)
|
||||
end
|
||||
|
||||
# Registers an activity provider.
|
||||
#
|
||||
# Options:
|
||||
@@ -147,5 +159,92 @@ module Redmine #:nodoc:
|
||||
def configurable?
|
||||
settings && settings.is_a?(Hash) && !settings[:partial].blank?
|
||||
end
|
||||
|
||||
# Hook is used to allow plugins to hook into Redmine at specific sections
|
||||
# to change it's behavior. See +Redmine::Plugin.add_hook+ for details.
|
||||
class Hook
|
||||
class Manager
|
||||
# Hooks and the procs added
|
||||
@@hooks = {
|
||||
:issue_show => [],
|
||||
:issue_edit => [],
|
||||
:issue_bulk_edit => [],
|
||||
:issue_bulk_edit_save => [],
|
||||
:issue_update => [],
|
||||
:project_member_list_header => [],
|
||||
:project_member_list_column_three => [],
|
||||
:issues_helper_show_details => []
|
||||
}
|
||||
|
||||
cattr_reader :hooks
|
||||
|
||||
class << self
|
||||
|
||||
def valid_hook?(hook_name)
|
||||
return @@hooks.has_key?(hook_name)
|
||||
end
|
||||
|
||||
# Add +method+ to +hook_name+
|
||||
def add_listener(hook_name, method)
|
||||
if valid_hook?(hook_name)
|
||||
@@hooks[hook_name.to_sym] << method
|
||||
puts "Listener added for #{hook_name.to_s}"
|
||||
end
|
||||
end
|
||||
|
||||
# Removes all listeners
|
||||
def clear_listeners()
|
||||
@@hooks.each do |hook, registrations|
|
||||
@@hooks[hook] = []
|
||||
end
|
||||
end
|
||||
|
||||
# Run all the hooks for +hook_name+ passing in +context+
|
||||
def call_hook(hook_name, context = { })
|
||||
response = ''
|
||||
@@hooks[hook_name.to_sym].each do |method|
|
||||
method_response = method.call(context)
|
||||
response += method_response unless method_response.nil?
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
# Are hooks registered for +hook_name+
|
||||
def hook_registered?(hook_name)
|
||||
return @@hooks[hook_name.to_sym].size > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Base class for Redmin Plugin hooks.
|
||||
class Base
|
||||
|
||||
# Class level access to Rails' helper methods.
|
||||
def self.help
|
||||
Helper.instance
|
||||
end
|
||||
|
||||
# Includes several Helper methods to be used in the class
|
||||
class Helper # :nodoc:
|
||||
include Singleton
|
||||
include ERB::Util
|
||||
include ActionView::Helpers::TagHelper
|
||||
include ActionView::Helpers::FormHelper
|
||||
include ActionView::Helpers::FormTagHelper
|
||||
include ActionView::Helpers::FormOptionsHelper
|
||||
include ActionView::Helpers::JavaScriptHelper
|
||||
include ActionView::Helpers::PrototypeHelper
|
||||
include ActionView::Helpers::NumberHelper
|
||||
include ActionView::Helpers::UrlHelper
|
||||
|
||||
include ActionController::UrlWriter
|
||||
|
||||
def protect_against_forgery? # :nodoc:
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
128
test/unit/lib/redmine/plugin_hook_test.rb
Normal file
128
test/unit/lib/redmine/plugin_hook_test.rb
Normal file
@@ -0,0 +1,128 @@
|
||||
require File.dirname(__FILE__) + '/../../../test_helper'
|
||||
|
||||
class Redmine::Plugin::Hook::ManagerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@manager = Redmine::Plugin::Hook::Manager
|
||||
end
|
||||
|
||||
def teardown
|
||||
@manager.clear_listeners
|
||||
end
|
||||
|
||||
def test_sanity
|
||||
assert true
|
||||
end
|
||||
|
||||
def test_hook_format
|
||||
assert_kind_of Hash, @manager::hooks
|
||||
@manager::hooks.each do |hook, registrations|
|
||||
assert_kind_of Symbol, hook
|
||||
assert_kind_of Array, registrations
|
||||
assert_equal 0, registrations.length
|
||||
end
|
||||
end
|
||||
|
||||
def test_valid_hook
|
||||
assert @manager::valid_hook?(:issue_show)
|
||||
end
|
||||
|
||||
def test_invalid_hook
|
||||
assert_equal false, @manager::valid_hook?(:an_invalid_hook_name)
|
||||
end
|
||||
|
||||
def test_clear_listeners
|
||||
assert_equal 0, @manager::hooks[:issue_show].length
|
||||
@manager.add_listener(:issue_show, Proc.new { } )
|
||||
@manager.add_listener(:issue_show, Proc.new { } )
|
||||
@manager.add_listener(:issue_show, Proc.new { } )
|
||||
@manager.add_listener(:issue_show, Proc.new { } )
|
||||
assert_equal 4, @manager::hooks[:issue_show].length
|
||||
|
||||
@manager.clear_listeners
|
||||
assert_equal 0, @manager::hooks[:issue_show].length
|
||||
end
|
||||
|
||||
def test_add_listener
|
||||
assert_equal 0, @manager::hooks[:issue_show].length
|
||||
@manager.add_listener(:issue_show, Proc.new { } )
|
||||
assert_equal 1, @manager::hooks[:issue_show].length
|
||||
end
|
||||
|
||||
def test_add_invalid_listener
|
||||
hooks = @manager::hooks
|
||||
@manager.add_listener(:invalid, Proc.new { } )
|
||||
assert_equal hooks, @manager::hooks
|
||||
end
|
||||
|
||||
def test_call_hook_with_response
|
||||
function = Proc.new { return 'response' }
|
||||
|
||||
@manager.add_listener(:issue_show, function)
|
||||
|
||||
assert_equal 'response', @manager.call_hook(:issue_show)
|
||||
end
|
||||
|
||||
def test_call_multiple_hooks_with_response
|
||||
function1 = Proc.new { return 'First Call.' }
|
||||
function2 = Proc.new { return 'Second Call.' }
|
||||
function3 = Proc.new { return 'Third Call.' }
|
||||
|
||||
@manager.add_listener(:issue_show, function1)
|
||||
@manager.add_listener(:issue_show, function2)
|
||||
@manager.add_listener(:issue_show, function3)
|
||||
|
||||
assert_equal 'First Call.Second Call.Third Call.', @manager.call_hook(:issue_show)
|
||||
end
|
||||
|
||||
def test_call_hook_without_response
|
||||
function = Proc.new { }
|
||||
|
||||
@manager.add_listener(:issue_show, function)
|
||||
|
||||
assert_equal '', @manager.call_hook(:issue_show)
|
||||
end
|
||||
|
||||
def test_call_multiple_hooks_without_responses
|
||||
function1 = Proc.new { }
|
||||
function2 = Proc.new { }
|
||||
function3 = Proc.new { }
|
||||
|
||||
@manager.add_listener(:issue_show, function1)
|
||||
@manager.add_listener(:issue_show, function2)
|
||||
@manager.add_listener(:issue_show, function3)
|
||||
|
||||
assert_equal '', @manager.call_hook(:issue_show)
|
||||
end
|
||||
|
||||
def test_hook_registered_yes
|
||||
@manager.add_listener(:issue_show, Proc.new { })
|
||||
assert @manager.hook_registered?(:issue_show)
|
||||
end
|
||||
|
||||
def test_hook_registered_no
|
||||
assert_equal false, @manager.hook_registered?(:issue_show)
|
||||
end
|
||||
end
|
||||
|
||||
class Redmine::Plugin::Hook::BaseTest < Test::Unit::TestCase
|
||||
def test_sanity
|
||||
assert true
|
||||
end
|
||||
|
||||
def test_help_should_be_a_singleton
|
||||
assert Redmine::Plugin::Hook::Base::Helper.include?(Singleton)
|
||||
end
|
||||
|
||||
def test_helper_should_include_actionview_helpers
|
||||
[ActionView::Helpers::TagHelper,
|
||||
ActionView::Helpers::FormHelper,
|
||||
ActionView::Helpers::FormTagHelper,
|
||||
ActionView::Helpers::FormOptionsHelper,
|
||||
ActionView::Helpers::JavaScriptHelper,
|
||||
ActionView::Helpers::PrototypeHelper,
|
||||
ActionView::Helpers::NumberHelper,
|
||||
ActionView::Helpers::UrlHelper].each do |helper|
|
||||
assert Redmine::Plugin::Hook::Base::Helper.include?(helper), "#{helper} wasn't included."
|
||||
end
|
||||
end
|
||||
end
|
||||
20
test/unit/lib/redmine/plugin_test.rb
Normal file
20
test/unit/lib/redmine/plugin_test.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require File.dirname(__FILE__) + '/../../../test_helper'
|
||||
|
||||
class Redmine::PluginTest < Test::Unit::TestCase
|
||||
def test_sanity
|
||||
assert true
|
||||
end
|
||||
|
||||
def test_add_hook
|
||||
assert_equal false, Redmine::Plugin::Hook::Manager.hook_registered?(:issue_show)
|
||||
Redmine::Plugin.add_hook(:issue_show, Proc.new { })
|
||||
assert Redmine::Plugin::Hook::Manager.hook_registered?(:issue_show)
|
||||
end
|
||||
|
||||
def test_add_hook_invalid
|
||||
assert_equal false, Redmine::Plugin::Hook::Manager.hook_registered?(:invalid)
|
||||
Redmine::Plugin.add_hook(:invalid, Proc.new { })
|
||||
assert Redmine::Plugin::Hook::Manager.hook_registered?(:invalid)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user