actionmailer 4.2.11.2 → 6.0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +53 -102
- 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 +6 -4
- 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 +107 -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 +26 -24
- 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: de242d8851f7d5940a59de2dd52dd79058abfc1829ae657718c8315d99ba7fd0
|
4
|
+
data.tar.gz: ac37fe72fdc553ea4f70504bb2eeeccb0f9b8a3b2aea6e246293923f955aa3cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b98de51cb6fbcdf058e6607d984cadf777201d10225279aba45b103aa98dabf2f8b7fdba37bdcee7cb557d136a1d9c88f468714e67f27c11bac625ebf1254114
|
7
|
+
data.tar.gz: 4810debde39deadb3ff9db7fec384ac1970acaa5a5990aed9214e22a0418b5171c0995625738297cd39b741b7970587a61665dc36b3c4a7781f68c22f47ce589
|
data/CHANGELOG.md
CHANGED
@@ -1,162 +1,113 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 6.0.2.1 (December 18, 2019) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails
|
7
|
-
|
8
|
-
* No changes.
|
6
|
+
## Rails 6.0.2 (December 13, 2019) ##
|
9
7
|
|
8
|
+
* Fix ActionMailer assertions don't work for parameterized mail with legacy delivery job.
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
* No changes.
|
10
|
+
*bogdanvlviv*
|
14
11
|
|
15
12
|
|
16
|
-
## Rails
|
13
|
+
## Rails 6.0.1 (November 5, 2019) ##
|
17
14
|
|
18
15
|
* No changes.
|
19
16
|
|
20
17
|
|
21
|
-
## Rails
|
18
|
+
## Rails 6.0.0 (August 16, 2019) ##
|
22
19
|
|
23
20
|
* No changes.
|
24
21
|
|
25
22
|
|
26
|
-
## Rails
|
23
|
+
## Rails 6.0.0.rc2 (July 22, 2019) ##
|
27
24
|
|
28
25
|
* No changes.
|
29
26
|
|
30
27
|
|
31
|
-
## Rails
|
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) ##
|
28
|
+
## Rails 6.0.0.rc1 (April 24, 2019) ##
|
40
29
|
|
41
30
|
* No changes.
|
42
31
|
|
43
32
|
|
44
|
-
## Rails
|
33
|
+
## Rails 6.0.0.beta3 (March 11, 2019) ##
|
45
34
|
|
46
35
|
* No changes.
|
47
36
|
|
48
37
|
|
49
|
-
## Rails
|
38
|
+
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
50
39
|
|
51
40
|
* No changes.
|
52
41
|
|
53
42
|
|
54
|
-
## Rails
|
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) ##
|
43
|
+
## Rails 6.0.0.beta1 (January 18, 2019) ##
|
94
44
|
|
95
|
-
*
|
45
|
+
* Deprecate `ActionMailer::Base.receive` in favor of [Action Mailbox](https://github.com/rails/rails/tree/master/actionmailbox).
|
96
46
|
|
47
|
+
*George Claghorn*
|
97
48
|
|
98
|
-
|
49
|
+
* Add `MailDeliveryJob` for delivering both regular and parameterized mail. Deprecate using `DeliveryJob` and `Parameterized::DeliveryJob`.
|
99
50
|
|
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.
|
51
|
+
*Gannon McGibbon*
|
104
52
|
|
105
|
-
|
53
|
+
* Fix ActionMailer assertions not working when a Mail defines
|
54
|
+
a custom delivery job class
|
106
55
|
|
107
|
-
*
|
108
|
-
Passing `only_path: false` is no longer needed.
|
56
|
+
*Edouard Chin*
|
109
57
|
|
110
|
-
|
58
|
+
* Mails with multipart `format` blocks with implicit render now also check for
|
59
|
+
a template name in options hash instead of only using the action name.
|
111
60
|
|
112
|
-
*
|
61
|
+
*Marcus Ilgner*
|
113
62
|
|
114
|
-
*
|
63
|
+
* `ActionDispatch::IntegrationTest` includes `ActionMailer::TestHelper` module by default.
|
115
64
|
|
116
|
-
|
65
|
+
*Ricardo Díaz*
|
117
66
|
|
118
|
-
|
67
|
+
* Add `perform_deliveries` to a payload of `deliver.action_mailer` notification.
|
119
68
|
|
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.
|
69
|
+
*Yoshiyuki Kinjo*
|
125
70
|
|
126
|
-
|
71
|
+
* Change delivery logging message when `perform_deliveries` is false.
|
127
72
|
|
128
|
-
*
|
73
|
+
*Yoshiyuki Kinjo*
|
129
74
|
|
130
|
-
|
75
|
+
* Allow call `assert_enqueued_email_with` with no block.
|
131
76
|
|
132
|
-
|
133
|
-
|
134
|
-
|
77
|
+
Example:
|
78
|
+
```
|
79
|
+
def test_email
|
80
|
+
ContactMailer.welcome.deliver_later
|
81
|
+
assert_enqueued_email_with ContactMailer, :welcome
|
82
|
+
end
|
135
83
|
|
136
|
-
|
84
|
+
def test_email_with_arguments
|
85
|
+
ContactMailer.welcome("Hello", "Goodbye").deliver_later
|
86
|
+
assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
|
87
|
+
end
|
88
|
+
```
|
137
89
|
|
138
|
-
*
|
139
|
-
This is a safeguard to prevent invalid emails.
|
90
|
+
*bogdanvlviv*
|
140
91
|
|
141
|
-
|
92
|
+
* Ensure mail gem is eager autoloaded when eager load is true to prevent thread deadlocks.
|
142
93
|
|
143
|
-
*
|
94
|
+
*Samuel Cochran*
|
144
95
|
|
145
|
-
*
|
96
|
+
* Perform email jobs in `assert_emails`.
|
146
97
|
|
147
|
-
|
148
|
-
environments other than development (such as staging).
|
98
|
+
*Gannon McGibbon*
|
149
99
|
|
150
|
-
|
100
|
+
* Add `Base.unregister_observer`, `Base.unregister_observers`,
|
101
|
+
`Base.unregister_interceptor`, `Base.unregister_interceptors`,
|
102
|
+
`Base.unregister_preview_interceptor` and `Base.unregister_preview_interceptors`.
|
103
|
+
This makes it possible to dynamically add and remove email observers and
|
104
|
+
interceptors at runtime in the same way they're registered.
|
151
105
|
|
152
|
-
*
|
106
|
+
*Claudio Ortolina*, *Kota Miyake*
|
153
107
|
|
154
|
-
*
|
155
|
-
`config.action_mailer.preview_interceptors`.
|
108
|
+
* Rails 6 requires Ruby 2.5.0 or newer.
|
156
109
|
|
157
|
-
|
110
|
+
*Jeremy Daer*, *Kasper Timm Hansen*
|
158
111
|
|
159
|
-
*Yves Senn*
|
160
112
|
|
161
|
-
Please check [
|
162
|
-
for previous changes.
|
113
|
+
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
|