aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer/lib/action_mailer
diff options
context:
space:
mode:
authorJosé Valim and Mikel Lindsaar <pair@programming.com>2010-01-23 12:20:20 +0100
committerJosé Valim and Mikel Lindsaar <pair@programming.com>2010-01-23 12:20:20 +0100
commit6ba944608e527b8d7fc564a6e450e2d4c4355ddb (patch)
tree48e44837879051f64f8e33969267690a8b572ae7 /actionmailer/lib/action_mailer
parent5a19d24892b9d842ef7d27875eacecbbad71a9aa (diff)
downloadrails-6ba944608e527b8d7fc564a6e450e2d4c4355ddb.tar.gz
rails-6ba944608e527b8d7fc564a6e450e2d4c4355ddb.tar.bz2
rails-6ba944608e527b8d7fc564a6e450e2d4c4355ddb.zip
Make implicit and explicit templates pass through the same part creation process.
Diffstat (limited to 'actionmailer/lib/action_mailer')
-rw-r--r--actionmailer/lib/action_mailer/base.rb126
-rw-r--r--actionmailer/lib/action_mailer/collector.rb25
2 files changed, 79 insertions, 72 deletions
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 28e4c88b5a..5e61b8693a 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -1,5 +1,5 @@
require 'active_support/core_ext/class'
-require "active_support/core_ext/module/delegation"
+require 'active_support/core_ext/module/delegation'
require 'mail'
require 'action_mailer/tmail_compat'
@@ -391,70 +391,63 @@ module ActionMailer #:nodoc:
end
end
+ # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
+ # will be initialized according to the named method. If not, the mailer will
+ # remain uninitialized (useful when you only need to invoke the "receive"
+ # method, for instance).
+ def initialize(method_name=nil, *args)
+ super()
+ @message = Mail.new
+ process(method_name, *args) if method_name
+ end
+
+ # Delivers a Mail object. By default, it delivers the cached mail
+ # object (from the <tt>create!</tt> method). If no cached mail object exists, and
+ # no alternate has been given as the parameter, this will fail.
+ def deliver!(mail = @message)
+ self.class.deliver(mail)
+ end
+
# TODO Add new delivery method goodness
def mail(headers = {})
# Guard flag to prevent both the old and the new API from firing
# Should be removed when old API is deprecated
@mail_was_called = true
- m = @message
- # Get default subject from I18n if none is set
- headers[:subject] ||= default_subject
+ m, sort_parts = @message, true
- # Give preference to headers and fallbacks to the ones set in mail
+ # Give preference to headers and fallback to the ones set in mail
content_type = headers[:content_type] || m.content_type
charset = headers[:charset] || m.charset || self.class.default_charset.dup
mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup
- m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject]
- m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to]
- m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from]
- m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc]
- m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc]
- m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to]
- m.date ||= headers[:date] if headers[:date]
+ headers[:subject] ||= default_subject
+ quote_fields(m, headers, charset)
- if headers[:body]
- templates = [ActionView::Template::Text.new(headers[:body], format_for_text)]
+ responses = if headers[:body]
+ [ { :body => headers[:body], :content_type => self.class.default_content_type.dup } ]
elsif block_given?
- collector = ActionMailer::Collector.new(self, {:charset => charset}) do
- render action_name
- end
- yield collector
-
- collector.responses.each do |response|
- part = Mail::Part.new(response)
- m.add_part(part)
- end
-
+ sort_parts = false
+ collector = ActionMailer::Collector.new(self) { render(action_name) }
+ yield(collector)
+ collector.responses
else
# TODO Ensure that we don't need to pass I18n.locale as detail
templates = self.class.template_root.find_all(action_name, {}, self.class.mailer_name)
- end
-
- if templates
- if templates.size == 1 && !m.has_attachments?
- content_type ||= templates[0].mime_type.to_s
- m.body = render_to_body(:_template => templates[0])
- elsif templates.size > 1 && m.has_attachments?
- container = Mail::Part.new
- container.content_type = "multipart/alternate"
- templates.each { |t| insert_part(container, t, charset) }
- m.add_part(container)
- else
- templates.each { |t| insert_part(m, t, charset) }
+
+ templates.map do |template|
+ { :body => render_to_body(:_template => template),
+ :content_type => template.mime_type.to_s }
end
end
- content_type ||= (m.has_attachments? ? "multipart/mixed" : "multipart/alternate")
+ content_type ||= create_parts_from_responses(m, responses, charset)
- # Check if the content_type was not overwriten along the way and if so,
- # fallback to default.
- m.content_type = content_type || self.class.default_content_type.dup
+ m.content_type = content_type
m.charset = charset
m.mime_version = mime_version
- if m.parts.present? && templates
+ if sort_parts && m.parts.present?
m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup)
m.body.sort_parts!
end
@@ -462,34 +455,43 @@ module ActionMailer #:nodoc:
m
end
- def default_subject
+ protected
+
+ def default_subject #:nodoc:
mailer_scope = self.class.mailer_name.gsub('/', '.')
I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize)
end
- def insert_part(container, template, charset)
- part = Mail::Part.new
- part.content_type = template.mime_type.to_s
- part.charset = charset
- part.body = render_to_body(:_template => template)
- container.add_part(part)
+ def quote_fields(m, headers, charset) #:nodoc:
+ m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject]
+ m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to]
+ m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from]
+ m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc]
+ m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc]
+ m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to]
+ m.date ||= headers[:date] if headers[:date]
end
- # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
- # will be initialized according to the named method. If not, the mailer will
- # remain uninitialized (useful when you only need to invoke the "receive"
- # method, for instance).
- def initialize(method_name=nil, *args)
- super()
- @message = Mail.new
- process(method_name, *args) if method_name
+ def create_parts_from_responses(m, responses, charset) #:nodoc:
+ if responses.size == 1 && !m.has_attachments?
+ m.body = responses[0][:body]
+ return responses[0][:content_type]
+ elsif responses.size > 1 && m.has_attachments?
+ container = Mail::Part.new
+ container.content_type = "multipart/alternate"
+ responses.each { |r| insert_part(container, r, charset) }
+ m.add_part(container)
+ else
+ responses.each { |r| insert_part(m, r, charset) }
+ end
+
+ m.has_attachments? ? "multipart/mixed" : "multipart/alternate"
end
- # Delivers a Mail object. By default, it delivers the cached mail
- # object (from the <tt>create!</tt> method). If no cached mail object exists, and
- # no alternate has been given as the parameter, this will fail.
- def deliver!(mail = @message)
- self.class.deliver(mail)
+ def insert_part(container, response, charset) #:nodoc:
+ response[:charset] ||= charset
+ part = Mail::Part.new(response)
+ container.add_part(part)
end
end
diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb
index 49c3f04bad..0891b6f123 100644
--- a/actionmailer/lib/action_mailer/collector.rb
+++ b/actionmailer/lib/action_mailer/collector.rb
@@ -1,23 +1,29 @@
require 'abstract_controller/collector'
+require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/core_ext/array/extract_options'
module ActionMailer #:nodoc:
-
class Collector
-
include AbstractController::Collector
-
- attr_accessor :responses
+ attr_reader :responses
- def initialize(context, options, &block)
- @default_options = options
- @default_render = block
- @default_formats = context.formats
+ def initialize(context, &block)
@context = context
@responses = []
+ @default_render = block
+ @default_formats = context.formats
+ end
+
+ # TODO Test me
+ def any(*args, &block)
+ options = args.extract_options!
+ raise "You have to supply at least one format" if args.empty?
+ args.each { |type| send(type, options, &block) }
end
+ alias :all :any
def custom(mime, options={}, &block)
- options = @default_options.merge(:content_type => mime.to_s).merge(options)
+ options.reverse_merge!(:content_type => mime.to_s)
@context.formats = [mime.to_sym]
options[:body] = if block
block.call
@@ -27,6 +33,5 @@ module ActionMailer #:nodoc:
@responses << options
@context.formats = @default_formats
end
-
end
end \ No newline at end of file