使用 Entity API
涵盖了通用实体的 API 方法
- Entity::create()
- Entity::load()
- Entity::save()
- Entity::id()
- Entity::bundle()
- Entity::isNew()
- Entity::label()
更具体的 API 将在专门章节中介绍。
检查
// 确认对象是一个实体。
if ($entity instanceof \Drupal\Core\Entity\EntityInterface) {
}
// 确认它是一个内容实体。
if ($entity instanceof \Drupal\Core\Entity\ContentEntityInterface) {
}
// 或者:
if ($entity->getEntityType()->getGroup() == 'content') {
}
// 获取实体类型或实体类型 ID。
$entity->getEntityType();
$entity->getEntityTypeId();
// 确认它是一个节点。
if ($entity instanceof \Drupal\node\NodeInterface) {
}
从实体获取信息 / 实体方法
有几个通用方法可用于从对象中获取信息,例如 ID、捆绑、修订 ID 等。详情请参见 EntityInterface 文档。
// 获取 ID。 $entity->id(); // 获取捆绑。 $entity->bundle(); // 检查实体是否为新实体。 $entity->isNew(); // 获取实体的标签。替代 entity_label()。 $entity->label(); // 获取实体的 URL 对象。 $entity->toUrl(); // 获取实体的内部路径或别名路径(如果存在)。 $entity->toUrl()->toString(); // 创建一个副本,可以作为新实体保存。 $duplicate = $entity->createDuplicate();
创建实体
// 如果你知道实体类,可以使用静态 create() 方法。
$node = Node::create([
'type' => 'article',
'title' => 'The node title',
]);
// 推荐使用实体类型管理器。
$node = \Drupal::entityTypeManager()->getStorage('node')->create(['type' => 'article', 'title' => 'Another node']);
// 或者使用过程式封装(已弃用)。
$node = entity_create('node', [
'title' => 'My node',
'body' => 'The body content. This just works like this due to the new Entity Field
API. It will be assigned as the value of the first field item in the
default language.',
]);
字段类型注解中的默认设置仅会为缺失的顶层键添加;不会进行深度合并。
避免在面向对象的代码中使用静态方法 Entity::create()。相反,应使用依赖注入来注入实体类型管理器,并通过 $this->entityTypeManager->getStorage($entity_type)->create() 创建实体。这能确保代码正确解耦,并可由模块测试。
为了在 IDE 中更好地发现,你也可以将实体存储接口分配给一个属性。例如,$this->nodeStorage = $this->entityTypeManager->getStorage('node'); 要创建实体时,可以使用 $this->nodeStorage->create()。
加载
// 使用静态方法。
$node = Node::load(1);
// 已弃用。动态实体类型,entity_load() 现在加载单个实体,7.x 的 entity_load() 被重命名为 entity_load_multiple()。
$entity = entity_load($entity_type, $id);
// 使用存储控制器(推荐)。
$entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load(1);
// 加载多个实体,也存在 entity_load_multiple()。
$entities = \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple([1, 2, 3]);
// 通过属性值加载实体。
$entities = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'article']);
要更新对象,先加载它,然后保存更改。
避免在面向对象的代码中使用静态方法 Entity::load()。相反,应使用依赖注入来注入实体类型管理器,并通过 $this->entityTypeManager->getStorage($entity_type)->load($entity_id) 加载实体。这能确保代码正确解耦,并可由模块测试。
保存实体
// 保存一个实体。 $entity->save();
这对新建和已有的实体都适用,实体本身会跟踪它是否为新建。对于内容实体来说,默认情况下这取决于它是否已有 ID。要将带 ID 的对象作为新对象保存(例如在导入某些东西时),可以应用 isNew 标记。
// 以下将尝试插入一个 ID 为 5 的新节点,如果该节点已存在则会失败。 $node->nid->value = 5; $node->enforceIsNew(TRUE); $node->save();
删除实体
// 删除单个实体。
$entity = \Drupal::entityTypeManager()->getStorage('node')->load(1);
$entity->delete();
// 一次性删除多个实体。
\Drupal::entityTypeManager()->getStorage($entity_type)->delete([$id1 => $entity1, $id2 => $entity2]);
访问控制
方法 access() 可用于检查谁能对实体执行什么操作。该方法支持多种操作,标准操作包括查看、更新、删除和创建。创建稍有特殊,见下文。
访问检查被传递给访问控制器。(TODO: 添加链接)
// 检查实体的查看权限。
// 默认检查当前登录用户的访问权限。
if ($entity->access('view')) {
}
// 检查指定用户是否可以删除实体。
if ($entity->access('delete', $account)) {
}
检查创建权限时通常还没有实体。仅仅为了检查某人是否能创建而创建一个实体是高开销操作。因此,创建权限应直接在访问控制器上进行检查。
\Drupal::entityTypeManager()->getAccessControlHandler('node')->createAccess('article');
如果实体已存在,$entity->access('create') 也能工作,它只是简单地将调用转发给 createAccess() 方法,就像其他操作将调用转发给访问控制器的 access() 方法一样。
注意: 一些在线指南使用 \Drupal::entityManager(),但在 8.x 版本中它已被弃用,并将在 9.x 中移除。因此,你可以使用 \Drupal::entityTypeManager() 来替代 \Drupal::entityManager()。