1

How can I update the value of the field in the nodes while save/update the node? When you save/update the node value from the field was taken and save in the same field in the other nodes. I tried to do it hook_ENTITY_TYPE_presave()

$nodes = Node::loadMultiple($nids);
foreach ($nodes as $node) {
  $node->set('name_field', $value);
  $node->save();
}

But this causes infinite recursion

1
  • 1
    It’s recursion error because you’re calling save within a presave hook which triggers the event again, infinitely.
    – Kevin
    Dec 10, 2017 at 3:31

4 Answers 4

2

You can use hook_entity_presave

function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {

    if ($entity->getEntityTypeId()=='node'){
        $value="099545";
        $entity->set('name_field', $value);
    }
}
2
  • They're already using this basically, with hook_node_presave(), right?
    – Kevin
    Dec 11, 2017 at 19:16
  • hook_ENTITY_TYPE_presave() is an implementation of hook_entity_presave() that is invoked only for a specific entity type, so what @Kevin says is correct.
    – apaderno
    Dec 10, 2018 at 9:20
0

Your code should be called only for the current node and only once. If you avoid calling your code snippet when its for the other nodes then you won't have any problem.

Since you are in presave hook You can wrap your code with the condition to be sure you only run the code for one node (Which suppose to contain the reference - $nids ) not for each node you want to change.

The condition can be the node type if the node you loaded has a different type from the nodes you want to update. I wrote example code how you can avoid that, I assume '$nids'contain the nodes ID's you want to update without the main node id which contains the reference for other nodes.

You can also avoid the whole loop by adding a small condition to be sure no recursion happened.

    if (!in_array($entity->id(), $nids){
      $nodes = Node::loadMultiple($nids);
      foreach ($nodes as $node) {
        $node->set('name_field', $value);
        $node->save();
      }
    }

Also another suggestion, you can add a custom submit handler for node add/edit form and you can do whatever you want in your handler create/update other nodes.

2
  • I think the best option is likely skipping it in the foreach or removing it from the $nids array. Wrapping the whole Node:loadMultiple changes the logic entirely.
    – rooby
    Dec 11, 2017 at 11:57
  • this more depends on the logic he has.
    – Ziftman
    Dec 12, 2017 at 15:57
0

You can use hook_ENTITY_TYPE_presave

use Drupal\node\NodeInterface;

function mymodule_node_presave(NodeInterface $node) {
  $node->set('name_field', $value');
}

Here no need to load node.

0

If that is the code executed in hook_ENTITY_TYPE_presave() there are two errors.

  • The parameter given to the hook is a single entity; it doesn't get an array of entity IDs

  • A hook_ENTITY_TYPE_presave() implementation cannot save any entity of the type it handles, since that would cause that hook to be invoked again, and since the hook saves an entity, it would cause an infinite loop

If you are updating nodes that are associated in someway to the updated one, it's better to implement hook_cron() to check those nodes that have been saved, and change the associated nodes.

Otherwise, if you are just trying to update the node that has been updated, you just need to use the following code.

use Drupal\node\NodeInterface;

function mymodule_node_presave(NodeInterface $node) {
  $node->set('name_field', $value');
}

Don't call $node->save(), which would cause the infinite loop, and it would not make sense, since the entity is going to be saved. (The hook is invoked before the entity is saved.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.