web-dev-qa-db-fra.com

Utiliser une autre valeur de champ comme condition dans la requête d'entité

J'exécute dans Drupal 8 an requête d'entité qui recherche les nœuds qui n'ont pas été modifiés depuis x jours, où x est un champ de nœud numérique (node.field_days Je voudrais donc effectuer une requête comme:

$query = \Drupal::entityQuery("node")
  ->condition('changed', strtotime('-node.field_days days'), '<=');

Je sais que cette condition prend comme valeur une chaîne et non une colonne db, mais est-il possible d'utiliser une requête d'entité avec une valeur dynamique?

2
Maria Ioannidou

La requête d'entité est un outil puissant et pratique pour rechercher du contenu et configurer des entités qui ont certaines propriétés/valeurs de champ/références de champ.

Pourtant, il a ses limites. La comparaison de deux champs n'est pas possible à l'aide de la requête d'entité générique et de sa méthode de condition.

Pour une telle tâche, vous devrez peut-être utiliser le niveau plus bas requêtes dynamiques (sélectionner) et sa méthode . Un exemple pour votre cas d'utilisation:

$connection = \Drupal::database();
// Query node base field table.
$query = $connection->select('node_field_data', 'n');
// Join with the `field_days` field table.
$query->leftjoin('node__field_days', 'd', 'd.entity_id = n.nid');
// Query for the node ID.
$query->fields('n', ['nid']);
// Your condition (a day has 86400 seconds; we multiply them with
// the value of the field_days field, add them to the changed
// timestamp of the node and compare it against the current time).
$query->where('n.changed + (d.field_days_value * 86400) <= :now', [
  ':now' => \Drupal::time()->getCurrentTime(),
]);
// Optional sorting.
$query->orderBy('n.changed', 'DESC');
// Fetch results.
$result = $query->execute()->fetchAllKeyed(0, 0);

L'exemple ci-dessus suppose:

  1. que vous avez utilisé un type de champ numérique pour field_days, afin que sa valeur stockée dans la base de données puisse être multipliée par secondes sans aucune conversion,
  2. que le field_days champ n'autorise qu'une seule valeur, afin que nous puissions ignorer les deltas de champ lors de la jointure
  3. cette field_days est présent sur tous les nœuds/bundles et a une valeur valide,
  4. que vous utilisez une seule langue dans votre site/le field_days la valeur n'est pas traduisible, nous pouvons donc également ignorer les langcodes.

Vous devrez peut-être modifier la requête en conséquence, si l'une de ces hypothèses n'est pas vraie.

4
Mario Steinitz