Création module drupal 7 avec EntityFieldQuery

Source: http://www.sitepoint.com/understanding-drupals-entityfieldquery/

Cette classe (abrégée ici en EFQ) est utilisée pour trouver des entitées drupal. Ex typique d'utilisation:

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

On va créer un module qui crée 3 types de contenus (Product, Films et Books) et un bloc affichant le résultat.
Les fichiers indispensables du modules sont zipés en PJ (entityquery.info entityquery.install et entityquery.module). Mettre le dossier en sites/all et aller à la liste des modules.
L'activer va créer les 3 types de contenus et le bloc.

Aller afficher et configurer ce bloc à admin/structure/block - le positionner sur toutes pages, en haut du contenu).

Une simple query avec EntityFieldQuery

But: récupérer tous les nodes qui utilisent la classe EFQ pour afficher les titres des nodes dans le bloc. Ce code est à insérer dans la fonction "entityquery_block_view", juste avant le return $block;

Une fois qu'on a récup les ID des nodes (de EFQ), on charge les nodes avec node_load_multiple et on les affiche:

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node');
on crée l'instance EFQ
récup que les nodes et ID (avec la fonction entityCondition)
$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('Un block affichant resultats de entityquery'), 'content' => $content, );
return $block;

exe query

isset détermine si une variable est définie et est différente de NULL
 

$options est lié à la fonction url

 

 

cf https://api.drupal.org/api/drupal/modules!system!theme.api.php/group/themeable/7

PJ: entityquery.module.txt -> renommer en entityquery.module et à copier en sites/all/modules/entityquery
En regardant le bloc, on voit le résultat. Ajouter des nodes de type Films et Books.

 

Ajouter des conditions sur les entitées

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

    $result = $query->execute();

n'affiche que les Products

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

    $result = $query->execute();

à l'aide d'un tableau (de bundle)
ex: Product et Films

Le bloc n'apparait que lorsque qu'on ouvre un des Produit, Book ou Film.

Conditions sur les propriétés (dépend des entity type)

Ex: requetes sur les nodes publiés, écrit par un user... Ici affiche les nodes publiés (status 1):

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

$result = $query->execute();

Ajout de conditions champ à EFQ et trier

Il faut bien sur que ces champs existent pour ces entitées... Ici, on va chercher tous les produits qui ont dans leur body le mot "discount". On va trier avec propertyOrderBy.

Pour récupérer Produits et Films qui ont dans body "discount", trié par ordre de création:

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

Extention de la classe EFQ

Souvent on a besoin de la meme requete à des endroits différents. On peux alors étendre la classe EFQ et créer une classe enfant.

Par ex, pour avoir la liste des users actifs, triée par ordre de la date de leur création. Si l'on crée cette classe:

class ActiveUsersEntityFieldQuery extends EntityFieldQuery {
  public function __construct() {

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

}

}

alors on peux utiliser partout la requete suivante:
    $activeUsers = new ActiveUsersEntityFieldQuery();
    $result2 = $activeUsers->execute();

 

Doc tek: 
Fichier attachéTaille
Plain text icon entityquery.module.txt2.89 Ko
Plain text icon entityqueryinfozip.txt1.92 Ko