mail_form 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,8 +1,16 @@
1
- * Version 1.0
1
+ # Version 1.2
2
2
 
3
- * Rename to mail_form and launch Rails 2.3 branch.
3
+ * No more class attributes, just define a headers method
4
4
 
5
- * Version 0.4
5
+ # Version 1.1
6
+
7
+ * Rails 3 compatibility
8
+
9
+ # Version 1.0
10
+
11
+ * Rename to mail_form and launch Rails 2.3 branch
12
+
13
+ # Version 0.4
6
14
 
7
15
  * Added support to template
8
16
 
@@ -16,16 +16,22 @@ MailForm allows you to send an e-mail straight from a form. For instance,
16
16
  if you want to make a contact form just the following lines are needed (including the e-mail):
17
17
 
18
18
  class ContactForm < MailForm::Base
19
- subject "My Contact Form"
20
- recipients "your.email@your.domain.com"
21
- sender{|c| %{"#{c.name}" <#{c.email}>} }
22
-
23
19
  attribute :name, :validate => true
24
20
  attribute :email, :validate => /[^@]+@[^\.]+\.[\w\.\-]+/
25
21
  attribute :file, :attachment => true
26
22
 
27
23
  attribute :message
28
24
  attribute :nickname, :captcha => true
25
+
26
+ # Declare the e-mail headers. It accepts anything the mail method
27
+ # in ActionMailer accepts.
28
+ def headers
29
+ {
30
+ :subject => "My Contact Form",
31
+ :to => "your.email@your.domain.com",
32
+ :from => %("#{name}" <#{email}>)
33
+ }
34
+ end
29
35
  end
30
36
 
31
37
  Then you start a script/console and type:
@@ -64,8 +70,13 @@ in your model and declare which attributes should be sent:
64
70
 
65
71
  append :remote_ip, :user_agent, :session
66
72
  attributes :name, :email, :created_at
67
- subject "New user created"
68
- recipients "your.email@your.domain.com"
73
+
74
+ def headers
75
+ {
76
+ :to => "your.email@your.domain.com",
77
+ :subject => "User created an account"
78
+ }
79
+ end
69
80
  end
70
81
 
71
82
  The delivery will be triggered in an after_create hook.
@@ -135,37 +146,6 @@ Examples:
135
146
  c = ContactForm.new(:name => 'José', :email => 'your@email.com')
136
147
  c.deliver #=> true
137
148
 
138
- === subject(string_or_symbol_or_block)
139
-
140
- Declares the subject of the contact email. It can be a string or a proc or a symbol.
141
-
142
- When a symbol is given, it will call a method on the form object with the same
143
- name as the symbol. As a proc, it receives a mail form instance. It defaults
144
- to the class human name.
145
-
146
- subject "My Contact Form"
147
- subject { |c| "Contacted by #{c.name}" }
148
-
149
- === sender(string_or_symbol_or_block)
150
-
151
- Declares contact email sender. It can be a string or a proc or a symbol.
152
-
153
- When a symbol is given, it will call a method on the form object with the same
154
- name as the symbol. As a proc, it receives a mail form instance. By default is:
155
-
156
- sender { |c| c.email }
157
-
158
- This requires that your MailForm object have an email attribute.
159
-
160
- === recipients(string_or_array_or_symbol_or_block)
161
-
162
- Who will receive the e-mail. Can be a string or array or a symbol or a proc.
163
-
164
- When a symbol is given, it will call a method on the form object with the same
165
- name as the symbol. As a proc, it receives a mail form instance.
166
-
167
- Both the proc and the symbol must return a string or an array. By default is nil.
168
-
169
149
  === append(*methods)
170
150
 
171
151
  MailForm also makes easy to append request information from client to the sent
@@ -185,23 +165,6 @@ The remote ip, user agent and session will be sent in the e-mail in a
185
165
  request information session. You can give to append any method that the
186
166
  request object responds to.
187
167
 
188
- === template(string_or_symbol_or_proc)
189
-
190
- Allow you to set the template that is going to rendered. This allows you to have
191
- several MailForm instances, using different templates.
192
-
193
- === headers(hash)
194
-
195
- Configure additional headers to your e-mail.
196
-
197
- === MailForm.template_root
198
-
199
- MailForm by default is configured to use the template which comes with the gem.
200
- If you want to use another, you just need to configure MailForm template root
201
- to point to your application:
202
-
203
- MailForm.template_root = File.join(Rails.root, "app", "views")
204
-
205
168
  == I18n
206
169
 
207
170
  I18n in MailForm works like in ActiveRecord, so all models, attributes and messages
@@ -237,4 +200,4 @@ is an I18n example file:
237
200
 
238
201
  If you discover any bug, please use github issues tracker.
239
202
 
240
- Copyright (c) 2009 Plataforma Tec http://blog.plataformatec.com.br/
203
+ Copyright (c) 2010 Plataforma Tec http://blog.plataformatec.com.br/
@@ -7,42 +7,20 @@ class MailForm < ActionMailer::Base
7
7
  append_view_path File.expand_path('../views', __FILE__)
8
8
 
9
9
  def contact(resource)
10
- @from = get_from_class_and_eval(resource, :mail_sender)
11
- @subject = get_from_class_and_eval(resource, :mail_subject)
12
- @recipients = get_from_class_and_eval(resource, :mail_recipients)
13
- @template = get_from_class_and_eval(resource, :mail_template)
14
-
15
- if @recipients.blank?
16
- raise ScriptError, "You forgot to setup #{resource.class.name} recipients"
17
- end
18
-
19
- if resource.request.nil? && resource.class.mail_appendable.present?
10
+ if resource.request.nil? && resource.class.mail_appendable.any?
20
11
  raise ScriptError, "You set :append values but forgot to give me the request object"
21
12
  end
22
13
 
23
14
  @resource = @form = resource
24
- @sent_on = Time.now.utc
25
- @headers = resource.class.mail_headers
26
- @content_type = 'text/html'
27
15
 
28
16
  resource.class.mail_attachments.each do |attribute|
29
17
  value = resource.send(attribute)
30
18
  next unless value.respond_to?(:read)
31
19
  attachments[value.original_filename] = value.read
32
20
  end
33
- end
34
21
 
35
- protected
36
-
37
- def get_from_class_and_eval(resource, method)
38
- duck = resource.class.send(method)
39
-
40
- if duck.is_a?(Proc)
41
- duck.call(resource)
42
- elsif duck.is_a?(Symbol)
43
- resource.send(duck)
44
- else
45
- duck
46
- end
22
+ headers = resource.headers
23
+ headers[:from] ||= resource.email
24
+ mail(headers)
47
25
  end
48
26
  end
@@ -1,30 +1,55 @@
1
1
  module MailForm::Delivery
2
2
  extend ActiveSupport::Concern
3
3
 
4
- ACCESSORS = [ :mail_attributes, :mail_subject, :mail_captcha,
5
- :mail_attachments, :mail_recipients, :mail_sender,
6
- :mail_headers, :mail_template, :mail_appendable ]
7
-
8
4
  included do
9
- class_inheritable_reader *ACCESSORS
10
- protected *ACCESSORS
5
+ class_attribute :mail_attributes
6
+ self.mail_attributes = []
7
+
8
+ class_attribute :mail_captcha
9
+ self.mail_captcha = []
11
10
 
12
- # Initialize arrays and hashes
13
- write_inheritable_array :mail_captcha, []
14
- write_inheritable_array :mail_appendable, []
15
- write_inheritable_array :mail_attributes, []
16
- write_inheritable_array :mail_attachments, []
11
+ class_attribute :mail_attachments
12
+ self.mail_attachments = []
17
13
 
18
- headers({})
19
- sender {|c| c.email }
20
- subject{|c| c.class.model_name.human }
21
- template 'contact'
14
+ class_attribute :mail_appendable
15
+ self.mail_appendable = []
22
16
 
23
17
  before_create :not_spam?
24
18
  after_create :deliver!
25
19
 
26
20
  attr_accessor :request
27
21
  alias :deliver :create
22
+
23
+ extend Deprecated
24
+ end
25
+
26
+ module Deprecated
27
+ def subject(duck=nil, &block)
28
+ ActiveSupport::Deprecation.warn "subject is deprecated. Please define a headers method " <<
29
+ "in your instance which returns a hash with :subject as key instead.", caller
30
+ end
31
+
32
+ def sender(duck=nil, &block)
33
+ ActiveSupport::Deprecation.warn "from/sender is deprecated. Please define a headers method " <<
34
+ "in your instance which returns a hash with :from as key instead.", caller
35
+ end
36
+ alias :from :sender
37
+
38
+ def recipients(duck=nil, &block)
39
+ ActiveSupport::Deprecation.warn "to/recipients is deprecated. Please define a headers method " <<
40
+ "in your instance which returns a hash with :to as key instead.", caller
41
+ end
42
+ alias :to :recipients
43
+
44
+ def headers(hash)
45
+ ActiveSupport::Deprecation.warn "to/recipients is deprecated. Please define a headers method " <<
46
+ "in your instance which returns the desired headers instead.", caller
47
+ end
48
+
49
+ def template(new_template)
50
+ ActiveSupport::Deprecation.warn "template is deprecated. Please define a headers method " <<
51
+ "in your instance which returns a hash with :template_name as key instead.", caller
52
+ end
28
53
  end
29
54
 
30
55
  module ClassMethods
@@ -71,11 +96,11 @@ module MailForm::Delivery
71
96
  attr_accessor *(accessors - instance_methods.map(&:to_sym))
72
97
 
73
98
  if options[:attachment]
74
- write_inheritable_array(:mail_attachments, accessors)
99
+ self.mail_attachments += accessors
75
100
  elsif options[:captcha]
76
- write_inheritable_array(:mail_captcha, accessors)
101
+ self.mail_captcha += accessors
77
102
  else
78
- write_inheritable_array(:mail_attributes, accessors)
103
+ self.mail_attributes += accessors
79
104
  end
80
105
 
81
106
  validation = options.delete(:validate)
@@ -99,95 +124,6 @@ module MailForm::Delivery
99
124
  end
100
125
  alias :attributes :attribute
101
126
 
102
- # Declares contact email sender. It can be a string or a proc or a symbol.
103
- #
104
- # When a symbol is given, it will call a method on the form object with
105
- # the same name as the symbol. As a proc, it receives a simple form
106
- # instance. By default is the class human name.
107
- #
108
- # == Examples
109
- #
110
- # class ContactForm < MailForm
111
- # subject "My Contact Form"
112
- # end
113
- #
114
- def subject(duck=nil, &block)
115
- write_inheritable_attribute(:mail_subject, duck || block)
116
- end
117
-
118
- # Declares contact email sender. It can be a string or a proc or a symbol.
119
- #
120
- # When a symbol is given, it will call a method on the form object with
121
- # the same name as the symbol. As a proc, it receives a simple form
122
- # instance. By default is:
123
- #
124
- # sender{ |c| c.email }
125
- #
126
- # This requires that your MailForm object have an email attribute.
127
- #
128
- # == Examples
129
- #
130
- # class ContactForm < MailForm
131
- # # Change sender to include also the name
132
- # sender { |c| %{"#{c.name}" <#{c.email}>} }
133
- # end
134
- #
135
- def sender(duck=nil, &block)
136
- write_inheritable_attribute(:mail_sender, duck || block)
137
- end
138
- alias :from :sender
139
-
140
- # Who will receive the e-mail. Can be a string or array or a symbol or a proc.
141
- #
142
- # When a symbol is given, it will call a method on the form object with
143
- # the same name as the symbol. As a proc, it receives a simple form instance.
144
- #
145
- # Both the proc and the symbol must return a string or an array. By default
146
- # is nil.
147
- #
148
- # == Examples
149
- #
150
- # class ContactForm < MailForm
151
- # recipients [ "first.manager@domain.com", "second.manager@domain.com" ]
152
- # end
153
- #
154
- def recipients(duck=nil, &block)
155
- write_inheritable_attribute(:mail_recipients, duck || block)
156
- end
157
- alias :to :recipients
158
-
159
- # Additional headers to your e-mail.
160
- #
161
- # == Examples
162
- #
163
- # class ContactForm < MailForm
164
- # headers { :content_type => 'text/html' }
165
- # end
166
- #
167
- def headers(hash)
168
- write_inheritable_hash(:mail_headers, hash)
169
- end
170
-
171
- # Customized template for your e-mail, if you don't want to use default
172
- # 'contact' template or need more than one contact form with different
173
- # template layouts.
174
- #
175
- # When a symbol is given, it will call a method on the form object with
176
- # the same name as the symbol. As a proc, it receives a simple form
177
- # instance. Both method and proc must return a string with the template
178
- # name. Defaults to 'contact'.
179
- #
180
- # == Examples
181
- #
182
- # class ContactForm < MailForm
183
- # # look for a template in views/mail_form/notifier/my_template.erb
184
- # template 'my_template'
185
- # end
186
- #
187
- def template(new_template)
188
- write_inheritable_attribute(:mail_template, new_template)
189
- end
190
-
191
127
  # Values from request object to be appended to the contact form.
192
128
  # Whenever used, you have to send the request object when initializing the object:
193
129
  #
@@ -203,7 +139,7 @@ module MailForm::Delivery
203
139
  # end
204
140
  #
205
141
  def append(*values)
206
- write_inheritable_array(:mail_appendable, values)
142
+ self.mail_appendable += values
207
143
  end
208
144
  end
209
145
 
@@ -215,7 +151,7 @@ module MailForm::Delivery
215
151
  # returns false otherwise.
216
152
  #
217
153
  def spam?
218
- mail_captcha.each do |field|
154
+ self.class.mail_captcha.each do |field|
219
155
  next if send(field).blank?
220
156
 
221
157
  if defined?(Rails) && Rails.env.development?
@@ -21,13 +21,22 @@ module MailForm::Shim
21
21
  end
22
22
  end
23
23
 
24
- # Initialize assigning the parameters given as hash (just as in ActiveRecord).
24
+ # Initialize assigning the parameters given as hash.
25
25
  def initialize(params={})
26
26
  params.each_pair do |attr, value|
27
27
  self.send(:"#{attr}=", value)
28
28
  end unless params.blank?
29
29
  end
30
30
 
31
+ # Returns a hash of attributes, according to the attributes existent in
32
+ # self.class.mail_attributes.
33
+ def attributes
34
+ self.class.mail_attributes.inject({}) do |hash, attr|
35
+ hash[attr.to_s] = send(attr)
36
+ hash
37
+ end
38
+ end
39
+
31
40
  # Always return true so when using form_for, the default method will be post.
32
41
  def new_record?
33
42
  true
@@ -1,3 +1,3 @@
1
1
  module MailForm
2
- VERSION = "1.1.0".freeze
2
+ VERSION = "1.2.0".freeze
3
3
  end
@@ -1,7 +1,6 @@
1
- <h4 style="text-decoration:underline"><%= mailer.subject %></h4>
1
+ <h4 style="text-decoration:underline"><%= message.subject %></h4>
2
2
 
3
- <% @resource.class.mail_attributes.each do |attribute|
4
- value = @resource.send(attribute)
3
+ <% @resource.attributes.each do |attribute, value|
5
4
  next if value.blank? %>
6
5
 
7
6
  <p><b><%= @resource.class.human_attribute_name(attribute) %>:</b>
@@ -9,7 +8,7 @@
9
8
  when /\n/
10
9
  raw(simple_format(h(value)))
11
10
  when Time, DateTime, Date
12
- I18n.l value
11
+ I18n.l(value)
13
12
  else
14
13
  value
15
14
  end
@@ -23,16 +22,17 @@
23
22
  value = @resource.request.send(attribute)
24
23
 
25
24
  value = if value.is_a?(Hash) && !value.empty?
26
- content_tag(:ul, value.to_a.map{|k,v| content_tag(:li, h("#{k}: #{v.inspect}")) }.join("\n"), :style => "list-style:none;")
25
+ list = value.to_a.map{ |k,v| content_tag(:li, h("#{k}: #{v.inspect}")) }.join("\n")
26
+ content_tag(:ul, raw(list), :style => "list-style:none;")
27
27
  elsif value.is_a?(String)
28
- h(value)
28
+ value
29
29
  else
30
- h(value.inspect)
30
+ value.inspect
31
31
  end
32
32
  %>
33
33
 
34
34
  <p><b><%= I18n.t attribute, :scope => [ :mail_form, :request ], :default => attribute.to_s.humanize %>:</b>
35
- <%= value.include?("\n") ? raw(simple_format(value)) : value %></p>
35
+ <%= value.include?("\n") ? simple_format(value) : value %></p>
36
36
  <% end %>
37
37
  <br />
38
38
  <% end %>
@@ -13,8 +13,6 @@ class MailFormNotifierTest < ActiveSupport::TestCase
13
13
  test_file = Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__), 'test_file.txt'))
