Problem/Motivation
Creating a duplicate of a content entity does not reset the default revision flag. That's not initially a problem as a new entity is enforced to be a default revision, but if you duplicate and then save an entity twice, extremely weird things happen because only the revision table is updated.
While this may sound like a weird thing to do, it is happening for us in context of paragraphs for example, where we had troubles when a paragraph was saved as non-default but not actually as a new revision.
The reason for that is that \Drupal\content_moderation\EntityTypeInfo::entityPrepareForm() switches the entity into a non-default revision (I don't really understand why, but that's a different topic), and then ERR ensures that all referenced paragraphs are in a non-default revision as well, then they are stored in form state. When you then duplicate a paragraph and change it at the same time, it does properly persist the changes. See #3198091: Changes of newly replicated Paragraphs are not saved. There is more going on there, but I think this change makes sense to do anyway.
Funny enough, we already "fixed" this in #2850022: Duplicating a non-default revision should produce a default revision for a newly created entity and we have a test for it: \Drupal\KernelTests\Core\Entity\EntityDuplicateTest::testDuplicateNonDefaultRevision. But we fixed it by checking isNew() in the isDefaultRevision() method, so the double save edge case is not covered yet.
Steps to reproduce
Proposed resolution
Remaining tasks
Extend the test by changing the saved entity again and resaving it.
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | 3220784-19.default-revision.patch | 2.66 KB | dww |
| #5 | 3220784-default-revision-duplicate-5-test-only.patch | 1.89 KB | johnchque |
Issue fork drupal-3220784
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 #2
berdirOh, even weirder. The test already does save multiple times, but only tests with a base field. The bug that we see with paragraphs happens only with configurable fields, because dedicated table *reads* are different.
Drupal reads base fields also from the revision table too, and since that is updated, the test is happy. But if actually check the database, you can see that the base table has _not_ been updated in that test.
I made the test more explicit by checking the new/default revision flags explicitly and also doing an entity query to check the base table values.
Comment #3
berdirI wonder if we can somehow detect if you attempt to save the default revision as not-the-default revision and throw an exception then or something because that is not a valid thing to do.
Comment #5
johnchqueAdding access check.
Comment #10
smustgrave commentedtriggering D10 tests
Comment #11
smustgrave commentedTests pass D10
The tests do an excellent job showing the issue.
Comment #12
quietone commenteds/and/and the/
I am not following the second sentence. That a new entity, once saved is no longer the default revision? Then what is the default revision for a newly saved entity?
Let's get this testing on a supported version of Drupal.
Comment #14
berdir> I am not following the second sentence. That a new entity, once saved is no longer the default revision? Then what is the default revision for a newly saved entity?
That's the point, there is no default revision anymore the in the loaded entity object.
The override that it is the default revision is transient and goes away as soon as it's saved:
So if it's unsaved, it's always default, but as soon as isNew() returns FALSE, it suddenly might no longer be, and if you save it again, you end up with an invalid state.
Comment #15
mathilde_dumond commentedI tried to rephrase the comment.
Comment #16
mathilde_dumond commentedoy sorry about the patch name, the .patch is not an interdiff
Comment #17
quietone commented@Berdir asked me in #contribute to review the comment. I still found it hard to follow, and in some ways the changes made it harder. I chatted with Berdir and he kindly explained what was happening. I now 'get it' and think the original comment make sense.
I am re-uploading the patch in #5 and testing with 11.x.
Sorry for delaying this!
Comment #18
quietone commentedThe patch I read and commented on in #12 was RTBC. That is the patch I re-uploaded. Since it is passing tests and there has been no changes to the patch, I am restoring the RTBC.
Comment #19
dwwThanks for opening this, and fixing it!
However, #17's duplicate of #5 didn't fix the first (valid) point from #12. Leaving RTBC since it's a trivial comment nit. Interdiff also seems a bit confused, and is showing a bigger change than I actually made, which is just:
Comment #22
berdir> I wonder if we can somehow detect if you attempt to save the default revision as not-the-default revision and throw an exception then or something because that is not a valid thing to do.
good thinking, past-me! current-me discovered this again and opened an issue for it: #3499181: Disallow saving the current default revision as a non-default revision. This is blocking that now.
This was RTBC and somehow fell off the bandwagon, lets try to finalize it. Still applies, not sure why it was needs work, random fail maybe?
Comment #23
berdirMerge request is green and identical to the patch that was RTBC.
Not sure if we want to keep the explicit test coverage with the direct query, as with the issue that this is blocking, saving would result in an exception instead, we're kind of testing that issue, not this.
Comment #28
catchLet's add the test coverage here and then consider modifying it in the other issue if we need to.
Committed/pushed to 11.x and cherry-picked to 11.1.x, 10.5.x, 10.4.x, thanks!