Est-il possible de sélectionner toutes les entités dont le champ xyz est vide?
J'ai essayé quelque chose comme ça:
->fieldCondition('field_name', 'value', NULL, 'IS NOT NULL');
Cependant, cela ne semble pas fonctionner.
Des idées?
Si vous regardez sur la page de documentation fieldCondition , vous verrez l'avertissement suivant:
Notez que les entités avec des valeurs de champ vides seront exclues des résultats EntityFieldQuery lors de l'utilisation de cette méthode.
Vérifier si un champ existe ou non a été ajouté à entityFieldQuery dans Drupal 8, mais malheureusement ne sera pas rétroporté vers Drupal 7 =.
Il existe différentes méthodes pour y parvenir:
_
$q = db_select('node', 'n');
$q->fields('n', array('type'))
->condition('n.type', 'my_node_type', '=')
->addJoin('LEFT', 'field_data_field_my_field', 'f', 'f.entity_id = n.nid');
$q->isNull('f.value');
$r = $q->execute();
Vous pouvez utiliser != NULL
, mais vous ne pouvez pas utiliser = NULL
pour certaines raisons.
Ceci est ma solution de contournement.
//Get all the entities that DO have values
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->fieldCondition('field_MY_FIELD', 'value', 'NULL', '!=');
$result = $query->execute();
if (is_array(@$result['registration'])) {
//Now get all the other entities, that aren't in the list you just retrieved
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->entityCondition('entity_id', array_keys($result['MY_TYPE']), 'NOT IN');
$result_two = $query->execute();
}
La réponse courte est que, directement, non, vous ne pouvez pas (voir EntityFieldQuery ne prend pas en charge isNull ou isNotNull ). Si je me souviens bien, c'est un effet secondaire du fait que EntityFieldQuery
utilise uniquement INNER JOIN
Pour joindre les tables.
Il existe cependant une solution de contournement, qui implique l'utilisation de hook_query_TAG_alter()
et l'ajout d'une balise à votre EntityFieldQuery
, il y a un exemple dans le dernier commentaire de la page à laquelle je suis lié au dessus de.
Selon la documentation vous pouvez utiliser null et isnull; il a juste une façon spécifique de l'écrire.
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'article')
->propertyCondition('status', 1)
->fieldCondition('field_news_types', 'value', 'spotlight', '=')
->fieldCondition('field_photo', 'fid', 'NULL', '!=')
->fieldCondition('field_faculty_tag', 'tid', $value)
->fieldCondition('field_news_publishdate', 'value', $year. '%', 'like')
->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);
}
Dans Drupal 7 veuillez vérifier la solution de contournement suivante proposée ici :
Enregistrez la balise pour modifier l'instance de requête:
<?php
/**
* Implements hook_query_TAG_alter()
*/
function MYMODULE_query_node_is_not_tagged_alter(QueryAlterableInterface $query) {
$query->leftJoin('field_data_field_tags', 'o', 'node.nid = o.entity_id AND o.entity_type = :entity_type');
$query->isNull('o.field_tags_tid');
}
?>
Obs.: Cette modification de balise de requête ne fonctionne que pour le type d'entité "nœud". Ne confondez pas les "field_tags" liés au vocabulaire des "Tags", il peut en être d'autres comme les "Catégories".
Obtenez tous les nœuds qui n'ont pas encore été balisés en utilisant EntityFieldQuery, regardez la méthode addTag ():
<?php
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'news')
->addTag('node_is_not_tagged')
->propertyCondition('status', 1);
$result = $query->execute();
?>
Autre exemple:
$result = $query
->entityCondition('entity_type', 'node')
->propertyCondition('type', 'my_content_type')
->fieldCondition('field_mine_one', 'value', '', '<>')
->fieldCondition('field_mine_two', 'value', '', '<>')
->addTag('my_custom_tag')
->deleted(FALSE)
->propertyOrderBy('changed', 'DESC')
->range(0, $my_range_value)
->execute();
Ensuite, j'ai implémenté
hook_query_TAG_alter
tirant parti du fait quemy_custom_tag
n'est défini que par moi:
/**
* Implements hook_query_TAG_alter()
*/
function MYMODULE_query_TAG_alter(QueryAlterableInterface $query) {
$query->leftJoin('field_data_field_other', 'o', 'node.nid = o.entity_id');
$query->isNull('o.field_other_value');
}
Un autre exemple:
<?php
//Get all the entities that DO have values
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->fieldCondition('field_MY_FIELD', 'value', 'NULL', '!=');
$result = $query->execute();
if (is_array(@$result['registration'])) {
//Now get all the other entities, that aren't in the list you just retrieved
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->entityCondition('entity_id', array_keys($result['MY_TYPE']), 'NOT IN');
$result_two = $query->execute();
}
?>
Exemple plus complet ci-dessous qui charge un tas de nœuds sur une tâche cron qui vide les références de termes de taxonomie et applique certaines modifications:
/**
* Implements hook_cron().
*/
function MYMODULE_cron() {
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'property')
->propertyOrderBy('changed', 'DESC')
->addTag('type_is_null')
->range(0,50); // Maximum of 50.
$result = $query->execute();
if (!empty($result['node'])) {
$nids = array_keys($result['node']);
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
// do_some_stuff($node);
}
}
}
/**
* Implements hook_query_TAG_alter()
*/
function MYMODULE_query_type_is_null_alter(QueryAlterableInterface $query) {
$query->leftJoin('field_data_field_foo', 'f', 'node.nid = f.entity_id AND f.entity_type = :entity_type');
$query->isNull('f.field_foo_tid'); // Check name by SQL: DESC field_data_field_foo
$query->leftJoin('field_data_field_bar', 'b', 'node.nid = b.entity_id AND b.entity_type = :entity_type');
$query->isNull('b.field_bar_tid'); // Check name by SQL: DESC field_data_field_bar
}
Vous devez mettre Null entre guillemets.
->fieldCondition('field_name', 'value', 'NULL', '!=');
Corrigez-moi si j'ai tort, s'il-vous plait. Il semble qu'il faut simplement
$query->fieldCondition('field_name');
pour exclure tous les nœuds avec un champ vide field_name
o_O
Testé en Drupal version >= 7.43
.