Quelle est la bonne utilisation de EntityFieldQuery?

37

Dans Drupal 7, la documentation de l'API pour node_load_multiple()spécifier l'utilisation du $conditionsparamètre a été déconseillée au profit de l'utilisation EntityFieldQuery. Comment utilise-t-on la classe pour générer une liste d'ID de nœuds à utiliser node_load_multiple()? Existe-t-il d'autres cas d'utilisation?

André Baumeier
la source

Réponses:

36

EntityFieldQuery utilise un ensemble de points d'ancrage pour assurer l'interface avec les modules de stockage de champs, tels que le stockage Field SQL, afin de gérer les champs ainsi que d'autres propriétés de nœud. À long terme, EntityFieldQuery est un moyen beaucoup plus fiable d’interroger tout type d’entité et, dans certains cas, il peut effectuer des interrogations inter-entités (voir field_has_data ou _list_values_in_use () pour obtenir un exemple.

Voici un exemple simple d'utilisation de EntityFieldQuery pour obtenir une liste de tous les nœuds publiés avant un horodatage spécifique:

$query = new EntityFieldQuery();

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

$result = $query->execute();

Les résultats de cette requête ressembleraient à ceci:

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

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

        )

)

Vous pouvez ensuite utiliser ce tableau comme entrée de node_load_multiple:

$nodes = node_load_multiple(array_keys($result['node']));
Mikey P
la source
3
field_has_data est un exemple plus intéressant que _list_values_in_use
15

J'ai trouvé un problème sur Drupal concernant l'ajout d'exemples pour EntityFieldQuery. Je l'utilise pour des exemples et pour exprimer mon opinion sur l'appel à davantage d'exemples.

" Avons-nous besoin d'un exemple EntityFieldQuery? "

Le commentaire # 11 montre l'utilisation de node_load_multiple()comme ci-dessous:

$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
la source
2
Attention, la méthode fieldOrderBy laissera de côté tous les nœuds dont le champ associé est vide. Ce qui est source de confusion, car il est uniquement supposé trier et non filtrer (vous vous attendriez à ce que les nœuds avec le champ vide se trouvent en haut ou en bas du jeu de résultats). Pour plus d'informations, vous pouvez trouver un correctif ici drupal.org/node/1611438 et ici drupal.org/node/1662942
Mario Awad
9

Voici un exemple de l'un des modules de test:

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

Ceci sélectionne les nœuds dont le corps de corps commence par "A". Voir aussi EntityFieldQuery :: execute () pour savoir comment utiliser le résultat renvoyé.

Il existe de nombreux cas d'utilisation. L'exemple typique consiste à interroger des entités sur une valeur de champ spécifique, telle que la zone de corps, comme indiqué dans le premier exemple.

L'avantage est que cela fonctionne quel que soit le champ field_storage que vous utilisez. Par exemple, vous pouvez avoir vos champs dans MongoDB et EntityQuery fonctionnera toujours sans interroger manuellement field_data_body.

Berdir
la source
0

Vous pouvez utiliser la classe EntityFieldQuery pour interroger la base de données et extraire les résultats sous forme de liste similaire à node_load_multiple().

Ceci peut être réalisé en créant une classe, en appliquant les conditions et en exécutant la requête, par exemple:

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

Cela générera un tableau tel que:

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

Pour récupérer l'ID du tableau de résultat, vous pouvez utiliser: current(current($result))->tid.

Voici un exemple plus avancé:

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

Voir: Comment utiliser EntityFieldQuery sur Drupal.org pour plus d'explications.

Kenorb
la source