36

In Drupal 7, the API documentation for node_load_multiple() specifies using the $conditions parameter has been deprecated in favor of using EntityFieldQuery. How does one use the class to generate a list of node IDs for use with node_load_multiple()? Are there any other use cases for it?

35

EntityFieldQuery uses a set of hooks to interface with field storage modules, such as Field SQL Storage, in order to work for fields as well as other node properties. Long term, EntityFieldQuery is a much more reliable way to query any type of entity, and in some situations it can perform cross entity queries (see field_has_data or _list_values_in_use() for an example.

Here's a simple example of using EntityFieldQuery to get a list of all nodes published before a specific timestamp:

$query = new EntityFieldQuery();

$query
  ->entityCondition('entity_type', 'node', '=')
  ->propertyCondition('status', 1, '=')
  ->propertyCondition('created', '1294694496', '<');

$result = $query->execute();

$results from that query would look something like this:

Array
(
    [node] => Array
        (
            [1] => stdClass Object
                (
                    [nid] => 1
                    [vid] => 49
                    [type] => article
                )

            [2] => stdClass Object
                (
                    [nid] => 2
                    [vid] => 2
                    [type] => page
                )

        )

)

You could then use that array as input to node_load_multiple:

$nodes = node_load_multiple(array_keys($result['node']));
  • 3
    field_has_data is a nicer example imo than _list_values_in_use – user49 Mar 2 '11 at 21:39
15

I found an issue on Drupal about adding examples for EntityFieldQuery. I've been using it for examples as well as to voice my opinion on the call for more examples.

"Do we need an EntityFieldQuery example?"

The comment #11 shows usage of node_load_multiple() as seen below:

$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
                        ->entityCondition('bundle', 'event')
                        ->propertyCondition('status', 1)
                        ->fieldCondition('field_date', 'value', array('2011-03-01', '2011-03-31'), 'BETWEEN')
                        ->fieldOrderBy('field_date', 'value', 'ASC')
                        ->execute();

$nodes = entity_load('node', array_keys($entities['node']));
return node_view_multiple($nodes, 'teaser');
  • 2
    Caution, the fieldOrderBy method will leave out any nodes that have the related field empty. Which is confusing cause this is only supposed to sort and not filter (you'd expect nodes with the empty field to be on top or bottom of the result set). More info and hopefully a fix can be found here drupal.org/node/1611438 and here drupal.org/node/1662942 – Mario Awad Sep 19 '12 at 12:58
9

Here is an example from one of the test modules:

http://api.drupal.org/api/drupal/modules--node--tests--node_access_test.module/function/node_access_entity_test_page/7

This selects nodes whose body field starts with "A". See also EntityFieldQuery::execute() on how to use the returned result.

There are many use cases, the typical example is querying entities for specific field value like the body field as shown in the first example.

The advantage is that it works whatever field_storage you are using. For example, you can have your fields in MongoDB and EntityQuery will still work while querying field_data_body manually wouldn't.

0

You can use EntityFieldQuery class to query the database and fetch the results in form of list similar to node_load_multiple().

This can be achieved by creating a class, applying the conditions and executing the query, for example:

<?php
$query = new EntityFieldQuery();
$query
  ->entityCondition('entity_type', 'TYPE') // E.g. node, entityform, taxonomy_term
  ->entityCondition('bundle', 'BUNDLE')
  ->fieldCondition('field_foo', 'value', 'STRING')
  ->range(0,10);
$result = $query->execute();
?>

This will generate the array such like:

array (
  'TYPE' =>
  array (
    123 =>
    stdClass::__set_state(array(
       'nid' => '123', // Can be also tid when loading terms.
       'key' => 'value',
    )),
    456 =>
    stdClass::__set_state(array(
       'nid' => '456',
       'key' => 'value',
    )),
  ),
)

To fetch the ID from the result array, you can use: current(current($result))->tid.

Here is more advanced example:

<?php
$query = new EntityFieldQuery();

$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'article')
  ->propertyCondition('status', NODE_PUBLISHED)
  ->fieldCondition('field_news_types', 'value', 'spotlight', '=')
  ->fieldCondition('field_photo', 'fid', 'NULL', '!=')
  ->fieldCondition('field_faculty_tag', 'tid', $value)
  ->fieldCondition('field_news_publishdate', 'value', $year . '%', 'like')
  ->fieldOrderBy('field_photo', 'fid', 'DESC')
  ->range(0, 10)
  ->addMetaData('account', user_load(1)); // Run the query as user 1.

$result = $query->execute();

if (isset($result['node'])) {
  $news_items_nids = array_keys($result['node']);
  $news_items = entity_load('node', $news_items_nids);
}
?>

See: How to use EntityFieldQuery at Drupal.org for more explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy