300 lines
8.1 KiB
Ruby
300 lines
8.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'hanami/utils/kernel'
|
|
require 'hanami/mailer/template_name'
|
|
require 'hanami/mailer/templates_finder'
|
|
|
|
module Hanami
|
|
class Mailer
|
|
# Framework configuration
|
|
#
|
|
# @since 0.1.0
|
|
class Configuration
|
|
# Default root
|
|
#
|
|
# @since 0.1.0
|
|
# @api private
|
|
DEFAULT_ROOT = '.'
|
|
|
|
# Default delivery method
|
|
#
|
|
# @since 0.1.0
|
|
# @api private
|
|
DEFAULT_DELIVERY_METHOD = :smtp
|
|
|
|
# Default charset
|
|
#
|
|
# @since 0.1.0
|
|
# @api private
|
|
DEFAULT_CHARSET = 'UTF-8'
|
|
|
|
private_constant(*constants(false))
|
|
|
|
# Initialize a configuration instance
|
|
#
|
|
# @yield [config] the new initialized configuration instance
|
|
# @return [Hanami::Mailer::Configuration] a new configuration's instance
|
|
#
|
|
# @since 0.1.0
|
|
#
|
|
# @example Basic Usage
|
|
# require 'hanami/mailer'
|
|
#
|
|
# configuration = Hanami::Mailer::Configuration.new do |config|
|
|
# config.delivery_method :smtp, ...
|
|
# end
|
|
def initialize
|
|
@mailers = {}
|
|
|
|
self.namespace = Object
|
|
self.root = DEFAULT_ROOT
|
|
self.delivery_method = DEFAULT_DELIVERY_METHOD
|
|
self.default_charset = DEFAULT_CHARSET
|
|
|
|
yield(self) if block_given?
|
|
@finder = TemplatesFinder.new(root)
|
|
end
|
|
|
|
# Set the Ruby namespace where to lookup for mailers.
|
|
#
|
|
# When multiple instances of the framework are used, we want to make sure
|
|
# that if a `MyApp` wants a `Mailers::Signup` mailer, we are loading the
|
|
# right one.
|
|
#
|
|
# @!attribute namespace
|
|
# @return [Class,Module,String] the Ruby namespace where the mailers
|
|
# are located
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
#
|
|
# @example
|
|
# require 'hanami/mailer'
|
|
#
|
|
# Hanami::Mailer::Configuration.new do |config|
|
|
# config.namespace = MyApp::Mailers
|
|
# end
|
|
attr_accessor :namespace
|
|
|
|
# Set the root path where to search for templates
|
|
#
|
|
# If not set, this value defaults to the current directory.
|
|
#
|
|
# @param value [String, Pathname] the root path for mailer templates
|
|
#
|
|
# @raise [Errno::ENOENT] if the path doesn't exist
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
#
|
|
# @see http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html
|
|
# @see http://rdoc.info/gems/hanami-utils/Hanami/Utils/Kernel#Pathname-class_method
|
|
#
|
|
# @example
|
|
# require 'hanami/mailer'
|
|
#
|
|
# Hanami::Mailer::Configuration.new do |config|
|
|
# config.root = 'path/to/templates'
|
|
# end
|
|
def root=(value)
|
|
@root = Utils::Kernel.Pathname(value).realpath
|
|
end
|
|
|
|
# @!attribute [r] root
|
|
# @return [Pathname] the root path for mailer templates
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
attr_reader :root
|
|
|
|
# @param blk [Proc] the code block
|
|
#
|
|
# @return [void]
|
|
#
|
|
# @raise [ArgumentError] if called without passing a block
|
|
#
|
|
# @since 0.1.0
|
|
#
|
|
# @see Hanami::Mailer.configure
|
|
def prepare(&blk)
|
|
raise ArgumentError.new('Please provide a block') unless block_given?
|
|
@modules.push(blk)
|
|
end
|
|
|
|
# Duplicate by copying the settings in a new instance.
|
|
#
|
|
# @return [Hanami::Mailer::Configuration] a copy of the configuration
|
|
#
|
|
# @since 0.1.0
|
|
# @api private
|
|
def duplicate
|
|
Configuration.new.tap do |c|
|
|
c.namespace = namespace
|
|
c.root = root.dup
|
|
c.modules = modules.dup
|
|
c.delivery_method = delivery_method
|
|
c.default_charset = default_charset
|
|
end
|
|
end
|
|
|
|
# Load the configuration
|
|
def load!
|
|
mailers.each { |m| m.__send__(:load!) }
|
|
freeze
|
|
end
|
|
|
|
# Reset the configuration
|
|
def reset!
|
|
root(DEFAULT_ROOT)
|
|
delivery_method(DEFAULT_DELIVERY_METHOD)
|
|
default_charset(DEFAULT_CHARSET)
|
|
|
|
@mailers = Set.new
|
|
@modules = []
|
|
end
|
|
|
|
alias unload! reset!
|
|
|
|
# Copy the configuration for the given mailer
|
|
#
|
|
# @param base [Class] the target mailer
|
|
#
|
|
# @return void
|
|
#
|
|
# @since 0.1.0
|
|
# @api private
|
|
def copy!(base)
|
|
modules.each do |mod|
|
|
base.class_eval(&mod)
|
|
end
|
|
end
|
|
|
|
# Specify a global delivery method for the mail gateway.
|
|
#
|
|
# It supports the following delivery methods:
|
|
#
|
|
# * Exim (`:exim`)
|
|
# * Sendmail (`:sendmail`)
|
|
# * SMTP (`:smtp`, for local installations)
|
|
# * SMTP Connection (`:smtp_connection`,
|
|
# via `Net::SMTP` - for remote installations)
|
|
# * Test (`:test`, for testing purposes)
|
|
#
|
|
# The default delivery method is SMTP (`:smtp`).
|
|
#
|
|
# Custom delivery methods can be specified by passing the class policy and
|
|
# a set of optional configurations. This class MUST respond to:
|
|
#
|
|
# * `initialize(options = {})`
|
|
# * `deliver!(mail)`
|
|
#
|
|
# @param method [Symbol, #initialize, deliver!] delivery method
|
|
# @param options [Hash] optional settings
|
|
#
|
|
# @return [Array] an array containing the delivery method and the optional settings as an Hash
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
#
|
|
# @example Setup delivery method with supported symbol
|
|
# require 'hanami/mailer'
|
|
#
|
|
# Hanami::Mailer::Configuration.new do |config|
|
|
# config.delivery_method = :sendmail
|
|
# end
|
|
#
|
|
# @example Setup delivery method with supported symbol and options
|
|
# require 'hanami/mailer'
|
|
#
|
|
# Hanami::Mailer::Configuration.new do |config|
|
|
# config.delivery_method = :smtp, address: "localhost", port: 1025
|
|
# end
|
|
#
|
|
# @example Setup custom delivery method with options
|
|
# require 'hanami/mailer'
|
|
#
|
|
# class MandrillDeliveryMethod
|
|
# def initialize(options)
|
|
# @options = options
|
|
# end
|
|
#
|
|
# def deliver!(mail)
|
|
# # ...
|
|
# end
|
|
# end
|
|
#
|
|
# Hanami::Mailer.Configuration.new do |config|
|
|
# config.delivery_method = MandrillDeliveryMethod,
|
|
# username: ENV['MANDRILL_USERNAME'],
|
|
# password: ENV['MANDRILL_API_KEY']
|
|
# end
|
|
attr_accessor :delivery_method
|
|
|
|
# Specify a default charset for all the delivered emails
|
|
#
|
|
# If not set, it defaults to `UTF-8`
|
|
#
|
|
# @!attribute default_charset
|
|
# @return [String] the charset
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
#
|
|
# @example
|
|
# require 'hanami/mailer'
|
|
#
|
|
# Hanami::Mailer::Configuration.new do |config|
|
|
# config.default_charset = "iso-8859-1"
|
|
# end
|
|
attr_accessor :default_charset
|
|
|
|
# Add a mailer to the registry
|
|
#
|
|
# @param mailer [Hanami::Mailer] a mailer
|
|
#
|
|
# @since 0.1.0
|
|
# @api unstable
|
|
def add_mailer(mailer)
|
|
template_name = TemplateName[mailer.template_name, namespace]
|
|
templates = finder.find(template_name)
|
|
|
|
mailers[mailer] = templates
|
|
end
|
|
|
|
# @param mailer [Hanami::Mailer] a mailer
|
|
# @param format [Symbol] the wanted format (eg. `:html`, `:txt`)
|
|
#
|
|
# @raise [Hanami::Mailer::UnknownMailerError] if the given mailer is not
|
|
# present in the configuration. This happens when the configuration is
|
|
# used before to being finalized.
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
def template(mailer, format)
|
|
mailers.fetch(mailer) { raise UnknownMailerError.new(mailer) }[format]
|
|
end
|
|
|
|
# Deep freeze the important instance variables
|
|
#
|
|
# @since next
|
|
# @api unstable
|
|
def freeze
|
|
delivery_method.freeze
|
|
default_charset.freeze
|
|
mailers.freeze
|
|
super
|
|
end
|
|
|
|
private
|
|
|
|
# @since 0.1.0
|
|
# @api private
|
|
attr_reader :mailers
|
|
|
|
# @since next
|
|
# @api unstable
|
|
attr_reader :finder
|
|
end
|
|
end
|
|
end
|