使用CCK创建节点类型
译者:老葛 Eskalate科技公司
使用前面你在joke.module中所用的方式创建一个节点类型,尽管可以完全的进行控制并具有较高的性能,但是这种方式有点枯燥无味。如果不做任何编程工作就可以组装一个新的节点类型的话,难道这种方式不会更好么?这就是CCK提供的方式。
■ 注意: 更多关于CCK的信息,访问CCK工程地址http://drupal.org/project/cck。
CCK中的部分已被发布到Drupal 5中。你现在可以导航到Administer ➤ Content
management ➤ Content types,通过后台管理接口页面添加一个新的内容类型(比如一个笑话(joke)内容类型)。如果你已经启用了joke.module的话,你要为节点类型起一个不同的名字以避免命名冲突。CCK中的其它部分尚未被加入到Drupal核心中,比如为新节点类型添加除标题和主体以外的其它字段的能力。在joke.module例子中,你需要三个字段:标题,笑话本身,和笑话妙语(包袱)。你使用Drupal的hook_node_info()将主体(body)字段改名为笑话(Joke);通过实现一些钩子函数,并为笑话妙语的存储创建你自己的数据库表,从而提供了笑话妙语(punchline)字段。在CCK中,你可以简单的创建一个名为punchline的文本输入字段,并将其添加到你的内容类型中。CCK替你负责数据的存储、取回、和删除。
注意:Drupal第3方模块库中包含了大量的CCK字段模块,用来添加图像、日期、e-mail、地址等等字段。CCK相关第3方模块位于:http://drupal.org/project/Modules/category/88。
由于在编写本书时,CCK的许多地方还在开发和完善中,所以我们在这里不讨论更多细节了。然而,可以清晰的看到,在将来使用编写模块的方式创建一个新的节点类型会越来越少,而使用CCK的方式通过管理接口页面组装一个新的节点类型会越来越流行。
限制为节点的访问
有多种方式用于限制对节点的访问。你已经看到了,如何使用hook_access()来限制对以节点类型的访问,以及使用hook_perm()定义权限。但是Drupal提供了控制访问的更丰富的工具集:使用表node_access以及两个访问钩子函数hook_node_grants()和hook_node_access_records()。
一般情况下,Drupal将拒绝对节点的访问,除非一个节点访问模块已向表node_access插入了定义如何访问的一行记录。
定义节点认可(Grants)
对应于节点之上的三种操作:查看、更新、删除,有三个基本的权限。当这些操作中的一个将要发生时,将首先使用实现节点类型的模块里面的函数node_access()。如果该模块没有定义是否允许访问的话,Drupal将向所有用于节点访问控制的模块询问—该操作是否应该被允许。通过使用hook_node_grants()为每个领域(realm)每个用户得到一个许可(grant)ID列表来完成这一工作。
什么是领域(Realm)?
一个领域是一个任意字符串,它用于允许多个节点访问控制模块共享数据库表node_access。例如,acl.module是一个使用访问控制列表(ACLs)来管理节点访问的第三方模块,它的领域就是acl。taxonomy_access.module是另一第3方模块,它基于分类词语来限制对节点的访问,它使用term_access作为领域。所以,领域就是在表node_access中标识你的模块空间的东西;他有点像命名空间。当要你的模块返回许可ID时,你将从你模块定义的领域中返回它。
什么是许可(Grant)ID
一个许可ID是一个标识符,用于为一个给定领域提供节点访问控制权限的信息。例如,一个节点访问控制模块——比如使用用户角色管理对论坛节点类型访问的forum_access.module——可以使用角色ID作为许可ID。一个使用US ZIP代码管理对节点类型访问的模块可以使用ZI P代码作为许可ID。在每种情况下,都是与用户有关的东西作为许可ID,比如该用户拥有这个角色么?这个用户的ZIP是12345么?用户是在这个访问控制列表中么?或者,这个用户的已定阅时间超过1年了么?
Although each grant ID means something special to the node access module that provides
grant IDs for the realm containing the grant ID, the mere presence of a row containing the grant
ID in the node_access table enables access, with the type of access being determined by the
presence of a 1 in the grant_view, grant_update, or grant_delete column.(不知道怎么翻译这一段,^<^)
在正在保存节点时会将许可ID插入到表node_access中。向每个实现了钩子hook_node_access_records()的模块传递该节点对象。模块将检查节点,或者简单的返回(如果它没有为该节点处理访问控制),或者返回一个用于插入到表node_access中的许可的数组。使用node_access_acquire_grants()可以批量的插入许可。下面是一个来自于forum_access.module的例子。
/**
* Implementation of hook_node_access_records().
*
* Returns a list of grant records for the passed in node object.
*/
function forum_access_node_access_records($node) {
...
if ($node->type == 'forum') {
$result = db_query('SELECT * FROM {forum_access} WHERE tid = %d', $node->tid);
while ($grant = db_fetch_object($result)) {
$grants[] = array(
'realm' => 'forum_access',
'gid' => $grant->rid,
'grant_view' => $grant->grant_view,
'grant_update' => $grant->grant_update,
'grant_delete' => $grant->grant_delete
);
}
return $grants;
}
}
节点访问流程
当要对节点进行某一操作时,Drupal将进入如图7-5所示的流程。
图7-5 决定是否允许对给定节点的访问
总结
读完本章后,你应该可以
• 理解什么是节点,什么是节点类型
• 编写模块来创建节点类型
• 理解如何在节点创建、保存、加载等等时插入钩子函数
• 理解如何决定对节点的访问控制