Class: MailEngine::MailTemplate

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/mail_engine/mail_template.rb

Overview

Schema Information

Table name: mail_templates

id            :integer         not null, primary key
name          :string(255)
subject       :string(255)
path          :string(255)
format        :string(255)     default("html")
locale        :string(255)
handler       :string(255)     default("liquid")
body          :text
partial       :boolean         default(FALSE)
for_marketing :boolean         default(FALSE)
layout        :string(255)     default("none")
zip_file      :string(255)
created_at    :datetime
updated_at    :datetime

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#create_by_uploadObject

Returns the value of attribute create_by_upload.



21
22
23
# File 'app/models/mail_engine/mail_template.rb', line 21

def create_by_upload
  @create_by_upload
end

Class Method Details

.all_system_mailersObject



111
112
113
114
115
116
# File 'app/models/mail_engine/mail_template.rb', line 111

def all_system_mailers
  mailer_path = File.join(Rails.root, "app", "mailers")
  mailers_found_on_system = `find #{mailer_path} -name *.rb`.split("\n")
  # remove mailer_path just show file names
  mailers_found_on_system.map {|mailer| mailer.sub(/^#{mailer_path}\//, '')}
end

.get_subject_from_bother_template(path, locale, for_marketing) ⇒ Object

get subject from other templates with same path



68
69
70
71
# File 'app/models/mail_engine/mail_template.rb', line 68

def get_subject_from_bother_template(path, locale, for_marketing)
  return nil if path.blank?
  MailEngine::MailTemplate.where(:path => path, :locale => locale, :for_marketing => for_marketing, :partial => false).select("subject").first.try(:subject)
end

.import_from_files!(mailer_name) ⇒ Object

import all mail template from exist system. format like: views/user_mailer/index.en.html.erb



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/models/mail_engine/mail_template.rb', line 75

def import_from_files!(mailer_name)
  mailer = mailer_name.classify.constantize
  raise "not a mailer or doesn't provide mailer." unless mailer.ancestors.include?(ActionMailer::Base)

  # prepare data
  mailer_actions     = mailer.action_methods
  file_view_paths    = mailer.view_paths.select {|path| path.is_a?(ActionView::FileSystemResolver)}
  available_formats  = [:text, :html]
  available_handlers = [:erb, :liquid, :rhtml]
  available_locales  = I18n.available_locales

  # collect all possible combinations
  search_envs = file_view_paths.product(mailer_actions, available_formats, available_handlers, available_locales)

  # [#<ActionView::FileSystemResolver>, "notify_to_user", :text, :erb, :zh]
  search_envs.map { |resolver, action, format, handler, locale|
    template_files = resolver.find_all "#{mailer.to_s.underscore}/#{action}", {}, false, {
      :locale => Array.wrap(locale),
      :formats => Array.wrap(format),
      :handlers => Array.wrap(handler)
    }

    # file_path => app/views/user_mailer/notify.html.erb
    template_files.map do |file_path|
      template = MailEngine::MailTemplate.create(
        :name    => "#{mailer.to_s.underscore}/#{action} - #{format}",
        :subject => "#{mailer.to_s.underscore}/#{action} - #{format}",
        :path    => "#{mailer.to_s.underscore}/#{action}",
        :format  => format.to_s,
        :locale  => locale.to_s,
        :body    => File.read(file_path.identifier)
      )
    end
  }.compact.flatten.uniq # search_envs
end

Instance Method Details

#actual_pathObject



142
143
144
145
# File 'app/models/mail_engine/mail_template.rb', line 142

def actual_path
  return "mail_engine/mail_dispatcher/#{self.path}" if self.for_marketing?
  self.path
end

#check_placeholders_for_layoutObject



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/models/mail_engine/mail_template.rb', line 184

def check_placeholders_for_layout
  return if self.partial?
  if self.template_partials.detect{ |tmp| !tmp.persisted? }.present? || self.layout == 'none'
    self.template_partials.delete_if { |tmp| tmp.persisted? }
  end

  names = self.template_partials.map(&:placeholder_name)

  case self.layout
  when "none"
    errors.add(:partials, "should have no partials") unless names.blank?
  when "only_footer"
    errors.add(:partials, "should have footer partial") unless names.include?('footer') and names.size == 1
  when "header_and_footer"
    errors.add(:partials, "should have header and footer partials") unless names.include?('header') and names.include?('footer') and names.size == 2
  else
  end
end

#check_zip_fileObject

if uploaded a zip file, check:

  1. only one html?

  2. has html



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/models/mail_engine/mail_template.rb', line 162

def check_zip_file
  begin
    @extracted_files, @extraction_dir_path = MailEngine::ZipProcessor.extract_all_files(self.zip_file.path, %w{css jpg jpeg gif png html htm})

    if @extracted_files.present?
      MailEngine::HtmlDocumentAssetsReplacer.check! @extracted_files if @extracted_files.present?
    else
      raise "Extract zip file failed or not zip file."
    end
  rescue => e
    errors.add(:file, e.message)
  end
end

#delete_partials_if_new_partials_addedObject

FIXME: if no changes just keep the same, it sill will remove the template partial and add a new one



153
154
155
156
157
# File 'app/models/mail_engine/mail_template.rb', line 153

def delete_partials_if_new_partials_added
  if self.template_partials.detect {|tmp| !tmp.persisted? }.present? || self.layout == 'none' # has new partials selected
    MailEngine::TemplatePartial.destroy_all(:mail_template_id => self) # remove previous partials
  end
end

#duplicate(merge_options = {}) ⇒ Object

return one clone version of self with all duplicated relations.



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'app/models/mail_engine/mail_template.rb', line 235

def duplicate merge_options = {}
  # start to clone
  duplicated_obj = self.clone :except => [:zip_file], :include => [:template_partials, :mail_template_files]
  duplicated_obj.zip_file = File.open(self.zip_file.path) if self.zip_file.path # it will make a copy version of zipfile
  duplicated_obj.attributes = merge_options if merge_options.is_a? Hash # merge custom options
  # without saving can't not create files. so save it first.
  duplicated_obj.save

  ### below code is used to clone mail_template_files and replace the new url for cloned template body.
  # pair the mail_template_files and insert into substitution_array.
  substitution_pair_array = []
  self.mail_template_files.each_with_index do |origin_file, index|
    substitution_pair_array << [origin_file, duplicated_obj.mail_template_files[index]]
  end

  # replace image or file url with new url.
  original_body = self.body

  substitution_pair_array.each do |origin_file, new_file|
    original_body = MailEngine::HtmlDocumentAssetsReplacer.replace_resource_in_html(
      original_body,
      origin_file.file.url,
      new_file.file.url,
      :url
    )
  end

  # write back the new body with cloned resource urls.
  duplicated_obj.update_attributes :body => original_body
  duplicated_obj
end

#existed_variations(for_partial = false) ⇒ Object



138
139
140
# File 'app/models/mail_engine/mail_template.rb', line 138

def existed_variations for_partial = false
  self.class.where(:path => self.path, :partial => for_partial).order("locale, format")
end

#filenameObject

prepend “_” at partial name.



221
222
223
224
225
226
227
228
# File 'app/models/mail_engine/mail_template.rb', line 221

def filename
  tmp_path = self.path
  if self.partial
    tmp_path.gsub(/([^\/]+)\z/, '_\1')
  else
    tmp_path
  end
end

#full_pathObject



230
231
232
# File 'app/models/mail_engine/mail_template.rb', line 230

def full_path
  "#{filename}.#{self.locale}.#{self.format}.#{self.handler}"
end

#logsObject

has_many :logs, :class_name => “MailEngine::MailLog”, :conditions => => self.path



148
149
150
# File 'app/models/mail_engine/mail_template.rb', line 148

def logs
  MailEngine::MailLog.where(:mail_template_path => self.actual_path).order("id desc").limit(10)
end

#partial_in_use?Boolean

detect if current partial template is used by other templates.

Returns:

  • (Boolean)


120
121
122
# File 'app/models/mail_engine/mail_template.rb', line 120

def partial_in_use?
  self.partial? and self.mail_templates.count > 0
end

#process_zip_file(hostname = ActionMailer::Base.default_url_options[:host] || "localhost:3000") ⇒ Object

FIXME: remove the hostname



177
178
179
180
181
182
# File 'app/models/mail_engine/mail_template.rb', line 177

def process_zip_file(hostname = ActionMailer::Base.default_url_options[:host] || "localhost:3000")
  return if @extracted_files.blank?
  self.update_attribute :body, MailEngine::HtmlDocumentAssetsReplacer.process(self, @extracted_files, hostname)
  # remove the tmp files
  system("rm -rf #{@extraction_dir_path}")
end

#template_nameObject

controller/action_name => for get the action_name



216
217
218
# File 'app/models/mail_engine/mail_template.rb', line 216

def template_name
  self.path.scan(/[^\/]+$/).first
end

#typeObject



209
210
211
212
213
# File 'app/models/mail_engine/mail_template.rb', line 209

def type
  return 'partial' if self.partial?
  return 'system' unless self.for_marketing?
  return 'marketing' if self.for_marketing?
end

#variations(for_partial = false) ⇒ Object

list the templates with same path, but different locale and format



125
126
127
128
129
130
131
132
133
134
135
136
# File 'app/models/mail_engine/mail_template.rb', line 125

def variations(for_partial = false)
  all_variation_codes = I18n.available_locales.product([:html, :text])
  current_existed_variations = existed_variations(for_partial)
  existed_variation_codes = current_existed_variations.map do |template|
                              [template.locale.to_sym, template.format.to_sym]
                            end
  missing_variations = (all_variation_codes - existed_variation_codes).map do |locale, format|
    MailEngine::MailTemplate.new :locale => locale.to_s, :format => format.to_s
  end

  missing_variations + current_existed_variations
end