Class: Doozer::Mailer

Inherits:
Object show all
Includes:
Util::Logger, ViewHelpers
Defined in:
lib/doozer/mailer.rb

Overview

The Mailer class operates in many ways like a Controller.

Mailers have access to all ViewHelpers methods.

Mailers can also load partials.

Limitations:

  • The current send implemntation must be overridden by your application.

  • Create multipart messages but only handles html content types. No text or attachment capabilities.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ViewHelpers

#alink, #app_name, #app_path, #aurl, #authtoken, #base_url, #feed, #h, #hash_to_props, #hash_to_qs, #img, #ip, #javascript, #link, #metatags, #path, #rack_env, #server_name, #session?, #static_url, #stylesheet, #title, #url

Methods included from Util::Logger

#logger

Constructor Details

#initialize(action, args = {}) ⇒ Mailer

Create a new Mailer object action: a symbol of the action to call args: optional list of arguments



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/doozer/mailer.rb', line 65

def initialize(action, args={})
  @controller = self.class.to_s
  @action = action
  
  #holds all variables for template binding
  @view={}
  @to = args[:to]
  @from = args[:from]
  @cc = args[:cc]
  @bcc = args[:bcc]
  @subject = args[:subject] || ''
  @date = args[:date] || Time.now()
  @charset = args[:charset] || "ISO-8859-1"
  
  @message_id = "#{DateTime.now().strftime('%Y%m%d%H%M%S')}.#{(rand(1000) * 1024).to_s}"
  @envelope = nil
  @render_args = {:layout=>nil, :view=>nil, :text=>nil}
  render({
    :view=>args[:view] || action,
    :layout=>args[:layout] || mailer_class.layout,
    :text=>args[:text]
  })
  
  # turn the rest of the args into instance variables
  args.delete(:view) if args[:view]
  args.delete(:layout) if args[:delete]
  args.delete(:text) if args[:text]
  args.each { |key, value| self.instance_variable_set("@#{key}".to_sym, value)}
  
end

Instance Attribute Details

#actionObject

Returns the value of attribute action.



21
22
23
# File 'lib/doozer/mailer.rb', line 21

def action
  @action
end

#bccObject

Returns the value of attribute bcc.



29
30
31
# File 'lib/doozer/mailer.rb', line 29

def bcc
  @bcc
end

#ccObject

Returns the value of attribute cc.



27
28
29
# File 'lib/doozer/mailer.rb', line 27

def cc
  @cc
end

#charsetObject

Returns the value of attribute charset.



39
40
41
# File 'lib/doozer/mailer.rb', line 39

def charset
  @charset
end

#controllerObject

Returns the value of attribute controller.



19
20
21
# File 'lib/doozer/mailer.rb', line 19

def controller
  @controller
end

#dateObject

Returns the value of attribute date.



33
34
35
# File 'lib/doozer/mailer.rb', line 33

def date
  @date
end

#envelopeObject

Returns the value of attribute envelope.



35
36
37
# File 'lib/doozer/mailer.rb', line 35

def envelope
  @envelope
end

#fromObject

Returns the value of attribute from.



23
24
25
# File 'lib/doozer/mailer.rb', line 23

def from
  @from
end

#message_idObject

Returns the value of attribute message_id.



37
38
39
# File 'lib/doozer/mailer.rb', line 37

def message_id
  @message_id
end

#render_argsObject

Returns the value of attribute render_args.



41
42
43
# File 'lib/doozer/mailer.rb', line 41

def render_args
  @render_args
end

#subjectObject

Returns the value of attribute subject.



31
32
33
# File 'lib/doozer/mailer.rb', line 31

def subject
  @subject
end

#toObject

Returns the value of attribute to.



25
26
27
# File 'lib/doozer/mailer.rb', line 25

def to
  @to
end

Class Method Details

.deliver(action, args = {}) ⇒ Object

Note: The send mechanism is empty and must be overriden in the calling application.



239
240
241
242
# File 'lib/doozer/mailer.rb', line 239

def self.deliver(action, args={})
  # puts "deliver.."  
  send(generate(action, args))
end

.generate(action, args = {}) ⇒ Object

Call this method to generate a Mailer#action instance

Arguments

  • action: The action of the mailer to call passed as a symbol.

  • args: The mail arguments to initialize the email with.

    All remaining arguments are turned into instance variables and bound to the view.
    


222
223
224
225
226
227
228
229
# File 'lib/doozer/mailer.rb', line 222

def self.generate(action, args={})
  # puts "process.."
  mailer = self.new(action, args)
  mailer.method(action).call()
  mailer.finished! #close the db connections
  mailer.package
  mailer
end

.include_view_helper(helper) ⇒ Object

Include the app/helpers file_name. Expects helper as a string.

You must pass the full file name if you use this method.

Example: self.include_view_helper(‘application_helper’)



211
212
213
214
# File 'lib/doozer/mailer.rb', line 211

def self.include_view_helper(helper)
    # importing view helpers into controller
    include Object.const_get(Doozer::Lib.classify("#{helper}"))
end

.include_view_helpersObject

Include additional view helpers declared for the class.

This method automatically appends ‘_helper’ to each required helper symbol



