0

0

扩展 Drupal 8 Mail API 的功能:第 1 部分

PHPz

PHPz

发布时间:2023-08-27 20:13:08

|

1085人浏览过

|

来源于php中文网

原创

扩展 drupal 8 mail api 的功能:第 1 部分

在这两个部分的系列中,我们将探索 Drupal 8 中的邮件 API。在此过程中,我们将涵盖两个主要方面:如何以编程方式使用它来发送电子邮件以及如何扩展它以使用外部像山魈一样的服务。

为了演示这一点,在第一部分中,我们将创建一个自定义电子邮件模板,用于在当前用户保存新的文章节点时向他/她发送电子邮件。此外,我们将了解其他人如何更改该模板,以便允许 HTML 呈现电子邮件正文而不是默认的纯文本。

在第二部分中,我们将研究扩展邮件系统并集成外部 API 以进行电子邮件传送。为此,我们将使用 Mandrill 及其 PHP 库,它为与其 API 交互提供了良好的基础。

我们完成的所有工作都可以在这个 Git 存储库中找到,作为我们将在这里开始编写的自定义 Drupal 8 模块的一部分。因此,如果您想继续了解,请随时查看。让我们开始吧。

该模块的第一个先决条件是它的 .info 文件:

d8mail.info.yml

name: Drupal 8 Mailer
description: 'Demonstrates the use of the Mail API in Drupal 8.'
core: 8.x
type: module

解决了这个问题,我们就可以根据需要在我们的网站上启用该模块。

我们如何发送电子邮件?

使用 Drupal 8 以编程方式发送电子邮件需要两个主要步骤。我们首先需要实现 hook_mail() 来定义一个或多个电子邮件模板。第二步是使用邮件管理器使用这些模板之一发送电子邮件。

虽然称为钩子,但 hook_mail() 并不是典型的钩子,而是更多的常规函数​​,通常仅由实现它的同一模块调用。换句话说,当您以编程方式发送电子邮件时,您需要指定实现 hook_mail() 的模块名称以及您想要使用且由该挂钩定义的模板 id。但我们很快就会看到这一点。首先,我们如何实现它?

d8mail.module

/**
 * Implements hook_mail().
 */
function d8mail_mail($key, &$message, $params) {
  $options = array(
    'langcode' => $message['langcode'],
  );

  switch ($key) {
    case 'node_insert':
      $message['from'] = \Drupal::config('system.site')->get('mail');
      $message['subject'] = t('Node created: @title', array('@title' => $params['node_title']), $options);
      $message['body'][] = SafeMarkup::checkPlain($params['message']);
      break;
  }
}

这是一个非常简单的实现,定义了一个标识为 node_insert$key)的模板。另外两个函数参数是:

  • $message:通过引用传递,在其中我们根据需要添加尽可能多的有关电子邮件的样板
  • $params:需要放入电子邮件中的额外数据数组,当我们尝试发送电子邮件时从邮件管理器传递该数组

如您所见,我们正在构建 $message 数组,其中包含我们希望此电子邮件包含在所有调用中的值。我们正在设置一个默认的 from 值,该值从配置系统检索并代表主站点电子邮件地址。我们设置一个样板电子邮件 subject ,让收件人知道创建了一个新节点,后跟节点的名称(将通过 $params 数组传入)。该主题也可以翻译成从调用者那里传递的语言。

最后,我们通过字符串清理程序运行消息 body,因为文本可能包含 HTML,如果我们不对 HTML 元素进行编码,它可能会被截断。由于我们使用的是 SafeMarkup 类,因此我们需要在顶部使用它:

use Drupal\Component\Utility\SafeMarkup;

此外,消息正文是一个数组,稍后将内爆为字符串。显然我们还可以设置许多其他参数,例如标头,但这对于本示例来说就足够了。

Krea AI
Krea AI

多功能的一站式AI图像生成和编辑平台

下载

这就是 hook_mail() 实现的全部内容。现在让我们看看每次创建新节点时运行的代码,hook_entity_insert():

/**
 * Implements hook_entity_insert().
 */
function d8mail_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {

  if ($entity->getEntityTypeId() !== 'node' || ($entity->getEntityTypeId() === 'node' && $entity->bundle() !== 'article')) {
    return;
  }

  $mailManager = \Drupal::service('plugin.manager.mail');

  $module = 'd8mail';
  $key = 'node_insert';
  $to = \Drupal::currentUser()->getEmail();
  $params['message'] = $entity->get('body')->value;
  $params['node_title'] = $entity->label();
  $langcode = \Drupal::currentUser()->getPreferredLangcode();
  $send = true;

  $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
  if ($result['result'] !== true) {
    $message = t('There was a problem sending your email notification to @email for creating node @id.', array('@email' => $to, '@id' => $entity->id()));
    drupal_set_message($message, 'error');
    \Drupal::logger('d8mail')->error($message);
    return;
  }

  $message = t('An email notification has been sent to @email for creating node @id.', array('@email' => $to, '@id' => $entity->id()));
  drupal_set_message($message);
  \Drupal::logger('d8mail')->notice($message);
}

