J'ai un type de contenu qui a un champ de référence d'entité qui permet aux utilisateurs d'ajouter plusieurs termes de taxonomie dans ce champ. J'essaie d'exécuter des requêtes qui récupèrent des nœuds qui ont un ensemble spécifique de termes de taxonomie dans ce champ.
Utiliser une valeur dans ce champ fonctionne très bien, comme ça.
$query = \Drupal::entityQuery('node')
->condition('status', NODE_PUBLISHED)
->condition('type', 'custom_type')
->condition('custom_taxonomy', 2)
->sort('field_last_name', DESC);
Où 2 est l'ID du terme que je recherche. Cependant, lorsque j'essaie de rechercher des nœuds contenant deux termes spécifiques comme celui-ci,
$query = \Drupal::entityQuery('node')
->condition('status', NODE_PUBLISHED)
->condition('type', 'custom_type')
->condition('custom_taxonomy', [2,8])
->sort('field_last_name', DESC);
Je reçois l'erreur
Numéro de paramètre non valide: le nombre de variables liées ne correspond pas au nombre de jetons:
J'ai aussi tenté
$query = \Drupal::entityQuery('node')
->condition('status', NODE_PUBLISHED)
->condition('type', 'custom_type')
->condition('custom_taxonomy', [2,8], 'IN')
->sort('field_last_name', DESC);
Ce qui n'échoue pas, mais ne fournit pas les résultats escomptés. Il affiche tous les nœuds qui ont soit le terme 2 OU terme 8. Au lieu du terme 2 ET terme 8 comme prévu. Comment pourrais-je effectuer une requête qui vérifie si un nœud a plusieurs valeurs spécifiques dans un champ de référence d'entité?
Utilisez deux andConditionGroup()
distinctes:
$query = \Drupal::entityQuery('node')
->condition('status', NODE_PUBLISHED)
->condition('type', 'custom_type');
$and = $query->andConditionGroup();
$and->condition('custom_taxonomy', 2);
$query->condition($and);
$and = $query->andConditionGroup();
$and->condition('custom_taxonomy', 8);
$query->condition($and);
$result = $query->execute();
Cela fonctionne quel que soit le nombre de termes dans le domaine ou dans quel delta ils se trouvent.
Modifier
Il en résulte ce SQL:
SELECT base_table.vid AS vid, base_table.nid AS nid
FROM
{node} base_table
INNER JOIN {node_field_data} node_field_data ON node_field_data.nid = base_table.nid
INNER JOIN {node__custom_taxonomy} node__custom_taxonomy ON node__custom_taxonomy.entity_id = base_table.nid
INNER JOIN {node__custom_taxonomy} node__custom_taxonomy_2 ON node__custom_taxonomy_2.entity_id = base_table.nid
WHERE (node_field_data.status = '1') AND (node_field_data.type = 'custom_type') AND( (node__custom_taxonomy.custom_taxonomy_target_id = '2') )AND( (node__custom_taxonomy_2.custom_taxonomy_target_id = '8') )
Pour effectuer des requêtes complexes comme vous l'avez demandé, vous devrez utiliser un groupe de conditions et interroger le delta.
$query = \Drupal::entityQuery('node');
$query->condition('status', NODE_PUBLISHED)
->condition('type', 'custom_type')
->condition('custom_taxonomy', [2, 8], 'IN')
->condition('custom_taxonomy.%delta', 2, '=')
->sort('field_last_name', DESC);
$or = $query->orConditionGroup();
$or->condition('custom_taxonomy.0.target_id', 2);
$or->condition('custom_taxonomy.0.target_id', 8);
$query->condition($or);
Voir QueryInterface :: condition documentation.
$taxonomy_term = 'taxonomy_term';
$vid = 'name_taxon';
$terms = $this->entity_type_manager->getStorage($taxonomy_term)
->loadTree($vid);
foreach ($terms as $term) {
$term_data[] = [
"vid" => $term->vid,
"name" => $term->name,
];
}