delivery_methods.rb 2.9 KB
Newer Older
1 2
require 'tmpdir'

3
module ActionMailer # :nodoc:
4 5
  # This module handles everything related to mail delivery, from registering
  # new delivery methods to configuring the mail object to be sent.
J
José Valim 已提交
6
  module DeliveryMethods
7
    extend ActiveSupport::Concern
J
José Valim 已提交
8

9
    included do
J
Jeremy Kemper 已提交
10
      class_attribute :delivery_methods, :delivery_method
J
José Valim 已提交
11

12 13 14 15 16 17 18
      # Do not make this inheritable, because we always want it to propagate
      cattr_accessor :raise_delivery_errors
      self.raise_delivery_errors = true

      cattr_accessor :perform_deliveries
      self.perform_deliveries = true

J
Jeremy Kemper 已提交
19
      self.delivery_methods = {}.freeze
20
      self.delivery_method  = :smtp
J
José Valim 已提交
21

22
      add_delivery_method :smtp, Mail::SMTP,
23 24 25 26 27 28 29
        address:              "localhost",
        port:                 25,
        domain:               'localhost.localdomain',
        user_name:            nil,
        password:             nil,
        authentication:       nil,
        enable_starttls_auto: true
J
José Valim 已提交
30

31
      add_delivery_method :file, Mail::FileDelivery,
32
        location: defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
J
José Valim 已提交
33

34
      add_delivery_method :sendmail, Mail::Sendmail,
35 36
        location:  '/usr/sbin/sendmail',
        arguments: '-i -t'
J
José Valim 已提交
37

38
      add_delivery_method :test, Mail::TestMailer
39
    end
J
José Valim 已提交
40

41
    # Helpers for creating and wrapping delivery behavior, used by DeliveryMethods.
42
    module ClassMethods
43
      # Provides a list of emails that have been delivered by Mail::TestMailer
44
      delegate :deliveries, :deliveries=, to: Mail::TestMailer
45

46 47
      # Adds a new delivery method through the given class using the given
      # symbol as alias and the default options supplied.
48
      #
49
      #   add_delivery_method :sendmail, Mail::Sendmail,
50 51
      #     location:  '/usr/sbin/sendmail',
      #     arguments: '-i -t'
52
      def add_delivery_method(symbol, klass, default_options={})
J
Jeremy Kemper 已提交
53
        class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
54
        send(:"#{symbol}_settings=", default_options)
J
Jeremy Kemper 已提交
55
        self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
56
      end
J
José Valim 已提交
57

58
      def wrap_delivery_behavior(mail, method=nil, options=nil) # :nodoc:
59
        method ||= self.delivery_method
60
        mail.delivery_handler = self
61

62 63 64 65
        case method
        when NilClass
          raise "Delivery method cannot be nil"
        when Symbol
66
          if klass = delivery_methods[method]
67
            mail.delivery_method(klass,(send(:"#{method}_settings") || {}).merge!(options || {}))
68 69 70
          else
            raise "Invalid delivery method #{method.inspect}"
          end
J
José Valim 已提交
71
        else
72
          mail.delivery_method(method)
J
José Valim 已提交
73
        end
74

75
        mail.perform_deliveries    = perform_deliveries
76
        mail.raise_delivery_errors = raise_delivery_errors
J
José Valim 已提交
77
      end
78
    end
J
José Valim 已提交
79

80
    def wrap_delivery_behavior!(*args) # :nodoc:
81
      self.class.wrap_delivery_behavior(message, *args)
J
José Valim 已提交
82 83
    end
  end
J
Jeremy Kemper 已提交
84
end