14
14
  @with_file = FileForm.new(:name => 'José', :email => 'my.email@my.domain.com', :message => "Cool", :file => test_file)
15
15
 
16
- @template = TemplateForm.new(@valid_attributes)
17
-
18
16
  ActionMailer::Base.deliveries = []
19
17
  end
20
18
 
@@ -23,50 +21,14 @@ class MailFormNotifierTest < ActiveSupport::TestCase
23
21
  assert_equal 1, ActionMailer::Base.deliveries.size
24
22
  end
25
23
 
26
- def test_subject_defaults_to_class_human_name
27
- @form.deliver
28
- assert_equal 'Contact form', first_delivery.subject
29
- end
30
-
31
- def test_subject_is_a_string
32
- @advanced.deliver
33
- assert_equal 'My Advanced Form', first_delivery.subject
34
- end
35
-
36
- def test_sender_defaults_to_form_email
37
- @form.deliver
38
- assert_equal ['my.email@my.domain.com'], first_delivery.from
39
- end
40
-
41
- def test_error_is_raised_when_recipients_is_nil
42
- assert_raise ScriptError do
43
- NullRecipient.new.deliver
44
- end
45
- end
46
-
47
- def test_recipients_is_a_string
24
+ def test_subject_defaults_to_action_mailer_one
48
25
  @form.deliver