199
200
201
202
203
204
# File 'lib/doozer/mailer.rb', line 199

def self.include_view_helpers
    # importing view helpers into controller
    self.require_view_helpers.each { | sym |
      self.include_view_helper("#{sym.to_s}_helper")
    }
end

.queue(action, args = {}) ⇒ Object

Call this method to queue a Mailer#action instance for defered sending

Arguments

  • action: The action of the mailer to call passed as a symbol.

  • args: The mail arguments to initialize the email with.

    All remaining arguments are turned into instance variables and bound to the view.
    


250
251
252
253
# File 'lib/doozer/mailer.rb', line 250

def self.queue(action, args={})
  # puts "save.."
  save(generate(action, args))
end

.save(mailer) ⇒ Object

The save method must be overriden by the calling class.

> Implement this method to serialize a mailer and store it in the db.

> The mailer object passed to this mehod of the instance of the mailer.

> You can access the mailer.envelope.encoded (tmail) object which handles all the encoding.



266
# File 'lib/doozer/mailer.rb', line 266

def self.save(mailer); end

.send(mailer) ⇒ Object

The send method must be overriden by the calling class.

> The mailer object passed to this mehod of the instance of the mailer.

> You can access the mailer.envelope.encoded (tmail) object which handles all the encoding.



259
# File 'lib/doozer/mailer.rb', line 259

def self.send(mailer); end

Instance Method Details

#bindObject

Erb binding



97
98
99
# File 'lib/doozer/mailer.rb', line 97

def bind
  @erb.result(binding)
end

#dbObject

Sequel ORM db connection



182
183
184
# File 'lib/doozer/mailer.rb', line 182

def db
  Doozer::Configs.db_conn
end

#finished!Object

Global teardown called at the end of every request. Hooks ORM.teardown



187
188
189
# File 'lib/doozer/mailer.rb', line 187

def finished!
  Doozer::ORM.after_request if Doozer::Configs.orm_loaded
end

#from_addressObject

Call this method to receive the list of only :from addresses. Use this when sending through SMTP.



142
143
144
145
# File 'lib/doozer/mailer.rb', line 142

def from_address
  out = []; @envelope.from_addrs.each{|a| out.push(a.address)}
  return out
end

#mailer_classObject

Returns the Mailer object



192
193
194
# File 'lib/doozer/mailer.rb', line 192

def mailer_class
  Object.const_get(self.class.to_s)
end

#packageObject

This method is called prior to #send and handles the creation of envelope.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/doozer/mailer.rb', line 102

def package
  raise "Missing from address" if self.from.nil?

  begin 
    @envelope = TMail::Mail.new()
  rescue => e
    begin
      require 'tmail'
      @envelope = TMail::Mail.new()
    rescue MissingSourceFile, Gem::LoadError => e
      logger.error("TMail Gem wasn't found. Please install if you want to send mail.")
    end
  end
  
  # http://tmail.rubyforge.org/rdoc/index.html
  @envelope.mime_version = "1.0"
  @envelope.charset = self.charset
  @envelope.message_id = self.message_id
  @envelope.from = [self.from]
  @envelope.to = [self.to] if self.to
  @envelope.cc = [self.cc] if self.cc
  @envelope.bcc = [self.bcc] if self.bcc
  @envelope.date = self.date
  @envelope.subject = self.subject
  
  html = TMail::Mail.new()
  html.body = self.render_result
  html.set_content_type('text','html')
  
  @envelope.parts << html
  @envelope.set_content_type('multipart', 'mixed') # needs to be set last or throws an error
end

#partial(file = nil, locals = {}) ⇒ Object

Helper method for initializing partials from views.



148
149
150
151
# File 'lib/doozer/mailer.rb', line 148

def partial(file=nil, locals={})
  locals[:view_dir] = mailer_class.view_dir
  Doozer::MailerPartial.partial(file, locals)
end

#render(args = {}) ⇒ Object

Renders an action with any of the following overridable parameters:

args=

:view=>Symbol, String or ERB,
:layout=>Symbol,
:text=>'this is the text to render'



161
162
163
164
165
# File 'lib/doozer/mailer.rb', line 161

def render(args={})
  change_layout(args[:layout]) if args[:layout]
  change_view(args[:view]) if args[:view]
  change_view(ERB.new(args[:text])) if args[:text]
end

#render_resultObject

This method creates the html part of the mail.



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/doozer/mailer.rb', line 168

def render_result
    layout = @render_args[:layout]
    view = @render_args[:view]
    if layout.kind_of? Symbol # this handles the layout(:none)
      view.result(binding)
    else
      @view[:timestamp] = "<!-- rendered: #{Time.now()} / env: #{rack_env} -->"
      @view[:body] = view.result(binding)
      # layout = @layout if layout.nil? # this handles the layout(:some_other_layout) case for formats
      layout.result(binding)
    end
end

#to_addressObject

Call this method to receive the list of only :to addresses. Use this when sending through SMTP.



136
137
138
139
# File 'lib/doozer/mailer.rb', line 136

def to_address
  out = []; @envelope.to_addrs.each{|a| out.push(a.address)}
  return out
end