cirandas.net

ref: master

lib/noosfero/plugin/manager.rb


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class Noosfero::Plugin::Manager

  attr_reader :environment
  attr_reader :context

  def initialize(environment, context)
    @environment = environment
    @context = context
  end

  delegate :each, :to => :enabled_plugins
  include Enumerable

  # Dispatches +event+ to each enabled plugin and collect the results.
  #
  # Returns an Array containing the objects returned by the event method in
  # each plugin. This array is compacted (i.e. nils are removed) and flattened
  # (i.e. elements of arrays are added to the resulting array). For example, if
  # the enabled plugins return 1, 0, nil, and [1,2,3], then this method will
  # return [1,0,1,2,3]
  #
  def dispatch(event, *args)
    dispatch_without_flatten(event, *args).flatten
  end

  def fetch_plugins(event, *args)
    map { |plugin| plugin.class if plugin.send(event, *args) }.compact.flatten
  end

  def dispatch_without_flatten(event, *args)
    map { |plugin| plugin.send(event, *args) }.compact
  end

  alias :dispatch_scopes :dispatch_without_flatten

  def dispatch_first(event, *args)
    each do |plugin|
      method = plugin.method event
      next unless method.owner == plugin.class
      return method.call(*args)
    end
    Noosfero::Plugin.new.send event, *args
  end

  def fetch_first_plugin(event, *args)
    default = Noosfero::Plugin.new.send event, *args
    each do |plugin|
      method = plugin.method event
      next unless method.owner == plugin.class
      next unless method.call(*args) != default
      return plugin.class
    end
    nil
  end

  def pipeline(event, *args)
    each do |plugin|
      result = Array(plugin.send event, *args)
      result = result.kind_of?(Array) ? result : [result]
      raise ArgumentError, "Pipeline broken by #{plugin.class.name} on #{event} with #{result.length} arguments instead of #{args.length}." if result.length != args.length
      args = result
    end
    args.length < 2 ? args.first : args
  end

  def filter(property, data)
    inject(data) {|data, plugin| data = plugin.send(property, data)}
  end

  def parse_macro(macro_name, macro, source = nil)
    macro_instance = enabled_macros[macro_name] || default_macro
    macro_instance.convert(macro, source)
  end

  def enabled_plugins
    environment_enabled_plugins = environment.present? ? environment.enabled_plugins : []
    @enabled_plugins ||= (Noosfero::Plugin.all & environment_enabled_plugins).map do |plugin|
      Noosfero::Plugin.load_plugin_identifier(plugin).new context
    end
  end

  def default_macro
    @default_macro ||= Noosfero::Plugin::Macro.new(context)
  end

  def enabled_macros
    @enabled_macros ||= dispatch(:macros).inject({}) do |memo, macro|
      memo.merge!(macro.identifier => macro.new(context))
    end
  end

  def [](class_name)
    enabled_plugins.select do |plugin|
      plugin.kind_of?(class_name.constantize)
    end.first
  end

end