drupal_了解Drupal的EntityFieldQuery

drupal

介绍 (Introduction)

When building complex web apps, you’ll eventually have to interact with a database. To retrieve data in Drupal one can use the database abstraction layer provided, which requires some SQL knowledge to be used properly. From Drupal 7 EntityFieldQuery API is provided, which lets you fetch information about entities from Drupal without actually building SQL queries. In this article, let’s see how we can use the EntityFieldQuery API to fetch data from Drupal and use it in our modules.

构建复杂的Web应用程序时,最终将不得不与数据库进行交互。 要在Drupal中检索数据,可以使用提供的数据库抽象层,这需要一些SQL知识才能正确使用。 从Drupal 7提供了EntityFieldQuery API,它使您可以从Drupal获取有关实体的信息,而无需实际构建SQL查询。 在本文中,让我们看看如何使用EntityFieldQuery API从Drupal获取数据并在我们的模块中使用它们。

EntityFieldQuery类 (The EntityFieldQuery class)

The EntityFieldQuery class is used to find entities in Drupal, which match some conditions. The EntityFieldQuery is present in the includes/entity.inc file in your Drupal installation. This class has different methods to specify the entity type and certain conditions based on which we can filter which data we want to fetch. We will see those methods in detail throughout this article. The basic usage, which you will follow while using EntityFieldQuery will be, first and foremost, creating an object of this class. Once the object is created you will add some conditions to it and then call the execute method to fetch the results.

EntityFieldQuery类用于在Drupal中查找符合某些条件的实体。 在您的Drupal安装中的include / entity.inc文件中存在EntityFieldQuery。 此类具有不同的方法来指定实体类型和某些条件,基于这些条件我们可以过滤要提取的数据。 我们将在本文中详细介绍这些方法。 使用EntityFieldQuery时将遵循的基本用法将首先是创建此类的对象。 创建对象后,您将向其中添加一些条件,然后调用execute方法来获取结果。

The general template is as follows

通用模板如下

$entityquery = new EntityFieldQuery();
/// Set some conditions   
$result = $query->execute ();

We are now going to create a Drupal module which will install 3 new Drupal node types: Product, Movies and Books and a block in which we will display our results. You can see how to create a node type in this article

现在,我们将创建一个Drupal模块,该模块将安装3种新的Drupal节点类型:产品,电影和书籍,以及一个将在其中显示结果的模块。 您可以在本文中了解如何创建节点类型

The code for the module is

该模块的代码是

entityquery.info

实体查询

name = entityquery
description = Shows how to use entity query to fetch data from drupal
package = Entity Query Example
core = 7.x

entityquery.install

entityquery.install

<?php
/**
 * Implement hook_install().
 */
function entityquery_install() {
    node_types_rebuild();
    $types = node_type_get_types();
    node_add_body_field($types['product']);
    node_add_body_field($types['movies']);
    node_add_body_field($types['books']);
}

entityquery.module

实体查询模块

<?php
/**
 * Implement hook_node_info()
 */
function entityquery_node_info() {
    return array(
        'product' => array(
            'name' => t('Product'),
            'base' => 'product',
            'description' => t('You can define new Products here'),
            'has_title' => TRUE,
            'title_label' => t('Product title')
         ),
        'movies' => array(
            'name' => t('Movies'),
            'base' => 'movies',
            'description' => t('You can define new Movies here'),
            'has_title' => TRUE,
            'title_label' => t('Movie title')
         ),
        'books' => array(
            'name' => t('Books'),
            'base' => 'Books',
            'description' => t('You can define new Books here'),
            'has_title' => TRUE,
            'title_label' => t('Books title')
         )
    );
}

/**
 * Implement hook_form()
 */
function product_form($node, $form_state) {
    return node_content_form($node, $form_state);
}

/**
 * Implement hook_form()
 */
function movies_form($node, $form_state) {
    return node_content_form($node, $form_state);
}

/**
 * Implement hook_form()
 */
function books_form($node, $form_state) {
    return node_content_form($node, $form_state);
}

