Remplacement des Entity Field Query en drupal 7, les Entity Query permettent d'effectuer des requêtes sur nos types d'entités, (custom ou non) selon leurs propriétés ou leurs champs (fields).
Elles sont une bonne solution pour faire des queries même avancées, sans avoir à faire des jointures à en perdre la tête.
Un exemple simple
Récupération et chargement de l'ensemble des utilisateurs activés.
//On commence par donner le type d'entité que l'on souhaite « requêter »
$query = \Drupal::entityQuery('user');
//On ajoute une condition, ici « status = 1 » pour ne récupérer que les utilisateurs actifs
$query->condition('status', 1);
//On lance la requête et récupère les ids des utilisateurs.
$users_ids = $query->execute();
//on charge les utilisateurs en question
$users = User::loadMultiple($users_ids);
Que peut-on peut requêter ?
Sous drupal 8, tout est entité (ou presque), on peut ainsi faire des requêtes sur :
- Les noeuds
- Les blocs
- Les utilisateurs
- Les menus
- Les éléments de menus
- Nos types d'entités custom
- ...
Bref, beaucoup de chose !
La déclaration du type d'entité se fait lors de la génération de la requête :
Pour requêter les utilisateurs
$query = \Drupal::entityQuery('user');
Pour requêter les noeuds
$query = \Drupal::entityQuery('node');
Les conditions
$query->condition(champ_ou_propriété, valeur, opérateur);
Le champ sur lequel on fait une condition peut -être soit une propriété (nid, changed, created, title, name...) ou bien un champ « field » (field_tags, field_image...)
Par défaut l'opérateur est : = (égal)
$query->condition('uid', 1);
mais on peut évidement le spécifier :
$query->condition('uid', $user->id(), '');
On peut utiliser le IN, afin de, par exemple récupérer et charger tous les users en fonction d'un field "interest" qui fait référence à des termes de taxonomies :
$interests = [127, 128, 27];
$query = \Drupal::entityQuery('user');
$query->condition('field_interests', $interests, 'IN');
$profils_similaires = $query->execute();
$users = User::loadMultiple($profils_similaires);
Avec un "LIKE", afin de tester le même département :
$query->condition('field_adresse_zipcode', substr($code_postal, 0, 2).'%', 'LIKE');
Conditions multiples
Aussi on peut ajouter plusieurs conditions, ici je fais un test sur la date de naissance, qu'elle soit bien comprise entre $min_date & $max_date :
$query = \Drupal::entityQuery('user');
$query->condition('field_interests', $interests, 'IN');
$query->condition('field_birthday', $min_date->format('Y-m-d'), 'condition('field_birthday', $max_date->format('Y-m-d'), '>');
$profils_similaires = $query->execute();
$users = User::loadMultiple($profils_similaires);
Avec des conditions Or
On peut utiliser des conditions logiques « OR », ici je veux récuperer les utilisateurs qui ont les mêmes centres d'intérêts (field_interests) OU qui sont manuellement mis en avant (field_pinned)
$query = \Drupal::entityQuery('user');
$condition_or = $query->orConditionGroup();
$condition_or->condition('field_pinned',1);
$condition_or->condition('field_interests', $interests, 'IN');
$query->condition($condition_or);
$profils_similaires = $query->execute();
$users = User::loadMultiple($profils_similaires);
Avec des conditions OR et AND
On peut faire des conditions un peu plus balaises, avec ici donc : soit les utilisateurs mis en avant (field_pinned) OU (qui ont les même centres d'intérêts (field_interest) ET qui sont nés après $max_date ET avant $min_date :
$query = \Drupal::entityQuery('user');
$condition_or = $query->orConditionGroup();
$condition_or->condition('field_pinned',1);
$condition_and = $query->andConditionGroup();
$condition_and->condition('field_interests', $interests, 'IN');
$condition_and->condition('field_birthday', $min_date->format('Y-m-d'), 'condition('field_birthday', $max_date->format('Y-m-d'), '>');
$condition_or->condition($condition_and);
$query->condition($condition_or);
$profils_similaires = $query->execute();
$users = User::loadMultiple($profils_similaires);
Gestion de la pagination et du nombre de résultats
$query->range(0, 20);
Gestion du tri
$query->sort('created');
ou en précisant le sens :
$query->sort('field_birthday', 'ASC');