49
- assert_equal ['my.email@my.domain.com'], first_delivery.to
50
- end
51
-
52
- def test_recipients_is_an_array
53
- @advanced.deliver
54
- assert_equal ['my.first@email.com', 'my.second@email.com'], first_delivery.to
55
- end
56
-
57
- def test_recipients_is_a_symbold
58
- @with_file.deliver
59
- assert_equal ['contact_file@my.domain.com'], first_delivery.to
60
- end
61
-
62
- def test_headers_is_a_hash
63
- @advanced.deliver
64
- assert_equal 'mypath', first_delivery.header['return-path'].to_s
26
+ assert_equal 'Contact', first_delivery.subject
65
27
  end
66
28
 
67
29
  def test_body_contains_subject
68
30
  @form.deliver
69
- assert_match /Contact form/, first_delivery.body.to_s
31
+ assert_match /Contact/, first_delivery.body.to_s
70
32
  end
71
33
 
72
34
  def test_body_contains_attributes_values
@@ -142,6 +104,7 @@ class MailFormNotifierTest < ActiveSupport::TestCase
142
104
  def test_request_info_hashes_are_print_inside_lis
143
105
  @request.session = { :my => :session, :user => "data" }
144
106
  @advanced.deliver
107
+ assert_match /<ul/, last_delivery.body.to_s
145
108
  assert_match /<li>my: :session<\/li>/, last_delivery.body.to_s
