drupal 查看版本
Even though Drupal 7 core fell short of a proper way of handling its brand new entity system (we currently rely on the great Entity module for that), it did give us EntityFieldQuery. For those of you who don’t know, EntityFieldQuery is a very powerful querying class used to search Drupal entities programatically (nodes, users, etc).
即使Drupal 7内核没有使用正确的方式来处理其全新的实体系统(我们目前依赖于出色的Entity模块),但确实为我们提供了EntityFieldQuery 。 对于不认识的人, EntityFieldQuery是一个非常强大的查询类,用于以编程方式搜索Drupal实体(节点,用户等)。
It provides a number of methods that make it easy to query entities based on conditions such as field values or class properties. If you don’t know how it works, feel free to check out this documentation page or this great tutorial on the subject.
它提供了许多方法,可轻松根据字段值或类属性等条件查询实体。 如果您不知道它是如何工作的,请随时查看此文档页面或有关该主题的出色教程 。
In this article I am going to talk about what we have in Drupal 8 for querying entities. There is no more EntityFieldQuery, but there’s an entity.query service that will instantiate a query object for a given entity type (and that implements the \Drupal\Core\Entity\Query\QueryInterface). We can access this service statically through the \Drupal namespace or using dependency injection.
在本文中,我将讨论Drupal 8中用于查询实体的内容。 没有更多的EntityFieldQuery ,但是有一个entity.query服务,它将为给定的实体类型实例化查询对象(并实现\ Drupal \ Core \ Entity \ Query \ QueryInterface )。 我们可以通过\ Drupal命名空间或使用依赖项注入来静态访问此服务。
First up, we’ll look at querying node entities and then we’ll see how to load them. The same techniques will work with other content entities as well (users, comments etc), but also with configuration entities, and that’s really cool.
首先,我们将看一下查询节点实体,然后看如何加载它们。 同样的技术也可以与其他内容实体(用户,评论等)一起使用,但也可以与配置实体一起使用,这真的很酷。
As mentioned, there are two ways we can access the entity.query service that we use for querying entities. Statically, we can do this:
如前所述,有两种方法可以访问用于查询实体的entity.query服务。 静态地,我们可以这样做:
$query = \Drupal::entityQuery('node');Instead of node, we can specify any other entity type machine name and what we get inside the $query variable is the query object for our entity type. The entityQuery() static method on the \Drupal namespace is a shortcut for doing so using the entity.query service.
代替node ,我们可以指定任何其他实体类型的机器名,并且在$query变量中得到的是我们实体类型的查询对象。 \Drupal命名空间上的entityQuery()静态方法是使用entity.query服务执行此操作的快捷方式。
Alternatively (and the highly recommended approach) is to use dependency injection.
或者(强烈推荐的方法)是使用依赖注入 。
If you have access to the container, you can load the service from there and then get the right query object:
如果您有权访问该容器,则可以从那里加载该服务,然后获取正确的查询对象:
$entity_query_service = $container->get('entity.query'); $query = $entity_query_service->get('node');As you can see, we use the get() method on the entity_query service to instantiate a query object for the entity type with the machine name passed as a parameter.
如您所见,我们在entity_query服务上使用get()方法来实例化一个实体类型的查询对象,该实体类型以传递的计算机名称作为参数。
Let’s illustrate a couple of examples of querying for node entities using this object.
让我们举例说明几个使用此对象查询节点实体的示例。
A very simple query that returns the published nodes:
一个非常简单的查询,它返回已发布的节点:
$query = \Drupal::entityQuery('node') ->condition('status', 1); $nids = $query->execute();$nids will be an array of entity ids (in our case node ids) keyed by the revision ids (if there is revisioning enabled for the entity type) or the entity ids if not. Let’s see an example in which we add more property conditions as well as field conditions:
$nids将是由修订ID(如果为实体类型启用了修订)键入的实体ID(在本例中为节点ID)的数组,否则为实体ID的数组。 让我们看一个示例,其中添加更多属性条件以及字段条件:
$query = \Drupal::entityQuery('node') ->condition('status', 1) ->condition('changed', REQUEST_TIME, '<') ->condition('title', 'cat', 'CONTAINS') ->condition('field_tags.entity.name', 'cats'); $nids = $query->execute();In this query, we retrieve the node ids of all the published nodes that have been last updated before the current time, that have the word cat inside their title and that have a taxonomy term called cats as a reference in the field_tags.
在此查询中,我们检索所有已发布节点的节点ID,这些节点ID在当前时间之前最后更新,其标题内包含单词cat 并且在field_tags中具有称为cats的分类术语作为参考。
As you can see, there is no more distinction between propertyCondition and fieldCondition (as there is in D7 with EntityFieldQuery). Additionally, we can include conditions based on referenced entities tacking on the entity.(column) to the entity reference field name.
正如你所看到的,之间没有任何区别更propertyCondition和fieldCondition (因为是在D7与EntityFieldQuery )。 另外,我们可以包括基于引用实体的条件,这些条件是在实体引用字段名称上附加到entity.(column)上的。
An important thing to note is that we also have the langcode parameter in the condition() method by which we can specify what translation of the node should be included in the query. For instance, we can retrieve node IDs that contain a specific value inside of a field in one language but another value inside the same field for another language.
需要注意的重要一点是,我们在condition()方法中还具有langcode参数,通过该参数可以指定查询中应包含节点的哪种转换。 例如,我们可以检索节点ID,这些节点ID在一种语言的字段中包含特定值,而在另一种语言的字段中包含另一值。
For more information on the condition() method you should consult the API documentation.
有关condition()方法的更多信息, 请查阅API文档 。
The next thing we are going to look at is using condition groups (both AND and OR) for more powerful queries:
接下来要看的是使用条件组( AND和OR )进行更强大的查询:
$query = \Drupal::entityQuery('node') ->condition('status', 1) ->condition('changed', REQUEST_TIME, '<'); $group = $query->orConditionGroup() ->condition('title', 'cat', 'CONTAINS') ->condition('field_tags.entity.name', 'cats'); $nids = $query->condition($group)->execute();Above, we altered our previous query so as to retrieve nodes that either have the cat string in their title or have a reference to the term called cats in their field_tags field. And we did so by creating an orConditionGroup object that we then pass to the query as a condition. And we can group together multiple conditions within a andConditionGroup as well.
上面,我们更改了之前的查询,以检索名称中包含cat字符串或在field_tags字段中引用了称为cats的术语的field_tags 。 为此 ,我们创建了一个orConditionGroup对象,然后将其作为条件传递给查询。 我们也可以将andConditionGroup中的多个条件组合在一起。
There are many other methods on the QueryInterface that can extend the query (such as for sorting, range, etc). I encourage you to check them out in the documentation and experiment with them. For now, though, let’s take a quick look at what to do with the result set.
QueryInterface上还有许多其他方法可以扩展查询(例如,排序,范围等)。 我鼓励您在文档中检查它们并进行试验。 现在,让我们快速看一下如何处理结果集。
As I mentioned above, the execute() method on the query object we’ve been working with returns an array of entity IDs. Supposedly we now have to load those entity objects and work with them. How do we do that?
如上所述,我们一直在使用的查询对象上的execute()方法返回一个实体ID数组。 假设我们现在必须加载这些实体对象并使用它们。 我们该怎么做?
In Drupal 7 we had the entity_load() function to which we passed an array of IDs and that would return an array of objects. In Drupal 8, this helper function is maintained and you can use it pretty much in the same way, except only for one entity at a time:
在Drupal 7中,我们有一个entity_load()函数,我们向该函数传递了一个ID数组,该函数将返回一个对象数组。 在Drupal 8中,维护了此辅助函数,您几乎可以以相同的方式使用它,但一次只能一个实体:
$node = entity_load('node', $nids[1]);And the return value is a node object. To load multiple nodes, you can use the entity_load_multiple() function:
返回值是一个节点对象。 要加载多个节点,可以使用entity_load_multiple()函数:
$nodes = entity_load_multiple('node', $nids);Which then returns an array of entity objects keyed by their ids.
然后,该数组返回由其ID键控的实体对象的数组。
A bonus nugget of information is that both of these functions are wrappers for the storage manager of the entities in question. They basically retrieve the storage manager statically and then call the load() and loadMultiple() methods, respectively, on it:
额外的信息是,这两个功能都是有关实体的存储管理器的包装器。 他们基本上是静态地检索存储管理器,然后分别在其上调用load()和loadMultiple()方法:
Statically, you could do similarly:
静态地,您可以执行类似的操作:
$node_storage = \Drupal::entityManager()->getStorage('node'); // Load multiple nodes $node_storage->loadMultiple($ids); // Load a single node $node_storage->load($id);But better yet, you could use dependency injection and retrieve the storage class from the container:
但更好的是,您可以使用依赖项注入并从容器中检索存储类:
$node_storage = $container->get('entity.manager')->getStorage('node');And then proceed with the loading. Using dependency injection is usually the recommended way to go when it’s possible, i.e. when working within a class. This makes it easier to test your class and better decouples it from the rest of the application.
然后继续加载。 在可能的情况下(即在类中工作时),通常建议使用依赖项注入。 这样可以更轻松地测试您的类,并更好地将其与应用程序的其余部分分离。
In this article we’ve seen how to work with querying and loading entities in Drupal 8. There has been an overhaul of the D7 EntityFieldQuery class that turned into a robust API for querying both content and configuration entities. We’ve looked at querying content entities but the system works just the same with config entities. And that is a bit of a win for the new Drupal 8 entity system.
在本文中,我们已经看到了如何在Drupal 8中使用查询和加载实体。对D7 EntityFieldQuery类进行了全面的EntityFieldQuery ,使其变成了用于查询内容和配置实体的可靠API。 我们已经研究了查询内容实体,但是系统与配置实体的工作原理相同。 对于新的Drupal 8实体系统而言,这是一个胜利。
We’ve also seen how to load entities based on the IDs resulted in these queries and what is actually behind the wrapper functions that perform these operations. Next up, we are going to look at defining our own content entity type in Drupal 8. For a refresher on how we do it in Drupal 7, you can check out these Sitepoint articles on the subject.
我们还看到了如何根据导致这些查询的ID加载实体以及执行这些操作的包装函数背后的实际含义。 接下来,我们将研究在Drupal 8中定义我们自己的内容实体类型。有关在Drupal 7中如何进行操作的更新,您可以查看有关此主题的这些Sitepoint文章 。
翻译自: https://www.sitepoint.com/drupal-8-version-entityfieldquery/
drupal 查看版本