Permalink
Browse files

Some refactoring.

  • Loading branch information...
1 parent 73a9000 commit 7409b734841c8bd691006634dd072212aa905cf4 José Valim and Mikel Lindsaar committed Jan 24, 2010
@@ -263,33 +263,42 @@ class Base < AbstractController::Base
include AbstractController::UrlFor
helper ActionMailer::MailHelper
+
include ActionMailer::DeprecatedApi
+ extend ActionMailer::DeliveryMethods
+
+ add_delivery_method :smtp, Mail::SMTP,
+ :address => "localhost",
+ :port => 25,
+ :domain => 'localhost.localdomain',
+ :user_name => nil,
+ :password => nil,
+ :authentication => nil,
+ :enable_starttls_auto => true
+
+ add_delivery_method :file, Mail::FileDelivery,
+ :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
+
+ add_delivery_method :sendmail, Mail::Sendmail,
+ :location => '/usr/sbin/sendmail',
+ :arguments => '-i -t'
- include ActionMailer::DeliveryMethods
+ add_delivery_method :test, Mail::TestMailer
+
+ superclass_delegating_reader :delivery_method
+ self.delivery_method = :smtp
private_class_method :new #:nodoc:
- @@raise_delivery_errors = true
cattr_accessor :raise_delivery_errors
+ @@raise_delivery_errors = true
- @@perform_deliveries = true
cattr_accessor :perform_deliveries
-
- # Provides a list of emails that have been delivered by Mail
- def self.deliveries
- Mail.deliveries
- end
-
- # Allows you to over write the default deliveries store from an array to some
- # other object. If you just want to clear the store, call Mail.deliveries.clear.
- def self.deliveries=(val)
- Mail.deliveries = val
- end
+ @@perform_deliveries = true
extlib_inheritable_accessor :default_charset
self.default_charset = "utf-8"
- # TODO This should be used when calling render
extlib_inheritable_accessor :default_content_type
self.default_content_type = "text/plain"
@@ -305,24 +314,9 @@ def self.deliveries=(val)
extlib_inheritable_accessor :default_implicit_parts_order
self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ]
- # Expose the internal Mail message
- # TODO: Make this an _internal ivar?
- attr_reader :message
-
- def headers(args=nil)
- if args
- ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller
- @headers = args
- else
- @message
- end
- end
-
- def attachments
- @message.attachments
- end
-
class << self
+ # Provides a list of emails that have been delivered by Mail
+ delegate :deliveries, :deliveries=, :to => Mail
def mailer_name
@mailer_name ||= name.underscore
@@ -359,6 +353,7 @@ def template_root=(root)
self.view_paths = ActionView::Base.process_view_paths(root)
end
+ # TODO The delivery should happen inside the instrument block
def delivered_email(mail)
ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload|
self.set_payload_for_mail(payload, mail)
@@ -377,66 +372,63 @@ def set_payload_for_mail(payload, mail) #:nodoc:
end
end
+ attr_internal :message
+
# 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
+ @_message = Mail.new
process(method_name, *args) if method_name
end
- # TODO: Clean this up and refactor before Rails 3.0 release.
- # This works for now, but not neat
- 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
+ def headers(args=nil)
+ if args
+ ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller[0,2]
+ @headers = args
+ else
+ @_message
+ end
+ end
- m = @message
+ def attachments
+ @_message.attachments
+ end
- m.register_for_delivery_notification(self.class)
+ def mail(headers={}, &block)
+ # Guard flag to prevent both the old and the new API from firing
+ # Should be removed when old API is removed
+ @mail_was_called = true
+ m = @_message
# 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
+ # Set subjects and fields quotings
headers[:subject] ||= default_subject
- quote_fields(m, headers, charset)
-
- sort_order = headers[:parts_order] || self.class.default_implicit_parts_order.dup
-
- responses = if headers[:body]
- [ { :body => headers[:body], :content_type => self.class.default_content_type.dup } ]
- elsif block_given?
- collector = ActionMailer::Collector.new(self) { render(action_name) }
- yield(collector)
- # Collect the sort order of the parts from the collector as Mail will always
- # sort parts on encode into a "sane" sequence.
- sort_order = collector.responses.map { |r| r[:content_type] }
- 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)
-
- templates.map do |template|
- { :body => render_to_body(:_template => template),
- :content_type => template.mime_type.to_s }
- end
- end
+ quote_fields!(headers, charset)
+ # Render the templates and blocks
+ responses, sort_order = collect_responses_and_sort_order(headers, &block)
content_type ||= create_parts_from_responses(m, responses, charset)
+
+ # Tidy up content type, charset, mime version and sort order
m.content_type = content_type
m.charset = charset
m.mime_version = mime_version
+ sort_order = headers[:parts_order] || sort_order || self.class.default_implicit_parts_order.dup
if m.multipart?
m.body.set_sort_order(sort_order)
m.body.sort_parts!
end
+ # Finaly set delivery behavior configured in class
+ wrap_delivery_behavior!(headers[:delivery_method])
m
end
@@ -448,14 +440,44 @@ def default_subject #:nodoc:
end
# TODO: Move this into Mail
- 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]
+ def quote_fields!(headers, charset) #:nodoc:
+ m = @_message
+ 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
+
+ def collect_responses_and_sort_order(headers) #:nodoc:
+ responses, sort_order = [], nil
+
+ if block_given?
+ collector = ActionMailer::Collector.new(self) { render(action_name) }
+ yield(collector)
+ sort_order = collector.responses.map { |r| r[:content_type] }
+ responses = collector.responses
+ elsif headers[:body]
+ responses << {
+ :body => headers[:body],
+ :content_type => self.class.default_content_type.dup
+ }
+ else
+ self.class.template_root.find_all(action_name, {}, self.class.mailer_name).each do |template|
+ responses << {
+ :body => render_to_body(:_template => template),
+ :content_type => template.mime_type.to_s
+ }
+ end
+ end
+
+ [responses, sort_order]
+ end
+
+ def wrap_delivery_behavior!(method=nil) #:nodoc:
+ self.class.wrap_delivery_behavior(@_message, method)
end
def create_parts_from_responses(m, responses, charset) #:nodoc:
@@ -1,73 +1,63 @@
module ActionMailer
# This modules makes a DSL for adding delivery methods to ActionMailer
module DeliveryMethods
- extend ActiveSupport::Concern
-
- included do
- add_delivery_method :smtp, Mail::SMTP,
- :address => "localhost",
- :port => 25,
- :domain => 'localhost.localdomain',
- :user_name => nil,
- :password => nil,
- :authentication => nil,
- :enable_starttls_auto => true
-
- add_delivery_method :file, Mail::FileDelivery,
- :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
+ # TODO Make me class inheritable
+ def delivery_settings
+ @@delivery_settings ||= Hash.new { |h,k| h[k] = {} }
+ end
- add_delivery_method :sendmail, Mail::Sendmail,
- :location => '/usr/sbin/sendmail',
- :arguments => '-i -t'
+ def delivery_methods
+ @@delivery_methods ||= {}
+ end
- add_delivery_method :test, Mail::TestMailer
+ def delivery_method=(method)
+ raise ArgumentError, "Unknown delivery method #{method.inspect}" unless delivery_methods[method]
+ @delivery_method = method
+ end
- superclass_delegating_reader :delivery_method
- self.delivery_method = :smtp
+ def add_delivery_method(symbol, klass, default_options={})
+ self.delivery_methods[symbol] = klass
+ self.delivery_settings[symbol] = default_options
end
- module ClassMethods
- # TODO Make me class inheritable
- def delivery_settings
- @@delivery_settings ||= Hash.new { |h,k| h[k] = {} }
- end
+ def wrap_delivery_behavior(mail, method=nil)
+ method ||= delivery_method
- def delivery_methods
- @@delivery_methods ||= {}
- end
+ mail.register_for_delivery_notification(self)
- def delivery_method=(method)
- raise ArgumentError, "Unknown delivery method #{method.inspect}" unless delivery_methods[method]
- @delivery_method = method
+ if method.is_a?(Symbol)
+ mail.delivery_method(delivery_methods[method],
+ delivery_settings[method])
+ else
+ mail.delivery_method(method)
end
- def add_delivery_method(symbol, klass, default_options={})
- self.delivery_methods[symbol] = klass
- self.delivery_settings[symbol] = default_options
- end
+ mail.perform_deliveries = perform_deliveries
+ mail.raise_delivery_errors = raise_delivery_errors
+ end
- def respond_to?(method_symbol, include_private = false) #:nodoc:
- matches_settings_method?(method_symbol) || super
- end
- protected
+ def respond_to?(method_symbol, include_private = false) #:nodoc:
+ matches_settings_method?(method_symbol) || super
+ end
- # TODO Get rid of this method missing magic
- def method_missing(method_symbol, *parameters) #:nodoc:
- if match = matches_settings_method?(method_symbol)
- if match[2]
- delivery_settings[match[1].to_sym] = parameters[0]
- else
- delivery_settings[match[1].to_sym]
- end
+ protected
+
+ # TODO Get rid of this method missing magic
+ def method_missing(method_symbol, *parameters) #:nodoc:
+ if match = matches_settings_method?(method_symbol)
+ if match[2]
+ delivery_settings[match[1].to_sym] = parameters[0]
else
- super
+ delivery_settings[match[1].to_sym]
end
+ else
+ super
end
+ end
- def matches_settings_method?(method_name) #:nodoc:
- /(#{delivery_methods.keys.join('|')})_settings(=)?$/.match(method_name.to_s)
- end
+ def matches_settings_method?(method_name) #:nodoc:
+ /(#{delivery_methods.keys.join('|')})_settings(=)?$/.match(method_name.to_s)
end
end
end
Oops, something went wrong.

0 comments on commit 7409b73

Please sign in to comment.