Commit 068f8f46bed55116269265d295b46af64afedd1d

Authored by Rodrigo Souto
2 parents dd7e39a5 3ca0b153

Merge branch 'dynamic-callbacks' into 'master'

plugin-hotspot: dinamic hotspot for models callbacks

With this, every model that includes Noosfero::Plugin::HotSpot will
provide callbacks hotspots for plugins to answer. The current callbacks
included are {after,before}_{create,destroy,save}.

So if a plugin wants to do something on a comment after_save, it should
define a hotspot somewhat like this:

  def comment_after_save_callback(comment)
    <code-goes-here>
  end

Obviously, the callback provides the object in context as parameter.

This will replace the problematic common practice of creating a
lib/ext/my_model.rb and injecting the callbacks inside the class which
bypass the enabled plugins logic.

Signed-off-by: Rodrigo Souto <rodrigo@colivre.coop.br>
Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>

See merge request !810
lib/noosfero/plugin.rb
... ... @@ -707,6 +707,10 @@ class Noosfero::Plugin
707 707 # returns = string with reason of expiration
708 708 elsif method.to_s =~ /^content_expire_(#{content_actions.join('|')})$/
709 709 nil
  710 + # -> Generic hotspots for models callbacks
  711 + # Example: article_after_create_callback
  712 + elsif method.to_s =~ /^(.+)_#{Noosfero::Plugin::HotSpot::CALLBACK_HOTSPOTS.join('|')}_callback$/
  713 + nil
710 714 elsif context.respond_to?(method)
711 715 context.send(method)
712 716 else
... ...
lib/noosfero/plugin/hot_spot.rb
... ... @@ -6,6 +6,7 @@
6 6 # Environment will be used to determine which plugins are enabled and therefore
7 7 # which plugins should be instantiated.
8 8 module Noosfero::Plugin::HotSpot
  9 + CALLBACK_HOTSPOTS =[:after_save, :after_destroy, :before_save, :before_destroy, :after_create, :before_create]
9 10  
10 11 # Returns an instance of Noosfero::Plugin::Manager.
11 12 #
... ... @@ -15,4 +16,26 @@ module Noosfero::Plugin::HotSpot
15 16 @plugins ||= Noosfero::Plugin::Manager.new(environment, self)
16 17 end
17 18  
  19 + def self.included(klass)
  20 + klass.extend(ClassMethods)
  21 + end
  22 +
  23 + module ClassMethods
  24 + def self.extended base
  25 + CALLBACK_HOTSPOTS.each do |callback|
  26 + if base.respond_to?(callback)
  27 + base.class_eval do
  28 + self.send callback do |object|
  29 + current=self.class
  30 + while current.included_modules.include? Noosfero::Plugin::HotSpot do
  31 + callback_name = "#{current.name.underscore}_#{callback}_callback"
  32 + plugins.dispatch(callback_name, object)
  33 + current=current.superclass
  34 + end
  35 + end
  36 + end
  37 + end
  38 + end
  39 + end
  40 + end
18 41 end
... ...
lib/noosfero/plugin/manager.rb
... ... @@ -75,7 +75,8 @@ class Noosfero::Plugin::Manager
75 75 end
76 76  
77 77 def enabled_plugins
78   - @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin|
  78 + environment_enabled_plugins = environment.present? ? environment.enabled_plugins : []
  79 + @enabled_plugins ||= (Noosfero::Plugin.all & environment_enabled_plugins).map do |plugin|
79 80 Noosfero::Plugin.load_plugin_identifier(plugin).new context
80 81 end
81 82 end
... ...
test/unit/plugin_hot_spot_test.rb
... ... @@ -15,4 +15,19 @@ class PluginHotSpotTest &lt; ActiveSupport::TestCase
15 15 assert_same @client.plugins, @client.plugins
16 16 end
17 17  
  18 + Noosfero::Plugin::HotSpot::CALLBACK_HOTSPOTS.each do |callback|
  19 + should "call #{callback} hotspot" do
  20 + class CoolPlugin < Noosfero::Plugin; end
  21 +
  22 + Noosfero::Plugin.stubs(:all).returns([CoolPlugin.name])
  23 + Environment.default.enable_plugin(CoolPlugin)
  24 + CoolPlugin.any_instance.expects("comment_#{callback}_callback".to_sym)
  25 +
  26 + person = fast_create(Person)
  27 + article = fast_create(Article, :profile_id => person.id)
  28 + comment = Comment.create!(:author => person, :title => 'test comment', :body => 'body!', :source => article)
  29 + comment.destroy
  30 + end
  31 + end
  32 +
18 33 end
... ...
vendor/plugins/action_tracker/lib/action_tracker_model.rb
... ... @@ -7,6 +7,8 @@ module ActionTracker
7 7 belongs_to :user, :polymorphic => true
8 8 belongs_to :target, :polymorphic => true
9 9  
  10 + alias :profile :user
  11 +
10 12 serialize :params, Hash
11 13  
12 14 before_validation :stringify_verb
... ...