I'm looking to modify the values within the paragraphs of a cloned node before cloning.
I notice if I clone an entity, I can use my own event subscriber to subscribe to EntityCloneEvents::PRE_CLONE and EntityCloneEvents::POST_CLONE. This works great to modify fields on the cloned entity itself.
The dispatch code in EntityCloneForm::submitForm() handles this nicely:
$duplicate = $this->entity->createDuplicate();
$this->eventDispatcher->dispatch(EntityCloneEvents::PRE_CLONE, new EntityCloneEvent($this->entity, $duplicate, $properties));
$cloned_entity = $entity_clone_handler->cloneEntity($this->entity, $duplicate, $properties);
$this->eventDispatcher->dispatch(EntityCloneEvents::POST_CLONE, new EntityCloneEvent($this->entity, $duplicate, $properties));
However, if the cloned entity has referenced entities (say, a paragraph), the event subscriber isn't fired. This code, in ContentEntityCloneBase::cloneReferencedEntities, doesn't have the event dispatch code:
$cloned_reference = $referenced_entity->createDuplicate();
/** @var \Drupal\entity_clone\EntityClone\EntityCloneInterface $entity_clone_handler */
$entity_clone_handler = $this->entityTypeManager->getHandler($referenced_entity->getEntityTypeId(), 'entity_clone');
$entity_clone_handler->cloneEntity($referenced_entity, $cloned_reference, $child_properties['children'], $already_cloned);
It looks like ContentEntityCloneBase doesn't easily inherit EntityCloneForm's EventDispacher, so it's not easy to add these extra PRE_CLONE and POST_CLONE lines there.
I could try to write up a quick patch for this, but am worried about how this eventDispatcher should best be passed down to the recursive levels and am hoping to get a little guidance.
Can eventDispatcher be passed as a parameter from EntityCloneForm:::submitForm() down to ContentEntityCloneBase::cloneEntity()? Or is there a more elegant way to pass that event dispatcher around the cloning process?
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | 3058025-15-move-preclonepostclone-event-dispatcher-2.0.0-beta4.patch | 6.79 KB | jaydip makawana |
Issue fork entity_clone-3058025
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
dieterholvoet commentedComment #5
sumit saini commentedRerolling patch for 2.x branch and 2.0.0-alpha1
Comment #6
sumit saini commentedAttaching interdiff for patches in #5
Comment #7
dieterholvoet commentedWe're working with a MR here, no patches. I'll rebase the MR against 2.x.
Comment #9
nitin shirole commentedRerolling patch for 2.x branch and 2.0.0-beta2
Comment #10
nitin shirole commentedComment #11
dieterholvoet commentedWe're working with a MR here, no patches.
Comment #12
nitin shirole commentedPatch rerolled for 2.x branch and 2.0.0-beta2
Comment #13
dieterholvoet commentedDid you not read the comment I just posted? We're working with a MR here, no patches. This is the third time I’ve had to say this in this issue, please stop re-rolling patches.
Comment #14
sumit saini commentedWith this patch/fix, the hooks are firing for the cloned referenced entities also. Using this fix on a site without any issue so, changing status to RTBC.
Can a new tag be released including this fix?
Comment #15
jaydip makawana commentedWe are waiting this changes to be release since long. We must have to upgrade the latest release of this module on our site. Hence created patch.
Comment #17
rajeshreeputraTest fails with latest code, not sure, if we add this in 2.x. Reverted the merge.
Comment #18
rajeshreeputraComment #20
rajeshreeputraComment #21
sumit saini commentedThis issue seems to address same problem as #3089105: When cloneReferencedEntities is called it should dispatch events (other issue patch also includes tests). Maybe we can close this as duplicate of #3089105.
Comment #24
jonathanshawI believe the approach here is better than #3089105: When cloneReferencedEntities is called it should dispatch events therefore I have closed that one as a duplicate.
What's better about the approach here is that is moves the events into the cloneEntity method, whereas the other approach keeps the events in the form, but also calls them when cloning child entities. The approach here avoids complicating the code base, and keeps in the direction of seperating the API from the UI.
I've moved the test across from #3089105: When cloneReferencedEntities is called it should dispatch events and suggest maintainers credit contributors to that issue.
I think this MR may have caused tests to fail previously when it was committed becaue it was buggy: in the committed version the pre-clone event dispatching was both left in the form and moved into the handler, so the dispatch was duplicated.
Comment #27
dieterholvoet commentedI squashed some commits to make it easier to rebase this branch. The branch now applies to 2.x again.
Comment #28
ankitv18 commentedPhpunit tests are failing: https://git.drupalcode.org/issue/entity_clone-3058025/-/jobs/2022248#L81
Also pipeline should be green for every job( along with phpcs and phpstan) except phpunit next major as per the latest change in 2.x-dev
Comment #29
ankitv18 commentedComment #30
ankitv18 commentedComment #31
rowen92 commentedI think passing $already_cloned variable would be really useful for modifying.
What do you think?
At least for cases when some extra referenced entities might be cloned.
In the current implementation we aren't able to know inside an even subscriber if a referenced entity is already cloned or not.
Comment #32
rowen92 commentedAnd you guys are breaking current implementation of users which already use existing implementation of event dispatching.
I think you have to implement another type of event if you really want to have it dispatched for references.
Comment #33
jonathanshawI think you might be right, but possibly this would be better done in a follow-up as it would presumably change the event for all invocations, references or not.
I don't really understand why cloneEntity() gets called on an already cloned entity in the first place.
You're right that is a risk. I think the natural pattern developers woud expect is single event, called in both circumstances. So maybe the thing to do is to create a new event and deprecate the old one, so we're not left with 2 forever.
I'd like to see what the maintainers say about this.
Comment #34
rowen92 commentedRegarding passing $already_cloned array to EntityCloneEvent
I think it's possible without breaking any functionality.
See an example with an optional parameter.
EntityCloneEvent::__construct(...)
Adding getter and setter methods would be great as well.
Comment #35
jonathanshawI agree, my concern is more with DX, trying to explain to developers working with the event what this means, why it is set or not set in this or that circumstance.
Comment #36
pbonnefoi commentedMessage posted to the wrong issue