tldr; function updateEntityAlias() needs to validate that a path alias does not exist before creating it, even if $op = 'insert'.
PROBLEM
I was getting duplicate path alias entries for certain types of nodes.
WHAT I THINK HAPPENED
Pathauto uses hook_entity_insert() to trigger the creation of a path alias. Pathauto uses module_set_weight() to give itself a high weight so it's hook functions typically run after other modules.
Sequence of events:
-
mymodule_entity_insert() triggers:
- load the newly created node with \Drupal\node\Entity\Node::load()
- edit the newly created node
- save the node with \Drupal\node\Entity\Node::save()
- Node::save() returns SAVED_UPDATED
- pathauto_entity_update() executed. Path alias does not exist at this point so an alias gets created.
- pathauto_entity_insert() triggers and creates a (duplicate) path alias for the newly created node.
SOLUTION
I don't have a good solution for this problem. I solved it by making a new module called zz_run_last and gave it a weight of 9999. I moved my hook_entity_insert() and _update() there. Now, I don't see the duplicate path alias. I assume that this is b\c my hooks are running after the pathauto hooks.
I think the real solution is to re-evaluate the use of the $op parameter in updateEntityAlias(). Regardless of $op, check if the alias exists and only insert if none is found.
Comments
Comment #2
Dave ReidI don't believe that triggering an entity save from within the same entity's hook_entity_insert() is recommended, because that is recursive. Is it possible you can make your necessary modifications to the entity using hook_entity_presave() instead, which would avoid needing to save it?
Comment #3
PratikshaD CreditAttribution: PratikshaD as a volunteer and commentedDuplicate alias issue resolved if I choose "update action" to "create a new alias and delete the old one".
Comment #4
ptmkenny CreditAttribution: ptmkenny commentedI'm having the same issue. I have the Update Action of Pathauto configured to "Create a new alias. Delete the old alias."
However, when I create a node, I get two duplicate aliases. If I update the node to change the alias, one of the two duplicate aliases will be deleted and replaced with a new one, but one of the duplicate aliases remains.
Why am I triggering an entity save within hook_entity_insert? Because I have a field that stores some HTML that is generated in hook_entity_presave(), and this HTML includes a link to the node. To generate a link to the node, I need to use the URL method, but this is not available on initial save, so I need to save the node upon insert so that the node is assigned a URL and my presave hook can use that in the second save.
This is an edge case, but I think this behavior of Pathauto should be considered a bug because it can result in duplicate aliases.