Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 612 lines (567 sloc) 26.827 kB
a9751a7 @josevalim Refactor ActionMailer layout and remove legacy one.
josevalim authored
1 require 'active_support/core_ext/class'
0ece244 Ensure implicit multipart templates with locale works as expected.
José Valim and Mikel Lindsaar authored
2 require 'active_support/core_ext/object/blank'
3 require 'active_support/core_ext/array/uniq_by'
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
4 require 'active_support/core_ext/module/delegation'
0ece244 Ensure implicit multipart templates with locale works as expected.
José Valim and Mikel Lindsaar authored
5 require 'active_support/core_ext/string/inflections'
616ebb8 @josevalim Remove unused code paths and require mail only when it's needed.
josevalim authored
6 require 'mail'
a288082 @mikel Adding :transfer_encoding -> :content_transfer_encoding as part of Tm…
mikel authored
7 require 'action_mailer/tmail_compat'
c985a0e Add some tests to collector with templates and any.
José Valim and Mikel Lindsaar authored
8 require 'action_mailer/collector'
a63caa4 Get tests to run (with failures) without old base around
Yehuda Katz + Carl Lerche authored
9
c4590d5 @dhh Fixed docs
dhh authored
10 module ActionMailer #:nodoc:
98dc582 @lifo Merge docrails.
lifo authored
11 # Action Mailer allows you to send email from your application using a mailer model and views.
db045db @dhh Initial
dhh authored
12 #
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
13 # = Mailer Models
20bd4bd @dhh Updated docs and otherwise
dhh authored
14 #
98dc582 @lifo Merge docrails.
lifo authored
15 # To use Action Mailer, you need to create a mailer model.
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
16 #
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
17 # $ script/generate mailer Notifier
18 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
19 # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods
20 # within the model which are then used to set variables to be used in the mail template, to
21 # change options on the mail, or to add attachments.
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
22 #
23 # Examples:
24 #
25 # class Notifier < ActionMailer::Base
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
26 # delivers_from 'system@example.com'
27 #
28 # def welcome(recipient)
29 # @account = recipient
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
30 # mail(:to => recipient.email_address_with_name,
31 # :bcc => ["bcc@example.com", "Order Watcher <watcher@example.com>"])
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
32 # end
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
33 # end
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
34 #
35 # Within the mailer method, you have access to the following methods:
36 #
37 # * <tt>attachments[]=</tt> - Allows you to add attachments to your email in an intuitive
38 # manner; <tt>attachments['filename.png'] = File.read('path/to/filename.png')</tt>
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
39 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
40 # * <tt>headers[]=</tt> - Allows you to specify non standard headers in your email such
41 # as <tt>headers['X-No-Spam'] = 'True'</tt>
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
42 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
43 # * <tt>mail</tt> - Allows you to specify your email to send.
44 #
45 # The hash passed to the mail method allows you to specify the most used headers in an email
46 # message, such as <tt>Subject</tt>, <tt>To</tt>, <tt>From</tt>, <tt>Cc</tt>, <tt>Bcc</tt>,
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
47 # <tt>Reply-To</tt> and <tt>Date</tt>. See the <tt>ActionMailer#mail</tt> method for more details.
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
48 #
49 # If you need other headers not listed above, use the <tt>headers['name'] = value</tt> method.
50 #
51 # The mail method, if not passed a block, will inspect your views and send all the views with
52 # the same name as the method, so the above action would send the +welcome.plain.erb+ view file
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
53 # as well as the +welcome.html.erb+ view file in a +multipart/alternative+ email.
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
54 #
55 # If you want to explicitly render only certain templates, pass a block:
56 #
57 # mail(:to => user.emai) do |format|
58 # format.text
59 # format.html
60 # end
20bd4bd @dhh Updated docs and otherwise
dhh authored
61 #
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
62 # The block syntax is useful if also need to specify information specific to a part:
63 #
64 # mail(:to => user.emai) do |format|
65 # format.text(:content_transfer_encoding => "base64")
66 # format.html
67 # end
68 #
69 # Or even to renderize a special view:
70 #
71 # mail(:to => user.emai) do |format|
72 # format.text
73 # format.html { render "some_other_template" }
74 # end
75 #
20bd4bd @dhh Updated docs and otherwise
dhh authored
76 # = Mailer views
77 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
78 # Like Action Controller, each mailer class has a corresponding view directory in which each
79 # method of the class looks for a template with its name.
80 #
81 # To define a template to be used with a mailing, create an <tt>.erb</tt> file with the same
82 # name as the method in your mailer model. For example, in the mailer defined above, the template at
83 # <tt>app/views/notifier/signup_notification.text.erb</tt> would be used to generate the email.
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
84 #
85 # Variables defined in the model are accessible as instance variables in the view.
86 #
87 # Emails by default are sent in plain text, so a sample view for our model example might look like this:
88 #
89 # Hi <%= @account.name %>,
90 # Thanks for joining our service! Please check back often.
91 #
20bd4bd @dhh Updated docs and otherwise
dhh authored
92 # You can even use Action Pack helpers in these views. For example:
93 #
94 # You got a new note!
ee70d1b @josevalim adv_attr_accessors in ActionMailer are not sent to the views, use the…
josevalim authored
95 # <%= truncate(@note.body, 25) %>
96 #
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
97 # If you need to access the subject, from or the recipients in the view, you can do that through message object:
ee70d1b @josevalim adv_attr_accessors in ActionMailer are not sent to the views, use the…
josevalim authored
98 #
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
99 # You got a new note from <%= message.from %>!
ee70d1b @josevalim adv_attr_accessors in ActionMailer are not sent to the views, use the…
josevalim authored
100 # <%= truncate(@note.body, 25) %>
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
101 #
20bd4bd @dhh Updated docs and otherwise
dhh authored
102 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
103 # = Generating URLs
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
104 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
105 # URLs can be generated in mailer views using <tt>url_for</tt> or named routes.
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
106 # Unlike controllers from Action Pack, the mailer instance doesn't have any context about the incoming request,
107 # so you'll need to provide all of the details needed to generate a URL.
20bd4bd @dhh Updated docs and otherwise
dhh authored
108 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
109 # When using <tt>url_for</tt> you'll need to provide the <tt>:host</tt>, <tt>:controller</tt>, and <tt>:action</tt>:
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
110 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
111 # <%= url_for(:host => "example.com", :controller => "welcome", :action => "greeting") %>
20bd4bd @dhh Updated docs and otherwise
dhh authored
112 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
113 # When using named routes you only need to supply the <tt>:host</tt>:
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
114 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
115 # <%= users_url(:host => "example.com") %>
116 #
117 # You will want to avoid using the <tt>name_of_route_path</tt> form of named routes because it doesn't make sense to
118 # generate relative URLs in email messages.
119 #
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
120 # It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt> option in
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
121 # the <tt>ActionMailer::Base.default_url_options</tt> hash as follows:
122 #
123 # ActionMailer::Base.default_url_options[:host] = "example.com"
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
124 #
dc4eec1 @lifo Merge docrails:
lifo authored
125 # This can also be set as a configuration option in <tt>config/environment.rb</tt>:
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
126 #
127 # config.action_mailer.default_url_options = { :host => "example.com" }
20bd4bd @dhh Updated docs and otherwise
dhh authored
128 #
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
129 # If you do decide to set a default <tt>:host</tt> for your mailers you will want to use the
130 # <tt>:only_path => false</tt> option when using <tt>url_for</tt>. This will ensure that absolute URLs are generated because
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
131 # the <tt>url_for</tt> view helper will, by default, generate relative URLs when a <tt>:host</tt> option isn't
4809dcc * Remove default_url_options from mailer generator
Cody Fauser authored
132 # explicitly provided.
20bd4bd @dhh Updated docs and otherwise
dhh authored
133 #
134 # = Sending mail
135 #
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
136 # Once a mailer action and template are defined, you can deliver your message or create it and save it
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
137 # for delivery later:
138 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
139 # Notifier.welcome(david).deliver # sends the email
140 # mail = Notifier.welcome(david) # => a Mail::Message object
141 # mail.deliver # sends the email
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
142 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
143 # You never instantiate your mailer class. Rather, you just call the method on the class itself.
20bd4bd @dhh Updated docs and otherwise
dhh authored
144 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
145 # = Multipart Emails
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
146 #
98dc582 @lifo Merge docrails.
lifo authored
147 # Multipart messages can also be used implicitly because Action Mailer will automatically
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
148 # detect and use multipart templates, where each template is named after the name of the action, followed
149 # by the content type. Each such detected template will be added as separate part to the message.
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
150 #
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
151 # For example, if the following templates existed:
21187c0 @dhh Apply the rest of Chads patch
dhh authored
152 # * signup_notification.text.plain.erb
153 # * signup_notification.text.html.erb
154 # * signup_notification.text.xml.builder
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
155 # * signup_notification.text.yaml.erb
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
156 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
157 # Each would be rendered and added as a separate part to the message, with the corresponding content
158 # type. The content type for the entire message is automatically set to <tt>multipart/alternative</tt>,
159 # which indicates that the email contains multiple different representations of the same email
160 # body. The same instance variables defined in the action are passed to all email templates.
359caef @jamis A very thorough refactoring, resulting in new mail property setters a…
jamis authored
161 #
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
162 # Implicit template rendering is not performed if any attachments or parts have been added to the email.
163 # This means that you'll have to manually add each part to the email and set the content type of the email
164 # to <tt>multipart/alternative</tt>.
20bd4bd @dhh Updated docs and otherwise
dhh authored
165 #
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
166 # = Attachments
20bd4bd @dhh Updated docs and otherwise
dhh authored
167 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
168 # You can see above how to make a multipart HTML / Text email, to send attachments is just
169 # as easy:
0a407bc ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, …
Marcel Molina authored
170 #
171 # class ApplicationMailer < ActionMailer::Base
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
172 # def welcome(recipient)
173 # attachments['free_book.pdf'] = { :data => File.read('path/to/file.pdf') }
174 # mail(:to => recipient, :subject => "New account information")
db045db @dhh Initial
dhh authored
175 # end
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
176 # end
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
177 #
178 # Which will (if it had both a <tt>.text.erb</tt> and <tt>.html.erb</tt> tempalte in the view
179 # directory), send a complete <tt>multipart/mixed</tt> email with two parts, the first part being
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
180 # a <tt>multipart/alternative</tt> with the text and HTML email parts inside, and the second being
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
181 # a <tt>application/pdf</tt> with a Base64 encoded copy of the file.pdf book with the filename
182 # +free_book.pdf+.
c927aa0 @dhh Updated documentation
dhh authored
183 #
20bd4bd @dhh Updated docs and otherwise
dhh authored
184 #
c927aa0 @dhh Updated documentation
dhh authored
185 # = Configuration options
186 #
187 # These options are specified on the class level, like <tt>ActionMailer::Base.template_root = "/my/templates"</tt>
188 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
189 # * <tt>delivers_from</tt> - Pass this the address that then defaults as the +from+ address on all the
190 # emails sent. Can be overridden on a per mail basis by passing <tt>:from => 'another@address'</tt> in
191 # the +mail+ method.
c927aa0 @dhh Updated documentation
dhh authored
192 #
193 # * <tt>logger</tt> - the logger is used for generating information on the mailing run if available.
194 # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
195 #
64092de @fxn Improve documentation coverage and markup
fxn authored
196 # * <tt>smtp_settings</tt> - Allows detailed configuration for <tt>:smtp</tt> delivery method:
dc4eec1 @lifo Merge docrails:
lifo authored
197 # * <tt>:address</tt> - Allows you to use a remote mail server. Just change it from its default "localhost" setting.
198 # * <tt>:port</tt> - On the off chance that your mail server doesn't run on port 25, you can change it.
199 # * <tt>:domain</tt> - If you need to specify a HELO domain, you can do it here.
200 # * <tt>:user_name</tt> - If your mail server requires authentication, set the username in this setting.
201 # * <tt>:password</tt> - If your mail server requires authentication, set the password in this setting.
b2504f8 @josh Tidy up ActionMailer rendering logic to take advantage of view path c…
josh authored
202 # * <tt>:authentication</tt> - If your mail server requires authentication, you need to specify the authentication type here.
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
203 # This is a symbol and one of <tt>:plain</tt>, <tt>:login</tt>, <tt>:cram_md5</tt>.
c2e7851 @josevalim Add ActionMailer::Base#enable_starttls_auto option for enabling/disab…
josevalim authored
204 # * <tt>:enable_starttls_auto</tt> - When set to true, detects if STARTTLS is enabled in your SMTP server and starts to use it.
205 # It works only on Ruby >= 1.8.7 and Ruby >= 1.9. Default is true.
c927aa0 @dhh Updated documentation
dhh authored
206 #
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
207 # * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
208 # * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
209 # * <tt>:arguments</tt> - The command line arguments. Defaults to <tt>-i -t</tt>.
dc4eec1 @lifo Merge docrails:
lifo authored
210 #
fbe6c3c @edavis10 Adds a :file delivery_method to save email to a file on disk
edavis10 authored
211 # * <tt>file_settings</tt> - Allows you to override options for the <tt>:file</tt> delivery method.
212 # * <tt>:location</tt> - The directory into which emails will be written. Defaults to the application <tt>tmp/mails</tt>.
213 #
dc4eec1 @lifo Merge docrails:
lifo authored
214 # * <tt>raise_delivery_errors</tt> - Whether or not errors should be raised if the email fails to be delivered.
c927aa0 @dhh Updated documentation
dhh authored
215 #
fbe6c3c @edavis10 Adds a :file delivery_method to save email to a file on disk
edavis10 authored
216 # * <tt>delivery_method</tt> - Defines a delivery method. Possible values are <tt>:smtp</tt> (default), <tt>:sendmail</tt>, <tt>:test</tt>,
f4f7677 @matthewrudy abstract all of the ActionMailer delivery methods into their own clas…
matthewrudy authored
217 # and <tt>:file</tt>. Or you may provide a custom delivery method object eg. MyOwnDeliveryMethodClass.new
c927aa0 @dhh Updated documentation
dhh authored
218 #
dc4eec1 @lifo Merge docrails:
lifo authored
219 # * <tt>perform_deliveries</tt> - Determines whether <tt>deliver_*</tt> methods are actually carried out. By default they are,
c927aa0 @dhh Updated documentation
dhh authored
220 # but this can be turned off to help functional testing.
221 #
64092de @fxn Improve documentation coverage and markup
fxn authored
222 # * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with <tt>delivery_method :test</tt>. Most useful
c927aa0 @dhh Updated documentation
dhh authored
223 # for unit and functional testing.
af56c80 @dhh Updated documentation
dhh authored
224 #
b2504f8 @josh Tidy up ActionMailer rendering logic to take advantage of view path c…
josh authored
225 # * <tt>default_charset</tt> - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
226 # pick a different charset from inside a method with +charset+.
c2e7851 @josevalim Add ActionMailer::Base#enable_starttls_auto option for enabling/disab…
josevalim authored
227 #
475bd74 @dhh Fix docs (closes #2598)
dhh authored
228 # * <tt>default_content_type</tt> - The default content type used for the main part of the message. Defaults to "text/plain". You
b2504f8 @josh Tidy up ActionMailer rendering logic to take advantage of view path c…
josh authored
229 # can also pick a different content type from inside a method with +content_type+.
c2e7851 @josevalim Add ActionMailer::Base#enable_starttls_auto option for enabling/disab…
josevalim authored
230 #
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
231 # * <tt>default_mime_version</tt> - The default mime version used for the message. Defaults to <tt>1.0</tt>. You
232 # can also pick a different value from inside a method with +mime_version+.
c2e7851 @josevalim Add ActionMailer::Base#enable_starttls_auto option for enabling/disab…
josevalim authored
233 #
475bd74 @dhh Fix docs (closes #2598)
dhh authored
234 # * <tt>default_implicit_parts_order</tt> - When a message is built implicitly (i.e. multiple parts are assembled from templates
5c98152 @jamis Better multipart support with implicit multipart/alternative and sort…
jamis authored
235 # which specify the content type in their filenames) this variable controls how the parts are ordered. Defaults to
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
236 # <tt>["text/html", "text/enriched", "text/plain"]</tt>. Items that appear first in the array have higher priority in the mail client
5c98152 @jamis Better multipart support with implicit multipart/alternative and sort…
jamis authored
237 # and appear last in the mime encoded message. You can also pick a different order from inside a method with
46f30f9 @lifo Merge documentation changes from docrails.
lifo authored
238 # +implicit_parts_order+.
4964d3b @josevalim Make ActionMailer::Base inherit from AbstractController::Base
josevalim authored
239 class Base < AbstractController::Base
0d931fe Finish cleaning up delivery methods implementation.
José Valim and Mikel Lindsaar authored
240 include DeliveryMethods, Quoting
f30d73b Add new class delivery method API.
José Valim and Mikel Lindsaar authored
241 abstract!
242
c03c40b @josevalim Expose a _render_partial hook as thhe _render_template one and make u…
josevalim authored
243 include AbstractController::Logger
83f4d86 @dhh Rename the RenderingController module to just plain Rendering
dhh authored
244 include AbstractController::Rendering
976c264 @josevalim Extracted localized_cache.rb from ActionController, added it to Abstr…
josevalim authored
245 include AbstractController::LocalizedCache
a9751a7 @josevalim Refactor ActionMailer layout and remove legacy one.
josevalim authored
246 include AbstractController::Layouts
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
247 include AbstractController::Helpers
f564f94 @josevalim Remove duplicated url_for code and move methods shared between Action…
josevalim authored
248 include AbstractController::UrlFor
359caef @jamis A very thorough refactoring, resulting in new mail property setters a…
jamis authored
249
ee70d1b @josevalim adv_attr_accessors in ActionMailer are not sent to the views, use the…
josevalim authored
250 helper ActionMailer::MailHelper
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
251
5dead5b Maintain old_api and deprecated_api in different files.
José Valim and Mikel Lindsaar authored
252 include ActionMailer::OldApi
f30d73b Add new class delivery method API.
José Valim and Mikel Lindsaar authored
253 include ActionMailer::DeprecatedApi
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
254
c927aa0 @dhh Updated documentation
dhh authored
255 private_class_method :new #:nodoc:
db045db @dhh Initial
dhh authored
256
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
257 extlib_inheritable_accessor :defaults
258 self.defaults = {}
e1c1318 Added delivers_from.
José Valim and Mikel Lindsaar authored
259
b30eb39 Add more tests to new API.
José Valim and Mikel Lindsaar authored
260 extlib_inheritable_accessor :default_charset
261 self.default_charset = "utf-8"
3fad0cd @dhh Added support for charsets for both subject and body. The default cha…
dhh authored
262
b30eb39 Add more tests to new API.
José Valim and Mikel Lindsaar authored
263 extlib_inheritable_accessor :default_content_type
264 self.default_content_type = "text/plain"
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Infl…
josh authored
265
b30eb39 Add more tests to new API.
José Valim and Mikel Lindsaar authored
266 extlib_inheritable_accessor :default_mime_version
267 self.default_mime_version = "1.0"
100fd72 @jamis Added a "content_type" accessor to allow messages to explicitly speci…
jamis authored
268
c039bcd @mikel Moved sort_parts into Mail, updated mail requirement to 1.4.2
mikel authored
269 # This specifies the order that the parts of a multipart email will be. Usually you put
270 # text/plain at the top so someone without a MIME capable email reader can read the plain
271 # text of your email first.
272 #
273 # Any content type that is not listed here will be inserted in the order you add them to
274 # the email after the content types you list here.
b30eb39 Add more tests to new API.
José Valim and Mikel Lindsaar authored
275 extlib_inheritable_accessor :default_implicit_parts_order
276 self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ]
5c98152 @jamis Better multipart support with implicit multipart/alternative and sort…
jamis authored
277
eda1719 @jamis ActionMailer::Base.deliver(email) had been accidentally removed, but …
jamis authored
278 class << self
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
279
bd5ed65 @technoweenie Update ActionMailer so it treats ActionView the same way that ActionC…
technoweenie authored
280 def mailer_name
281 @mailer_name ||= name.underscore
282 end
0750304 @mikel Migrated over to Mail doing delivery.
mikel authored
283 attr_writer :mailer_name
284 alias :controller_path :mailer_name
81c416b @josevalim More refactoring on ActionMailer::Base.
josevalim authored
285
59f1df1 @jamis Update/extend ActionMailer documentation (rdoc)
jamis authored
286 # Receives a raw email, parses it into an email object, decodes it,
287 # instantiates a new mailer, and passes the email object to the mailer
98dc582 @lifo Merge docrails.
lifo authored
288 # object's +receive+ method. If you want your mailer to be able to
289 # process incoming messages, you'll need to implement a +receive+
59f1df1 @jamis Update/extend ActionMailer documentation (rdoc)
jamis authored
290 # method that accepts the email object as a parameter:
291 #
292 # class MyMailer < ActionMailer::Base
293 # def receive(mail)
294 # ...
295 # end
296 # end
704daad @josevalim Ensure we just send Ruby Stdlib objects in ActionMailer notifications.
josevalim authored
297 def receive(raw_mail)
298 ActiveSupport::Notifications.instrument("action_mailer.receive") do |payload|
299 mail = Mail.new(raw_mail)
300 set_payload_for_mail(payload, mail)
2a6bc12 @josevalim Add subscriber to ActionMailer.
josevalim authored
301 new.receive(mail)
302 end
eda1719 @jamis ActionMailer::Base.deliver(email) had been accidentally removed, but …
jamis authored
303 end
304
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
305 # Delivers a mail object. This is actually called by the <tt>Mail::Message</tt> object
306 # itself through a call back when you call <tt>:deliver</tt> on the Mail::Message,
307 # calling +deliver_mail+ directly and passing an Mail::Message will do nothing.
e4a989e Added delivery_handler method to mail and implemented in ActionMailer…
José Valim and Mikel Lindsaar authored
308 def deliver_mail(mail) #:nodoc:
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
309 ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload|
258ca14 Delegated ActionMailer::Base.deliveries to Mail.deliveries, added cal…
José Valim and Mikel Lindsaar authored
310 self.set_payload_for_mail(payload, mail)
ace7497 Got AM working with Mail yield on delivery_handler and updated tests
José Valim and Mikel Lindsaar authored
311 yield # Let Mail do the delivery actions
258ca14 Delegated ActionMailer::Base.deliveries to Mail.deliveries, added cal…
José Valim and Mikel Lindsaar authored
312 end
313 end
314
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
315 def respond_to?(method, *args) #:nodoc:
316 super || action_methods.include?(method.to_s)
317 end
318
319 protected
320
704daad @josevalim Ensure we just send Ruby Stdlib objects in ActionMailer notifications.
josevalim authored
321 def set_payload_for_mail(payload, mail) #:nodoc:
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
322 payload[:mailer] = self.name
c905fce @josevalim Add message_id to AM payload and don't send bcc and cc if they were n…
josevalim authored
323 payload[:message_id] = mail.message_id
324 payload[:subject] = mail.subject
325 payload[:to] = mail.to
326 payload[:from] = mail.from
327 payload[:bcc] = mail.bcc if mail.bcc.present?
328 payload[:cc] = mail.cc if mail.cc.present?
329 payload[:date] = mail.date
330 payload[:mail] = mail.encoded
704daad @josevalim Ensure we just send Ruby Stdlib objects in ActionMailer notifications.
josevalim authored
331 end
f30d73b Add new class delivery method API.
José Valim and Mikel Lindsaar authored
332
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
333 def method_missing(method, *args) #:nodoc:
f30d73b Add new class delivery method API.
José Valim and Mikel Lindsaar authored
334 if action_methods.include?(method.to_s)
335 new(method, *args).message
336 else
337 super
338 end
339 end
eda1719 @jamis ActionMailer::Base.deliver(email) had been accidentally removed, but …
jamis authored
340 end
341
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
342 attr_internal :message
343
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
344 # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
345 # will be initialized according to the named method. If not, the mailer will
346 # remain uninitialized (useful when you only need to invoke the "receive"
347 # method, for instance).
348 def initialize(method_name=nil, *args)
349 super()
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
350 @_message = Mail.new
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
351 process(method_name, *args) if method_name
352 end
353
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
354 # Allows you to pass random and unusual headers to the new +Mail::Message+ object
355 # which will add them to itself.
356 #
357 # headers['X-Special-Domain-Specific-Header'] = "SecretValue"
358 #
359 # The resulting Mail::Message will have the following in it's header:
360 #
361 # X-Special-Domain-Specific-Header: SecretValue
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
362 def headers(args=nil)
363 if args
364 ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller[0,2]
365 @headers = args
366 else
367 @_message
368 end
369 end
c34cfcc @mikel Created mail method for new API
mikel authored
370
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
371 # Allows you to add attachments to an email, like so:
372 #
373 # mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
374 #
375 # If you do this, then Mail will take the file name and work out the mime type
376 # set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
377 # base64 encode the contents of the attachment all for you.
378 #
379 # You can also specify overrides if you want by passing a hash instead of a string:
380 #
381 # mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
382 # :content => File.read('/path/to/filename.jpg')}
383 #
384 # If you want to use a different encoding than Base64, you can pass an encoding in,
385 # but then it is up to you to pass in the content pre-encoded, and don't expect
386 # Mail to know how to decode this data:
387 #
388 # file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
389 # mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
390 # :encoding => 'SpecialEncoding',
391 # :content => file_content }
392 #
393 # You can also search for specific attachments:
394 #
395 # # By Filename
396 # mail.attachments['filename.jpg'] #=> Mail::Part object or nil
397 #
398 # # or by index
399 # mail.attachments[0] #=> Mail::Part (first attachment)
400 #
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
401 def attachments
402 @_message.attachments
403 end
dcb9253 Add basic template rendering to new DSL.
José Valim and Mikel Lindsaar authored
404
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
405 # The main method that creates the message and renders the email templates. There are
406 # two ways to call this method, with a block, or without a block.
407 #
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
408 # Both methods accept a headers hash. This hash allows you to specify the most used headers
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
409 # in an email message, these are:
410 #
411 # * <tt>:subject</tt> - The subject of the message, if this is omitted, ActionMailer will
412 # ask the Rails I18n class for a translated <tt>:subject</tt> in the scope of
413 # <tt>[:actionmailer, mailer_scope, action_name]</tt> or if this is missing, will translate the
414 # humanized version of the <tt>action_name</tt>
415 # * <tt>:to</tt> - Who the message is destined for, can be a string of addresses, or an array
416 # of addresses.
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
417 # * <tt>:from</tt> - Who the message is from
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
418 # * <tt>:cc</tt> - Who you would like to Carbon-Copy on this email, can be a string of addresses,
419 # or an array of addresses.
420 # * <tt>:bcc</tt> - Who you would like to Blind-Carbon-Copy on this email, can be a string of
421 # addresses, or an array of addresses.
422 # * <tt>:reply_to</tt> - Who to set the Reply-To header of the email to.
423 # * <tt>:date</tt> - The date to say the email was sent on.
424 #
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
425 # You can set default values for any of the above headers (except :date) by using the <tt>defaults</tt>
426 # class method:
427 #
428 # class Notifier
429 # self.defaults = {:from => 'no-reply@test.lindsaar.net',
430 # :bcc => 'email_logger@test.lindsaar.net',
431 # :reply_to => 'bounces@test.lindsaar.net' }
432 # end
433 #
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
434 # If you need other headers not listed above, use the <tt>headers['name'] = value</tt> method.
435 #
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
436 # When a <tt>:return_path</tt> is specified as header, that value will be used as the 'envelope from'
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
437 # address for the Mail message. Setting this is useful when you want delivery notifications
438 # sent to a different address than the one in <tt>:from</tt>. Mail will actually use the
439 # <tt>:return_path</tt> in preference to the <tt>:sender</tt> in preference to the <tt>:from</tt>
440 # field for the 'envelope from' value.
441 #
442 # If you do not pass a block to the +mail+ method, it will find all templates in the
443 # template path that match the method name that it is being called from, it will then
444 # create parts for each of these templates intelligently, making educated guesses
445 # on correct content type and sequence, and return a fully prepared Mail::Message
446 # ready to call <tt>:deliver</tt> on to send.
447 #
448 # If you do pass a block, you can render specific templates of your choice:
449 #
450 # mail(:to => 'mikel@test.lindsaar.net') do |format|
451 # format.text
452 # format.html
453 # end
454 #
455 # You can even render text directly without using a template:
456 #
457 # mail(:to => 'mikel@test.lindsaar.net') do |format|
458 # format.text { render :text => "Hello Mikel!" }
459 # format.html { render :text => "<h1>Hello Mikel!</h1>" }
460 # end
461 #
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
462 # Which will render a <tt>multipart/alternative</tt> email with <tt>text/plain</tt> and
4a6eba3 Added initial documentation for the new API
José Valim and Mikel Lindsaar authored
463 # <tt>text/html</tt> parts.
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
464 #
465 # The block syntax also allows you to customize the part headers if desired:
466 #
467 # mail(:to => 'mikel@test.lindsaar.net') do |format|
468 # format.text(:content_transfer_encoding => "base64")
469 # format.html
470 # end
471 #
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
472 def mail(headers={}, &block)
473 # Guard flag to prevent both the old and the new API from firing
474 # Should be removed when old API is removed
475 @mail_was_called = true
476 m = @_message
258ca14 Delegated ActionMailer::Base.deliveries to Mail.deliveries, added cal…
José Valim and Mikel Lindsaar authored
477
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
478 # Give preference to headers and fallback to the ones set in mail
1cd5592 First work on implicit multipart.
José Valim and Mikel Lindsaar authored
479 content_type = headers[:content_type] || m.content_type
951397b Get implicit multipart and attachments working together.
José Valim and Mikel Lindsaar authored
480 charset = headers[:charset] || m.charset || self.class.default_charset.dup
481 mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup
1cd5592 First work on implicit multipart.
José Valim and Mikel Lindsaar authored
482
e1c1318 Added delivers_from.
José Valim and Mikel Lindsaar authored
483 # Set fields quotings
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
484 headers = set_defaults(headers)
485
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
486 quote_fields!(headers, charset)
951397b Get implicit multipart and attachments working together.
José Valim and Mikel Lindsaar authored
487
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
488 # Render the templates and blocks
489 responses, sort_order = collect_responses_and_sort_order(headers, &block)
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
490
491 create_parts_from_responses(m, responses, charset)
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
492
493 # Tidy up content type, charset, mime version and sort order
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
494 m.content_type = set_content_type(m, content_type)
951397b Get implicit multipart and attachments working together.
José Valim and Mikel Lindsaar authored
495 m.charset = charset
496 m.mime_version = mime_version
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
497 sort_order = headers[:parts_order] || sort_order || self.class.default_implicit_parts_order.dup
951397b Get implicit multipart and attachments working together.
José Valim and Mikel Lindsaar authored
498
e7e4ed4 Set sort order for explicit parts from the collector's template sequence
José Valim and Mikel Lindsaar authored
499 if m.multipart?
500 m.body.set_sort_order(sort_order)
951397b Get implicit multipart and attachments working together.
José Valim and Mikel Lindsaar authored
501 m.body.sort_parts!
502 end
bb9d71f Move class methods to deprecated stuff.
José Valim and Mikel Lindsaar authored
503
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
504 # Finaly set delivery behavior configured in class
505 wrap_delivery_behavior!(headers[:delivery_method])
c34cfcc @mikel Created mail method for new API
mikel authored
506 m
507 end
508
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
509 protected
510
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
511 def set_content_type(m, user_content_type)
512 params = m.content_type_parameters || {}
513 case
514 when user_content_type.present?
515 user_content_type
516 when m.has_attachments?
517 ["multipart", "mixed", params]
518 when m.multipart?
519 ["multipart", "alternative", params]
520 else
521 self.class.default_content_type.dup
522 end
523 end
524
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
525 def set_defaults(headers)
526 headers[:subject] ||= default_subject
527 headers[:to] ||= self.class.defaults[:to].to_s.dup
528 headers[:from] ||= self.class.defaults[:from].to_s.dup
529 headers[:cc] ||= self.class.defaults[:cc].to_s.dup
530 headers[:bcc] ||= self.class.defaults[:bcc].to_s.dup
531 headers[:reply_to] ||= self.class.defaults[:reply_to].to_s.dup
532 headers
533 end
534
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
535 def default_subject #:nodoc:
5c3ef8c Refactor subject with i18n.
José Valim and Mikel Lindsaar authored
536 mailer_scope = self.class.mailer_name.gsub('/', '.')
0b05acd @mikel Implementing class level :defaults hash, instead of delivers_from et al
mikel authored
537 self.class.defaults[:subject] || I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize)
5c3ef8c Refactor subject with i18n.
José Valim and Mikel Lindsaar authored
538 end
539
73a9000 Adding failing tests for calling just the action, instead of :create_…
José Valim and Mikel Lindsaar authored
540 # TODO: Move this into Mail
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
541 def quote_fields!(headers, charset) #:nodoc:
542 m = @_message
543 m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject]
544 m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to]
545 m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from]
546 m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc]
547 m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc]
548 m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to]
549 m.date ||= headers[:date] if headers[:date]
550 end
551
552 def collect_responses_and_sort_order(headers) #:nodoc:
553 responses, sort_order = [], nil
554
555 if block_given?
556 collector = ActionMailer::Collector.new(self) { render(action_name) }
557 yield(collector)
558 sort_order = collector.responses.map { |r| r[:content_type] }
559 responses = collector.responses
560 elsif headers[:body]
561 responses << {
562 :body => headers[:body],
563 :content_type => self.class.default_content_type.dup
564 }
565 else
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
566 each_template do |template|
7409b73 Some refactoring.
José Valim and Mikel Lindsaar authored
567 responses << {
568 :body => render_to_body(:_template => template),
569 :content_type => template.mime_type.to_s
570 }
571 end
572 end
573
574 [responses, sort_order]
575 end
576
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
577 def each_template(&block) #:nodoc:
578 self.class.view_paths.each do |load_paths|
579 templates = load_paths.find_all(action_name, {}, self.class.mailer_name)
0ece244 Ensure implicit multipart templates with locale works as expected.
José Valim and Mikel Lindsaar authored
580 templates = templates.uniq_by { |t| t.details[:formats] }
581
99f960a Handle some TODOs and deprecations.
José Valim and Mikel Lindsaar authored
582 unless templates.empty?
583 templates.each(&block)
584 return
585 end
586 end
587 end
588
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
589 def create_parts_from_responses(m, responses, charset) #:nodoc:
590 if responses.size == 1 && !m.has_attachments?
6589976 Remove old files, add some information to docs and improve test suite.
José Valim and Mikel Lindsaar authored
591 headers = responses[0]
592 headers.each { |k,v| m[k] = v }
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
593 return responses[0][:content_type]
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
594 elsif responses.size > 1 && m.has_attachments?
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
595 container = Mail::Part.new
74a5889 Refactor content type setting, added tests to ensure boundary exists …
José Valim and Mikel Lindsaar authored
596 container.content_type = "multipart/alternative"
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
597 responses.each { |r| insert_part(container, r, charset) }
598 m.add_part(container)
599 else
600 responses.each { |r| insert_part(m, r, charset) }
601 end
359caef @jamis A very thorough refactoring, resulting in new mail property setters a…
jamis authored
602 end
603
6ba9446 Make implicit and explicit templates pass through the same part creat…
José Valim and Mikel Lindsaar authored
604 def insert_part(container, response, charset) #:nodoc:
605 response[:charset] ||= charset
606 part = Mail::Part.new(response)
607 container.add_part(part)
359caef @jamis A very thorough refactoring, resulting in new mail property setters a…
jamis authored
608 end
3fad0cd @dhh Added support for charsets for both subject and body. The default cha…
dhh authored
609
db045db @dhh Initial
dhh authored
610 end
611 end
Something went wrong with that request. Please try again.