/**
 * Implement hook_block_info().
 */
function entityquery_block_info() {
  $blocks = array();

  $blocks['entityqueryblock'] = array(
    'info' => t('A block to display results from entityquery'),
  );

  return $blocks;
}

/**
 * Implement hook_block_view().
 */
function entityquery_block_view($block_name = '') {
  if ($block_name == 'entityqueryblock') {
    $content ='';
    $block = array(
      'subject' => t('A block to display results from entityquery'),
      'content' => $content,
    );
    return $block;
  }
}

Put this module in your modules folder and if everything has gone well you will be able to see the entityquery module in your module list as shown below.

将此模块放在模块文件夹中,如果一切顺利,您将可以在模块列表中看到EntityQuery模块,如下所示。

alt

Once you have installed the module you should be able to see the new node types also in the Add content section of your Drupal admin panel as follows

一旦安装了模块,您就应该能够在Drupal管理面板的“添加内容”部分中看到新的节点类型,如下所示

alt

使用EntityFieldQuery执行简单查询 (Executing a simple query using EntityFieldQuery)

Once we have the basic module set up for using EntityFieldQuery, let’s start writing some queries to fetch data from Drupal. The first query we will write is to get all the nodes using EntityFieldQuery. Then we will use that to display the titles of the nodes in our block.

设置好用于使用EntityFieldQuery的基本模块后,让我们开始编写一些查询以从Drupal获取数据。 我们将编写的第一个查询是使用EntityFieldQuery获取所有节点。 然后,我们将使用它来显示块中节点的标题。

As stated earlier the first thing to do is to create an instance of EFQ. To fetch a type of entity you have to add the entity_type condition to it. In this case we want to fetch nodes so the code for it will be as follows:

如前所述,要做的第一件事是创建EFQ实例。 要获取实体的类型,您必须向其中添加entity_type条件。 在这种情况下,我们要获取节点,因此其代码如下:

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node');

The entity condition is set using the function entityCondition in which we are setting the entity type as node. Once we have set the entity condition, we are ready to execute the query. The node ids are returned in an array in the node key of the result. The complete code to display the nodes will be as follows:

实体条件是使用functionEntityCondition entityCondition ,其中我们将实体类型设置为节点。 设置实体条件后,就可以执行查询了。 节点ID在结果的节点键中的数组中返回。 显示节点的完整代码如下:

$query = new EntityFieldQuery();
    $query
    ->entityCondition('entity_type', 'node');


    $result = $query->execute();
    $nodes = array();
    if (isset($result['node'])) {
      $nids = array_keys($result['node']);
      $nodes = node_load_multiple($nids);
    }

    $list = array();
    foreach ($nodes as $node) {
      $options = array('absolute' => TRUE);
      $url = url('node/' . $node->nid, $options);
      $list[] = '<a href='.$url.'>'.$node->title.'</a>';
    }

    $theme_args = array('items' => $list, 'type' => 'ol');
    $content = theme('item_list', $theme_args);

    $block = array(
      'subject' => t('A block to display results from entityquery'),
      'content' => $content,
    );
    return $block;

Now if you go and see your block you should be able to see all nodes in it as follows

现在,如果您去查看您的块,您应该能够看到其中的所有节点,如下所示

alt

You should now try to add different nodes like movies and books and check them being displayed in the block. In the above, code once we have the node ids from EntityFieldQuery, we load the nodes using node_load_multiple and display them.

现在,您应该尝试添加不同的节点,例如电影和书籍,并检查它们是否显示在块中。 在上面的代码中,一旦我们从EntityFieldQuery获得了节点ID,便使用node_load_multiple加载节点并显示它们。

将实体条件添加到EntityFieldQuery (Adding entity conditions to EntityFieldQuery)

You can add entity conditions to show only particular types of nodes. If we want to display only “products” from the type of nodes, the query we will use is:

您可以添加实体条件以仅显示特定类型的节点。 如果我们只想显示节点类型的“产品”,我们将使用的查询是:

$query = new EntityFieldQuery();
    $query
    ->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'product'); 

    $result = $query->execute();

