Problem/Motivation
Similar to #2699085: Lock Panels IPE when a user has made TempStore changes, the section storage needs to have multiple versions of itself stored in TempStore.
Putting this additional information into getStorageId() would change a lot of other logic in places, as well as all of the URLs.
Proposed resolution
Introduce a separate interface to be able to provide a more granular ID
There is no functional change to Layout Builder at this moment, but this patch blocks the work done in #2946333: Allow synced Layout override Translations: translating labels and inline blocks and enables the benefits of #3004536: Move the Layout Builder UI into an entity form for better integration with other content authoring modules and core features to be realized.
Remaining tasks
N/A
User interface changes
N/A
API changes
Add a new interface (marked @internal) TempStoreIdentifierInterface
This could live upstream and has a follow-up issue referenced via an @todo: #3026957: Provide a generic TempStoreIdentifierInterface that any object can use to better identify itself
SectionStorageBase implements this interface, and all other SectionStorage plugins that do not implement the new interface on their own or via SectionStorageBase will continue to work as expected.
Data model changes
N/A
Release notes snippet
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #38 | 3026698-tempstore-38.patch | 19.59 KB | tim.plunkett |
| #38 | 3026698-tempstore-38-interdiff.txt | 1.71 KB | tim.plunkett |
| #37 | 3026698-tempstore-37-interdiff.txt | 893 bytes | tim.plunkett |
| #37 | 3026698-tempstore-37.patch | 19.46 KB | tim.plunkett |
| #32 | 3026698-tempstore-32-interdiff.txt | 2.04 KB | tim.plunkett |
Comments
Comment #2
tim.plunkettComment #3
tedbowThis seems like a good ID and could be used in
If we want as much of information as possible should just include now as much information as we have. So add view_mode now even though it won't vary by that now.
That way if we add that in the future an in process tempstore would still work.
Do. Do we add @internal but note that it could be put in another namespace. I could see this being useful in other situations.
Comment #4
tim.plunkett1) Fixed
2) Opened #3026957: Provide a generic TempStoreIdentifierInterface that any object can use to better identify itself and included an @todo.
Comment #5
kristen polI reviewed that the Id => Key in the interdiff but it probably makes sense for @tedbow to have a look. Is there any way to manually test this?
Comment #6
tim.plunkettActually the bug you hit in #3028821-7: Layout builder doesn't redirect properly to the translation might be a way to test this...
Comment #7
kristen polI'm still seeing the bug from https://www.drupal.org/project/drupal/issues/3028821#comment-12945393 with patch from #4.
Comment #8
tim.plunkettI wasn't sure that this would fix that bug completely. I think a better way to test this would be to make (but not save) an override in English, and then make (but not save) an override in any other language, and be sure that changes you make to the temporary copy in one language do not affect the temporary copy for the other language.
Here's a reroll.
Comment #9
kristen polOk, I created but didn't save layout changes in English. When going to French URL as same user then it shows the changes that were made in English (without saving). If I added to French layout and not save and then reload the English URL as same user then I see the French changes.
Back to "Needs work".
Comment #10
tim.plunkettHmm, this doesn't do anything functionally visible without #3004536: Move the Layout Builder UI into an entity form for better integration with other content authoring modules and core features. Sorry for the confusion. But applying that patch (conflicts only on
usestatements) allows this to be tested.Alternately, it can be seen in the
key_value_expiretable of the DB that the language is applied to the tempstore key...Comment #11
tim.plunkettUpdated the IS and bumping to major
Comment #12
tedbowIssue summary looks good.
the problems documented in #9 will be addressed in #2946333: Allow synced Layout override Translations: translating labels and inline blocks which this patch helps
Comment #13
xjmI think this needs an upgrade path of some sort; when I applied the patch to my site and cleared caches with an existing LB tempstore I got some really weird results (a persistent message about the layout being locked that would not go away no matter how many times I saved the layout as the owner or tried to break the lock as the other user).
Comment #14
xjm(FWIW I was testing the patch together with #3025231: Concurrent editing of layouts is very confusing so that the tempstore actually worked in the first place.)
Comment #15
tim.plunkettThis only happens in conjunction with that issue. This is safe to commit on it's own, or should be NW'd if the other one goes in first.
Comment #16
xjmNo, I don't think it's OK on its own either... it's still causing the tempstore data to be effectively lost. STR:
admin/structure/types/manage/article/display. Check "Use Layout Builder" and "Allow each content item to have its layout customized." Save.A tempstore is not a cache; it is actual stored data from user input that is supposed to persist (for a week in this case) and cannot be regenerated. So I still think it needs either an upgrade path, or some sort of fallback to allow it to find the old tempstores. Furthermore, even though #3026698: Allow section storage to provide a more granular ID for tempstore is not committed yet, the persistent "break lock" message that's impossible to get rid of does demonstrate that the data integrity problem, which may also be surfaced in other ways we haven't thought of as well, including with contrib or custom code that interacts with this tempstore.
@tim.plunkett contended that we don't need an upgrade path for data in
key_value_expirethat only persists for 7 days. However, I think we do need to do something for this issue, because it still is a data integrity problem for those 7 days. I'll ask other committers what they think.Comment #17
tim.plunkettHere's an update path and test.
Comment #18
tim.plunkettProtecting against non-reproducible theoretical issues, but why not.
See #3031130: \Drupal\Core\KeyValueStore\MemoryStorage::rename() erases data if keys match
DatabaseStorage is used during functional tests and in runtime, so it's irrelevant here.
Comment #20
kristen polShould this be manually tested again?
Comment #21
tim.plunkettThis fix in this issue cannot be manually tested. The update path can: start an override on a nice but do not save, apply the patch, note that your in-progress work is missing, run the DB update, see your work has returned
Comment #22
phenaproximaWalked through the patch and discussed with @tim.plunkett. I think everything here makes perfect sense. RTBC!
Comment #23
tim.plunkettAfter discussion with @xjm, this needs both an inline comment and an explicit test
Comment #24
tim.plunkettI structured the code like this so that the @todo is clearly only for the workaround line, and the comment with the fix is a separate line.
Comment #25
phenaproximaInline comment is helpful and the test makes sense to me. RTBC when Christmas arrives.
Comment #27
tim.plunkettConflict on a recent commit also adding a post_update hook to the end of the file...
Straight reroll.
Comment #28
tim.plunkettSame thing, but again
Comment #30
tim.plunkettComment #31
xjmSo the update path fixes the data integrity problem. My data is safely there after I run
update.php.However, the "You have unsaved changes" message disappears from in-progress overrides.
For more fun, when this is combined with #3025231: Concurrent editing of layouts is very confusing, there are no warnings about unsaved changes nor any "break this lock" messages. So essentially, when someone updates to 8.7.0 with both these changes, the fix for #3025231: Concurrent editing of layouts is very confusing takes seven days to take effect. 😂
@tim.plunkett is looking into this. Setting NR for discussion.
Comment #32
tim.plunkettThis line (plus the update path) is what prevents the data loss.
LB assumes
full, but in a stock Drupal install the view mode will actually bedefault.However, this needs to be reflected within the temporary section storage itself. Otherwise we get the correct data, but the UI doesn't recognize the temporary override and doesn't show the message.
Since one of the changes was to a file git considers "binary", this isn't visible in the patch.
I changed
s:7:"default";to
s:4:"full";for the tempstore's section storage view mode. This represents the mismatch that @xjm was hitting (and that I was able to reproduce).
The FAIL patch is the previous patch plus that fixture change without the change in the interdiff.
Comment #35
tim.plunkettFAIL patch worked as expected:
Random OffCanvas fail on PATCH, retesting.
Comment #36
xjmGood BC all around here.
Another "why am I @internal?" here.
Comment #37
tim.plunkettFixed #37.2
Comment #38
tim.plunkett@tedbow ran into an issue when you start using Layout Builder after updating to the new code but before running update.php
He, @xjm, and I collaborated on a fix.
I attempted to write coverage for this, but it is not really possible. We agreed that the fix was sufficient and thoroughly manually tested.
Interdiff was made with
-wfor reviewabilityComment #41
tedbowThis looks good. I manually tested it and it works good now.
Comment #43
xjmCommitted and pushed to 8.7.x. Thanks!
Comment #44
tacituseu commentedTest introduced here hit something on PHP 7.3.x:
https://www.drupal.org/pift-ci-job/1201988
https://www.drupal.org/pift-ci-job/1202908
Comment #45
tim.plunkettLooks like a bug in 7.3: https://bugs.php.net/bug.php?id=77302
Symfony hit it as well: https://github.com/symfony/symfony/issues/29459
Seems there was a problem with the way I manipulated the serialized string.
calling
serialize(unserialize($string))on it has changed the value.Opened #3033691: Serialized Layout Builder fixture is invalid in PHP 7.3 to fix this