6.2 entity_metadata_wrapper
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
Entity API模块,还提供了一个元数据封装器函数,entity_metadata_wrapper,通过这个函数的封装,我们可以更加方便的访问实体及其属性。这个函数给我们带来了哪些便利呢?我们通过代码示例来了解一下。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
Entity API模块,还提供了一个元数据封装器函数,entity_metadata_wrapper,通过这个函数的封装,我们可以更加方便的访问实体及其属性。这个函数给我们带来了哪些便利呢?我们通过代码示例来了解一下。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
Entity API模块定义了一个新的钩子,hook_entity_property_info(),通过这个钩子函数,就可以定义实体包含哪些属性信息了,这个信息里面还包括,属性的数据类型、获取、设置属性的回调函数。注意,很多常用的模块,都用到了这里定义的属性,比如Rules模块。而前面的entity_get_property_info,则是用来获取hook_entity_property_info()里面的定义信息的。这个钩子函数比较抽象,我们可以看一个例子,在sites\all\modules\entity\modules下面可以找到,Drupal核心中各个子系统的钩子实现。下面这个是用户系统的实现:
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
这个模块提供了更多的API函数,比如entity_create()、 entity_save()、 entity_delete()、 entity_view()、 entity_access(),这些函数可以用来方便的创建、保存、删除、查看实体,最后一个entity_access用来控制访问权限的。除了这几个以外,还有entity_id()、 entity_export()、 entity_import()、entity_get_property_info()。entity_id()是用来获取id的,entity_export负责导出,entity_import负责导入;entity_get_property_info是用来做什么的?它是用来获取实体上面的属性信息的,注意这里的属性,和Drupal核心里面的属性是不一样的概念,在Drupal7核心里面,属性是属性,字段是字段,而在Entity API模块里面,属性、字段都是属性。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
我们需要注意,模块的名字就叫Entity API,简称entity,这个名字起的够霸道的,模块的作者也很牛,就是fago,Drupal核心Entity系统的维护者。在Drupal7将要发布的时候,Fago就认识到了Drupal7里面,对实体的支持,还很不完善,他还专门写了一篇文章,指出未来的方向是实体,为此他开发了Entity API模块,作为Drupal核心实体系统的补充,Entity API模块里面的很多概念,被Fago搬到了Drupal8的内核里面了。Entity API模块做了多方面的扩展,我们这里简单了解一下。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
在Drupal7中,核心的实体系统,存放在includes下面的entity.inc文件中,这里面,包含一个DrupalEntityControllerInterface接口、DrupalDefaultEntityController类、EntityFieldQueryException类、EntityFieldQuery类、EntityMalformedException类。所有的实体,必须实现DrupalEntityControllerInterface接口,对于我们常见的大多数实体,只需要继承DrupalDefaultEntityController类即可,如果需要实现的实体不是存放在数据库中的,此时则需要单独的实现DrupalEntityControllerInterface接口。EntityFieldQuery对Entity Field的SQL查询做了封装,当然,封装的不是很彻底,有很多的局限性,对于我们常见的查询,尤其涉及到字段的,用起来非常方便。我们在本章会对EntityFieldQuery做专门的介绍。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
现在,节点、分类术语、评论、用户都统一到了实体上来了,这是不是意味着说,所有的东西都是实体呢?当然不是。在Drupal7的核心系统里面,区块系统就不是实体,菜单系统也不是实体,因此,我们可以说,不是所有的东西都是实体。但是这些东西,正在被转为实体,比如区块,现在有一个第三方模块bean,全称为“Block Entities Aren't Nodes” “区块实体不是节点”,此外,在Drupal8的核心开发里面,菜单连接,也正在被转为实体。此外,比如webform模块,一直都是非常流行的,但是到了Drupal7下面,出现了Entity form模块,与之竞争,将来webform是否会被Entity form模块所取代,这个现在还不好判断。比如在Ubercart、Commerce里面,订单,都已经被处理成为了实体,而在Commerce里面,产品、客户信息都已被处理成为实体。还有我们提到过的,Field Collection模块,字段实体的出现,更是扩展了实体的应用范围。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
伴随着,实体的出现,还出现了另一个概念,Bundle,中文可以翻译为“包”。什么是Bundle呢,我们可把它看作,一种实体下面的一个具体实现。以节点为例:
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
在CCK进入Drupal7内核的时候,很多人进一步思考的CCK的优势,并且认识到,很多其它的系统,比如用户系统、分类系统、评论系统,也都存在利用CCK的需求。因此,在Drupal7下,对CCK模块做了进一步的扩充,并将其更名为Field模块,使得用户可以向节点、评论、分类术语、用户上面添加字段。而这种扩充的结果,就是引入了实体(Entity)这样的一个概念,实体是伴随着Field进入Drupal内核,而衍生抽象出来的一个概念。什么是实体呢?这种概念性质的东西,不是一句话就理解透的,我们看看例子: