From 06c13aaeed3d5f0ef85ab45b87c084aa43bb49b7 Mon Sep 17 00:00:00 2001 From: Rodrigo Souto Date: Thu, 5 Jul 2012 17:11:05 -0300 Subject: [PATCH] Modularizing the hotspot feature --- app/controllers/application_controller.rb | 4 ++-- config/initializers/plugins.rb | 1 + lib/noosfero/plugin/acts_as_having_hotspots.rb | 44 ++++++++++++++++++++++++++++++++++++++++++++ lib/noosfero/plugin/context.rb | 2 +- lib/noosfero/plugin/manager.rb | 31 ++++++++++--------------------- test/unit/person_test.rb | 4 ++++ test/unit/plugin_manager_test.rb | 4 ++-- test/unit/profile_test.rb | 4 ++++ 8 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 lib/noosfero/plugin/acts_as_having_hotspots.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1f30fc1..db8abb9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,8 @@ class ApplicationController < ActionController::Base before_filter :change_pg_schema + before_filter :detect_stuff_by_domain + before_filter :init_noosfero_plugins include ApplicationHelper layout :get_layout @@ -51,8 +53,6 @@ class ApplicationController < ActionController::Base include NeedsProfile - before_filter :detect_stuff_by_domain - before_filter :init_noosfero_plugins attr_reader :environment before_filter :load_terminology diff --git a/config/initializers/plugins.rb b/config/initializers/plugins.rb index b579332..a7fd78a 100644 --- a/config/initializers/plugins.rb +++ b/config/initializers/plugins.rb @@ -1,4 +1,5 @@ require 'noosfero/plugin' +require 'noosfero/plugin/acts_as_having_hotspots' require 'noosfero/plugin/manager' require 'noosfero/plugin/context' require 'noosfero/plugin/active_record' diff --git a/lib/noosfero/plugin/acts_as_having_hotspots.rb b/lib/noosfero/plugin/acts_as_having_hotspots.rb new file mode 100644 index 0000000..c766a81 --- /dev/null +++ b/lib/noosfero/plugin/acts_as_having_hotspots.rb @@ -0,0 +1,44 @@ +module ActsAsHavingHotspots + module ClassMethods + # Adding this feature to a class demands that it defines an instance method + # 'environment' that returns the environment associated with the instance. + def acts_as_having_hotspots + send :include, InstanceMethods + end + + module InstanceMethods + # 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) + enabled_plugins.map { |plugin| plugin.send(event, *args) }.compact.flatten + end + + # Dispatch without flatten since scopes are executed if you run flatten on them + def dispatch_scopes(event, *args) + enabled_plugins.map { |plugin| plugin.send(event, *args) }.compact + end + + def enabled_plugins + Thread.current[:enabled_plugins] ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin_name| + plugin = plugin_name.constantize.new + plugin.context = context + plugin + end + end + + if !method_defined?(:context) + define_method(:context) do + Noosfero::Plugin::Context.new + end + end + end + end +end + +ActiveRecord::Base.send(:extend, ActsAsHavingHotspots::ClassMethods) diff --git a/lib/noosfero/plugin/context.rb b/lib/noosfero/plugin/context.rb index f340f79..54ebd24 100644 --- a/lib/noosfero/plugin/context.rb +++ b/lib/noosfero/plugin/context.rb @@ -2,7 +2,7 @@ # controller that can be accessed by plugins class Noosfero::Plugin::Context - def initialize(controller) + def initialize(controller = ApplicationController.new) @controller = controller end diff --git a/lib/noosfero/plugin/manager.rb b/lib/noosfero/plugin/manager.rb index f49369c..5bec6ac 100644 --- a/lib/noosfero/plugin/manager.rb +++ b/lib/noosfero/plugin/manager.rb @@ -1,31 +1,20 @@ class Noosfero::Plugin::Manager - attr_reader :context + extend ActsAsHavingHotspots::ClassMethods + acts_as_having_hotspots - def initialize(controller) - @context = Noosfero::Plugin::Context.new(controller) - end + attr_reader :context + delegate :environment, :to => :context 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) - map { |plugin| plugin.send(event, *args) }.compact.flatten - end - - def enabled_plugins - @enabled_plugins ||= (Noosfero::Plugin.all & context.environment.enabled_plugins).map do |plugin| - p = plugin.constantize.new - p.context = context - p + def initialize(controller) + @context = Noosfero::Plugin::Context.new(controller) + Thread.current[:enabled_plugins] = (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin_name| + plugin = plugin_name.constantize.new + plugin.context = context + plugin end end diff --git a/test/unit/person_test.rb b/test/unit/person_test.rb index e1f3368..c203f35 100644 --- a/test/unit/person_test.rb +++ b/test/unit/person_test.rb @@ -3,6 +3,10 @@ require File.dirname(__FILE__) + '/../test_helper' class PersonTest < ActiveSupport::TestCase fixtures :profiles, :users, :environments + def teardown + Thread.current[:enabled_plugins] = nil + end + def test_person_must_come_form_the_cration_of_an_user p = Person.new(:environment => Environment.default, :name => 'John', :identifier => 'john') assert !p.valid? diff --git a/test/unit/plugin_manager_test.rb b/test/unit/plugin_manager_test.rb index a984dba..ac96a9b 100644 --- a/test/unit/plugin_manager_test.rb +++ b/test/unit/plugin_manager_test.rb @@ -10,10 +10,8 @@ class PluginManagerTest < ActiveSupport::TestCase @controller.stubs(:response).returns() @controller.stubs(:environment).returns(@environment) @controller.stubs(:params).returns() - @manager = Noosfero::Plugin::Manager.new(@controller) end attr_reader :environment - attr_reader :manager should 'return the intersection between environment\'s enabled plugins and system available plugins' do class Plugin1 < Noosfero::Plugin; end; @@ -22,6 +20,7 @@ class PluginManagerTest < ActiveSupport::TestCase class Plugin4 < Noosfero::Plugin; end; environment.stubs(:enabled_plugins).returns([Plugin1.to_s, Plugin2.to_s, Plugin4.to_s]) Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin3.to_s, Plugin4.to_s]) + manager = Noosfero::Plugin::Manager.new(@controller) plugins = manager.enabled_plugins.map { |instance| instance.class.to_s } assert_equal [Plugin1.to_s, Plugin4.to_s], plugins end @@ -50,6 +49,7 @@ class PluginManagerTest < ActiveSupport::TestCase p1 = Plugin1.new p2 = Plugin2.new + manager = Noosfero::Plugin::Manager.new(@controller) assert_equal [p1.random_event, p2.random_event], manager.dispatch(:random_event) end diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb index 454aeb4..d53b2fc 100644 --- a/test/unit/profile_test.rb +++ b/test/unit/profile_test.rb @@ -3,6 +3,10 @@ require File.dirname(__FILE__) + '/../test_helper' class ProfileTest < ActiveSupport::TestCase fixtures :profiles, :environments, :users, :roles, :domains + def teardown + Thread.current[:enabled_plugins] = nil + end + def test_identifier_validation p = Profile.new p.valid? -- libgit2 0.21.2