理解事件和触发器
Drupal在运行时,会经历一系列的事件。这些内部事件实际上是一种时间点,在这些时间点上,可以通过代码介入Drupal的运行过程,并与其进行交互。下图显示了某些Drupal的事件:
对于Drupal的开发者来说,这些内部事件,也被称为“钩子”。这是因为当某个事件发生时,Drupal允许模块“钩入”代码执行的轨迹(当然可以进而改变和定制其行为)。你在前面章节中应该已经见过几个钩子了。通常,开发模块的过程中要考虑到你希望修改哪些Drupal的行为,也就是你希望在自己的模块中实现哪些钩子。
设想你有一个刚刚建立的网站,此刻你正从你家的地下室的电脑中操纵这个网站。当网站访问量越来越大时,你计划把它卖给一家大公司以变得有钱。同时,你希望每次有用户登录时,都会被提醒。你于是决定,一旦有用户登录时,就让计算机叫一声beep。但是,因为你的猫在睡觉,它很讨厌这样beep的一声,所以你决定暂时用一个简单的日志项来代替beep。你可以很快的写个.info文件,然后把它放在sites/all/modules/custom/beep.info
; $Id$
name = Beep
description = Simulates a system beep.
package = Pro Drupal Development
core = 6.x
接下来,写个文件放在sites/all/modules/custom/beep/beep.module:
<?php
// $Id$
/**
* @file
* Provide a simulated beep.
*/
function beep_beep() {
watchdog('beep', 'Beep!');
}
这样,就把”beep”这个信息写入了Drupal的日志。目前来说这已经足够了。接下来,就该让告诉Drupal,下次有人登录的时候,要发出一声响。想要实现这个非常简单,只需要在我们的模块中实现hook_user()这个钩子,捕获用户登录(login)的这个操作就可以了。
/**
* Implementation of hook_user().
*/
function beep_user($op, &$edit, &$account, $category = NULL) {
if ($op == 'login') {
beep_beep();
}
}
看到了吧,这很容易。那么,如果我们想让网站有任何新内容添加时,也beep的响一下,该怎么实现呢?只需要通过在我们自己的模块中实现hook_nodeapi()这个钩子,捕获到节点的insert这个操作就可以了:
/**
* Implementation of hook_nodeapi().
*/
function hook_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if ($op == 'insert') {
beep_beep();
}
}
那么,如果我们想在有人添加一条新的评论时让机器beep一下呢?这也很简单,只需要实现hook_comment()这个钩子,捕获到insert这个操作就可以了。让我们停下来想想,前面这些操作,我们实际上一直在重复一件事,就是实现钩子,捕获某个操作。如果此时,能够有一个图形界面,让我们轻松的把”beep”这个动作同任意一个钩子的任意一个操作关联起来,这是不是很酷呢?很好,这实际上,就是Drupal内置的trigger模块所做的事。它允许把某个动作(action)同某个事件(event)关联起来。在代码中,一个事件被定义为一个“钩子+针对于该钩子的一个操作”的组合。例如,“用户钩子+登录操作”又或是“nodeapi钩子+insert操作”。当某一个这种操作发生时,trigger.module这个模块会让你触发一个动作。
为避免混淆,让我们来澄清一些术语:
• 事件(Event):从一种通用的编程思维上看,这个术语可以被理解为系统中一个组件发向另一组件的消息。
• 钩子(Hook):这一种在Drupal使用中的编程技巧,它允许代码可以“钩入”正常的程序执行流程,以达到扩展功能的效果。
• 操作(Operation):这指的是在某一个钩子内发生的具体的执行流程,例如,在hook_user()这个钩子里,有一个流程就叫login,也就是用户登录。
• 触发器(trigger):它指的是某个钩子和操作的组合,同时,还有一个或多个动作被关联到这个组合上来。例如,beeping这个动作,是与user_hook和login这个操作进行关联的。
Taxonomy upgrade extras