defmodule Mix.Tasks.Pow.Extension.Phoenix.Mailer.Gen.Templates do
@shortdoc "Generates mailer templates for extensions"
@moduledoc """
Generates mailer templates for extensions.
mix pow.extension.phoenix.mailer.gen.templates --extension PowEmailConfirmation --extension PowResetPassword
## Arguments
* `--extension` - extension to generate templates for
* `--context-app` - app to use for path and module names
"""
use Mix.Task
alias Mix.{Pow, Pow.Extension, Pow.Phoenix, Pow.Phoenix.Mailer}
@switches [context_app: :string, extension: :keep]
@default_opts []
@mix_task "pow.extension.phoenix.mailer.gen.templates"
@impl true
def run(args) do
Pow.no_umbrella!(@mix_task)
Pow.ensure_phoenix!(@mix_task, args)
args
|> Pow.parse_options(@switches, @default_opts)
|> create_template_files()
|> print_shell_instructions(Pow.schema_options_from_args())
end
@extension_templates %{
PowResetPassword => ~w(reset_password)a,
PowEmailConfirmation => ~w(email_confirmation)a,
PowInvitation => ~w(invitation)a
}
defp create_template_files({config, _parsed, _invalid}) do
structure = Phoenix.parse_structure(config)
web_module = structure[:web_module]
web_prefix = structure[:web_prefix]
web_app = structure[:web_app]
extensions =
config
|> Extension.extensions(web_app)
|> Enum.map(fn extension ->
mails = Map.get(@extension_templates, extension, [])
create_mail_templates(extension, mails, web_module, web_prefix)
extension
end)
%{extensions: extensions, web_app: web_app, structure: structure}
end
defp create_mail_templates(extension, [], _web_module, _web_prefix) do
Mix.shell().info("Notice: No mailer templates will be generated for #{inspect extension} as this extension doesn't have any mailer template defined.")
end
defp create_mail_templates(extension, mails, web_module, web_prefix) do
Mailer.create_mail_module(extension, mails, web_module, web_prefix)
Mix.shell().info("Pow mailer templates has been installed in your phoenix app!")
end
defp print_shell_instructions(%{extensions: [], web_app: web_app}, _schema_opts) do
Extension.no_extensions_error(web_app)
end
defp print_shell_instructions(%{structure: structure} = config, schema_opts) do
[
config_file_injection(structure, schema_opts),
web_file_injection(structure)
]
|> Pow.inject_files()
|> case do
:ok ->
config
:error ->
Mix.raise "Couldn't configure Pow! Did you run this inside your Phoenix app?"
end
end
defp config_file_injection(structure, schema_opts) do
file = Path.expand(Keyword.fetch!(Mix.Project.config(), :config_path))
content = " web_mailer_module: #{inspect(structure.web_module)},"
%{
file: file,
injections: [%{
content: content,
test: "web_mailer_module: #{inspect(structure.web_module)}",
needle: "config #{inspect(structure.web_app)}, :pow,"
}],
instructions:
"""
Add `#{String.trim(content)}` to your configuration in #{Path.relative_to_cwd(file)}:
config #{inspect(structure.web_app)}, :pow,
#{content}
user: #{inspect(structure.context_base)}.#{schema_opts.schema_name},
# ...
"""
}
end
defp web_file_injection(structure) do
file = Path.expand("#{structure.web_prefix}.ex")
content =
"""
def mail do
quote do
use Pow.Phoenix.Mailer.Component
unquote(html_helpers())
end
end
"""
%{
file: file,
injections: [%{
content: content,
test: "def mail do",
needle: "def router do",
prepend: true
}],
instructions:
"""
Add `mail/0` to #{Path.relative_to_cwd(file)}:
defmodule #{inspect(structure.web_module)} do
# ...
#{content}
# ...
end
"""
}
end
end