Как правильно использовать EntityFieldQuery?

37

В Drupal 7 документация API для node_load_multiple()спецификаций, использующих $conditionsпараметр, устарела в пользу использования EntityFieldQuery. Как использовать класс для создания списка идентификаторов узлов для использования с node_load_multiple()? Есть ли другие варианты использования для этого?

Андре Баумайер
источник

Ответы:

36

EntityFieldQuery использует набор хуков для взаимодействия с полевыми модулями хранения, такими как Field SQL Storage, для работы с полями, а также с другими свойствами узла. В долгосрочной перспективе EntityFieldQuery является гораздо более надежным способом запроса сущностей любого типа, и в некоторых ситуациях он может выполнять перекрестные запросы сущностей (см., Например, field_has_data или _list_values_in_use () .

Вот простой пример использования EntityFieldQuery для получения списка всех узлов, опубликованных до определенной отметки времени:

$query = new EntityFieldQuery();

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

$result = $query->execute();

$ результаты этого запроса будут выглядеть примерно так:

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

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

        )

)

Затем вы можете использовать этот массив в качестве входных данных для node_load_multiple:

$nodes = node_load_multiple(array_keys($result['node']));
Майки П
источник
3
field_has_data - лучший пример imo, чем _list_values_in_use
15

На Drupal я обнаружил проблему с добавлением примеров для EntityFieldQuery. Я использовал это для примеров, а также высказал свое мнение о вызове для большего количества примеров.

" Нужен ли нам пример EntityFieldQuery? "

Комментарий # 11 показывает использование , node_load_multiple()как показано ниже:

$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');
electblake
источник
2
Внимание, метод fieldOrderBy пропустит все узлы, у которых связанное поле будет пустым. Это сбивает с толку, потому что предполагается, что это только сортировка, а не фильтрация (можно ожидать, что узлы с пустым полем будут сверху или снизу от набора результатов). Больше информации и, надеюсь, исправление можно найти здесь: drupal.org/node/1611438 и здесь drupal.org/node/1662942
Mario Awad
9

Вот пример из одного из тестовых модулей:

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

Это выбирает узлы, чье поле тела начинается с «A». Смотрите также EntityFieldQuery :: execute () о том, как использовать возвращаемый результат.

Существует много вариантов использования, типичным примером является запрос сущностей для конкретного значения поля, такого как поле body, как показано в первом примере.

Преимущество состоит в том, что он работает независимо от того, какое field_storage вы используете. Например, вы можете иметь свои поля в MongoDB, и EntityQuery будет по-прежнему работать, а запрос field_data_body вручную не будет.

Berdir
источник
0

Вы можете использовать класс EntityFieldQuery для запроса базы данных и получения результатов в виде списка, подобного node_load_multiple().

Это может быть достигнуто путем создания класса, применения условий и выполнения запроса, например:

<?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();
?>

Это сгенерирует массив, такой как:

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',
    )),
  ),
)

Чтобы извлечь идентификатор из результирующего массива, вы можете использовать: current(current($result))->tid.

Вот более продвинутый пример:

<?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);
}
?>

Смотрите: Как использовать EntityFieldQuery на Drupal.org для более подробного объяснения.

kenorb
источник