actionmailer 5.2.8.1 → 6.0.6
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 +123 -39
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -39
- data/lib/action_mailer/base.rb +56 -22
- data/lib/action_mailer/delivery_job.rb +9 -0
- data/lib/action_mailer/gem_version.rb +4 -4
- data/lib/action_mailer/inline_preview_interceptor.rb +1 -3
- data/lib/action_mailer/log_subscriber.rb +6 -2
- data/lib/action_mailer/mail_delivery_job.rb +43 -0
- data/lib/action_mailer/message_delivery.rb +10 -3
- data/lib/action_mailer/parameterized.rb +25 -7
- data/lib/action_mailer/preview.rb +21 -5
- data/lib/action_mailer/railtie.rb +18 -7
- data/lib/action_mailer/test_case.rb +0 -2
- data/lib/action_mailer/test_helper.rb +32 -14
- data/lib/action_mailer.rb +2 -1
- data/lib/rails/generators/mailer/mailer_generator.rb +1 -1
- metadata +20 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe6f6cbc34bc7f86f69dfa5dfc71f59aa29683c80a50de2df742cc32ab56f874
|
4
|
+
data.tar.gz: 8ad68f46ec8fb91e8965228a592f99a1b95b2f6af13302ac6fa12534ce185cae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fa6e8431a41a9fcf48c6a176d854bf8ffa83a18e9d050098417382fcc35bde9d4f7f7098423b9b784f00c00b6beafc50588fa7d900710bb0ead0249ff2c9e17
|
7
|
+
data.tar.gz: 7c06b4dcaadaf47f69c245c0b897d32a3af564552ae7a65a1576bd709945f67f0a3434b3ed77cd057d3e0f8e5ee03ca538d3aff33acf5c063b4931a5d09bdb34
|
data/CHANGELOG.md
CHANGED
@@ -1,134 +1,218 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 6.0.6 (September 09, 2022) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails 5.
|
6
|
+
## Rails 6.0.5.1 (July 12, 2022) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails
|
11
|
+
## Rails 6.0.5 (May 09, 2022) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails
|
16
|
+
## Rails 6.0.4.8 (April 26, 2022) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails
|
21
|
+
## Rails 6.0.4.7 (March 08, 2022) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails
|
26
|
+
## Rails 6.0.4.6 (February 11, 2022) ##
|
27
27
|
|
28
28
|
* No changes.
|
29
29
|
|
30
30
|
|
31
|
-
## Rails
|
31
|
+
## Rails 6.0.4.5 (February 11, 2022) ##
|
32
32
|
|
33
33
|
* No changes.
|
34
34
|
|
35
35
|
|
36
|
-
## Rails
|
36
|
+
## Rails 6.0.4.4 (December 15, 2021) ##
|
37
37
|
|
38
38
|
* No changes.
|
39
39
|
|
40
40
|
|
41
|
-
## Rails
|
41
|
+
## Rails 6.0.4.3 (December 14, 2021) ##
|
42
42
|
|
43
43
|
* No changes.
|
44
44
|
|
45
45
|
|
46
|
-
## Rails
|
46
|
+
## Rails 6.0.4.2 (December 14, 2021) ##
|
47
47
|
|
48
48
|
* No changes.
|
49
49
|
|
50
50
|
|
51
|
-
## Rails
|
51
|
+
## Rails 6.0.4.1 (August 19, 2021) ##
|
52
52
|
|
53
53
|
* No changes.
|
54
54
|
|
55
55
|
|
56
|
-
## Rails
|
56
|
+
## Rails 6.0.4 (June 15, 2021) ##
|
57
57
|
|
58
58
|
* No changes.
|
59
59
|
|
60
60
|
|
61
|
-
## Rails
|
61
|
+
## Rails 6.0.3.7 (May 05, 2021) ##
|
62
62
|
|
63
63
|
* No changes.
|
64
64
|
|
65
65
|
|
66
|
-
## Rails
|
66
|
+
## Rails 6.0.3.6 (March 26, 2021) ##
|
67
67
|
|
68
68
|
* No changes.
|
69
69
|
|
70
70
|
|
71
|
-
## Rails
|
71
|
+
## Rails 6.0.3.5 (February 10, 2021) ##
|
72
72
|
|
73
73
|
* No changes.
|
74
74
|
|
75
75
|
|
76
|
-
## Rails
|
76
|
+
## Rails 6.0.3.4 (October 07, 2020) ##
|
77
77
|
|
78
78
|
* No changes.
|
79
79
|
|
80
80
|
|
81
|
-
## Rails
|
81
|
+
## Rails 6.0.3.3 (September 09, 2020) ##
|
82
82
|
|
83
83
|
* No changes.
|
84
84
|
|
85
85
|
|
86
|
-
## Rails
|
86
|
+
## Rails 6.0.3.2 (June 17, 2020) ##
|
87
87
|
|
88
88
|
* No changes.
|
89
89
|
|
90
90
|
|
91
|
-
## Rails
|
91
|
+
## Rails 6.0.3.1 (May 18, 2020) ##
|
92
92
|
|
93
93
|
* No changes.
|
94
94
|
|
95
95
|
|
96
|
-
## Rails
|
96
|
+
## Rails 6.0.3 (May 06, 2020) ##
|
97
97
|
|
98
98
|
* No changes.
|
99
99
|
|
100
100
|
|
101
|
-
## Rails
|
101
|
+
## Rails 6.0.2.2 (March 19, 2020) ##
|
102
102
|
|
103
|
-
*
|
103
|
+
* No changes.
|
104
104
|
|
105
|
-
|
105
|
+
|
106
|
+
## Rails 6.0.2.1 (December 18, 2019) ##
|
107
|
+
|
108
|
+
* No changes.
|
109
|
+
|
110
|
+
|
111
|
+
## Rails 6.0.2 (December 13, 2019) ##
|
112
|
+
|
113
|
+
* Fix ActionMailer assertions don't work for parameterized mail with legacy delivery job.
|
114
|
+
|
115
|
+
*bogdanvlviv*
|
116
|
+
|
117
|
+
|
118
|
+
## Rails 6.0.1 (November 5, 2019) ##
|
119
|
+
|
120
|
+
* No changes.
|
106
121
|
|
107
122
|
|
108
|
-
## Rails
|
123
|
+
## Rails 6.0.0 (August 16, 2019) ##
|
109
124
|
|
110
|
-
*
|
111
|
-
|
125
|
+
* No changes.
|
126
|
+
|
127
|
+
|
128
|
+
## Rails 6.0.0.rc2 (July 22, 2019) ##
|
129
|
+
|
130
|
+
* No changes.
|
131
|
+
|
132
|
+
|
133
|
+
## Rails 6.0.0.rc1 (April 24, 2019) ##
|
134
|
+
|
135
|
+
* No changes.
|
136
|
+
|
137
|
+
|
138
|
+
## Rails 6.0.0.beta3 (March 11, 2019) ##
|
139
|
+
|
140
|
+
* No changes.
|
112
141
|
|
113
|
-
*Jimmy Bourassa*
|
114
142
|
|
115
|
-
|
143
|
+
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
144
|
+
|
145
|
+
* No changes.
|
146
|
+
|
147
|
+
|
148
|
+
## Rails 6.0.0.beta1 (January 18, 2019) ##
|
149
|
+
|
150
|
+
* Deprecate `ActionMailer::Base.receive` in favor of [Action Mailbox](https://github.com/rails/rails/tree/master/actionmailbox).
|
151
|
+
|
152
|
+
*George Claghorn*
|
153
|
+
|
154
|
+
* Add `MailDeliveryJob` for delivering both regular and parameterized mail. Deprecate using `DeliveryJob` and `Parameterized::DeliveryJob`.
|
155
|
+
|
156
|
+
*Gannon McGibbon*
|
157
|
+
|
158
|
+
* Fix ActionMailer assertions not working when a Mail defines
|
159
|
+
a custom delivery job class
|
160
|
+
|
161
|
+
*Edouard Chin*
|
162
|
+
|
163
|
+
* Mails with multipart `format` blocks with implicit render now also check for
|
164
|
+
a template name in options hash instead of only using the action name.
|
165
|
+
|
166
|
+
*Marcus Ilgner*
|
167
|
+
|
168
|
+
* `ActionDispatch::IntegrationTest` includes `ActionMailer::TestHelper` module by default.
|
169
|
+
|
170
|
+
*Ricardo Díaz*
|
171
|
+
|
172
|
+
* Add `perform_deliveries` to a payload of `deliver.action_mailer` notification.
|
173
|
+
|
174
|
+
*Yoshiyuki Kinjo*
|
175
|
+
|
176
|
+
* Change delivery logging message when `perform_deliveries` is false.
|
177
|
+
|
178
|
+
*Yoshiyuki Kinjo*
|
179
|
+
|
180
|
+
* Allow call `assert_enqueued_email_with` with no block.
|
181
|
+
|
182
|
+
Example:
|
183
|
+
```
|
184
|
+
def test_email
|
185
|
+
ContactMailer.welcome.deliver_later
|
186
|
+
assert_enqueued_email_with ContactMailer, :welcome
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_email_with_arguments
|
190
|
+
ContactMailer.welcome("Hello", "Goodbye").deliver_later
|
191
|
+
assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
*bogdanvlviv*
|
196
|
+
|
197
|
+
* Ensure mail gem is eager autoloaded when eager load is true to prevent thread deadlocks.
|
198
|
+
|
199
|
+
*Samuel Cochran*
|
116
200
|
|
117
|
-
|
118
|
-
ContactMailer.welcome.deliver_later
|
119
|
-
end
|
201
|
+
* Perform email jobs in `assert_emails`.
|
120
202
|
|
121
|
-
*
|
203
|
+
*Gannon McGibbon*
|
122
204
|
|
123
|
-
*
|
205
|
+
* Add `Base.unregister_observer`, `Base.unregister_observers`,
|
206
|
+
`Base.unregister_interceptor`, `Base.unregister_interceptors`,
|
207
|
+
`Base.unregister_preview_interceptor` and `Base.unregister_preview_interceptors`.
|
208
|
+
This makes it possible to dynamically add and remove email observers and
|
209
|
+
interceptors at runtime in the same way they're registered.
|
124
210
|
|
125
|
-
|
126
|
-
self.delivery_job = MyCustomDeliveryJob
|
211
|
+
*Claudio Ortolina*, *Kota Miyake*
|
127
212
|
|
128
|
-
|
129
|
-
end
|
213
|
+
* Rails 6 requires Ruby 2.5.0 or newer.
|
130
214
|
|
131
|
-
*
|
215
|
+
*Jeremy Daer*, *Kasper Timm Hansen*
|
132
216
|
|
133
217
|
|
134
|
-
Please check [5-
|
218
|
+
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:
|
@@ -150,7 +116,7 @@ The latest version of Action Mailer can be installed with RubyGems:
|
|
150
116
|
|
151
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/main/actionmailer
|
154
120
|
|
155
121
|
|
156
122
|
== License
|
@@ -164,7 +130,7 @@ Action Mailer is released under the MIT license:
|
|
164
130
|
|
165
131
|
API documentation is at
|
166
132
|
|
167
|
-
*
|
133
|
+
* https://api.rubyonrails.org
|
168
134
|
|
169
135
|
Bug reports for the Ruby on Rails project can be filed here:
|
170
136
|
|
@@ -172,4 +138,4 @@ Bug reports for the Ruby on Rails project can be filed here:
|
|
172
138
|
|
173
139
|
Feature requests should be discussed on the rails-core mailing list here:
|
174
140
|
|
175
|
-
* https://
|
141
|
+
* https://discuss.rubyonrails.org/c/rubyonrails-core
|
data/lib/action_mailer/base.rb
CHANGED
@@ -408,7 +408,7 @@ module ActionMailer
|
|
408
408
|
# really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
|
409
409
|
# of an OpenSSL verify constant (<tt>'none'</tt> or <tt>'peer'</tt>) or directly the constant
|
410
410
|
# (<tt>OpenSSL::SSL::VERIFY_NONE</tt> or <tt>OpenSSL::SSL::VERIFY_PEER</tt>).
|
411
|
-
#
|
411
|
+
# * <tt>:ssl/:tls</tt> Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)
|
412
412
|
#
|
413
413
|
# * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
|
414
414
|
# * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
|
@@ -475,11 +475,21 @@ module ActionMailer
|
|
475
475
|
observers.flatten.compact.each { |observer| register_observer(observer) }
|
476
476
|
end
|
477
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
|
+
|
478
483
|
# Register one or more Interceptors which will be called before mail is sent.
|
479
484
|
def register_interceptors(*interceptors)
|
480
485
|
interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
|
481
486
|
end
|
482
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
|
+
|
483
493
|
# Register an Observer which will be notified when mail is delivered.
|
484
494
|
# Either a class, string or symbol can be passed in as the Observer.
|
485
495
|
# If a string or symbol is passed in it will be camelized and constantized.
|
@@ -487,6 +497,13 @@ module ActionMailer
|
|
487
497
|
Mail.register_observer(observer_class_for(observer))
|
488
498
|
end
|
489
499
|
|
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))
|
505
|
+
end
|
506
|
+
|
490
507
|
# Register an Interceptor which will be called before mail is sent.
|
491
508
|
# Either a class, string or symbol can be passed in as the Interceptor.
|
492
509
|
# If a string or symbol is passed in it will be camelized and constantized.
|
@@ -494,6 +511,13 @@ module ActionMailer
|
|
494
511
|
Mail.register_interceptor(observer_class_for(interceptor))
|
495
512
|
end
|
496
513
|
|
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))
|
519
|
+
end
|
520
|
+
|
497
521
|
def observer_class_for(value) # :nodoc:
|
498
522
|
case value
|
499
523
|
when String, Symbol
|
@@ -541,6 +565,11 @@ module ActionMailer
|
|
541
565
|
# end
|
542
566
|
# end
|
543
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
|
+
|
544
573
|
ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
|
545
574
|
mail = Mail.new(raw_mail)
|
546
575
|
set_payload_for_mail(payload, mail)
|
@@ -562,17 +591,17 @@ module ActionMailer
|
|
562
591
|
end
|
563
592
|
|
564
593
|
private
|
565
|
-
|
566
594
|
def set_payload_for_mail(payload, mail)
|
567
|
-
payload[:
|
568
|
-
payload[:
|
569
|
-
payload[:
|
570
|
-
payload[:
|
571
|
-
payload[:
|
572
|
-
payload[:
|
573
|
-
payload[:
|
574
|
-
payload[:
|
575
|
-
payload[:
|
595
|
+
payload[:mail] = mail.encoded
|
596
|
+
payload[:mailer] = name
|
597
|
+
payload[:message_id] = mail.message_id
|
598
|
+
payload[:subject] = mail.subject
|
599
|
+
payload[:to] = mail.to
|
600
|
+
payload[:from] = mail.from
|
601
|
+
payload[:bcc] = mail.bcc if mail.bcc.present?
|
602
|
+
payload[:cc] = mail.cc if mail.cc.present?
|
603
|
+
payload[:date] = mail.date
|
604
|
+
payload[:perform_deliveries] = mail.perform_deliveries
|
576
605
|
end
|
577
606
|
|
578
607
|
def method_missing(method_name, *args)
|
@@ -582,6 +611,7 @@ module ActionMailer
|
|
582
611
|
super
|
583
612
|
end
|
584
613
|
end
|
614
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
585
615
|
|
586
616
|
def respond_to_missing?(method, include_all = false)
|
587
617
|
action_methods.include?(method.to_s) || super
|
@@ -843,7 +873,6 @@ module ActionMailer
|
|
843
873
|
end
|
844
874
|
|
845
875
|
private
|
846
|
-
|
847
876
|
# Used by #mail to set the content type of the message.
|
848
877
|
#
|
849
878
|
# It will use the given +user_content_type+, or multipart if the mail
|
@@ -877,7 +906,7 @@ module ActionMailer
|
|
877
906
|
# If the subject has interpolations, you can pass them through the +interpolations+ parameter.
|
878
907
|
def default_i18n_subject(interpolations = {}) # :doc:
|
879
908
|
mailer_scope = self.class.mailer_name.tr("/", ".")
|
880
|
-
I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
|
909
|
+
I18n.t(:subject, **interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
|
881
910
|
end
|
882
911
|
|
883
912
|
# Emails do not support relative path links.
|
@@ -914,11 +943,9 @@ module ActionMailer
|
|
914
943
|
assignable.each { |k, v| message[k] = v }
|
915
944
|
end
|
916
945
|
|
917
|
-
def collect_responses(headers)
|
946
|
+
def collect_responses(headers, &block)
|
918
947
|
if block_given?
|
919
|
-
|
920
|
-
yield(collector)
|
921
|
-
collector.responses
|
948
|
+
collect_responses_from_block(headers, &block)
|
922
949
|
elsif headers[:body]
|
923
950
|
collect_responses_from_text(headers)
|
924
951
|
else
|
@@ -926,6 +953,13 @@ module ActionMailer
|
|
926
953
|
end
|
927
954
|
end
|
928
955
|
|
956
|
+
def collect_responses_from_block(headers)
|
957
|
+
templates_name = headers[:template_name] || action_name
|
958
|
+
collector = ActionMailer::Collector.new(lookup_context) { render(templates_name) }
|
959
|
+
yield(collector)
|
960
|
+
collector.responses
|
961
|
+
end
|
962
|
+
|
929
963
|
def collect_responses_from_text(headers)
|
930
964
|
[{
|
931
965
|
body: headers.delete(:body),
|
@@ -938,10 +972,10 @@ module ActionMailer
|
|
938
972
|
templates_name = headers[:template_name] || action_name
|
939
973
|
|
940
974
|
each_template(Array(templates_path), templates_name).map do |template|
|
941
|
-
|
975
|
+
format = template.format || self.formats.first
|
942
976
|
{
|
943
|
-
body: render(template: template),
|
944
|
-
content_type:
|
977
|
+
body: render(template: template, formats: [format]),
|
978
|
+
content_type: Mime[format].to_s
|
945
979
|
}
|
946
980
|
end
|
947
981
|
end
|
@@ -951,7 +985,7 @@ module ActionMailer
|
|
951
985
|
if templates.empty?
|
952
986
|
raise ActionView::MissingTemplate.new(paths, name, paths, false, "mailer")
|
953
987
|
else
|
954
|
-
templates.uniq(&:
|
988
|
+
templates.uniq(&:format).each(&block)
|
955
989
|
end
|
956
990
|
end
|
957
991
|
|
@@ -983,7 +1017,7 @@ module ActionMailer
|
|
983
1017
|
end
|
984
1018
|
|
985
1019
|
def instrument_name
|
986
|
-
"action_mailer"
|
1020
|
+
"action_mailer"
|
987
1021
|
end
|
988
1022
|
|
989
1023
|
ActiveSupport.run_load_hooks(:action_mailer, self)
|
@@ -12,9 +12,18 @@ module ActionMailer
|
|
12
12
|
|
13
13
|
rescue_from StandardError, with: :handle_exception_with_mailer_class
|
14
14
|
|
15
|
+
before_perform do
|
16
|
+
ActiveSupport::Deprecation.warn <<~MSG.squish
|
17
|
+
Sending mail with DeliveryJob and Parameterized::DeliveryJob
|
18
|
+
is deprecated and will be removed in Rails 6.1.
|
19
|
+
Please use MailDeliveryJob instead.
|
20
|
+
MSG
|
21
|
+
end
|
22
|
+
|
15
23
|
def perform(mailer, mail_method, delivery_method, *args) #:nodoc:
|
16
24
|
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
|
17
25
|
end
|
26
|
+
ruby2_keywords(:perform) if respond_to?(:ruby2_keywords, true)
|
18
27
|
|
19
28
|
private
|
20
29
|
# "Deserialize" the mailer class name by hand in case another argument
|
@@ -9,8 +9,12 @@ module ActionMailer
|
|
9
9
|
# An email was delivered.
|
10
10
|
def deliver(event)
|
11
11
|
info do
|
12
|
-
|
13
|
-
|
12
|
+
perform_deliveries = event.payload[:perform_deliveries]
|
13
|
+
if perform_deliveries
|
14
|
+
"Delivered mail #{event.payload[:message_id]} (#{event.duration.round(1)}ms)"
|
15
|
+
else
|
16
|
+
"Skipped delivery of mail #{event.payload[:message_id]} as `perform_deliveries` is false"
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
debug { event.payload[:mail] }
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_job"
|
4
|
+
|
5
|
+
module ActionMailer
|
6
|
+
# The <tt>ActionMailer::MailDeliveryJob</tt> class is used when you
|
7
|
+
# want to send emails outside of the request-response cycle. It supports
|
8
|
+
# sending either parameterized or normal mail.
|
9
|
+
#
|
10
|
+
# Exceptions are rescued and handled by the mailer class.
|
11
|
+
class MailDeliveryJob < ActiveJob::Base # :nodoc:
|
12
|
+
queue_as { ActionMailer::Base.deliver_later_queue_name }
|
13
|
+
|
14
|
+
rescue_from StandardError, with: :handle_exception_with_mailer_class
|
15
|
+
|
16
|
+
def perform(mailer, mail_method, delivery_method, args:, kwargs: nil, params: nil)
|
17
|
+
mailer_class = params ? mailer.constantize.with(params) : mailer.constantize
|
18
|
+
message = if kwargs
|
19
|
+
mailer_class.public_send(mail_method, *args, **kwargs)
|
20
|
+
else
|
21
|
+
mailer_class.public_send(mail_method, *args)
|
22
|
+
end
|
23
|
+
message.send(delivery_method)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
# "Deserialize" the mailer class name by hand in case another argument
|
28
|
+
# (like a Global ID reference) raised DeserializationError.
|
29
|
+
def mailer_class
|
30
|
+
if mailer = Array(@serialized_arguments).first || Array(arguments).first
|
31
|
+
mailer.constantize
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_exception_with_mailer_class(exception)
|
36
|
+
if klass = mailer_class
|
37
|
+
klass.handle_exception exception
|
38
|
+
else
|
39
|
+
raise exception
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -23,13 +23,14 @@ module ActionMailer
|
|
23
23
|
@processed_mailer = nil
|
24
24
|
@mail_message = nil
|
25
25
|
end
|
26
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
26
27
|
|
27
28
|
# Method calls are delegated to the Mail::Message that's ready to deliver.
|
28
29
|
def __getobj__ #:nodoc:
|
29
30
|
@mail_message ||= processed_mailer.message
|
30
31
|
end
|
31
32
|
|
32
|
-
# Unused except for delegator internals (dup,
|
33
|
+
# Unused except for delegator internals (dup, marshalling).
|
33
34
|
def __setobj__(mail_message) #:nodoc:
|
34
35
|
@mail_message = mail_message
|
35
36
|
end
|
@@ -135,9 +136,15 @@ module ActionMailer
|
|
135
136
|
"#deliver_later, 2. only touch the message *within your mailer " \
|
136
137
|
"method*, or 3. use a custom Active Job instead of #deliver_later."
|
137
138
|
else
|
138
|
-
args = @mailer_class.name, @action.to_s, delivery_method.to_s, *@args
|
139
139
|
job = @mailer_class.delivery_job
|
140
|
-
|
140
|
+
|
141
|
+
if job <= MailDeliveryJob
|
142
|
+
job.set(options).perform_later(
|
143
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, args: @args)
|
144
|
+
else
|
145
|
+
job.set(options).perform_later(
|
146
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, *@args)
|
147
|
+
end
|
141
148
|
end
|
142
149
|
end
|
143
150
|
end
|
@@ -115,17 +115,26 @@ module ActionMailer
|
|
115
115
|
super
|
116
116
|
end
|
117
117
|
end
|
118
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
118
119
|
|
119
120
|
def respond_to_missing?(method, include_all = false)
|
120
121
|
@mailer.respond_to?(method, include_all)
|
121
122
|
end
|
122
123
|
end
|
123
124
|
|
125
|
+
class DeliveryJob < ActionMailer::DeliveryJob # :nodoc:
|
126
|
+
def perform(mailer, mail_method, delivery_method, params, *args)
|
127
|
+
mailer.constantize.with(params).public_send(mail_method, *args).send(delivery_method)
|
128
|
+
end
|
129
|
+
ruby2_keywords(:perform) if respond_to?(:ruby2_keywords, true)
|
130
|
+
end
|
131
|
+
|
124
132
|
class MessageDelivery < ActionMailer::MessageDelivery # :nodoc:
|
125
133
|
def initialize(mailer_class, action, params, *args)
|
126
134
|
super(mailer_class, action, *args)
|
127
135
|
@params = params
|
128
136
|
end
|
137
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
129
138
|
|
130
139
|
private
|
131
140
|
def processed_mailer
|
@@ -139,16 +148,25 @@ module ActionMailer
|
|
139
148
|
if processed?
|
140
149
|
super
|
141
150
|
else
|
142
|
-
|
143
|
-
|
151
|
+
job = delivery_job_class
|
152
|
+
|
153
|
+
if job <= MailDeliveryJob
|
154
|
+
job.set(options).perform_later(
|
155
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, params: @params, args: @args)
|
156
|
+
else
|
157
|
+
job.set(options).perform_later(
|
158
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args)
|
159
|
+
end
|
144
160
|
end
|
145
161
|
end
|
146
|
-
end
|
147
162
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
163
|
+
def delivery_job_class
|
164
|
+
if @mailer_class.delivery_job <= MailDeliveryJob
|
165
|
+
@mailer_class.delivery_job
|
166
|
+
else
|
167
|
+
Parameterized::DeliveryJob
|
168
|
+
end
|
169
|
+
end
|
152
170
|
end
|
153
171
|
end
|
154
172
|
end
|
@@ -31,22 +31,38 @@ module ActionMailer
|
|
31
31
|
interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
|
32
32
|
end
|
33
33
|
|
34
|
+
# Unregister one or more previously registered Interceptors.
|
35
|
+
def unregister_preview_interceptors(*interceptors)
|
36
|
+
interceptors.flatten.compact.each { |interceptor| unregister_preview_interceptor(interceptor) }
|
37
|
+
end
|
38
|
+
|
34
39
|
# Register an Interceptor which will be called before mail is previewed.
|
35
40
|
# Either a class or a string can be passed in as the Interceptor. If a
|
36
41
|
# string is passed in it will be constantized.
|
37
42
|
def register_preview_interceptor(interceptor)
|
38
|
-
preview_interceptor =
|
43
|
+
preview_interceptor = interceptor_class_for(interceptor)
|
44
|
+
|
45
|
+
unless preview_interceptors.include?(preview_interceptor)
|
46
|
+
preview_interceptors << preview_interceptor
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Unregister a previously registered Interceptor.
|
51
|
+
# Either a class or a string can be passed in as the Interceptor. If a
|
52
|
+
# string is passed in it will be constantized.
|
53
|
+
def unregister_preview_interceptor(interceptor)
|
54
|
+
preview_interceptors.delete(interceptor_class_for(interceptor))
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def interceptor_class_for(interceptor)
|
39
59
|
case interceptor
|
40
60
|
when String, Symbol
|
41
61
|
interceptor.to_s.camelize.constantize
|
42
62
|
else
|
43
63
|
interceptor
|
44
64
|
end
|
45
|
-
|
46
|
-
unless preview_interceptors.include?(preview_interceptor)
|
47
|
-
preview_interceptors << preview_interceptor
|
48
65
|
end
|
49
|
-
end
|
50
66
|
end
|
51
67
|
end
|
52
68
|
|
@@ -46,10 +46,25 @@ module ActionMailer
|
|
46
46
|
register_preview_interceptors(options.delete(:preview_interceptors))
|
47
47
|
register_observers(options.delete(:observers))
|
48
48
|
|
49
|
+
if delivery_job = options.delete(:delivery_job)
|
50
|
+
self.delivery_job = delivery_job.constantize
|
51
|
+
end
|
52
|
+
|
49
53
|
options.each { |k, v| send("#{k}=", v) }
|
50
54
|
end
|
51
55
|
|
52
|
-
ActiveSupport.on_load(:action_dispatch_integration_test)
|
56
|
+
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
57
|
+
include ActionMailer::TestHelper
|
58
|
+
include ActionMailer::TestCase::ClearTestDeliveries
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
initializer "action_mailer.set_autoload_paths" do |app|
|
63
|
+
options = app.config.action_mailer
|
64
|
+
|
65
|
+
if options.show_previews && options.preview_path
|
66
|
+
ActiveSupport::Dependencies.autoload_paths << options.preview_path
|
67
|
+
end
|
53
68
|
end
|
54
69
|
|
55
70
|
initializer "action_mailer.compile_config_methods" do
|
@@ -69,12 +84,8 @@ module ActionMailer
|
|
69
84
|
|
70
85
|
if options.show_previews
|
71
86
|
app.routes.prepend do
|
72
|
-
get "/rails/mailers"
|
73
|
-
get "/rails/mailers/*path"
|
74
|
-
end
|
75
|
-
|
76
|
-
if options.preview_path
|
77
|
-
ActiveSupport::Dependencies.autoload_paths << options.preview_path
|
87
|
+
get "/rails/mailers" => "rails/mailers#index", internal: true
|
88
|
+
get "/rails/mailers/*path" => "rails/mailers#preview", internal: true
|
78
89
|
end
|
79
90
|
end
|
80
91
|
end
|
@@ -22,7 +22,6 @@ module ActionMailer
|
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
|
-
|
26
25
|
def clear_test_deliveries
|
27
26
|
if ActionMailer::Base.delivery_method == :test
|
28
27
|
ActionMailer::Base.deliveries.clear
|
@@ -76,7 +75,6 @@ module ActionMailer
|
|
76
75
|
end
|
77
76
|
|
78
77
|
private
|
79
|
-
|
80
78
|
def initialize_test_deliveries
|
81
79
|
set_delivery_method :test
|
82
80
|
@old_perform_deliveries = ActionMailer::Base.perform_deliveries
|
@@ -28,13 +28,13 @@ module ActionMailer
|
|
28
28
|
#
|
29
29
|
# assert_emails 2 do
|
30
30
|
# ContactMailer.welcome.deliver_now
|
31
|
-
# ContactMailer.welcome.
|
31
|
+
# ContactMailer.welcome.deliver_later
|
32
32
|
# end
|
33
33
|
# end
|
34
|
-
def assert_emails(number)
|
34
|
+
def assert_emails(number, &block)
|
35
35
|
if block_given?
|
36
36
|
original_count = ActionMailer::Base.deliveries.size
|
37
|
-
|
37
|
+
perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, &block)
|
38
38
|
new_count = ActionMailer::Base.deliveries.size
|
39
39
|
assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
|
40
40
|
else
|
@@ -90,10 +90,23 @@ module ActionMailer
|
|
90
90
|
# end
|
91
91
|
# end
|
92
92
|
def assert_enqueued_emails(number, &block)
|
93
|
-
assert_enqueued_jobs
|
93
|
+
assert_enqueued_jobs(number, only: ->(job) { delivery_job_filter(job) }, &block)
|
94
94
|
end
|
95
95
|
|
96
|
-
# Asserts that
|
96
|
+
# Asserts that a specific email has been enqueued, optionally
|
97
|
+
# matching arguments.
|
98
|
+
#
|
99
|
+
# def test_email
|
100
|
+
# ContactMailer.welcome.deliver_later
|
101
|
+
# assert_enqueued_email_with ContactMailer, :welcome
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# def test_email_with_arguments
|
105
|
+
# ContactMailer.welcome("Hello", "Goodbye").deliver_later
|
106
|
+
# assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# If a block is passed, that block should cause the specified email
|
97
110
|
# to be enqueued.
|
98
111
|
#
|
99
112
|
# def test_email_in_block
|
@@ -106,20 +119,17 @@ module ActionMailer
|
|
106
119
|
#
|
107
120
|
# def test_parameterized_email
|
108
121
|
# assert_enqueued_email_with ContactMailer, :welcome,
|
109
|
-
# args: {email: 'user@example.com} do
|
122
|
+
# args: {email: 'user@example.com'} do
|
110
123
|
# ContactMailer.with(email: 'user@example.com').welcome.deliver_later
|
111
124
|
# end
|
112
125
|
# end
|
113
126
|
def assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block)
|
114
|
-
if args.is_a?
|
115
|
-
|
116
|
-
args = [mailer.to_s, method.to_s, "deliver_now", args]
|
127
|
+
args = if args.is_a?(Hash)
|
128
|
+
[mailer.to_s, method.to_s, "deliver_now", params: args, args: []]
|
117
129
|
else
|
118
|
-
|
119
|
-
args = [mailer.to_s, method.to_s, "deliver_now", *args]
|
130
|
+
[mailer.to_s, method.to_s, "deliver_now", args: Array(args)]
|
120
131
|
end
|
121
|
-
|
122
|
-
assert_enqueued_with(job: job, args: args, queue: queue, &block)
|
132
|
+
assert_enqueued_with(job: mailer.delivery_job, args: args, queue: queue, &block)
|
123
133
|
end
|
124
134
|
|
125
135
|
# Asserts that no emails are enqueued for later delivery.
|
@@ -138,7 +148,15 @@ module ActionMailer
|
|
138
148
|
# end
|
139
149
|
# end
|
140
150
|
def assert_no_enqueued_emails(&block)
|
141
|
-
|
151
|
+
assert_enqueued_emails 0, &block
|
142
152
|
end
|
153
|
+
|
154
|
+
private
|
155
|
+
def delivery_job_filter(job)
|
156
|
+
job_class = job.is_a?(Hash) ? job.fetch(:job) : job.class
|
157
|
+
|
158
|
+
Base.descendants.map(&:delivery_job).include?(job_class) ||
|
159
|
+
ActionMailer::Parameterized::DeliveryJob == job_class
|
160
|
+
end
|
143
161
|
end
|
144
162
|
end
|
data/lib/action_mailer.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2019 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -52,6 +52,7 @@ module ActionMailer
|
|
52
52
|
autoload :TestHelper
|
53
53
|
autoload :MessageDelivery
|
54
54
|
autoload :DeliveryJob
|
55
|
+
autoload :MailDeliveryJob
|
55
56
|
|
56
57
|
def self.eager_load!
|
57
58
|
super
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionmailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 6.0.6
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 6.0.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: actionview
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 6.0.6
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 6.0.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activejob
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 6.0.6
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 6.0.6
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: mail
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,8 +86,8 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '2.0'
|
89
|
-
description: Email on Rails. Compose, deliver,
|
90
|
-
|
89
|
+
description: Email on Rails. Compose, deliver, and test emails using the familiar
|
90
|
+
controller/view pattern. First-class support for multipart email and attachments.
|
91
91
|
email: david@loudthinking.com
|
92
92
|
executables: []
|
93
93
|
extensions: []
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- lib/action_mailer/gem_version.rb
|
105
105
|
- lib/action_mailer/inline_preview_interceptor.rb
|
106
106
|
- lib/action_mailer/log_subscriber.rb
|
107
|
+
- lib/action_mailer/mail_delivery_job.rb
|
107
108
|
- lib/action_mailer/mail_helper.rb
|
108
109
|
- lib/action_mailer/message_delivery.rb
|
109
110
|
- lib/action_mailer/parameterized.rb
|
@@ -117,12 +118,16 @@ files:
|
|
117
118
|
- lib/rails/generators/mailer/mailer_generator.rb
|
118
119
|
- lib/rails/generators/mailer/templates/application_mailer.rb.tt
|
119
120
|
- lib/rails/generators/mailer/templates/mailer.rb.tt
|
120
|
-
homepage:
|
121
|
+
homepage: https://rubyonrails.org
|
121
122
|
licenses:
|
122
123
|
- MIT
|
123
124
|
metadata:
|
124
|
-
|
125
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
125
|
+
bug_tracker_uri: https://github.com/rails/rails/issues
|
126
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.0.6/actionmailer/CHANGELOG.md
|
127
|
+
documentation_uri: https://api.rubyonrails.org/v6.0.6/
|
128
|
+
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
129
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.0.6/actionmailer
|
130
|
+
rubygems_mfa_required: 'true'
|
126
131
|
post_install_message:
|
127
132
|
rdoc_options: []
|
128
133
|
require_paths:
|
@@ -131,7 +136,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
136
|
requirements:
|
132
137
|
- - ">="
|
133
138
|
- !ruby/object:Gem::Version
|
134
|
-
version: 2.
|
139
|
+
version: 2.5.0
|
135
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
141
|
requirements:
|
137
142
|
- - ">="
|
@@ -142,5 +147,5 @@ requirements:
|
|
142
147
|
rubygems_version: 3.3.3
|
143
148
|
signing_key:
|
144
149
|
specification_version: 4
|
145
|
-
summary: Email composition
|
150
|
+
summary: Email composition and delivery framework (part of Rails).
|
146
151
|
test_files: []
|