From 418c3f801cd436f011b37fe69059073e69e05084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 21 Oct 2009 21:05:55 -0200 Subject: Another refactoring on AM. body is deprecated, use render instead. --- actionmailer/lib/action_mailer.rb | 1 + actionmailer/lib/action_mailer/base.rb | 152 ++++++---------------- actionmailer/lib/action_mailer/deprecated_body.rb | 44 +++++++ actionmailer/test/mail_service_test.rb | 8 +- 4 files changed, 90 insertions(+), 115 deletions(-) create mode 100644 actionmailer/lib/action_mailer/deprecated_body.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 8d99d36b36..23f04a11ba 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -32,6 +32,7 @@ module ActionMailer end autoload :AdvAttrAccessor, 'action_mailer/adv_attr_accessor' + autoload :DeprecatedBody, 'action_mailer/deprecated_body' autoload :Base, 'action_mailer/base' autoload :DeliveryMethod, 'action_mailer/delivery_method' autoload :Part, 'action_mailer/part' diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index e3690577e1..3d71ba5a14 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -263,6 +263,8 @@ module ActionMailer #:nodoc: include ActionController::UrlWriter end + include ActionMailer::DeprecatedBody + private_class_method :new #:nodoc: class_inheritable_accessor :view_paths @@ -304,16 +306,11 @@ module ActionMailer #:nodoc: cattr_accessor :default_implicit_parts_order cattr_reader :protected_instance_variables - @@protected_instance_variables = %w(@body) + @@protected_instance_variables = [] # Specify the BCC addresses for the message adv_attr_accessor :bcc - # Define the body of the message. This is either a Hash (in which case it - # specifies the variables to pass to the template when it is rendered), - # or a string, in which case it specifies the actual text of the message. - adv_attr_accessor :body - # Specify the CC addresses for the message. adv_attr_accessor :cc @@ -358,33 +355,27 @@ module ActionMailer #:nodoc: # have multiple mailer methods share the same template. adv_attr_accessor :template + # The mail and action_name instances referenced by this mailer. + attr_reader :mail, :action_name + + # Where the response body is stored. + attr_internal :response_body + # Override the mailer name, which defaults to an inflected version of the # mailer's class name. If you want to use a template in a non-standard # location, you can use this to specify that location. + attr_writer :mailer_name + def mailer_name(value = nil) if value - self.mailer_name = value + @mailer_name = value else - self.class.mailer_name + @mailer_name || self.class.mailer_name end end - def mailer_name=(value) - self.class.mailer_name = value - end - - # The mail object instance referenced by this mailer. - attr_reader :mail - attr_reader :template_name, :default_template_name, :action_name - attr_internal :response_body - - def controller_path - self.class.controller_path - end - - def formats - [:"*/*"] - end + # Alias controller_path to mailer_name so render :partial in views work. + alias :controller_path :mailer_name class << self attr_writer :mailer_name @@ -393,10 +384,6 @@ module ActionMailer #:nodoc: @mailer_name ||= name.underscore end - # for ActionView compatibility - alias_method :controller_name, :mailer_name - alias_method :controller_path, :mailer_name - def respond_to?(method_symbol, include_private = false) #:nodoc: matches_dynamic_method?(method_symbol) || super end @@ -472,58 +459,8 @@ module ActionMailer #:nodoc: initialize_defaults(method_name) __send__(method_name, *parameters) - # Check if render was called. - @body = self.response_body if @body.is_a?(Hash) && @body.empty? - - # If an explicit, textual body has not been set, we check assumptions. - unless String === @body - # TODO Fix me. Deprecate assigns to be given as a :body hash - if @body.is_a?(Hash) - @body.each do |k, v| - instance_variable_set(:"@#{k}", v) - end - end - - # First, we look to see if there are any likely templates that match, - # which include the content-type in their file name (i.e., - # "the_template_file.text.html.erb", etc.). Only do this if parts - # have not already been specified manually. - # if @parts.empty? - template_root.find_all(@template, {}, template_path).each do |template| - @parts << Part.new( - :content_type => template.mime_type ? template.mime_type.to_s : "text/plain", - :disposition => "inline", - :charset => charset, - :body => render_to_body(:_template => template) - ) - end - - if @parts.size > 1 - @content_type = "multipart/alternative" if @content_type !~ /^multipart/ - @parts = sort_parts(@parts, @implicit_parts_order) - end - # end - - # Then, if there were such templates, we check to see if we ought to - # also render a "normal" template (without the content type). If a - # normal template exists (or if there were no implicit parts) we render - # it. - # ==== - # TODO: Revisit this - # template_exists = @parts.empty? - # template_exists ||= template_root.find("#{mailer_name}/#{@template}") - # @body = render_message(@template, @body) if template_exists - - # Finally, if there are other message parts and a textual body exists, - # we shift it onto the front of the parts and set the body to nil (so - # that create_mail doesn't try to render it in addition to the parts). - # ==== - # TODO: Revisit this - # if !@parts.empty? && String === @body - # @parts.unshift Part.new(:charset => charset, :body => @body) - # @body = nil - # end - end + # Create e-mail parts + create_parts # If this is a multipart e-mail add the mime_version if it is not # already set. @@ -556,6 +493,7 @@ module ActionMailer #:nodoc: end private + # Set up the default values for the various instance variables of this # mailer. Subclasses may override this method to provide different # defaults. @@ -568,38 +506,42 @@ module ActionMailer #:nodoc: @mailer_name ||= self.class.name.underscore @parts ||= [] @headers ||= {} - @body ||= {} @mime_version = @@default_mime_version.dup if @@default_mime_version @sent_on ||= Time.now - end - def render(*args) - # TODO Fix me. Deprecate assigns to be given as a :body hash - options = args.last.is_a?(Hash) ? args.last : {} - if options[:body] - options.delete(:body).each do |k, v| - instance_variable_set(:"@#{k}", v) - end - end - - super + super # Run deprecation hooks end - def template_root - self.class.template_root - end + def create_parts + super # Run deprecation hooks - def template_root=(root) - self.class.template_root = root - end + if String === response_body + @parts.unshift Part.new( + :content_type => "text/plain", + :disposition => "inline", + :charset => charset, + :body => response_body + ) + else + self.class.template_root.find_all(@template, {}, mailer_name).each do |template| + @parts << Part.new( + :content_type => template.mime_type ? template.mime_type.to_s : "text/plain", + :disposition => "inline", + :charset => charset, + :body => render_to_body(:_template => template) + ) + end - def template_path - "#{mailer_name}" + if @parts.size > 1 + @content_type = "multipart/alternative" if @content_type !~ /^multipart/ + @parts = sort_parts(@parts, @implicit_parts_order) + end + end end def sort_parts(parts, order = []) order = order.collect { |s| s.downcase } - + parts = parts.sort do |a, b| a_ct = a.content_type.downcase b_ct = b.content_type.downcase @@ -648,14 +590,6 @@ module ActionMailer #:nodoc: m.set_content_type(real_content_type, nil, ctype_attrs) m.body = normalize_new_lines(@parts.first.body) else - if String === body - part = TMail::Mail.new - part.body = normalize_new_lines(body) - part.set_content_type(real_content_type, nil, ctype_attrs) - part.set_content_disposition "inline" - m.parts << part - end - @parts.each do |p| part = (TMail::Mail === p ? p : p.to_mail(self)) m.parts << part diff --git a/actionmailer/lib/action_mailer/deprecated_body.rb b/actionmailer/lib/action_mailer/deprecated_body.rb new file mode 100644 index 0000000000..982f098bc5 --- /dev/null +++ b/actionmailer/lib/action_mailer/deprecated_body.rb @@ -0,0 +1,44 @@ +module ActionMailer + # TODO Remove this module all together in a next release. Ensure that super + # hooks in ActionMailer::Base are removed as well. + module DeprecatedBody + def self.included(base) + base.class_eval do + # Define the body of the message. This is either a Hash (in which case it + # specifies the variables to pass to the template when it is rendered), + # or a string, in which case it specifies the actual text of the message. + adv_attr_accessor :body + end + end + + def initialize_defaults(method_name) + @body ||= {} + end + + def create_parts + if String === @body + ActiveSupport::Deprecation.warn('body is deprecated. To set the body with a text ' << + 'call render(:text => "body").', caller[7,1]) + self.response_body = @body + elsif @body.is_a?(Hash) && !@body.empty? + ActiveSupport::Deprecation.warn('body is deprecated. To set assigns simply ' << + 'use instance variables', caller[7,1]) + @body.each { |k, v| instance_variable_set(:"@#{k}", v) } + end + end + + def render(*args) + options = args.last.is_a?(Hash) ? args.last : {} + if options[:body] + ActiveSupport::Deprecation.warn(':body is deprecated. To set assigns simply ' << + 'use instance variables', caller[0,1]) + + options.delete(:body).each do |k, v| + instance_variable_set(:"@#{k}", v) + end + end + + super + end + end +end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 680fe283bd..cda394d926 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -1,6 +1,5 @@ # encoding: utf-8 require 'abstract_unit' -require 'active_support/testing/pending' class FunkyPathMailer < ActionMailer::Base self.template_root = "#{File.dirname(__FILE__)}/fixtures/path.with.dots" @@ -291,7 +290,6 @@ end class ActionMailerTest < Test::Unit::TestCase include ActionMailer::Quoting - include ActiveSupport::Testing::Pending def encode( text, charset="utf-8" ) quoted_printable( text, charset ) @@ -979,10 +977,8 @@ EOF end def test_body_is_stored_as_an_ivar - pending "needs attr_internal on @body" do - mail = TestMailer.create_body_ivar(@recipient) - assert_equal "body: foo\nbar: baz", mail.body - end + mail = TestMailer.create_body_ivar(@recipient) + assert_equal "body: foo\nbar: baz", mail.body end def test_starttls_is_enabled_if_supported -- cgit v1.2.3