Problem/Motivation
In testing workspaces, I found the following issue:
- Enable workspaces, standard profile.
- Create an article with title and body, "foo".
- Switch to the stage workspace.
- Update both the title and body to "bar".
- Deploy the stage workspace, switch back to the live workspace.
- The article will contain title "bar" but body will remain "foo.
This is caused by:
WorkspacePublisher::publishloads the entity, sets it as the default revision and saves it.EntityStorageBase::doPreSavesees that no $entity->original exists, so it loads the default entity usingloadUnchanged.- Workspaces detects an entity is being loaded and swaps the default entity with the latest entity in the active workspace.
- Both
$entity->originaland $entity are the same and thusContentEntityStorageBase::hasFieldValueChangedreturnsFALSEand fails to write to the shared entity tables.
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | 2998414-14.patch | 7.08 KB | sam152 |
| #14 | interdiff.txt | 2.22 KB | sam152 |
| #12 | 2998414-12.patch | 7.03 KB | sam152 |
| #8 | 2998414-COMBINED-7.patch | 11.92 KB | sam152 |
| #8 | 2998414-REVIEW_ONLY-7.patch | 4.27 KB | sam152 |
Comments
Comment #2
sam152 commentedNot sure what the fix for this is yet, seeing if I can reproduce this in a test.
Comment #3
sam152 commentedI've dug into this and can confirm the body field doesn't update because in
ContentEntityStorageBase::hasFieldValueChanged$original->body === $entity->body. Then the following code inEntityStorageBase::doPreSaveruns:Which workspaces subsequently alters and replaces with the latest revision in the current workspace. So
$entity->originalis no longer the default revision that is the target of the update, the the same revision that is being saved.Adding some related issues, since they related to assumptions about
$entity->originaland its use inhasFieldValueChanged.Comment #4
sam152 commentedComment #5
sam152 commentedTest case for this issue.
Comment #6
sam152 commentedUpdating IS with a summary of the root cause.
Comment #8
sam152 commentedHere is a fix blocked behind #2968452: Add a way to execute a function in the context of a specific workspace. I can't think of a better way of handling this, without completely rethinking
$entity->originaland removing the importance of this when entities are persisted. This way it's set to the revision we are updating from, in the context of the workspace we are targeting in a publish, not the active workspace.Comment #10
amateescu commentedJust now I realize what @FabianX was trying to tell me a few months ago (probably in the issue where the new core module was introduced) :)
I think it would be better if we wrap the whole piece of code inside the first
foreachto be executed in the context of the live workspace, that will make thesave()process think that it's being done in Live, and there won't be any other code trying to interfere with entity loading.Also, as a performance improvement, we can also do a multiple (default revision) load for the entity IDs that are about to be saved and assign the
originalproperty ourselves, just like the latest patch does.Comment #11
sam152 commentedThanks for the review!
Works for me. May as well wait for the blocker to be in before making those adjustments.
Comment #12
sam152 commentedAddressing feedback now that the blocker is in. Assigning
$entity->originalis purely a performance optimisation as you suggest, the tests pass without it.Comment #13
amateescu commentedLooks great!
This comment needs to be re-wrapped.
Just a cosmetic request: let's use different values for the title and the body field, like 'Foo title' and 'Foo body' :)
Comment #14
sam152 commentedDone and done :)
Comment #15
amateescu commentedAwesome!
Comment #17
catchCommitted/pushed to 8.7.x, thanks!