actionmailer 4.2.11.2 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionmailer might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -114
- data/MIT-LICENSE +1 -1
- data/README.rdoc +8 -43
- data/lib/action_mailer.rb +22 -10
- data/lib/action_mailer/base.rb +291 -213
- data/lib/action_mailer/collector.rb +5 -3
- data/lib/action_mailer/delivery_job.rb +34 -3
- data/lib/action_mailer/delivery_methods.rb +15 -17
- data/lib/action_mailer/gem_version.rb +7 -5
- data/lib/action_mailer/inline_preview_interceptor.rb +12 -16
- data/lib/action_mailer/log_subscriber.rb +13 -7
- data/lib/action_mailer/mail_delivery_job.rb +38 -0
- data/lib/action_mailer/mail_helper.rb +16 -2
- data/lib/action_mailer/message_delivery.rb +79 -42
- data/lib/action_mailer/parameterized.rb +171 -0
- data/lib/action_mailer/preview.rb +52 -27
- data/lib/action_mailer/railtie.rb +41 -12
- data/lib/action_mailer/rescuable.rb +29 -0
- data/lib/action_mailer/test_case.rb +28 -10
- data/lib/action_mailer/test_helper.rb +106 -6
- data/lib/action_mailer/version.rb +3 -1
- data/lib/rails/generators/mailer/USAGE +3 -3
- data/lib/rails/generators/mailer/mailer_generator.rb +24 -5
- data/lib/rails/generators/mailer/templates/application_mailer.rb.tt +6 -0
- data/lib/rails/generators/mailer/templates/{mailer.rb → mailer.rb.tt} +2 -2
- metadata +24 -25
- data/lib/rails/generators/mailer/templates/application_mailer.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55ef14268d45d7a535760751b1b1fb2753af791ae34074e3ebea138f2abd5b0f
|
4
|
+
data.tar.gz: 6f3bc72286f71badba0715b37dc1fd1fdb740a97723f2d2d46f551821d61de72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2613c547a7061aa3bc303faedc72020cd50166347ab01065d8ac0f4a2cfeea69a174f8570a004fb95725eac3c91c85adba6265bae4559fe33b32074d3e9f13bc
|
7
|
+
data.tar.gz: e22509967176e017ed6cef838ea3cc9844d1468a32a9b769d87305cb7bac103b5604b110638a713167cda51c06166f8b690befe73a12af5d7c1eb5a1e1618024
|
data/CHANGELOG.md
CHANGED
@@ -1,162 +1,96 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 6.0.0 (August 16, 2019) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails
|
6
|
+
## Rails 6.0.0.rc2 (July 22, 2019) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails
|
11
|
+
## Rails 6.0.0.rc1 (April 24, 2019) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails
|
16
|
+
## Rails 6.0.0.beta3 (March 11, 2019) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails
|
21
|
+
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails
|
26
|
+
## Rails 6.0.0.beta1 (January 18, 2019) ##
|
27
27
|
|
28
|
-
*
|
29
|
-
|
30
|
-
|
31
|
-
## Rails 4.2.7 (July 12, 2016) ##
|
32
|
-
|
33
|
-
* Removes `-t` from default Sendmail arguments to match the underlying
|
34
|
-
`Mail::Sendmail` setting.
|
35
|
-
|
36
|
-
*Clayton Liggitt*
|
37
|
-
|
38
|
-
|
39
|
-
## Rails 4.2.6 (March 07, 2016) ##
|
40
|
-
|
41
|
-
* No changes.
|
42
|
-
|
43
|
-
|
44
|
-
## Rails 4.2.5.2 (February 26, 2016) ##
|
45
|
-
|
46
|
-
* No changes.
|
47
|
-
|
48
|
-
|
49
|
-
## Rails 4.2.5.1 (January 25, 2015) ##
|
50
|
-
|
51
|
-
* No changes.
|
52
|
-
|
53
|
-
|
54
|
-
## Rails 4.2.5 (November 12, 2015) ##
|
55
|
-
|
56
|
-
* No changes.
|
57
|
-
|
58
|
-
|
59
|
-
## Rails 4.2.4 (August 24, 2015) ##
|
60
|
-
|
61
|
-
* No Changes *
|
62
|
-
|
63
|
-
|
64
|
-
## Rails 4.2.3 (June 25, 2015) ##
|
65
|
-
|
66
|
-
* `assert_emails` in block form use the given number as expected value.
|
67
|
-
This makes the error message much easier to understand.
|
68
|
-
|
69
|
-
*Yuji Yaginuma*
|
70
|
-
|
71
|
-
* Mailer preview now uses `url_for` to fix links to emails for apps running on
|
72
|
-
a subdirectory.
|
73
|
-
|
74
|
-
*Remo Mueller*
|
75
|
-
|
76
|
-
* Mailer previews no longer crash when the `mail` method wasn't called
|
77
|
-
(`NullMail`).
|
78
|
-
|
79
|
-
Fixes #19849.
|
80
|
-
|
81
|
-
*Yves Senn*
|
82
|
-
|
83
|
-
* Make sure labels and values line up in mailer previews.
|
84
|
-
|
85
|
-
*Yves Senn*
|
86
|
-
|
87
|
-
|
88
|
-
## Rails 4.2.2 (June 16, 2015) ##
|
89
|
-
|
90
|
-
* No Changes *
|
91
|
-
|
92
|
-
|
93
|
-
## Rails 4.2.1 (March 19, 2015) ##
|
94
|
-
|
95
|
-
* No Changes *
|
28
|
+
* Deprecate `ActionMailer::Base.receive` in favor of [Action Mailbox](https://github.com/rails/rails/tree/master/actionmailbox).
|
96
29
|
|
30
|
+
*George Claghorn*
|
97
31
|
|
98
|
-
|
32
|
+
* Add `MailDeliveryJob` for delivering both regular and parameterized mail. Deprecate using `DeliveryJob` and `Parameterized::DeliveryJob`.
|
99
33
|
|
100
|
-
*
|
101
|
-
now includes `<html>` and `<body>` tags which improve the spam rating in
|
102
|
-
some spam detection engines. Mailers now inherit from `ApplicationMailer`
|
103
|
-
which sets the default layout.
|
34
|
+
*Gannon McGibbon*
|
104
35
|
|
105
|
-
|
36
|
+
* Fix ActionMailer assertions not working when a Mail defines
|
37
|
+
a custom delivery job class
|
106
38
|
|
107
|
-
*
|
108
|
-
Passing `only_path: false` is no longer needed.
|
39
|
+
*Edouard Chin*
|
109
40
|
|
110
|
-
|
41
|
+
* Mails with multipart `format` blocks with implicit render now also check for
|
42
|
+
a template name in options hash instead of only using the action name.
|
111
43
|
|
112
|
-
*
|
44
|
+
*Marcus Ilgner*
|
113
45
|
|
114
|
-
*
|
46
|
+
* `ActionDispatch::IntegrationTest` includes `ActionMailer::TestHelper` module by default.
|
115
47
|
|
116
|
-
|
48
|
+
*Ricardo Díaz*
|
117
49
|
|
118
|
-
|
50
|
+
* Add `perform_deliveries` to a payload of `deliver.action_mailer` notification.
|
119
51
|
|
120
|
-
*
|
121
|
-
favor of `#deliver_now`. `#deliver_later` will enqueue a job to render and
|
122
|
-
deliver the mail instead of delivering it immediately. The job is enqueued
|
123
|
-
using the new Active Job framework in Rails and will use the queue that you
|
124
|
-
have configured in Rails.
|
52
|
+
*Yoshiyuki Kinjo*
|
125
53
|
|
126
|
-
|
54
|
+
* Change delivery logging message when `perform_deliveries` is false.
|
127
55
|
|
128
|
-
*
|
56
|
+
*Yoshiyuki Kinjo*
|
129
57
|
|
130
|
-
|
58
|
+
* Allow call `assert_enqueued_email_with` with no block.
|
131
59
|
|
132
|
-
|
133
|
-
|
134
|
-
|
60
|
+
Example:
|
61
|
+
```
|
62
|
+
def test_email
|
63
|
+
ContactMailer.welcome.deliver_later
|
64
|
+
assert_enqueued_email_with ContactMailer, :welcome
|
65
|
+
end
|
135
66
|
|
136
|
-
|
67
|
+
def test_email_with_arguments
|
68
|
+
ContactMailer.welcome("Hello", "Goodbye").deliver_later
|
69
|
+
assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
|
70
|
+
end
|
71
|
+
```
|
137
72
|
|
138
|
-
*
|
139
|
-
This is a safeguard to prevent invalid emails.
|
73
|
+
*bogdanvlviv*
|
140
74
|
|
141
|
-
|
75
|
+
* Ensure mail gem is eager autoloaded when eager load is true to prevent thread deadlocks.
|
142
76
|
|
143
|
-
*
|
77
|
+
*Samuel Cochran*
|
144
78
|
|
145
|
-
*
|
79
|
+
* Perform email jobs in `assert_emails`.
|
146
80
|
|
147
|
-
|
148
|
-
environments other than development (such as staging).
|
81
|
+
*Gannon McGibbon*
|
149
82
|
|
150
|
-
|
83
|
+
* Add `Base.unregister_observer`, `Base.unregister_observers`,
|
84
|
+
`Base.unregister_interceptor`, `Base.unregister_interceptors`,
|
85
|
+
`Base.unregister_preview_interceptor` and `Base.unregister_preview_interceptors`.
|
86
|
+
This makes it possible to dynamically add and remove email observers and
|
87
|
+
interceptors at runtime in the same way they're registered.
|
151
88
|
|
152
|
-
*
|
89
|
+
*Claudio Ortolina*, *Kota Miyake*
|
153
90
|
|
154
|
-
*
|
155
|
-
`config.action_mailer.preview_interceptors`.
|
91
|
+
* Rails 6 requires Ruby 2.5.0 or newer.
|
156
92
|
|
157
|
-
|
93
|
+
*Jeremy Daer*, *Kasper Timm Hansen*
|
158
94
|
|
159
|
-
*Yves Senn*
|
160
95
|
|
161
|
-
Please check [
|
162
|
-
for previous changes.
|
96
|
+
Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/actionmailer/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -13,6 +13,8 @@ Additionally, an Action Mailer class can be used to process incoming email,
|
|
13
13
|
such as allowing a blog to accept new posts from an email (which could even
|
14
14
|
have been sent from a phone).
|
15
15
|
|
16
|
+
You can read more about Action Mailer in the {Action Mailer Basics}[https://edgeguides.rubyonrails.org/action_mailer_basics.html] guide.
|
17
|
+
|
16
18
|
== Sending emails
|
17
19
|
|
18
20
|
The framework works by initializing any instance variables you want to be
|
@@ -93,42 +95,6 @@ Example:
|
|
93
95
|
.....
|
94
96
|
end
|
95
97
|
|
96
|
-
== Receiving emails
|
97
|
-
|
98
|
-
To receive emails, you need to implement a public instance method called
|
99
|
-
+receive+ that takes an email object as its single parameter. The Action Mailer
|
100
|
-
framework has a corresponding class method, which is also called +receive+, that
|
101
|
-
accepts a raw, unprocessed email as a string, which it then turns into the email
|
102
|
-
object and calls the receive instance method.
|
103
|
-
|
104
|
-
Example:
|
105
|
-
|
106
|
-
class Mailman < ActionMailer::Base
|
107
|
-
def receive(email)
|
108
|
-
page = Page.find_by(address: email.to.first)
|
109
|
-
page.emails.create(
|
110
|
-
subject: email.subject, body: email.body
|
111
|
-
)
|
112
|
-
|
113
|
-
if email.has_attachments?
|
114
|
-
email.attachments.each do |attachment|
|
115
|
-
page.attachments.create({
|
116
|
-
file: attachment, description: email.subject
|
117
|
-
})
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
This Mailman can be the target for Postfix or other MTAs. In Rails, you would use
|
124
|
-
the runner in the trivial case like this:
|
125
|
-
|
126
|
-
rails runner 'Mailman.receive(STDIN.read)'
|
127
|
-
|
128
|
-
However, invoking Rails in the runner for each mail to be received is very
|
129
|
-
resource intensive. A single instance of Rails should be run within a daemon, if
|
130
|
-
it is going to process more than just a limited amount of email.
|
131
|
-
|
132
98
|
== Configuration
|
133
99
|
|
134
100
|
The Base class has the full list of configuration options. Here's an example:
|
@@ -146,31 +112,30 @@ The Base class has the full list of configuration options. Here's an example:
|
|
146
112
|
|
147
113
|
The latest version of Action Mailer can be installed with RubyGems:
|
148
114
|
|
149
|
-
|
115
|
+
$ gem install actionmailer
|
150
116
|
|
151
|
-
Source code can be downloaded as part of the Rails project on GitHub
|
117
|
+
Source code can be downloaded as part of the Rails project on GitHub:
|
152
118
|
|
153
|
-
* https://github.com/rails/rails/tree/
|
119
|
+
* https://github.com/rails/rails/tree/master/actionmailer
|
154
120
|
|
155
121
|
|
156
122
|
== License
|
157
123
|
|
158
124
|
Action Mailer is released under the MIT license:
|
159
125
|
|
160
|
-
*
|
126
|
+
* https://opensource.org/licenses/MIT
|
161
127
|
|
162
128
|
|
163
129
|
== Support
|
164
130
|
|
165
131
|
API documentation is at
|
166
132
|
|
167
|
-
*
|
133
|
+
* https://api.rubyonrails.org
|
168
134
|
|
169
|
-
Bug reports
|
135
|
+
Bug reports for the Ruby on Rails project can be filed here:
|
170
136
|
|
171
137
|
* https://github.com/rails/rails/issues
|
172
138
|
|
173
139
|
Feature requests should be discussed on the rails-core mailing list here:
|
174
140
|
|
175
141
|
* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
|
176
|
-
|
data/lib/action_mailer.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2019 David Heinemeier Hansson
|
3
5
|
#
|
4
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
7
|
# a copy of this software and associated documentation files (the
|
@@ -21,15 +23,16 @@
|
|
21
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
24
|
#++
|
23
25
|
|
24
|
-
require
|
25
|
-
require
|
26
|
+
require "abstract_controller"
|
27
|
+
require "action_mailer/version"
|
26
28
|
|
27
29
|
# Common Active Support usage in Action Mailer
|
28
|
-
require
|
29
|
-
require
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
30
|
+
require "active_support"
|
31
|
+
require "active_support/rails"
|
32
|
+
require "active_support/core_ext/class"
|
33
|
+
require "active_support/core_ext/module/attr_internal"
|
34
|
+
require "active_support/core_ext/string/inflections"
|
35
|
+
require "active_support/lazy_load_hooks"
|
33
36
|
|
34
37
|
module ActionMailer
|
35
38
|
extend ::ActiveSupport::Autoload
|
@@ -42,15 +45,24 @@ module ActionMailer
|
|
42
45
|
autoload :DeliveryMethods
|
43
46
|
autoload :InlinePreviewInterceptor
|
44
47
|
autoload :MailHelper
|
48
|
+
autoload :Parameterized
|
45
49
|
autoload :Preview
|
46
|
-
autoload :Previews,
|
50
|
+
autoload :Previews, "action_mailer/preview"
|
47
51
|
autoload :TestCase
|
48
52
|
autoload :TestHelper
|
49
53
|
autoload :MessageDelivery
|
50
54
|
autoload :DeliveryJob
|
55
|
+
autoload :MailDeliveryJob
|
56
|
+
|
57
|
+
def self.eager_load!
|
58
|
+
super
|
59
|
+
|
60
|
+
require "mail"
|
61
|
+
Mail.eager_autoload!
|
62
|
+
end
|
51
63
|
end
|
52
64
|
|
53
|
-
autoload :Mime,
|
65
|
+
autoload :Mime, "action_dispatch/http/mime_type"
|
54
66
|
|
55
67
|
ActiveSupport.on_load(:action_view) do
|
56
68
|
ActionView::Base.default_formats ||= Mime::SET.symbols
|
data/lib/action_mailer/base.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
|
2
|
-
require 'action_mailer/collector'
|
3
|
-
require 'active_support/core_ext/string/inflections'
|
4
|
-
require 'active_support/core_ext/hash/except'
|
5
|
-
require 'active_support/core_ext/module/anonymous'
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
require
|
3
|
+
require "mail"
|
4
|
+
require "action_mailer/collector"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
6
|
+
require "active_support/core_ext/hash/except"
|
7
|
+
require "active_support/core_ext/module/anonymous"
|
8
|
+
|
9
|
+
require "action_mailer/log_subscriber"
|
10
|
+
require "action_mailer/rescuable"
|
8
11
|
|
9
12
|
module ActionMailer
|
10
13
|
# Action Mailer allows you to send email from your application using a mailer model and views.
|
@@ -21,11 +24,11 @@ module ActionMailer
|
|
21
24
|
# the mailer views, options on the mail itself such as the <tt>:from</tt> address, and attachments.
|
22
25
|
#
|
23
26
|
# class ApplicationMailer < ActionMailer::Base
|
24
|
-
# default from: 'from@
|
27
|
+
# default from: 'from@example.com'
|
25
28
|
# layout 'mailer'
|
26
29
|
# end
|
27
30
|
#
|
28
|
-
# class
|
31
|
+
# class NotifierMailer < ApplicationMailer
|
29
32
|
# default from: 'no-reply@example.com',
|
30
33
|
# return_path: 'system@example.com'
|
31
34
|
#
|
@@ -56,7 +59,7 @@ module ActionMailer
|
|
56
59
|
# The hash passed to the mail method allows you to specify any header that a <tt>Mail::Message</tt>
|
57
60
|
# will accept (any valid email header including optional fields).
|
58
61
|
#
|
59
|
-
# The mail method, if not passed a block, will inspect your views and send all the views with
|
62
|
+
# The +mail+ method, if not passed a block, will inspect your views and send all the views with
|
60
63
|
# the same name as the method, so the above action would send the +welcome.text.erb+ view
|
61
64
|
# file as well as the +welcome.html.erb+ view file in a +multipart/alternative+ email.
|
62
65
|
#
|
@@ -86,9 +89,9 @@ module ActionMailer
|
|
86
89
|
# Like Action Controller, each mailer class has a corresponding view directory in which each
|
87
90
|
# method of the class looks for a template with its name.
|
88
91
|
#
|
89
|
-
# To define a template to be used with a
|
92
|
+
# To define a template to be used with a mailer, create an <tt>.erb</tt> file with the same
|
90
93
|
# name as the method in your mailer model. For example, in the mailer defined above, the template at
|
91
|
-
# <tt>app/views/
|
94
|
+
# <tt>app/views/notifier_mailer/welcome.text.erb</tt> would be used to generate the email.
|
92
95
|
#
|
93
96
|
# Variables defined in the methods of your mailer model are accessible as instance variables in their
|
94
97
|
# corresponding view.
|
@@ -132,38 +135,41 @@ module ActionMailer
|
|
132
135
|
#
|
133
136
|
# config.action_mailer.default_url_options = { host: "example.com" }
|
134
137
|
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# <tt>
|
138
|
+
# You can also define a <tt>default_url_options</tt> method on individual mailers to override these
|
139
|
+
# default settings per-mailer.
|
140
|
+
#
|
141
|
+
# By default when <tt>config.force_ssl</tt> is +true+, URLs generated for hosts will use the HTTPS protocol.
|
139
142
|
#
|
140
143
|
# = Sending mail
|
141
144
|
#
|
142
|
-
# Once a mailer action and template are defined, you can deliver your message or
|
143
|
-
# for
|
145
|
+
# Once a mailer action and template are defined, you can deliver your message or defer its creation and
|
146
|
+
# delivery for later:
|
147
|
+
#
|
148
|
+
# NotifierMailer.welcome(User.first).deliver_now # sends the email
|
149
|
+
# mail = NotifierMailer.welcome(User.first) # => an ActionMailer::MessageDelivery object
|
150
|
+
# mail.deliver_now # generates and sends the email now
|
144
151
|
#
|
145
|
-
#
|
146
|
-
#
|
147
|
-
#
|
152
|
+
# The <tt>ActionMailer::MessageDelivery</tt> class is a wrapper around a delegate that will call
|
153
|
+
# your method to generate the mail. If you want direct access to the delegator, or <tt>Mail::Message</tt>,
|
154
|
+
# you can call the <tt>message</tt> method on the <tt>ActionMailer::MessageDelivery</tt> object.
|
148
155
|
#
|
149
|
-
#
|
150
|
-
# you want direct access to the <tt>Mail::Message</tt> object you can call the <tt>message</tt> method on
|
151
|
-
# the <tt>ActionMailer::MessageDelivery</tt> object.
|
156
|
+
# NotifierMailer.welcome(User.first).message # => a Mail::Message object
|
152
157
|
#
|
153
|
-
#
|
158
|
+
# Action Mailer is nicely integrated with Active Job so you can generate and send emails in the background
|
159
|
+
# (example: outside of the request-response cycle, so the user doesn't have to wait on it):
|
154
160
|
#
|
155
|
-
#
|
156
|
-
# of the request-response cycle, so the user doesn't have to wait on it):
|
161
|
+
# NotifierMailer.welcome(User.first).deliver_later # enqueue the email sending to Active Job
|
157
162
|
#
|
158
|
-
#
|
163
|
+
# Note that <tt>deliver_later</tt> will execute your method from the background job.
|
159
164
|
#
|
160
165
|
# You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
|
166
|
+
# All instance methods are expected to return a message object to be sent.
|
161
167
|
#
|
162
168
|
# = Multipart Emails
|
163
169
|
#
|
164
170
|
# Multipart messages can also be used implicitly because Action Mailer will automatically detect and use
|
165
171
|
# multipart templates, where each template is named after the name of the action, followed by the content
|
166
|
-
# type. Each such detected template will be added as a separate part
|
172
|
+
# type. Each such detected template will be added to the message, as a separate part.
|
167
173
|
#
|
168
174
|
# For example, if the following templates exist:
|
169
175
|
# * signup_notification.text.erb
|
@@ -184,7 +190,7 @@ module ActionMailer
|
|
184
190
|
#
|
185
191
|
# Sending attachment in emails is easy:
|
186
192
|
#
|
187
|
-
# class
|
193
|
+
# class NotifierMailer < ApplicationMailer
|
188
194
|
# def welcome(recipient)
|
189
195
|
# attachments['free_book.pdf'] = File.read('path/to/file.pdf')
|
190
196
|
# mail(to: recipient, subject: "New account information")
|
@@ -200,19 +206,32 @@ module ActionMailer
|
|
200
206
|
# If you need to send attachments with no content, you need to create an empty view for it,
|
201
207
|
# or add an empty body parameter like this:
|
202
208
|
#
|
203
|
-
# class
|
209
|
+
# class NotifierMailer < ApplicationMailer
|
204
210
|
# def welcome(recipient)
|
205
211
|
# attachments['free_book.pdf'] = File.read('path/to/file.pdf')
|
206
212
|
# mail(to: recipient, subject: "New account information", body: "")
|
207
213
|
# end
|
208
214
|
# end
|
209
215
|
#
|
216
|
+
# You can also send attachments with html template, in this case you need to add body, attachments,
|
217
|
+
# and custom content type like this:
|
218
|
+
#
|
219
|
+
# class NotifierMailer < ApplicationMailer
|
220
|
+
# def welcome(recipient)
|
221
|
+
# attachments["free_book.pdf"] = File.read("path/to/file.pdf")
|
222
|
+
# mail(to: recipient,
|
223
|
+
# subject: "New account information",
|
224
|
+
# content_type: "text/html",
|
225
|
+
# body: "<html><body>Hello there</body></html>")
|
226
|
+
# end
|
227
|
+
# end
|
228
|
+
#
|
210
229
|
# = Inline Attachments
|
211
230
|
#
|
212
231
|
# You can also specify that a file should be displayed inline with other HTML. This is useful
|
213
232
|
# if you want to display a corporate logo or a photo.
|
214
233
|
#
|
215
|
-
# class
|
234
|
+
# class NotifierMailer < ApplicationMailer
|
216
235
|
# def welcome(recipient)
|
217
236
|
# attachments.inline['photo.png'] = File.read('path/to/photo.png')
|
218
237
|
# mail(to: recipient, subject: "Here is what we look like")
|
@@ -251,7 +270,7 @@ module ActionMailer
|
|
251
270
|
# Action Mailer provides some intelligent defaults for your emails, these are usually specified in a
|
252
271
|
# default method inside the class definition:
|
253
272
|
#
|
254
|
-
# class
|
273
|
+
# class NotifierMailer < ApplicationMailer
|
255
274
|
# default sender: 'system@example.com'
|
256
275
|
# end
|
257
276
|
#
|
@@ -259,8 +278,8 @@ module ActionMailer
|
|
259
278
|
# <tt>ActionMailer::Base</tt> sets the following:
|
260
279
|
#
|
261
280
|
# * <tt>mime_version: "1.0"</tt>
|
262
|
-
# * <tt>charset: "UTF-8"
|
263
|
-
# * <tt>content_type: "text/plain"
|
281
|
+
# * <tt>charset: "UTF-8"</tt>
|
282
|
+
# * <tt>content_type: "text/plain"</tt>
|
264
283
|
# * <tt>parts_order: [ "text/plain", "text/enriched", "text/html" ]</tt>
|
265
284
|
#
|
266
285
|
# <tt>parts_order</tt> and <tt>charset</tt> are not actually valid <tt>Mail::Message</tt> header fields,
|
@@ -269,27 +288,26 @@ module ActionMailer
|
|
269
288
|
# As you can pass in any header, you need to either quote the header as a string, or pass it in as
|
270
289
|
# an underscored symbol, so the following will work:
|
271
290
|
#
|
272
|
-
# class
|
291
|
+
# class NotifierMailer < ApplicationMailer
|
273
292
|
# default 'Content-Transfer-Encoding' => '7bit',
|
274
293
|
# content_description: 'This is a description'
|
275
294
|
# end
|
276
295
|
#
|
277
|
-
# Finally, Action Mailer also supports passing <tt>Proc</tt> objects into the default hash,
|
278
|
-
# can define methods that evaluate as the message is being generated:
|
296
|
+
# Finally, Action Mailer also supports passing <tt>Proc</tt> and <tt>Lambda</tt> objects into the default hash,
|
297
|
+
# so you can define methods that evaluate as the message is being generated:
|
279
298
|
#
|
280
|
-
# class
|
281
|
-
# default 'X-Special-Header' => Proc.new { my_method }
|
299
|
+
# class NotifierMailer < ApplicationMailer
|
300
|
+
# default 'X-Special-Header' => Proc.new { my_method }, to: -> { @inviter.email_address }
|
282
301
|
#
|
283
302
|
# private
|
284
|
-
#
|
285
303
|
# def my_method
|
286
304
|
# 'some complex call'
|
287
305
|
# end
|
288
306
|
# end
|
289
307
|
#
|
290
|
-
# Note that the proc is evaluated right at the start of the mail message generation, so if you
|
291
|
-
# set something in the
|
292
|
-
# mailer method, it will get
|
308
|
+
# Note that the proc/lambda is evaluated right at the start of the mail message generation, so if you
|
309
|
+
# set something in the default hash using a proc, and then set the same thing inside of your
|
310
|
+
# mailer method, it will get overwritten by the mailer method.
|
293
311
|
#
|
294
312
|
# It is also possible to set these default options that will be used in all mailers through
|
295
313
|
# the <tt>default_options=</tt> configuration in <tt>config/application.rb</tt>:
|
@@ -298,11 +316,11 @@ module ActionMailer
|
|
298
316
|
#
|
299
317
|
# = Callbacks
|
300
318
|
#
|
301
|
-
# You can specify callbacks using before_action and after_action for configuring your messages.
|
319
|
+
# You can specify callbacks using <tt>before_action</tt> and <tt>after_action</tt> for configuring your messages.
|
302
320
|
# This may be useful, for example, when you want to add default inline attachments for all
|
303
321
|
# messages sent out by a certain mailer class:
|
304
322
|
#
|
305
|
-
# class
|
323
|
+
# class NotifierMailer < ApplicationMailer
|
306
324
|
# before_action :add_inline_attachment!
|
307
325
|
#
|
308
326
|
# def welcome
|
@@ -310,7 +328,6 @@ module ActionMailer
|
|
310
328
|
# end
|
311
329
|
#
|
312
330
|
# private
|
313
|
-
#
|
314
331
|
# def add_inline_attachment!
|
315
332
|
# attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
|
316
333
|
# end
|
@@ -321,8 +338,9 @@ module ActionMailer
|
|
321
338
|
# callbacks in the same manner that you would use callbacks in classes that
|
322
339
|
# inherit from <tt>ActionController::Base</tt>.
|
323
340
|
#
|
324
|
-
# Note that unless you have a specific reason to do so, you should prefer
|
325
|
-
# rather than after_action in your
|
341
|
+
# Note that unless you have a specific reason to do so, you should prefer
|
342
|
+
# using <tt>before_action</tt> rather than <tt>after_action</tt> in your
|
343
|
+
# Action Mailer classes so that headers are parsed properly.
|
326
344
|
#
|
327
345
|
# = Previewing emails
|
328
346
|
#
|
@@ -330,9 +348,9 @@ module ActionMailer
|
|
330
348
|
# <tt>ActionMailer::Base.preview_path</tt>. Since most emails do something interesting
|
331
349
|
# with database data, you'll need to write some scenarios to load messages with fake data:
|
332
350
|
#
|
333
|
-
# class
|
351
|
+
# class NotifierMailerPreview < ActionMailer::Preview
|
334
352
|
# def welcome
|
335
|
-
#
|
353
|
+
# NotifierMailer.welcome(User.first)
|
336
354
|
# end
|
337
355
|
# end
|
338
356
|
#
|
@@ -388,13 +406,13 @@ module ActionMailer
|
|
388
406
|
# to use it. Defaults to <tt>true</tt>.
|
389
407
|
# * <tt>:openssl_verify_mode</tt> - When using TLS, you can set how OpenSSL checks the certificate. This is
|
390
408
|
# really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
|
391
|
-
# of an OpenSSL verify constant (<tt>'none'</tt
|
392
|
-
# <tt>
|
393
|
-
#
|
409
|
+
# of an OpenSSL verify constant (<tt>'none'</tt> or <tt>'peer'</tt>) or directly the constant
|
410
|
+
# (<tt>OpenSSL::SSL::VERIFY_NONE</tt> or <tt>OpenSSL::SSL::VERIFY_PEER</tt>).
|
411
|
+
# * <tt>:ssl/:tls</tt> Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)
|
394
412
|
#
|
395
413
|
# * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
|
396
414
|
# * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
|
397
|
-
# * <tt>:arguments</tt> - The command line arguments. Defaults to <tt>-i
|
415
|
+
# * <tt>:arguments</tt> - The command line arguments. Defaults to <tt>-i</tt> with <tt>-f sender@address</tt>
|
398
416
|
# added automatically before the message is sent.
|
399
417
|
#
|
400
418
|
# * <tt>file_settings</tt> - Allows you to override options for the <tt>:file</tt> delivery method.
|
@@ -414,8 +432,12 @@ module ActionMailer
|
|
414
432
|
#
|
415
433
|
# * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with
|
416
434
|
# <tt>delivery_method :test</tt>. Most useful for unit and functional testing.
|
435
|
+
#
|
436
|
+
# * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>. Defaults to +mailers+.
|
417
437
|
class Base < AbstractController::Base
|
418
438
|
include DeliveryMethods
|
439
|
+
include Rescuable
|
440
|
+
include Parameterized
|
419
441
|
include Previews
|
420
442
|
|
421
443
|
abstract!
|
@@ -427,6 +449,7 @@ module ActionMailer
|
|
427
449
|
include AbstractController::Translation
|
428
450
|
include AbstractController::AssetPaths
|
429
451
|
include AbstractController::Callbacks
|
452
|
+
include AbstractController::Caching
|
430
453
|
|
431
454
|
include ActionView::Layouts
|
432
455
|
|
@@ -438,10 +461,8 @@ module ActionMailer
|
|
438
461
|
|
439
462
|
helper ActionMailer::MailHelper
|
440
463
|
|
441
|
-
|
442
|
-
|
443
|
-
class_attribute :default_params
|
444
|
-
self.default_params = {
|
464
|
+
class_attribute :delivery_job, default: ::ActionMailer::DeliveryJob
|
465
|
+
class_attribute :default_params, default: {
|
445
466
|
mime_version: "1.0",
|
446
467
|
charset: "UTF-8",
|
447
468
|
content_type: "text/plain",
|
@@ -454,40 +475,60 @@ module ActionMailer
|
|
454
475
|
observers.flatten.compact.each { |observer| register_observer(observer) }
|
455
476
|
end
|
456
477
|
|
478
|
+
# Unregister one or more previously registered Observers.
|
479
|
+
def unregister_observers(*observers)
|
480
|
+
observers.flatten.compact.each { |observer| unregister_observer(observer) }
|
481
|
+
end
|
482
|
+
|
457
483
|
# Register one or more Interceptors which will be called before mail is sent.
|
458
484
|
def register_interceptors(*interceptors)
|
459
485
|
interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
|
460
486
|
end
|
461
487
|
|
488
|
+
# Unregister one or more previously registered Interceptors.
|
489
|
+
def unregister_interceptors(*interceptors)
|
490
|
+
interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
|
491
|
+
end
|
492
|
+
|
462
493
|
# Register an Observer which will be notified when mail is delivered.
|
463
494
|
# Either a class, string or symbol can be passed in as the Observer.
|
464
495
|
# If a string or symbol is passed in it will be camelized and constantized.
|
465
496
|
def register_observer(observer)
|
466
|
-
|
467
|
-
|
468
|
-
observer.to_s.camelize.constantize
|
469
|
-
else
|
470
|
-
observer
|
471
|
-
end
|
497
|
+
Mail.register_observer(observer_class_for(observer))
|
498
|
+
end
|
472
499
|
|
473
|
-
|
500
|
+
# Unregister a previously registered Observer.
|
501
|
+
# Either a class, string or symbol can be passed in as the Observer.
|
502
|
+
# If a string or symbol is passed in it will be camelized and constantized.
|
503
|
+
def unregister_observer(observer)
|
504
|
+
Mail.unregister_observer(observer_class_for(observer))
|
474
505
|
end
|
475
506
|
|
476
507
|
# Register an Interceptor which will be called before mail is sent.
|
477
508
|
# Either a class, string or symbol can be passed in as the Interceptor.
|
478
509
|
# If a string or symbol is passed in it will be camelized and constantized.
|
479
510
|
def register_interceptor(interceptor)
|
480
|
-
|
481
|
-
|
482
|
-
interceptor.to_s.camelize.constantize
|
483
|
-
else
|
484
|
-
interceptor
|
485
|
-
end
|
511
|
+
Mail.register_interceptor(observer_class_for(interceptor))
|
512
|
+
end
|
486
513
|
|
487
|
-
|
514
|
+
# Unregister a previously registered Interceptor.
|
515
|
+
# Either a class, string or symbol can be passed in as the Interceptor.
|
516
|
+
# If a string or symbol is passed in it will be camelized and constantized.
|
517
|
+
def unregister_interceptor(interceptor)
|
518
|
+
Mail.unregister_interceptor(observer_class_for(interceptor))
|
488
519
|
end
|
489
520
|
|
490
|
-
|
521
|
+
def observer_class_for(value) # :nodoc:
|
522
|
+
case value
|
523
|
+
when String, Symbol
|
524
|
+
value.to_s.camelize.constantize
|
525
|
+
else
|
526
|
+
value
|
527
|
+
end
|
528
|
+
end
|
529
|
+
private :observer_class_for
|
530
|
+
|
531
|
+
# Returns the name of the current mailer. This method is also being used as a path for a view lookup.
|
491
532
|
# If this is an anonymous mailer, this method will return +anonymous+ instead.
|
492
533
|
def mailer_name
|
493
534
|
@mailer_name ||= anonymous? ? "anonymous" : name.underscore
|
@@ -524,6 +565,11 @@ module ActionMailer
|
|
524
565
|
# end
|
525
566
|
# end
|
526
567
|
def receive(raw_mail)
|
568
|
+
ActiveSupport::Deprecation.warn(<<~MESSAGE.squish)
|
569
|
+
ActionMailer::Base.receive is deprecated and will be removed in Rails 6.1.
|
570
|
+
Use Action Mailbox to process inbound email.
|
571
|
+
MESSAGE
|
572
|
+
|
527
573
|
ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
|
528
574
|
mail = Mail.new(raw_mail)
|
529
575
|
set_payload_for_mail(payload, mail)
|
@@ -544,65 +590,60 @@ module ActionMailer
|
|
544
590
|
end
|
545
591
|
end
|
546
592
|
|
547
|
-
|
548
|
-
|
593
|
+
private
|
594
|
+
|
595
|
+
def set_payload_for_mail(payload, mail)
|
596
|
+
payload[:mail] = mail.encoded
|
597
|
+
payload[:mailer] = name
|
598
|
+
payload[:message_id] = mail.message_id
|
599
|
+
payload[:subject] = mail.subject
|
600
|
+
payload[:to] = mail.to
|
601
|
+
payload[:from] = mail.from
|
602
|
+
payload[:bcc] = mail.bcc if mail.bcc.present?
|
603
|
+
payload[:cc] = mail.cc if mail.cc.present?
|
604
|
+
payload[:date] = mail.date
|
605
|
+
payload[:perform_deliveries] = mail.perform_deliveries
|
549
606
|
end
|
550
607
|
|
551
|
-
|
552
|
-
|
553
|
-
def set_payload_for_mail(payload, mail) #:nodoc:
|
554
|
-
payload[:mailer] = name
|
555
|
-
payload[:message_id] = mail.message_id
|
556
|
-
payload[:subject] = mail.subject
|
557
|
-
payload[:to] = mail.to
|
558
|
-
payload[:from] = mail.from
|
559
|
-
payload[:bcc] = mail.bcc if mail.bcc.present?
|
560
|
-
payload[:cc] = mail.cc if mail.cc.present?
|
561
|
-
payload[:date] = mail.date
|
562
|
-
payload[:mail] = mail.encoded
|
563
|
-
end
|
564
|
-
|
565
|
-
def method_missing(method_name, *args) # :nodoc:
|
608
|
+
def method_missing(method_name, *args)
|
566
609
|
if action_methods.include?(method_name.to_s)
|
567
610
|
MessageDelivery.new(self, method_name, *args)
|
568
611
|
else
|
569
612
|
super
|
570
613
|
end
|
571
614
|
end
|
615
|
+
|
616
|
+
def respond_to_missing?(method, include_all = false)
|
617
|
+
action_methods.include?(method.to_s) || super
|
618
|
+
end
|
572
619
|
end
|
573
620
|
|
574
621
|
attr_internal :message
|
575
622
|
|
576
|
-
|
577
|
-
# will be initialized according to the named method. If not, the mailer will
|
578
|
-
# remain uninitialized (useful when you only need to invoke the "receive"
|
579
|
-
# method, for instance).
|
580
|
-
def initialize(method_name=nil, *args)
|
623
|
+
def initialize
|
581
624
|
super()
|
582
625
|
@_mail_was_called = false
|
583
626
|
@_message = Mail.new
|
584
|
-
process(method_name, *args) if method_name
|
585
627
|
end
|
586
628
|
|
587
629
|
def process(method_name, *args) #:nodoc:
|
588
630
|
payload = {
|
589
631
|
mailer: self.class.name,
|
590
|
-
action: method_name
|
632
|
+
action: method_name,
|
633
|
+
args: args
|
591
634
|
}
|
592
635
|
|
593
636
|
ActiveSupport::Notifications.instrument("process.action_mailer", payload) do
|
594
|
-
lookup_context.skip_default_locale!
|
595
|
-
|
596
637
|
super
|
597
638
|
@_message = NullMail.new unless @_mail_was_called
|
598
639
|
end
|
599
640
|
end
|
600
641
|
|
601
642
|
class NullMail #:nodoc:
|
602
|
-
def body;
|
643
|
+
def body; "" end
|
603
644
|
def header; {} end
|
604
645
|
|
605
|
-
def respond_to?(string, include_all=false)
|
646
|
+
def respond_to?(string, include_all = false)
|
606
647
|
true
|
607
648
|
end
|
608
649
|
|
@@ -662,21 +703,21 @@ module ActionMailer
|
|
662
703
|
#
|
663
704
|
# mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
|
664
705
|
#
|
665
|
-
# If you do this, then Mail will take the file name and work out the mime type
|
666
|
-
# set the Content-Type, Content-Disposition, Content-Transfer-Encoding
|
667
|
-
#
|
706
|
+
# If you do this, then Mail will take the file name and work out the mime type.
|
707
|
+
# It will also set the Content-Type, Content-Disposition, Content-Transfer-Encoding
|
708
|
+
# and encode the contents of the attachment in Base64.
|
668
709
|
#
|
669
710
|
# You can also specify overrides if you want by passing a hash instead of a string:
|
670
711
|
#
|
671
|
-
# mail.attachments['filename.jpg'] = {mime_type: 'application/
|
712
|
+
# mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
|
672
713
|
# content: File.read('/path/to/filename.jpg')}
|
673
714
|
#
|
674
|
-
# If you want to use
|
675
|
-
#
|
676
|
-
#
|
715
|
+
# If you want to use encoding other than Base64 then you will need to pass encoding
|
716
|
+
# type along with the pre-encoded content as Mail doesn't know how to decode the
|
717
|
+
# data:
|
677
718
|
#
|
678
719
|
# file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
|
679
|
-
# mail.attachments['filename.jpg'] = {mime_type: 'application/
|
720
|
+
# mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
|
680
721
|
# encoding: 'SpecialEncoding',
|
681
722
|
# content: file_content }
|
682
723
|
#
|
@@ -798,151 +839,188 @@ module ActionMailer
|
|
798
839
|
# end
|
799
840
|
#
|
800
841
|
def mail(headers = {}, &block)
|
801
|
-
return
|
802
|
-
|
803
|
-
m = @_message
|
842
|
+
return message if @_mail_was_called && headers.blank? && !block
|
804
843
|
|
805
844
|
# At the beginning, do not consider class default for content_type
|
806
845
|
content_type = headers[:content_type]
|
807
846
|
|
808
|
-
|
809
|
-
default_values = {}
|
810
|
-
self.class.default.each do |k,v|
|
811
|
-
default_values[k] = v.is_a?(Proc) ? instance_eval(&v) : v
|
812
|
-
end
|
813
|
-
|
814
|
-
# Handle defaults
|
815
|
-
headers = headers.reverse_merge(default_values)
|
816
|
-
headers[:subject] ||= default_i18n_subject
|
847
|
+
headers = apply_defaults(headers)
|
817
848
|
|
818
849
|
# Apply charset at the beginning so all fields are properly quoted
|
819
|
-
|
850
|
+
message.charset = charset = headers[:charset]
|
820
851
|
|
821
852
|
# Set configure delivery behavior
|
822
|
-
wrap_delivery_behavior!(headers
|
853
|
+
wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options])
|
823
854
|
|
824
|
-
|
825
|
-
assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
|
826
|
-
assignable.each { |k, v| m[k] = v }
|
855
|
+
assign_headers_to_message(message, headers)
|
827
856
|
|
828
857
|
# Render the templates and blocks
|
829
858
|
responses = collect_responses(headers, &block)
|
830
859
|
@_mail_was_called = true
|
831
860
|
|
832
|
-
create_parts_from_responses(
|
861
|
+
create_parts_from_responses(message, responses)
|
833
862
|
|
834
863
|
# Setup content type, reapply charset and handle parts order
|
835
|
-
|
836
|
-
|
864
|
+
message.content_type = set_content_type(message, content_type, headers[:content_type])
|
865
|
+
message.charset = charset
|
837
866
|
|
838
|
-
if
|
839
|
-
|
840
|
-
|
867
|
+
if message.multipart?
|
868
|
+
message.body.set_sort_order(headers[:parts_order])
|
869
|
+
message.body.sort_parts!
|
841
870
|
end
|
842
871
|
|
843
|
-
|
872
|
+
message
|
844
873
|
end
|
845
874
|
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
875
|
+
private
|
876
|
+
|
877
|
+
# Used by #mail to set the content type of the message.
|
878
|
+
#
|
879
|
+
# It will use the given +user_content_type+, or multipart if the mail
|
880
|
+
# message has any attachments. If the attachments are inline, the content
|
881
|
+
# type will be "multipart/related", otherwise "multipart/mixed".
|
882
|
+
#
|
883
|
+
# If there is no content type passed in via headers, and there are no
|
884
|
+
# attachments, or the message is multipart, then the default content type is
|
885
|
+
# used.
|
886
|
+
def set_content_type(m, user_content_type, class_default) # :doc:
|
887
|
+
params = m.content_type_parameters || {}
|
888
|
+
case
|
889
|
+
when user_content_type.present?
|
890
|
+
user_content_type
|
891
|
+
when m.has_attachments?
|
892
|
+
if m.attachments.detect(&:inline?)
|
893
|
+
["multipart", "related", params]
|
894
|
+
else
|
895
|
+
["multipart", "mixed", params]
|
896
|
+
end
|
897
|
+
when m.multipart?
|
898
|
+
["multipart", "alternative", params]
|
865
899
|
else
|
866
|
-
|
900
|
+
m.content_type || class_default
|
867
901
|
end
|
868
|
-
when m.multipart?
|
869
|
-
["multipart", "alternative", params]
|
870
|
-
else
|
871
|
-
m.content_type || class_default
|
872
902
|
end
|
873
|
-
end
|
874
903
|
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
904
|
+
# Translates the +subject+ using Rails I18n class under <tt>[mailer_scope, action_name]</tt> scope.
|
905
|
+
# If it does not find a translation for the +subject+ under the specified scope it will default to a
|
906
|
+
# humanized version of the <tt>action_name</tt>.
|
907
|
+
# If the subject has interpolations, you can pass them through the +interpolations+ parameter.
|
908
|
+
def default_i18n_subject(interpolations = {}) # :doc:
|
909
|
+
mailer_scope = self.class.mailer_name.tr("/", ".")
|
910
|
+
I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
|
911
|
+
end
|
912
|
+
|
913
|
+
# Emails do not support relative path links.
|
914
|
+
def self.supports_path? # :doc:
|
915
|
+
false
|
916
|
+
end
|
917
|
+
|
918
|
+
def apply_defaults(headers)
|
919
|
+
default_values = self.class.default.map do |key, value|
|
920
|
+
[
|
921
|
+
key,
|
922
|
+
compute_default(value)
|
923
|
+
]
|
924
|
+
end.to_h
|
925
|
+
|
926
|
+
headers_with_defaults = headers.reverse_merge(default_values)
|
927
|
+
headers_with_defaults[:subject] ||= default_i18n_subject
|
928
|
+
headers_with_defaults
|
929
|
+
end
|
883
930
|
|
884
|
-
|
885
|
-
|
931
|
+
def compute_default(value)
|
932
|
+
return value unless value.is_a?(Proc)
|
933
|
+
|
934
|
+
if value.arity == 1
|
935
|
+
instance_exec(self, &value)
|
936
|
+
else
|
937
|
+
instance_exec(&value)
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
def assign_headers_to_message(message, headers)
|
942
|
+
assignable = headers.except(:parts_order, :content_type, :body, :template_name,
|
943
|
+
:template_path, :delivery_method, :delivery_method_options)
|
944
|
+
assignable.each { |k, v| message[k] = v }
|
945
|
+
end
|
946
|
+
|
947
|
+
def collect_responses(headers, &block)
|
948
|
+
if block_given?
|
949
|
+
collect_responses_from_block(headers, &block)
|
950
|
+
elsif headers[:body]
|
951
|
+
collect_responses_from_text(headers)
|
952
|
+
else
|
953
|
+
collect_responses_from_templates(headers)
|
954
|
+
end
|
955
|
+
end
|
886
956
|
|
887
|
-
|
888
|
-
|
957
|
+
def collect_responses_from_block(headers)
|
958
|
+
templates_name = headers[:template_name] || action_name
|
959
|
+
collector = ActionMailer::Collector.new(lookup_context) { render(templates_name) }
|
889
960
|
yield(collector)
|
890
|
-
|
891
|
-
|
892
|
-
|
961
|
+
collector.responses
|
962
|
+
end
|
963
|
+
|
964
|
+
def collect_responses_from_text(headers)
|
965
|
+
[{
|
893
966
|
body: headers.delete(:body),
|
894
|
-
content_type:
|
895
|
-
}
|
896
|
-
|
897
|
-
templates_path = headers.delete(:template_path) || self.class.mailer_name
|
898
|
-
templates_name = headers.delete(:template_name) || action_name
|
967
|
+
content_type: headers[:content_type] || "text/plain"
|
968
|
+
}]
|
969
|
+
end
|
899
970
|
|
900
|
-
|
901
|
-
|
971
|
+
def collect_responses_from_templates(headers)
|
972
|
+
templates_path = headers[:template_path] || self.class.mailer_name
|
973
|
+
templates_name = headers[:template_name] || action_name
|
902
974
|
|
903
|
-
|
904
|
-
|
905
|
-
|
975
|
+
each_template(Array(templates_path), templates_name).map do |template|
|
976
|
+
format = template.format || self.formats.first
|
977
|
+
{
|
978
|
+
body: render(template: template, formats: [format]),
|
979
|
+
content_type: Mime[format].to_s
|
906
980
|
}
|
907
981
|
end
|
908
982
|
end
|
909
983
|
|
910
|
-
|
911
|
-
|
984
|
+
def each_template(paths, name, &block)
|
985
|
+
templates = lookup_context.find_all(name, paths)
|
986
|
+
if templates.empty?
|
987
|
+
raise ActionView::MissingTemplate.new(paths, name, paths, false, "mailer")
|
988
|
+
else
|
989
|
+
templates.uniq(&:format).each(&block)
|
990
|
+
end
|
991
|
+
end
|
912
992
|
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
993
|
+
def create_parts_from_responses(m, responses)
|
994
|
+
if responses.size == 1 && !m.has_attachments?
|
995
|
+
responses[0].each { |k, v| m[k] = v }
|
996
|
+
elsif responses.size > 1 && m.has_attachments?
|
997
|
+
container = Mail::Part.new
|
998
|
+
container.content_type = "multipart/alternative"
|
999
|
+
responses.each { |r| insert_part(container, r, m.charset) }
|
1000
|
+
m.add_part(container)
|
1001
|
+
else
|
1002
|
+
responses.each { |r| insert_part(m, r, m.charset) }
|
1003
|
+
end
|
919
1004
|
end
|
920
|
-
end
|
921
1005
|
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
container = Mail::Part.new
|
927
|
-
container.content_type = "multipart/alternative"
|
928
|
-
responses.each { |r| insert_part(container, r, m.charset) }
|
929
|
-
m.add_part(container)
|
930
|
-
else
|
931
|
-
responses.each { |r| insert_part(m, r, m.charset) }
|
1006
|
+
def insert_part(container, response, charset)
|
1007
|
+
response[:charset] ||= charset
|
1008
|
+
part = Mail::Part.new(response)
|
1009
|
+
container.add_part(part)
|
932
1010
|
end
|
933
|
-
end
|
934
1011
|
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
1012
|
+
# This and #instrument_name is for caching instrument
|
1013
|
+
def instrument_payload(key)
|
1014
|
+
{
|
1015
|
+
mailer: mailer_name,
|
1016
|
+
key: key
|
1017
|
+
}
|
1018
|
+
end
|
940
1019
|
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
end
|
1020
|
+
def instrument_name
|
1021
|
+
"action_mailer"
|
1022
|
+
end
|
945
1023
|
|
946
|
-
|
1024
|
+
ActiveSupport.run_load_hooks(:action_mailer, self)
|
947
1025
|
end
|
948
1026
|
end
|