Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
It seems that users have a local version of the form cached, so edits by other users disappear when they try to edit them.
Steps to reproduce:
1. User A creates a webform, adds fields, saves.
2. User B views the form node and sees the form
3. User B hits the 'webform' tab, adds another field, and saves.
4. User A refreshes the node view, sees the extra field User B has added.
5. User A hits the 'webform' tab. On the edit screen the field User B added does not appear!
6. If user A now hits save, the webform is updated and the field user B added is no longer there.
I hope that makes sense.
Comment | File | Size | Author |
---|---|---|---|
#19 | 2034543-form_builder-delete-cache-when-rendering-form_builder_interface-19.patch | 1.41 KB | torotil |
#16 | 2034543-16-hook_cron-delete-stale-cache-entries.patch | 563 bytes | torotil |
Comments
Comment #1
tripper54 CreditAttribution: tripper54 commentedOn further testing, if the user changes web browser (eg FF to chrome) they get the latest version of the form. So it must be a client side cached file that should expire but doesn't.
Comment #2
tripper54 CreditAttribution: tripper54 commentedOK, it seems when a webform is saved, the entries for the form builder cache for that user are deleted, but not for other users.
So when another user tries to edit the form, they load their (old) cache data, and boom, there goes the changes.
Attached patch alters form_builder_cache_delete to remove ALL form builder cache entries for the particular form, not just the current user's.
I haven't looked into all the circumstances under which this function is called, so maybe I've broken something somewhere else by making this change.
But it solves this bug, and I guess it gets the ball rolling!
Comment #3
quicksketchI think it would be a better solution to make a new parameter (or some special case for $sid) that makes it possible to delete all cache entries for a particular form, rather than taking an $sid argument that doesn't do anything at all.
Comment #3.0
quicksketchUpdated issue summary.
Comment #4
tripper54 CreditAttribution: tripper54 commentedCould we just drop the $sid argument altogether?
Is there a reason why you would need to delete cache entries for just one session but preserve others?
It sounds like a recipe for version conflicts as per the one above.
Comment #5
torotil CreditAttribution: torotil commentedDropping the $sid argument like in the patch would lead to a broken interface for simultaneous edits:
I'd suggest another approach: Delete the form_builder cache whenever the form_builder interface is loaded. This would also solve other issues with stale form_builder caches.
Comment #6
torotil CreditAttribution: torotil commentedHere is a patch that resets the form_builder cache whenever node/%/webform is loaded (or to be more precise: whenever form_builder_interface() is called).
To make things work I've also had to change two other things:
Comment #7
torotil CreditAttribution: torotil commentedComment #8
torotil CreditAttribution: torotil commentedThere was an issue with the previous patch: Triggering the ajax submission via .mousedown() had the side-effect of setting mousePressed=1. This patch uses a slightly more cautious approach of only calling triggerHandler('mousedown').
Comment #9
matthias_mo CreditAttribution: matthias_mo commentedwith the patch of comment #8 a new bug is introduced:
So it seems that already saved fields (with CID's ??) are treated differently than new fields.
I've tracked the problem down to the form_builder.js function
Drupal.formBuilder.updateElementPosition
When the last line
$('#form-builder-positions input[type="submit"]').triggerHandler('mousedown');
is called for an already existing field then in ajax.js the code
is executed. This Ajax code is not called with newly created fieldsets/fields.
Comment #10
torotil CreditAttribution: torotil commentedThe reason for the problems in #9 was addElement replaces the position-form without calling Drupal.attachBehaviors. So event-handlers weren't registered anymore after that.
The newly attached patch fixes that too.
Comment #11
quicksketchI'm not sure about this change @torotil. With Form Builder, it's common that users may assemble rather lengthy forms all in a single page load (similar to the amount of work done when assembling a View in Views module). Form Builder intentionally saves the users work and reloads it so that if they accidentally leave or reload the page, their work is not lost. I'd really prefer to keep the autosaving functionality rather than discarding any in-progress work when the page is loaded.
Comment #12
torotil CreditAttribution: torotil commentedYes that's a valid concern. Currently it's bought with inconsistencies and the danger of overriding changes made by other uses.
What about storing a hash of the unchanged form that the form_builder_cache entry is based on and then show a warning if it has changed. The user should then have 2 options:
Comment #13
torotil CreditAttribution: torotil commentedFor us users unintentionally overriding changes of others was a huge issue. The usual course of events would be:
While users tend to blame themselves when they lose data due to leaving the site - they sure tend to blame the software / us if they don't know how they lost the data.
Comment #14
quicksketchWe should implement hook_cron() to clean up the entries in
form_builder_cache
. I'm rather surprised we don't clean up after an editing session has been abandoned.I think we already have per-user caches, since the $sid column in the form_builder_cache table is tied to a user's session ID. The only way two users should be seeing each others work would be if they were using the same computer. If that's not the case already, we need to correct this to prevent user's sharing in-progress work.
I don't think we have any warning system for users editing the same form at the same time though, it'd be great to have the same options as Views for showing locked forms and allowing the user to "break" the lock and start a new editing session.
Comment #15
torotil CreditAttribution: torotil commented… and that is the core of the problem described in #13. Users which don't save the form for a long time don't see changes made (and saved) by other users.
Cleaning up the form_builder_cache during cron-runs is in general a good idea and should be easy enough to implement.
We could improve on that by sending an AJAX request whenever a user leaves/abandons the form_builder session. This would mean starting with a fresh session every time a user opens the form_bulder interface (which is exactly what my patches already implement).
Comment #16
torotil CreditAttribution: torotil commentedHere is a patch that implements hook_cron to delete stale cache entries. By default it deletes them after 6h (which equals the hardcoded core cache_form limit).
Comment #18
torotil CreditAttribution: torotil at more onion commentedI've now committed the migration to the core ajax functionality separately. Here is a patch for the remaining changes.
Comment #19
torotil CreditAttribution: torotil at more onion commentedUpdate the path to the current 7.x-1.x version.
Comment #20
joelpittetWhat would this change?
Comment #21
torotil CreditAttribution: torotil at more onion commentedFurther up in the patch the call to
form_builder_webform_save_form()
is modified to reset the form-cache, while the call toform_builder_interface()
(re)generates it. Therefore the order of the two calls is important.EDIT: If it's that unclear it might be better to do clear the object-cache in another place, though.
Comment #22
torotil CreditAttribution: torotil at more onion commentedComment #23
torotil CreditAttribution: torotil at more onion commentedActually the patch might mitigate the issue a lot. So this might be an easy provisional solution.
Comment #25
torotil CreditAttribution: torotil at more onion commentedjoelpittet: You were right about your comment to the patch. What I remembered was about some previous version of it.
I've committed this to 7.x-1.x.