Hi everyone!

When a paragraph gets duplicated it creates new entities with the same values, thus duplicating entities correctly. But for files, which may be inside those entities, there is no duplication of the file, in this case, all duplicate FileItems are referencing the same physical file. which causes an unusual behavior when a user deletes the file, then at the next rebuild of the form the files on the other paragraphs which are referencing the same file will also disappear.

Steps to reproduce the bug:

  1. Create a paragraph type with a file field.
  2. On the form display of the paragraph set the experimental widget and allow the user to duplicate the paragraph.
  3. Assign that paragraph to an entity that you can edit, like node type.
  4. Go to node/add/[node-type] to be able to create a new paragraph instance
  5. Upload a file to the paragraph instance
  6. Duplicate the paragraph instance
  7. Duplicate the paragraph instance (optional)
  8. Remove only one file from one of the duplicated paragraphs
  9. Duplicate any paragraph
  10. All files from duplicated paragraphs are gone.

I will soon upload a patch that I've been working to fix this issue.

Issue fork paragraphs-3079729

Command icon 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

BetoAveiga created an issue. See original summary.

betoaveiga’s picture

betoaveiga’s picture

I need to work more on my previous patch, it has a typo and also if I correct the typo then it is not working for deeper structures.
Just in case don't use the previous patch.

betoaveiga’s picture

This patch corrects the typo from the previous patch.
Also, it does a more generic way of checking for files inside a paragraph, by checking "Drupal\file\Plugin\Field\FieldType\FileFieldItemList" class, and when generates the file, it gets the correct upload destination.

andrew.martin’s picture

Status: Active » Closed (cannot reproduce)

The patch fails with recent versions of the module. After investigating to see if the behavior still existed, or if we'd need to re-roll the patch, it would appear that this bug has already been resolved. The steps to reproduce above no longer work, at step 10, only the image that was removed is gone - the rest remain.

vikramsaini1609’s picture

Version: 8.x-1.8 » 8.x-1.9
Status: Closed (cannot reproduce) » Active

Step to reproduce

  1. Create a paragraph with an image field.
  2. Add the paragraph to a node.
  3. Upload an image to the paragraph's image field.
  4. Before saving, duplicate the paragraph.
  5. Remove the image from the duplicated paragraph's image field.
  6. Save the node.
  7. You will notice that the image is also removed from the original paragraph.

vikramsaini1609 changed the visibility of the branch 3079729-remove-file-on to hidden.

vikramsaini1609 changed the visibility of the branch 3079729- to active.

herved’s picture

Noticed the same with layout_paragraphs, D11.2 added a hook to react on entity clone in #3040556: It is not possible to react to an entity being duplicated
Maybe we should leverage this? OTOH it would not solve it for sites <11.2 :\
So the changes in the MR seem to make sense to me, but I did not check in detail.

saidatom made their first commit to this issue’s fork.

saidatom’s picture

saidatom’s picture

Status: Active » Needs review

saidatom’s picture

Status: Needs review » Reviewed & tested by the community

Looks good move to RTBC.

berdir’s picture

Status: Reviewed & tested by the community » Needs work

Tests conflict.

I don't see this is our responsibility. Files are mostly hidden entities, if you delete them then they are gone, I don't think you can even do that in core in the UI. Why would this be different for paragraphs than for files on duplicates notes, blocks or any other entity?

herved’s picture

#30 This issue happens when a user duplicates a paragraph that contains a file field and then removes a file reference in one of the paragraphs in the form (so not really the file entity itself).

This is most probably not restricted to paragraphs though. Maybe now that hook_entity_duplicate is here (https://www.drupal.org/node/3268812) the file module should implement this logic.

berdir’s picture

Something doesn't add up to me. Can you try to reproduce with a duplicated node? Does it happen if you duplicate a node with a paragraph with a file? Maybe it's just a UI/widget but when the same file is used multiple times on the same page? I'm aware of similar bugs with entity browser that should be mostly fixed at this point.

That would be a core bug in the file widget or even file element then.

Files have built-in usage management, they are explicitly designed to be reused (although these days mostly through media entities) and deleted only if all usages are removed, including old revisions. Duplicating the file leads to duplication and extra disk usage

berdir’s picture

One way to figure out if is just a widget problem would be to use the closed + autoclose mode, so that you always only see one file widget. If the problem can't be reproduced like that then I am almost certain the problem somewhere in the form handling around file element/widget.

herved’s picture

#32-33, you're right, I'm using layout_paragraphs, I need to investigate what's going on.

alorenc made their first commit to this issue’s fork.

herved’s picture

I created a branch 3079729-test-only with a test proving the bug. The IS is still accurate.

The problem is \Drupal\file\Element\ManagedFile::submit that deletes the file as soon as we click on the remove button:

// If it's a temporary file we can safely remove it immediately,
// otherwise it's up to the implementing module to remove usages of
// files to have them removed.
if ($element['#files'][$fid] && $element['#files'][$fid]->isTemporary()) {
  $element['#files'][$fid]->delete();
}

Commenting that code makes the test pass.
That code does not account for paragraphs duplication.
Since the parent entity doesn't exist yet, we cannot rely on file usage.
I assume removing that deletion from core and deferring to cron is not safe either as it would allow a malicious user to flood the server with temporary files that only get cleaned up hours later.
So it's a tricky issue... Any ideas?

dimilias’s picture

For the record, putting here something that we discussed in chat.
Not deleting files on removal is a no go as a security concern. Because I can remove and add new files back and forth and fill in the space in the server.

My idea would be that the paragraphs duplicate mechanism have some sort of way to duplicate the actual files in order to ensure that files will not be lost between paragraphs, but maybe have the paragraphs reference or the entity itself, track somehow the duplicated files.
Then, on save, those that refer duplicated files, will all share the initial one.

However, that is a theory, it involves storing sub-entity references and duplicating the file_usage table functionality but in memory.. I don't even know if it is worth :/
The simpler idea would be to assume that paragraphs always duplicate files when clicking duplicate.