To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / lib / redmine / hook.rb @ 1298:4f746d8966dd
History | View | Annotate | Download (5.59 KB)
| 1 | 0:513646585e45 | Chris | # Redmine - project management software
|
|---|---|---|---|
| 2 | 1295:622f24f53b42 | Chris | # Copyright (C) 2006-2013 Jean-Philippe Lang
|
| 3 | 0:513646585e45 | Chris | #
|
| 4 | # This program is free software; you can redistribute it and/or
|
||
| 5 | # modify it under the terms of the GNU General Public License
|
||
| 6 | # as published by the Free Software Foundation; either version 2
|
||
| 7 | # of the License, or (at your option) any later version.
|
||
| 8 | 909:cbb26bc654de | Chris | #
|
| 9 | 0:513646585e45 | Chris | # This program is distributed in the hope that it will be useful,
|
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
| 12 | # GNU General Public License for more details.
|
||
| 13 | 909:cbb26bc654de | Chris | #
|
| 14 | 0:513646585e45 | Chris | # You should have received a copy of the GNU General Public License
|
| 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.
|
||
| 17 | |||
| 18 | module Redmine |
||
| 19 | module Hook |
||
| 20 | @@listener_classes = []
|
||
| 21 | @@listeners = nil |
||
| 22 | @@hook_listeners = {}
|
||
| 23 | 909:cbb26bc654de | Chris | |
| 24 | 0:513646585e45 | Chris | class << self |
| 25 | # Adds a listener class.
|
||
| 26 | # Automatically called when a class inherits from Redmine::Hook::Listener.
|
||
| 27 | def add_listener(klass) |
||
| 28 | raise "Hooks must include Singleton module." unless klass.included_modules.include?(Singleton) |
||
| 29 | @@listener_classes << klass
|
||
| 30 | clear_listeners_instances |
||
| 31 | end
|
||
| 32 | 909:cbb26bc654de | Chris | |
| 33 | 0:513646585e45 | Chris | # Returns all the listerners instances.
|
| 34 | def listeners |
||
| 35 | @@listeners ||= @@listener_classes.collect {|listener| listener.instance} |
||
| 36 | end
|
||
| 37 | 909:cbb26bc654de | Chris | |
| 38 | 0:513646585e45 | Chris | # Returns the listeners instances for the given hook.
|
| 39 | def hook_listeners(hook) |
||
| 40 | @@hook_listeners[hook] ||= listeners.select {|listener| listener.respond_to?(hook)}
|
||
| 41 | end
|
||
| 42 | 909:cbb26bc654de | Chris | |
| 43 | 0:513646585e45 | Chris | # Clears all the listeners.
|
| 44 | def clear_listeners |
||
| 45 | @@listener_classes = []
|
||
| 46 | clear_listeners_instances |
||
| 47 | end
|
||
| 48 | 909:cbb26bc654de | Chris | |
| 49 | 0:513646585e45 | Chris | # Clears all the listeners instances.
|
| 50 | def clear_listeners_instances |
||
| 51 | @@listeners = nil |
||
| 52 | @@hook_listeners = {}
|
||
| 53 | end
|
||
| 54 | 909:cbb26bc654de | Chris | |
| 55 | 0:513646585e45 | Chris | # Calls a hook.
|
| 56 | # Returns the listeners response.
|
||
| 57 | def call_hook(hook, context={}) |
||
| 58 | 37:94944d00e43c | chris | [].tap do |response|
|
| 59 | 0:513646585e45 | Chris | hls = hook_listeners(hook) |
| 60 | if hls.any?
|
||
| 61 | hls.each {|listener| response << listener.send(hook, context)}
|
||
| 62 | end
|
||
| 63 | end
|
||
| 64 | end
|
||
| 65 | end
|
||
| 66 | |||
| 67 | # Base class for hook listeners.
|
||
| 68 | class Listener |
||
| 69 | include Singleton
|
||
| 70 | include Redmine::I18n |
||
| 71 | |||
| 72 | # Registers the listener
|
||
| 73 | def self.inherited(child) |
||
| 74 | Redmine::Hook.add_listener(child) |
||
| 75 | super
|
||
| 76 | end
|
||
| 77 | |||
| 78 | end
|
||
| 79 | |||
| 80 | # Listener class used for views hooks.
|
||
| 81 | # Listeners that inherit this class will include various helpers by default.
|
||
| 82 | class ViewListener < Listener |
||
| 83 | include ERB::Util |
||
| 84 | include ActionView::Helpers::TagHelper |
||
| 85 | include ActionView::Helpers::FormHelper |
||
| 86 | include ActionView::Helpers::FormTagHelper |
||
| 87 | include ActionView::Helpers::FormOptionsHelper |
||
| 88 | include ActionView::Helpers::JavaScriptHelper |
||
| 89 | include ActionView::Helpers::NumberHelper |
||
| 90 | include ActionView::Helpers::UrlHelper |
||
| 91 | include ActionView::Helpers::AssetTagHelper |
||
| 92 | include ActionView::Helpers::TextHelper |
||
| 93 | 1115:433d4f72a19b | Chris | include Rails.application.routes.url_helpers
|
| 94 | 0:513646585e45 | Chris | include ApplicationHelper
|
| 95 | |||
| 96 | # Default to creating links using only the path. Subclasses can
|
||
| 97 | # change this default as needed
|
||
| 98 | def self.default_url_options |
||
| 99 | {:only_path => true }
|
||
| 100 | end
|
||
| 101 | 909:cbb26bc654de | Chris | |
| 102 | 0:513646585e45 | Chris | # Helper method to directly render a partial using the context:
|
| 103 | 909:cbb26bc654de | Chris | #
|
| 104 | 0:513646585e45 | Chris | # class MyHook < Redmine::Hook::ViewListener
|
| 105 | 909:cbb26bc654de | Chris | # render_on :view_issues_show_details_bottom, :partial => "show_more_data"
|
| 106 | 0:513646585e45 | Chris | # end
|
| 107 | #
|
||
| 108 | def self.render_on(hook, options={}) |
||
| 109 | define_method hook do |context|
|
||
| 110 | 1115:433d4f72a19b | Chris | if context[:hook_caller].respond_to?(:render) |
| 111 | context[:hook_caller].send(:render, {:locals => context}.merge(options)) |
||
| 112 | elsif context[:controller].is_a?(ActionController::Base) |
||
| 113 | context[:controller].send(:render_to_string, {:locals => context}.merge(options)) |
||
| 114 | else
|
||
| 115 | raise "Cannot render #{self.name} hook from #{context[:hook_caller].class.name}"
|
||
| 116 | end
|
||
| 117 | 0:513646585e45 | Chris | end
|
| 118 | end
|
||
| 119 | 1115:433d4f72a19b | Chris | |
| 120 | def controller |
||
| 121 | nil
|
||
| 122 | end
|
||
| 123 | |||
| 124 | def config |
||
| 125 | ActionController::Base.config |
||
| 126 | end
|
||
| 127 | 0:513646585e45 | Chris | end
|
| 128 | |||
| 129 | 909:cbb26bc654de | Chris | # Helper module included in ApplicationHelper and ActionController so that
|
| 130 | 0:513646585e45 | Chris | # hooks can be called in views like this:
|
| 131 | 909:cbb26bc654de | Chris | #
|
| 132 | 0:513646585e45 | Chris | # <%= call_hook(:some_hook) %>
|
| 133 | 909:cbb26bc654de | Chris | # <%= call_hook(:another_hook, :foo => 'bar') %>
|
| 134 | #
|
||
| 135 | 0:513646585e45 | Chris | # Or in controllers like:
|
| 136 | # call_hook(:some_hook)
|
||
| 137 | 909:cbb26bc654de | Chris | # call_hook(:another_hook, :foo => 'bar')
|
| 138 | #
|
||
| 139 | # Hooks added to views will be concatenated into a string. Hooks added to
|
||
| 140 | 0:513646585e45 | Chris | # controllers will return an array of results.
|
| 141 | #
|
||
| 142 | # Several objects are automatically added to the call context:
|
||
| 143 | 909:cbb26bc654de | Chris | #
|
| 144 | 0:513646585e45 | Chris | # * project => current project
|
| 145 | # * request => Request instance
|
||
| 146 | # * controller => current Controller instance
|
||
| 147 | 1115:433d4f72a19b | Chris | # * hook_caller => object that called the hook
|
| 148 | 909:cbb26bc654de | Chris | #
|
| 149 | 0:513646585e45 | Chris | module Helper |
| 150 | def call_hook(hook, context={}) |
||
| 151 | if is_a?(ActionController::Base) |
||
| 152 | 1115:433d4f72a19b | Chris | default_context = {:controller => self, :project => @project, :request => request, :hook_caller => self}
|
| 153 | 0:513646585e45 | Chris | Redmine::Hook.call_hook(hook, default_context.merge(context)) |
| 154 | else
|
||
| 155 | 1115:433d4f72a19b | Chris | default_context = { :project => @project, :hook_caller => self }
|
| 156 | default_context[:controller] = controller if respond_to?(:controller) |
||
| 157 | default_context[:request] = request if respond_to?(:request) |
||
| 158 | Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe |
||
| 159 | 909:cbb26bc654de | Chris | end
|
| 160 | 0:513646585e45 | Chris | end
|
| 161 | end
|
||
| 162 | end
|
||
| 163 | end
|
||
| 164 | |||
| 165 | ApplicationHelper.send(:include, Redmine::Hook::Helper) |
||
| 166 | ActionController::Base.send(:include, Redmine::Hook::Helper) |