X-Git-Url: https://projects.mako.cc/source/selectricity/blobdiff_plain/a12d4f62752f546f57421244e370e79965706ffb..f7aee769411a893c1059c529a220c0d25c72974f:/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb diff --git a/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb b/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb new file mode 100644 index 0000000..839cd40 --- /dev/null +++ b/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb @@ -0,0 +1,140 @@ +# Overriding ActionMailer to teach it about Engines... +module ActionMailer + class Base + + # Initialize the mailer via the given +method_name+. The body will be + # rendered and a new TMail::Mail object created. + def create!(method_name, *parameters) #:nodoc: + initialize_defaults(method_name) + send(method_name, *parameters) + + + # If an explicit, textual body has not been set, we check assumptions. + unless String === @body + # First, we look to see if there are any likely templates that match, + # which include the content-type in their file name (i.e., + # "the_template_file.text.html.rhtml", etc.). Only do this if parts + # have not already been specified manually. + + templates = get_all_templates_for_action(@template) + + #RAILS_DEFAULT_LOGGER.debug "template: #{@template}; templates: #{templates.inspect}" + + if @parts.empty? + + # /app/views/ / .something.rhtml + + #templates = Dir.glob("#{template_path}/#{@template}.*") + + # this loop expects an array of paths to actual template files which match + # the given action name + templates.each do |path| + # TODO: don't hardcode rhtml|rxml + basename = File.basename(path) + next unless md = /^([^\.]+)\.([^\.]+\.[^\+]+)\.(rhtml|rxml)$/.match(basename) + + template_name = basename + content_type = md.captures[1].gsub('.', '/') + + @parts << Part.new(:content_type => content_type, + :disposition => "inline", :charset => charset, + :body => render_message(template_name, @body)) + end + unless @parts.empty? + @content_type = "multipart/alternative" + @parts = sort_parts(@parts, @implicit_parts_order) + end + end + + # Then, if there were such templates, we check to see if we ought to + # also render a "normal" template (without the content type). If a + # normal template exists (or if there were no implicit parts) we render + # it. + template_exists = @parts.empty? + # template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| i.split(".").length == 2 } + template_exists ||= templates.any? do |i| + arr = File.basename(i).split(".") + (arr.length == 2) && (arr[0] == @template) + end + @body = render_message(@template, @body) if template_exists + + # Finally, if there are other message parts and a textual body exists, + # we shift it onto the front of the parts and set the body to nil (so + # that create_mail doesn't try to render it in addition to the parts). + if !@parts.empty? && String === @body + @parts.unshift Part.new(:charset => charset, :body => @body) + @body = nil + end + end + + # If this is a multipart e-mail add the mime_version if it is not + # already set. + @mime_version ||= "1.0" if !@parts.empty? + + # build the mail object itself + @mail = create_mail + end + + private + + + # JGA - Modified to pass the method name to initialize_template_class + def render(opts) + body = opts.delete(:body) + initialize_template_class(body, opts[:file]).render(opts) + end + + + # Return all ActionView template paths from the app and all Engines + def template_paths + paths = [template_path] + Engines.each { |engine| + # add a path for every engine if one exists. + engine_template_path = File.join(engine.root, "app", "views", mailer_name) + paths << engine_template_path if File.exists?(engine_template_path) + } + paths + end + + # Returns a list of all template paths in the app and Engines + # which contain templates that might be used for the given action + def get_all_templates_for_action(action) + # can we trust uniq! to do this? i'm not sure... + templates = [] + seen_names = [] + template_paths.each { |path| + all_templates_for_path = Dir.glob(File.join(path, "#{action}*")) + all_templates_for_path.each { |template| + name = File.basename(template) + if !seen_names.include?(name) + seen_names << name + templates << template + end + } + } + templates + end + + # Returns the first path to the given template in our + # app/Engine 'chain'. + def find_template_root_for(template) + all_paths = get_all_templates_for_action(template) + if all_paths.empty? + return template_path + else + return File.dirname(all_paths[0]) + end + end + + # JGA - changed here to include the method name that we + # are interested in, so that we can re-locate the proper + # template root + def initialize_template_class(assigns, method_name) + engine_template = find_template_root_for(method_name) + action_view_class = Class.new(ActionView::Base).send(:include, master_helper_module) + action_view_class.new(engine_template, assigns, self) + end + + + end +end