邮件
本节介绍如何使用 Joomla 的 Mail
类或 MailTemplate
类从您的扩展程序发送电子邮件。
要使此功能正常工作,您应确保您的 Joomla 实例在全局配置/服务器选项卡中配置正确,并且“发送测试邮件”工作正常。
还有一个示例 com_sendmail
组件,您可以下载并运行它来试验 Joomla Mail。使用说明位于此页面底部。
发送电子邮件
获取 Joomla Mail 实例
首先,您必须获取 Joomla 的 Mail
实例。最简单的方法是
use Joomla\CMS\Factory;
use Joomla\CMS\Mail\MailerFactoryInterface;
$mailer = Factory::getContainer()->get(MailerFactoryInterface::class)->createMailer();
当 Joomla 初始化时,它在依赖注入容器中设置了一个条目,其中包含
- 键 - MailerFactoryInterface::class(即此类的完全限定名称,作为字符串)
- 值 - 将返回
MailerFactory
实例的代码。
在这里,我们从 DIC 中获取该 MailerFactory
实例,并调用其上的 createMailer()
以提供 Joomla 的 Mail
实例。
或者,如果您正在组件控制器或模型类中编写代码,并且该代码已使用 MVCFactory
创建,则可以获取 MVCFactory
以为您提供 MailerFactory
实例。
您的控制器/模型需要
- 提供
MailerFactory
的 getter 和 setter - 您使用MailerFactoryAwareTrait
来执行此操作 - 告诉其他类您拥有此 getter 和 setter - 通过指定您的类实现
MailerFactoryAwareInterface
这是代码段
use Joomla\CMS\Factory;
use Joomla\CMS\Mail\MailerFactoryAwareTrait;
use Joomla\CMS\Mail\MailerFactoryAwareInterface;
class MyController extends ... implements MailerFactoryAwareInterface
{
use MailerFactoryAwareTrait;
public function sendMail()
{
$mailer = $this->getMailerFactory()->createMailer();
...
当 MVCFactory
创建您的控制器时,它会检查它是否实现了 MailerFactoryAwareInterface,如果实现了,它将使用您的 setter 在您的类中设置 MailerFactory
。
然后,您可以使用您的 getter 获取 MailerFactory
并调用 createMailer()
来创建 Mail
实例。
发送电子邮件
获得 Mail
实例(上面的 $mailer
)后,您可以使用 Mail API 配置电子邮件的各个方面。
Mail
实例以全局配置/服务器选项卡中定义的数据作为默认值。因此,例如,如果您未设置发件人,则它将采用全局配置中的发件人数据。
至少应设置
- 收件人的电子邮件地址
- 邮件主题
- 邮件正文(文本)
$mailer->addRecipient('[email protected]');
$mailer->setSubject('test');
$mailer->setBody('Hello!');
try
{
$mailer->send();
$this->app->enqueueMessage("Mail successfully sent", 'info');
}
catch (\Exception $e)
{
$this->app->enqueueMessage("Failed to send mail, " . $e->getMessage(), 'error');
}
如果电子邮件发送失败,则 send()
将抛出异常,因此建议在 try/catch 块中调用它。
以上内容在本文末尾描述的示例 com_sendmail
程序中进行了编码。
故障排除
如果您确实遇到发送电子邮件的问题,则显示的排队消息可能不太有帮助。
相反,您应该在全局配置/日志记录中检查“几乎记录所有内容”是否已打开,这应该意味着您将在日志文件中看到与邮件服务器的低级交互。
(您可能会看到许多包含错误消息的行,但它们并不是真正的错误!)
即便如此,问题根源可能也不明显。例如,在将 $mailer->isHtml()
设置为以 HTML 格式发送电子邮件后,我发现服务器返回了以下内容
550-We're sorry, but we can't send your email. Either the subject matter, a link, or an attachment potentially contains
550 spam, or phishing or malware. Please check or edit your message and try sending it again.
SMTP 服务器不允许带有 Content-Type text/html 的电子邮件。
邮件模板
您可以改用邮件模板发送电子邮件。
您可以通过转到管理员系统仪表板并在“模板”面板中选择“邮件模板”来查看(并修改)Joomla 使用的邮件模板。
如果您不熟悉此功能,则应在测试 Joomla 实例中试用一下,因为这将使以下内容更加清晰。
还要查看更改邮件模板配置选项的效果。
定义邮件模板
Joomla 不提供创建邮件模板的功能。
相反,您应该在代码中创建它们,例如在您的安装脚本文件中,使用 邮件模板 API。
API 提供静态函数
- createTemplate
- updateTemplate
- deleteTemplate
数据映射到 #__mail_templates
数据库表。
对于您定义的每个模板
- 模板键 - 包括您的扩展程序,例如“com_sendmail.example”
- 电子邮件主题的文本 - 定义为语言常量
- 电子邮件正文的文本 - 定义为语言常量
- 标签数组 - 电子邮件主题和正文中将被值替换的字段
您需要在您的 .ini 语言文件中定义这些电子邮件主题和正文语言常量(站点或管理员,具体取决于您从哪里发送电子邮件)。
您可以以 HTML 和纯文本格式定义电子邮件正文文本。
您还需要定义 Joomla 从您的模板键中形成的某些语言常量。
对于“com_sendmail.example”,您需要在管理员的 .sys.ini 语言文件中
- COM_SENDMAIL_MAIL_EXAMPLE_TITLE
- COM_SENDMAIL_MAIL_EXAMPLE_DESC
- COM_SENDMAIL
这些都显示在管理员邮件模板表单中。
在您的管理员 .ini 语言文件中,您将需要(重复)
- COM_SENDMAIL_MAIL_EXAMPLE_TITLE
- COM_SENDMAIL_MAIL_EXAMPLE_DESC
因为当您查看/编辑单个邮件模板时也会显示这些内容。
配置邮件模板
创建邮件模板后,管理员可以使用管理员邮件模板区域中的功能对其进行编辑。
管理员可以更改电子邮件主题和正文的文本,其中应显示您定义的标签字段,以及应添加的附件(如果设置了此选项,则来自 Joomla 拥有文件夹外部的文件夹)。
仅当邮件模板配置选项“邮件格式”包含 HTML 时,才会显示 HTML 正文(如果设置)。
如果设置了邮件模板配置选项“每个模板邮件设置”,则管理员可以通过“选项”选项卡(编辑邮件模板时)设置更多选项。
尽管在创建邮件模板时,您将电子邮件主题和正文定义为语言常量,但在显示模板时,这些语言常量会被翻译并以特定语言显示。
如果管理员更改并保存模板,则它将存储在 #__mail_templates
数据库表中,其中 language
列设置为显示该模板的语言的语言代码。
这意味着在 #__mail_templates
数据库表中,您可以为每个邮件模板有多个记录
- 一个记录用于您创建的邮件模板,其中语言字段设置为空字符串,以及
- 管理员为该语言修改模板的每个语言的一条记录。
当您在扩展程序的代码中使用模板发送电子邮件时,您必须指定语言。Joomla 首先会查找具有您指定语言的记录(管理员编辑的记录),如果找不到,则会回退到您的组件创建的默认记录。
使用邮件模板发送电子邮件
MailTemplate
充当 Mail
类的包装器,因此您可以添加收件人、附件、回复地址并通过 邮件模板 API 发送电子邮件。
您最初会像上面描述的那样获取 Mail
实例,但之后会使用 MailTemplate
实例
$mailer = Factory::getContainer()->get(MailerFactoryInterface::class)->createMailer();
// if you want to use the language of the currently logged-on user ...
$user = $this->app->getIdentity();
// pass your template id, language and the $mailer instance into the MailTemplate constructor
$mailTemplate = new MailTemplate('com_sendmail.example', $user->getParam('language', $this->app->get('language')), $mailer);
// add the recipient via the MailTemplate
$mailTemplate->addRecipient('[email protected]');
// here you get the MailTemplate to replace the tags in the mail template with the data you provide
// In the com_sendmail example the tags are 'name', 'p1' and 'p2', so you want to have a $data array with those keys
$mailTemplate->addTemplateData(
[
'name' => $data['name'],
'p1' => $data['p1'],
'p2' => $data['p2']
]
);
// Send the email using the MailTemplate as well. If it fails it will raise an exception
try {
$mailTemplate->send();
} catch (\Exception $e) {
$this->app->enqueueMessage("Failed to send mail, " . $e->getMessage(), 'error');
}
示例 com_sendmail 组件
您可以下载并安装 此示例 com_sendmail 组件。它演示了如何使用 Mail
类和 MailTemplate
类发送电子邮件。
作为安装的一部分,com_sendmail
创建了一个键为“com_sendmail.example”的 MailTemplate,然后您可以通过管理员邮件模板功能查看和编辑它。
要运行该组件,您应该导航到 <your domain>/index.php/component/sendmail
。
该组件将显示一个表单,该表单将
- 允许您选择是要使用
Mail
还是MailTemplate
发送电子邮件,以及 - 捕获适合您选择的数据。
您还可以确保通过全局配置/日志记录打开日志记录,并在日志文件中查看低级邮件交互。