diff --git a/app/models/post.rb b/app/models/post.rb index 30afdb38fdb..7828a01b899 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -6,6 +6,7 @@ require_dependency 'enum' require_dependency 'trashable' require_dependency 'post_analyzer' require_dependency 'validators/post_validator' +require_dependency 'plugin/filter' require 'archetype' require 'digest/sha1' @@ -108,7 +109,7 @@ class Post < ActiveRecord::Base end def cook(*args) - post_analyzer.cook(*args) + Plugin::Filter.apply(:after_post_cook, self, post_analyzer.cook(*args)) end diff --git a/lib/plugin/filter.rb b/lib/plugin/filter.rb new file mode 100644 index 00000000000..771de6e95a1 --- /dev/null +++ b/lib/plugin/filter.rb @@ -0,0 +1,18 @@ +require_dependency 'plugin/filter_manager' +# this concept is borrowed straight out of wordpress +module Plugin + class Filter + def self.manager + @manager ||= FilterManager.new + end + + def self.register(name, &blk) + manager.register(name, &blk) + end + + def self.apply(name, context, result) + manager.apply(name, context, result) + end + + end +end diff --git a/lib/plugin/filter_manager.rb b/lib/plugin/filter_manager.rb new file mode 100644 index 00000000000..10da578bd9c --- /dev/null +++ b/lib/plugin/filter_manager.rb @@ -0,0 +1,23 @@ +module Plugin + class FilterManager + + def initialize + @map = {} + end + + def register(name, &blk) + raise ArgumentException unless blk && blk.arity == 2 + filters = @map[name] ||= [] + filters << blk + end + + def apply(name, context, result) + if filters = @map[name] + filters.each do |blk| + result = blk.call(context, result) + end + end + result + end + end +end diff --git a/spec/components/plugin/filter_manager_spec.rb b/spec/components/plugin/filter_manager_spec.rb new file mode 100644 index 00000000000..ac0c9610c3a --- /dev/null +++ b/spec/components/plugin/filter_manager_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' +require_dependency 'plugin/filter_manager' + +describe Plugin::FilterManager do + let(:instance){ Plugin::FilterManager.new } + + it "calls registered filters correctly" do + instance.register(:added_numbers) do |context,result| + context + result + 1 + end + + instance.register(:added_numbers) do |context,result| + context + result + 2 + end + + instance.apply(:added_numbers, 1, 0).should == 5 + end + + it "should raise an exception if wrong arity is passed in" do + lambda do + instance.register(:test) do + end + end.should raise_exception + end + + it "should return the original if no filters exist" do + instance.apply(:foo, nil, 42).should == 42 + end + + it "should raise an exception if no block is passed in" do + lambda do + instance.register(:test) + end.should raise_exception + end +end