Ayez CONTENT_TYPE_NAME
Avec field_counter
Que l'utilisateur peut définir lors de la modification d'un nœud. Si un utilisateur modifie et met à jour ce champ, je veux que tous les autres nœuds qui ont ce champ défini (à une valeur égale ou supérieure) incrémentent leurs valeurs de 1. Je remplace hook_entity_presave
À cet effet.
Comme vous pouvez le voir dans le code suivant, j'obtiens tous les nœuds du même type de contenu en utilisant entityQuery
à l'exclusion du nœud qui était sur le point d'être enregistré. Pour tous les nœuds trouvés, j'obtiens l'entité et j'incrémente la valeur de champ de 1, je définis la valeur de champ et j'enregistre le nœud.
function MY_MODULE_entity_presave(EntityInterface $entity){
if ($entity->getEntityType()->id() == 'node') {
$changed_field = array(
"field_counter",
);
$nid = $entity->id();
foreach($changed_field as $field ){
$value = $entity->{$field}->value;
if(isset($value) && $value !=""){
MY_MODULE_change_field_value($field,$value,$nid);
//...
}
}
}
}
function MY_MODULE_change_field_value($field,$value,$xeid){
$query = \Drupal::entityQuery('node')
->condition('status', 1)
->condition('type', 'CONTENT_TYPE_NAME')
->condition('nid', $xeid,"<>")
->condition($field,$value,">=");
$nids = $query->execute();
foreach ($nids as $nid) {
$node = \Drupal\node\Entity\Node::load($nid);
//or
//$node = \Drupal::entityTypeManager()->getStorage("node")->load($nid);
$old_value = $node->{$field}->value;
$old_value++;
$node->{$field}->value = $old_value;
$node->save();
}
}
Ce code fonctionne avec mais a un problème. Tous les nœuds mis à jour par programmation appellent à nouveau entity_presave et provoquent une boucle infinie.
Je n'ai pas trouvé de moyen de mettre à jour la valeur du champ sans appeler node->save()
s'il y a un moyen, veuillez me le faire savoir (je sais qu'il y avait un moyen de drupal 7 field_attach_update
Qui est obsolète à partir de 8.0.x je pense)
Existe-t-il un moyen d'appeler node->save()
sans provoquer hook_entity_presave
?
ou alternativelly quelles vérifications puis-je faire dans le hook_entity_presave
pour savoir si le champ vient d'être mis à jour par programme et non depuis la modification par l'utilisateur?
Je pense avoir trouvé une solution simple
ajouter un message de révision avec une chaîne UNIQUE avant d'enregistrer le nœud
//...
$node->setNewRevision(TRUE);
$node->revision_log->value = "AUTOMATED-UPDATE ". $field." incremented to ".$old_value ;
$node->save();
vérifier le hook_entity_presave
que la révision n'a pas été AUTOMATISÉE en vérifiant dans le journal notre chaîne UNIQUE
if ($entity->getEntityType()->id() == 'node') {
$log = $entity->revision_log->value;
if( substr( $log, 0, 16 ) === "AUTOMATED-UPDATE" )
return;
...