146
109
  assert_match /<li>user: &quot;data&quot;<\/li>/, last_delivery.body.to_s
147
110
  end
@@ -163,17 +126,6 @@ class MailFormNotifierTest < ActiveSupport::TestCase
163
126
  assert_no_match /File:/, first_delivery.body.to_s
164
127
  end
165
128
 
166
- def test_form_with_customized_template_render_correct_template
167
- begin
168
- previous_view_path = MailForm.view_paths
169
- MailForm.prepend_view_path File.join(File.dirname(__FILE__), 'views')
170
- @template.deliver
171
- assert_match 'Hello from my custom template!', last_delivery.body.to_s
172
- ensure
173
- MailForm.view_paths = previous_view_path
174
- end
175
- end
176
-
177
129
  protected
178
130
 
179
131
  def first_delivery
@@ -19,8 +19,6 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
19
19
  require 'mail_form'
20
20
 
21
21
  class ContactForm < MailForm::Base
22
- recipients 'my.email@my.domain.com'
23
-
24
22
  attribute :name, :validate => true
25
23
  attribute :email, :validate => /[^@]+@[^\.]+\.[\w\.\-]+/
26
24
  attribute :category, :validate => ["Interface bug", "General"], :allow_blank => true
@@ -30,6 +28,10 @@ class ContactForm < MailForm::Base
30
28
 