这个钩子在每次节点保存后都会被触发,我们所要做的就是确保我们瞄准正确的节点并包含我们的逻辑。

检查节点实体的类型为 article 后,我们加载 Drupal 邮件管理器服务并开始为电子邮件设置一些值。我们需要以下信息:

  • 实现 hook_mail() 并定义我们的模板(我上面提到的)的模块名称
  • 模板 ID($key
  • 收件人电子邮件地址(在当前用户帐户中找到的地址)
  • 进入 $params 数组并用于翻译主题消息的语言 ($langcode)
  • 将添加到电子邮件主题的节点标题
  • 电子邮件正文,在我们的例子中将是节点正文字段的值
  • 指示是否应实际发送电子邮件的布尔值

然后我们将所有这些值传递给邮件管理器的 mail() 方法。后者负责构建电子邮件(调用正确的 hook_mail() 实现是其中的一方面)并最终将实际交付委托给负责的插件。默认情况下,这将是 PHPMail,它使用 PHP 自带的默认 mail() 函数。

如果邮件管理器成功发送电子邮件(不考虑实际发送,而是考虑成功的 PHP 操作),则 mail() 方法将返回一个包含 result 键的数组,其中包含以下内容:邮件插件返回。通过检查该值,我们可以了解电子邮件操作是否成功,并通知用户我们已通知他们他们的操作。否则,我们将打印并记录一条错误消息。

就是这样。清除缓存并创建文章节点应该会在您的收件箱中收到一封电子邮件。如果您没有收到任何信息,并且屏幕上没有错误迹象,请务必检查服务器日志和邮件队列,以验证电子邮件是否已发出。

在继续之前,我想快速说明一下这个钩子的实现。在这个例子中,我直接将所有逻辑放在其中。此外,我在顶部使用了早期返回,这本质上意味着除了特定于文章节点的逻辑之外,不能添加其他逻辑。在实际应用程序中,我建议将邮件逻辑重构为单独的函数或类,并遵循该逻辑。此外,您不应在钩子实现中使用提前返回,而应在满足条件时调用其他函数。

我们如何更改电子邮件?

一旦所有这些都到位,我们就可以使用另一个工具来更改现有的设置:hook_mail_alter()。在负责的邮件插件发送电子邮件之前,从邮件管理器内部调用此挂钩。目的是允许其他模块对正在发送的现有电子邮件进行最终更改。

虽然其他模块也可以使用它,但我们将在我们一直使用的同一模块中说明示例实现。为此,我们将通过更改其默认标头之一来更改电子邮件,以便将其从纯文本转换为 HTML。我们可以这样做:

/**
 * Implements hook_mail_alter().
 */
function d8mail_mail_alter(&$message) {
  switch ($message['key']) {
    case 'node_insert':
      $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
      break;
  }
}

如您所见,这是对 Content-Type 标头的简单更改,可将电子邮件转换为 HTML。这样纯文本 HTML 实体将被邮件客户端解析为 HTML。使用 switch case,我们确保这只发生在我们之前定义的电子邮件模板中。

这里需要注意的一件事是,在相关的 hook_mail() 实现之后调用 alter hook。因此,在此之后,对电子邮件进行的唯一处理是在邮件插件的 format() 方法内完成的(由其接口强制执行)。

结论

这几乎就是使用 Drupal 8 以编程方式发送电子邮件的全部内容。我们已经了解了以编程方式设置电子邮件模板所需的步骤,只要我们需要,这些模板就会由邮件管理器进行水合。我们还提到了 Drupal 8 中用于发送电子邮件的默认邮件传递插件。最后,我们看到了其他模块现在如何通过添加新标头、更改主题、将值连接到邮件正文来更改我们的电子邮件等

在下一篇文章中,我们将考虑用我们自己的自定义实现替换默认的 PHPMail 插件。我们将在 PHP 库的帮助下设置一个使用 Mandrill 的邮件程序。目标是允许我们自己的模块使用此邮件程序,而应用程序的其余部分继续使用默认的 PHPMailer。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

569

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

441

2024.03.13

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

887

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

461

2024.06.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号