delivery_methods.rb 2.9 KB
Newer Older
1 2
# frozen_string_literal: true

3
require "tmpdir"
4

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

11
    included do
12
      # Do not make this inheritable, because we always want it to propagate
13 14 15
      cattr_accessor :raise_delivery_errors, default: true
      cattr_accessor :perform_deliveries, default: true
      cattr_accessor :deliver_later_queue_name, default: :mailers
16

17 18
      class_attribute :delivery_methods, default: {}.freeze
      class_attribute :delivery_method, default: :smtp
J
José Valim 已提交
19

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

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

32
      add_delivery_method :sendmail, Mail::Sendmail,
33 34
        location:  "/usr/sbin/sendmail",
        arguments: "-i"
J
José Valim 已提交
35

36
      add_delivery_method :test, Mail::TestMailer
37
    end
J
José Valim 已提交
38

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

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

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

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

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

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