原文地址:
https://docs.acquia.com/article/lesson-62-loading-entities
加载实体
查询对象的 execute() 方法只是返回实体 ID 数组。要使用这些实体我们必须加载这些实体对象。
Drupal 7 使用 entity_load() 函数返回一个实体对象数组(基于传递给它的 ID 数组)。
Drupal 8 里这个函数变为只返回一个实体对象(当然参数也不再是 ID 数组,而只是一个 ID),而额外又提供了一个加载多个实体的方法: entity_load_multiple() 。
有三种方法加载实体:
- 类方法(推荐)
依赖注入将在之后章节讨论。代码中的重要部分是 example() 方法,它使用 entityManager 对象构建了一个节点存储对象。之后我们使用这个存储对象获得一个节点对象或者节点对象列表。
下载文件protected $entityManager; /** * {@inheritdoc} */ public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager') ); } /** * Return a list of nodes that are published. */ protected function example() { // We get the node storage object. $node_storage = $this->entityManager->getStorage('node'); // We use the load function to load a single node object. $nid = 1; $node = $node_storage->load($nid); // We load a revision $revision_id = 1; $node = $node_storage->loadRevision($revision_id); // We use the loadMultiple function to load an array of node objects keyed // by node ID. $nids = [1,2,3,4]; $nodes = $node_storage->loadMultiple($nids); // We will discuss this in future lessons, but you can get the value of // simple fields using ->get('field_name')->value. return [ '#markup' => $node->get('title')->value, ]; }
- 静态方法(不推荐)
当容器无效时,你也可以使用静态方法。// Get a node storage object. $node_storage = \Drupal::entityManager()->getStorage('node'); // Load a single node. $node_storage->load($nid); // Load multiple nodes. $node_storage->loadMultiple($nids);
- 全局方法(不推荐)
全局方法类似 Drupal 7。// Load a single entity. $node = entity_load('node', $nid); // Load multiple entities. $nodes = entity_load_multiple('node', $nids);
安装 query_example 模块
把第一课中的 page_example 文件和结构拷贝出来。在 modules/examples/ 目录创建文件夹 query_example,把 page_example 内的以下文件拷贝到新文件夹并重新命名:
- page_example.info.yml(重命名为 query_example.info.yml,更新里面值以适合新模块)
- src/Controller/PageExampleController.php (重命名为 QueryExampleController.php)
- page_example.routing.yml(重命名为 query_example.routing.yml)
创建控制器
我们把这些碎片汇总下。使用例子模块,在 QueryExampleController.php 的方法内追加查询对象获得节点 ID。
<?php /** * @file * Contains \Drupal\query_example\Controller\QueryExampleController. */ namespace Drupal\query_example\Controller; use Drupal\Core\Entity\Query\QueryFactory; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Controller\ControllerBase; /** * Controller routines for page example routes. */ class QueryExampleController extends ControllerBase { protected $entity_query; public function __construct(QueryFactory $entity_query) { $this->entity_query = $entity_query; } public static function create(ContainerInterface $container) { return new static( $container->get('entity.query') ); } protected function simpleQuery() { $query = $this->entity_query->get('node') ->condition('status', 1); $nids = $query->execute(); return array_values($nids); } public function basicQuery() { return [ '#title' => 'Published Nodes', 'content' => [ '#theme' => 'item_list', '#items' => $this->simpleQuery() ] ]; } protected function intermediateQuery() { $query = $this->entity_query->get('node') ->condition('status', 1) ->condition('changed', REQUEST_TIME, '<') ->condition('title', 'ipsum lorem', 'CONTAINS') ->condition('field_tags.entity.name', 'test'); $nids = $query->execute(); return array_values($nids); } public function conditionalQuery() { return [ '#title' => 'Published Nodes Called "ipsum lorem" That Have a Tag "test"', 'content' => [ '#theme' => 'item_list', '#items' => $this->intermediateQuery() ] ]; } protected function advancedQuery() { $query = $this->entity_query->get('node') ->condition('status', 1) ->condition('changed', REQUEST_TIME, '<'); $group = $query->orConditionGroup() ->condition('title', 'ipsum lorem', 'CONTAINS') ->condition('field_tags.entity.name', 'test'); $nids = $query->condition($group)->execute(); return array_values($nids); } public function conditionalGroupQuery() { return [ '#title' => 'Published Nodes That Are Called "ipsum lorem" Or Have a Tag "test"', 'content' => [ '#theme' => 'item_list', '#items' => $this->advancedQuery() ] ]; }
下一步编辑既存的路由文件,调用公有方法:
query_example.simple: path: 'examples/query_example/simple' defaults: _controller: '\Drupal\query_example\Controller\QueryExampleController::basicQuery' requirements: _access: 'TRUE' query_example.intermediate: path: 'examples/query_example/intermediate' defaults: _controller: '\Drupal\query_example\Controller\QueryExampleController::conditionalQuery' requirements: _access: 'TRUE' query_example.advanced: path: 'examples/query_example/advanced' defaults: _controller: '\Drupal\query_example\Controller\QueryExampleController::conditionalGroupQuery' requirements: _access: 'TRUE'