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 ne sera malheureusement 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 une raison quelconque.
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();
}
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);
}
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
n'utilise que INNER JOIN
s pour joindre les tables.
Il existe cependant une solution de contournement, qui implique l'utilisation hook_query_TAG_alter()
et l'ajout d'une balise à votre EntityFieldQuery
, il y a un exemple dans le dernier commentaire sur la page que j'ai liée ci-dessus.
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 "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 mis en œuvre en
hook_query_TAG_alter
tirant parti du fait que je n'aimy_custom_tag
défini que:
/**
* 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 field_name
champ vide o_O
Testé sur Drupal version >= 7.43
.