31
29
  before_create :set_created_at
32
30
 
31
+ def headers
32
+ { :to => 'my.email@my.domain.com' }
33
+ end
34
+
33
35
  def set_created_at
34
36
  created_at = Date.today
35
37
  end
@@ -42,10 +44,13 @@ end
42
44
  class AdvancedForm < ContactForm
43
45
  append :remote_ip, :user_agent, :session
44
46
 
45
- recipients [ 'my.first@email.com', 'my.second@email.com' ]
46
- subject 'My Advanced Form'
47
- sender{|c| %{"#{c.name}" <#{c.email}>} }
48
- headers 'return-path' => 'mypath'
47
+ def headers
48
+ { :to => [ 'my.first@email.com', 'my.second@email.com' ],
49
+ :subject => "My Advanced Form",
50
+ :from => %{"#{name}" <#{email}>},
51
+ "return-path" => "mypath"
52
+ }
53
+ end
49
54
  end
50
55
 
51
56
  class FileForm < ContactForm
@@ -61,18 +66,6 @@ class FileForm < ContactForm
61
66
  end
62
67
  end
63
68
 
64
- class NullRecipient < MailForm::Base
65
- sender 'my.email@my.domain.com'
66
- end
67
-
68
- class TemplateForm < ContactForm
69
- template 'custom_template'
70
- end
71
-
72
- class WrongForm < ContactForm
73
- template 'does_not_exist'
74
- end
75
-
76
69
  # Needed to correctly test an uploaded file
77
70
  class Rack::Test::UploadedFile
78
71
  def read
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Jos\xC3\xA9 Valim"
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-02-07 00:00:00 +01:00
13
+ date: 2010-03-03 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies: []
16
16