Drupal 8 模块开发 6.2 : 加载实体

蒲公英 提交于 周四, 08/17/2017 - 16:16
Drupal8模块开发

原文地址:
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'