使用Drupal时,一个常见的目标就是,当一个事件发生时需要做些东西。例如,站点管理员可能希望在一个消息发布以后收到一封电子邮件。或者当用户在评论中使用了违禁词语,那么就会被自动封号。本章将描述如何使用Drupal的事件钩子,从而当那些事件发生时,能够运行自己的代码。
老葛的Drupal培训班 Think in Drupal
老葛的Drupal培训班 Think in Drupal
• 触发器:它指的是,一个具体的钩子操作联合体与一个或多个动作的关联。例如,嘟嘟这个动作可以与用户钩子的登录操作关联起来。
一个动作就是Drupal要做的一些事情。下面是一些例子:
老葛的Drupal培训班 Think in Drupal
如果将我们的嘟嘟函数转化为一个完整的动作,那么我们需要做哪些工作呢?这有两个步骤:
现在,让我们重新回到“管理➤站点构建 ➤触发器”。如果你正确的完成了前面所给的这些东西,那么你的动作将会出现在这个用户界面,如图3-2所示。
老葛的Drupal培训班 Think in Drupal
如果你修改了该动作所支持的触发器,那么你就能够在用户界面中看到相应的变化。例如,如果你将beep_action_info()改成如下的内容,那么你的“Beep”动作只能用于触发器“在删除文章之后”:
动作主要有两种类型:带有参数的动作和不带参数的动作。我们前面所写的“嘟嘟”动作就是不带参数的动作。当动作执行时,它嘟嘟一下,这就完事了。但是许多时候,动作可能需要更多一点的上下文。例如,一个“发送电子邮件”动作,需要知道将电子邮件的发收件人以及邮件的标题和正文。这种需要为其在配置表单中做些设定的动作,就是高级动作,也称为可配置动作。
让我们快速的检查一下,我们的实现是否正确,导航到“管理➤站点配置➤动作”。不错,动作出现在了高级动作的下拉选择框中了,如图3-3所示。
老葛的Drupal培训班 Think in Drupal
第一个函数向Drupal描述了表单。我们只定义了一个文本输入框字段,这样管理员就可以输入嘟嘟的次数了。当管理员选择添加一个高级动作“嘟嘟多次”时,如图3-3所示,Drupal将会使用我们的表单字段来呈现一个完整的动作配置表单,如图3-4所示。
老葛的Drupal培训班 Think in Drupal
我们在前面已经看到,动作的函数签名的一般形式为example_action($object,$context)。下面让我们学习一下这些参数的具体含义。
老葛的Drupal培训班 Think in Drupal
当Drupal运行action_info钩子时,每个模块都可以声明它所提供动作,Drupal还给了模块一个机会,让它们修改该信息----包括其它模块提供的信息。下面让我们修改“阻止当前用户”这个动作,让它可以用于评论插入这个触发器:
由于我们已经分配了动作,所以当一个新评论被发布时,当前用户将被阻止。让我们仔细的看一下,这里都发生了什么。我们已经知道,Drupal是通过触发钩子来向模块通知特定事件的。在这里触发的就是评论钩子。由于当前是一个新评论正被添加进来,所以当前的特定操作就是insert操作。触发器模块实现了评论钩子。在这个钩子内部,它对数据库进行查询,来获取分配到这个特定触发器上的所有动作。数据库就会将我们分配的动作“阻止当前用户”返回给该钩子。现在,触发器模块就可以执行该动作了,它符合标准的动作函数签名example_action($object, $context)。
将钩子和操作放在上下文中,这一点非常有用。我们举个例子,动作“发送电子邮件”就大量的利用了这一点。这个动作的类型为system,它可以被分配给许多不同的触发器。
老葛的Drupal培训班 Think in Drupal
触发器模块仅是调用动作的一种方式。你可能想写一个单独的模块,它需要自己负责动作的调用和参数的准备。如果是这样的话,那么推荐使用actions_do()来调用动作。函数的签名如下:
Drupal是怎么知道,有哪些触发器是可以显示在触发器用户界面的?按照典型的方式,它能够让模块通过钩子声明该模块所实现的钩子。例如,这里是来自comment.module的hook_hook_info()实现。定义触发器描述的地方就是hook_hook_info()的实现:
老葛的Drupal培训班 Think in Drupal
有时候,如果你的代码新增了一个操作的话,那么你可能想要在一个已有的钩子上添加触发器。例如,你可能想向nodeapi钩子添加一个操作。假定你编写了一个模块,用来存档旧节点并将其迁移到数据仓库中。由于这个操作是作用于节点的,所以你可能想在nodeapi钩子下面添加一个archive操作,这样对于内容的所有操作,都会显示在触发器界面的同一个标签下。下面的代码用来添加一个额外的触发器:
读完本章后,你应该能够