Now if we check our block it will display only products:

现在,如果我们检查块,它将仅显示产品:

alt

We can even specify an array of node types to fetch multiple types of nodes using entityCondition. To fetch all products and movies from your database:

我们甚至可以指定一个节点类型数组,以使用entityCondition获取多种类型的节点。 要从数据库中获取所有产品和电影:

$query = new EntityFieldQuery();
    $query
    ->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', array('product', 'movies')); 

    $result = $query->execute();

向EntityFieldQuery添加属性条件 (Adding property conditions to EntityFieldQuery)

We can even add property conditions to the query. These would depend on the entity type you are querying for. In most cases, the property condition will be on the fields of the entity type you are querying for. You can, for example, query for nodes which are published, or are written by a particular user etc.

我们甚至可以向查询添加属性条件。 这些将取决于您要查询的实体类型。 在大多数情况下,属性条件将位于您要查询的实体类型的字段上。 例如,您可以查询已发布的节点或由特定用户编写的节点等。

The query to show only published nodes using propertyCondition is as follows

使用propertyCondition仅显示已发布节点的查询如下

$query = new EntityFieldQuery();
    $query
    ->entityCondition('entity_type', 'node')
    ->propertyCondition('status', 1);

    $result = $query->execute();

将字段条件添加到EntityFieldQuery和排序 (Adding field conditions to EntityFieldQuery and ordering)

The field conditions are specific to the fields which are present on the entity. So suppose we want to find all the products which have the word discount in their body – we can do it using the field condition. We can even order the results using the propertyOrderBy function.

字段条件特定于实体上存在的字段。 因此,假设我们要查找所有在其体内带有折扣字样的产品-我们可以使用现场条件来做到这一点。 我们甚至可以使用propertyOrderBy函数对结果进行排序。

If we want the products and movies which have “discount” in their body, arranged in descending order of their creation, the query will be as follows:

如果我们希望产品和电影的主体以“降价”的方式降序排列,则查询如下:

$query = new EntityFieldQuery();
    $query
    ->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', array('product', 'movies'))
    ->propertyCondition('status', 1)
    ->fieldCondition('body', 'value', 'discount', 'CONTAINS')
    ->propertyOrderBy('created', 'DESC');

    $result = $query->execute();

The output of this query will be as follows

该查询的输出如下

alt

扩展EntityFieldQuery类 (Extending the EntityFieldQuery class)

Sometimes, you might have to build the same query in many places. A good way to abstract that would be to extend the EntityFieldQuery class and create your own child class.

有时,您可能必须在许多地方构建相同的查询。 一种抽象的好方法是扩展EntityFieldQuery类并创建自己的子类。

Suppose you want to build a query to get all active users in ascending order of their creation date:

假设您要构建一个查询,以按创建日期的升序获取所有活动用户:

class ActiveUsersEntityFieldQuery extends EntityFieldQuery {

  public function __construct() {

    $this
      ->entityCondition('entity_type', 'user')
      ->propertyCondition('status', 1)
      ->propertyOrderBy('created', 'ASC');

  }

}

Now you can use this query anywhere like so:

现在,您可以在任何地方使用此查询,如下所示:

$activeUsers = new ActiveUsersEntityFieldQuery();
$result2 = $activeUsers->execute();

结论 (Conclusion)

Many modules in Drupal will need you to fetch entity content from the database. One can directly use the Drupal database layer, but for that you have to have at least a working knowledge of SQL and it could be more prone to errors. The EntityFieldQuery class is a part of Drupal’s core and you can easily use it without dependency on other modules. Have fun creating your next Drupal module!

Drupal中的许多模块将需要您从数据库中获取实体内容。 可以直接使用Drupal数据库层,但是为此,您至少必须具有SQL的工作知识,并且它更容易出错。 EntityFieldQuery类是Drupal核心的一部分,您可以轻松使用它而无需依赖其他模块。 乐于创建您的下一个Drupal模块!

翻译自: https://www.sitepoint.com/understanding-drupals-entityfieldquery/

drupal

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值