Problem/Motivation
When cloning a new paragraph containing nested paragraph child(s), the original and cloned paragraphs point to the same child entity after the node save.
Steps to reproduce
1. Go to https://simplytest.me
2. Launch a site using Paragraphs 8.x-1.x-dev
3. Create 2 new paragraph types, a) Text containing a text field and b) Section containing a paragraph reference field of Text
4. Update the Basic page content type to contain a Content field that's a paragraph reference field of Section
5. Add a new Basic page
6. Add some text to the first Section > Text, e.g. "Hello World"
7. Now click on the "..." of the Section and click "Duplicate"
8. Update the text of cloned Section > Text to something else, e.g. "Hello World2"
9. Save the node
10. Both text will display "Hello World2"
Proposed resolution
In this issue: https://www.drupal.org/project/paragraphs/issues/3495373
A new condition !$item->entity->isNew() was introduced to prevent nested paragraphs from being cloned in this scenario. However, I'm uncertain about the original intent behind this change, so I can't suggest a solution at this stage.
Issue fork paragraphs-3510842
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:
- 3510842-cloning_nested_paragraph_creates_shared_child_reference
changes, plain diff MR !253
- cloning-nested-paragraph-3510842
changes, plain diff MR !202
- paragraph-nested-any-entity-3510842
changes, plain diff MR !201
- unsaved-nested-paragraphs-3510842
changes, plain diff MR !199 /
changes, plain diff MR !200
Comments
Comment #2
arunsahijpal commentedComment #4
arunsahijpal commentedHi @peterwcm,
I've updated the createDuplicate method please check.
Also @berdir pls check is this a good solution?
Thanks,
Arun
Comment #5
peterwcm commentedHi @arunsahijpal,
Thanks for working on this. The patch fixes the issue, but it causes orphaned paragraphs to be created before users save the node. I think there could be issues with translations as well.
I'm puzzled about the
!$item->entity->isNew()condition, as it seemed to work fine without it before. Could we consider removing that condition instead? @berdirRegards
Peter
Comment #6
arunsahijpal commented@peterwcm,
I've updated the code and now no more orphaned paragraphs and everything saves when the node saves by referencing the entity directly instead of manually setting target_id.
and I also think this condition
!$item->entity->isNew()is not necessary.For the translation thing there is one limitation that - Paragraphs are referenced entities, not simple text fields.
Drupal does not natively support translating entity reference fields.
When I tried to translate it shows this error
. Yo can checkout this link for more info .
I think there is one tot check translation with Paragraphs Library module but I'm not sure.
Could you pls check it, if it works then I think we can safely remove that condition.
Comment #7
peterwcm commentedHi @arunsahijpal,
Thanks for addressing this so quickly.
I just did some quick tests, and the latest patch has fixed the issues.
Comment #10
berdirThe check is in preparation for the new hook in Drupal 11.2 to avoid additional duplication. The changes remove the relevant todo and there is no test coverage for the bug that this seems to fix.
We have fairly extensive duplication tests, if there is a bug then that should be covered by tests.
Comment #11
dxvargas commentedThis problem is not happening when using drupal core 11.2 In this case, the
\Drupal\paragraphs\Hook\EntityHooks::duplicateis doing the job.@peterwcm, @arunsahijpal can you please tell us if you're using a version of drupal prior to 11.2?
Comment #12
dxvargas commentedStill, I want to confirm that there is a bug when using Drupal core prior to 11.2 (when the new hook "entity_duplicate" is not run).
It happens when we duplicate a new introduced paragraph (with nested paragraphs).
In that case the new condition
!$item->entity->isNew()is FALSE and the nested paragraphs are not duplicated. They end up being used in the original and in the duplicated paragraph.Sorry that I can't provide a test ATM.
Just removing the new condition
!$item->entity->isNew()fixes this.Comment #13
peterwcm commentedHi @dxvargas,
Yes, we are now using Drupal 10.4.6. I couldn't remember the version I tested when using simplytest.me, but looking at the options, it would also be prior to Drupal 11.
Comment #16
vikramsaini1609 commentedI am not able to add the https://www.drupal.org/project/paragraphs/issues/3079729 patch with this patch. Instead of writing whole function
createDuplicate(). Can we simply remove the!$item->entity->isNew()condition line?Comment #29
herved commentedPer #11-12, what about centralizing code then?
Update \Drupal\paragraphs\Entity\Paragraph::createDuplicate to something like
Then it's clear that this code can be removed once <11.2 is no longer supported.
Comment #30
mediabounds commentedI tried the suggestion in #29—I had to manually instantiate the class since it is not a service, but it resolved the problem we were having with duplicated child references (as of paragraphs 1.19.0 in Drupal 10.5).
Here's the full implementation of createDuplicate we're using:
Comment #31
andreasderijckeI've updated the issue title and description to emphasize the fact that the paragraph that is being cloned must be new aka not yet saved to the database.
This detail eluded myself and predecessor looking into this issue in some projects, making us doubt if the proposed patch here would fix our issue.
Without the patch, when cloning a new nested paragraph, the respective child paragraphs will be created as different revision of the same paragraph, each referring to different parent paragraph.
You can verify this when comparing the records in paragraphs_item_field_data table versus paragraphs_item_revision_field_data for given node and parent paragraphs.
With patch, you can see each child paragraph being created as separate entities.
Comment #32
andreasderijckeAlso, after more testing, we noticed issues when the nested paragraphs contained entity reference fields to Media, and in our case Bynder Media.
In the duplicates, the Media references disappeared saving the cloned paragraphs with the patch applied.
I didn't debug what happens in de creatDuplicate function, but it made sense that entity references to anything other than the (child) paragraphs, should not be duplicated (like nodes, users, terms,...).
For our project scope, an additional check on the entity being a paragraph, fixed the unwanted side behaviour:
After checking the entity_duplicate hook, it seems that the if above could be the same as https://git.drupalcode.org/project/paragraphs/-/blob/8.x-1.x/src/Hook/En... (same check, just different way to do it and actually prefer the 'instance of' approach).
Comment #33
berdirAre you on D10? Per recent comments, this should not happen on D11.2+, nor should it happen when using the replicate module.
The MR is definitely not correct and should not be used. Feel free to create a new MR with the proposal from #29/#30 as a workaround for sites stuck on older core versions.
Comment #34
herved commentedFor #30 the
EntityHooksclass can be registered as service, see #3079729: Remove file on original/duplicated paragraph removes the file on all original/duplicated paragraphs's MR for example.