This is the code I am using.

function walk_handler_entity_presave(EntityInterface $entity) {
  if (method_exists($entity, 'getType') && $entity->getType() === 'walk') {
    $elements = [];

    $elements[] = [
      '#title' => 'This is a test',
      '#type' => 'textfield'

    $webform = Webform::create([
      'id' => 'walk_' . $entity->id(),
      'title' => 'Test',
      'elements' => Yaml::encode($elements),
      'settings' => Webform::getDefaultSettings()


Somehow, this hook will get triggered twice: once when the node is getting submitted, and another time when the webform is getting created. The result is that I'm getting an error about the Webform object not having a getType() method and this is why I'm using method_exists() in the condition.

I can't seem to find any hook that would only focus on nodes and not on webforms.

What other hook can I use to react to new nodes being created?


hook_entity_presave() is called for every entity being saved which means that, since that hook_entity_presave() implementation is saving an entity, it is being invoked twice.

Using method_exists() is generally wrong, as in PHP is generally preferable to check if the object is an instance of a class implementing an interface or a class extending another class.
In this case, it's also wrong because the code isn't supposed to run for every entity that has a getType() method, but just for nodes. (While nodes are the only Drupal core entities with that method, there could be entities implemented from third-party modules that define that method, possibly for different purposes.)

You should check the entity type as said from berramou or use hook_ENTITY_TYPE_presave() as said from No Sssweat.
Since the question is asking how to create a webform when a node is created, I would rather use hook_ENTITY_TYPE_insert() which is invoked:

  • Only when an entity is created, not when an entity is updated
  • After the entity has been saved in the storage

Using this hook has the benefit of not creating a new webform every time a node is edited. The implementation code is also simpler, as it doesn't require checking the webform is already created for that node.


hook_entity_presave() runs when any entity is inserted or saved; thus, it runs twice in your case, since you have a Node and a Webform entity being saved.

You would have to add a conditional to check the entity type as @berramou's answer suggests.

Alternatively, you could use hook_ENTITY_TYPE_presave() and target the node.

 * Implements hook_ENTITY_TYPE_presave()
function MODULE_NAME_node_presave(Drupal\node\NodeInterface $node) {
  // your code goes here

If you want the hook_entity_presave() to only focus on nodes and not on webforms, you can check the entity type like in the following code.

 * Implements hook_entity_presave().
function YourModule_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node') {
    // Do you webform creation code here 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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