Closed (won't fix)
Project:
Drupal core
Version:
7.x-dev
Component:
forms system
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
24 Nov 2007 at 09:46 UTC
Updated:
26 Nov 2009 at 19:47 UTC
http://drupal.org/node/193191 added a number of fixes for AHAH callbacks and button handling, but the addition of the drupal_rebuild_form() function appears to have broken the $form['#cache'] flag -- while drupal_get_form() respects that flag, drupal_rebuild_form() does not.
The attached patch adds the check back to ensure things continue to work correctly.
| Comment | File | Size | Author |
|---|---|---|---|
| form_cache.patch | 925 bytes | eaton |
Comments
Comment #1
eaton commentedAlso, a fun tip: if you ever put a SimpleXML object in $form_state, be sure you set $form['#cache'] to FALSE. SimpleXML objects, they don't like to be serialized, see...
Comment #2
chx commentedI heartily recommend reading up older versions of form.inc. Rebuild always cached.
Comment #3
eaton commentedYou're right -- I only just noticed the shift with the existence of drupal_rebuild_form(). This is still a pretty significant problem, though, as $form['#cache'] SHOULD be respected. Obviously, a form marked as no-cache will not be compatible with various AHAH techniques and so on.
The issue still needs attention; without this change, #cache is all but useless: it only applies to the first time a form is displayed.
Also, I notice that the tweaky handling of form caching when #process callbacks are involved is not duplicated in drupal_rebuild_form(). I assume this is intentional, to avoid double-processing of items, or something like that?
Comment #4
eaton commentedChanging the title to reflect the details.
The easiest example of where this is a problem would be listing pages where a form is clicked, and the results are displayed below the input field. This is easy to do with a combination of form_state and rebuild, but at present it causes the entire form, and the form_state, to be cached unnecessarily.
Comment #5
chx commentedThe forkflow is like this: on rebuild, I cache_get the form, change it as needed and put it back. This was the reasoning behind not checking for $form['#cache']. If you do not change the form then it's surely cacheable as we just retrieved it from cache. If you change the form, it should be cached. So, either form_set_cache needs to be run or there can be no problems with it.
Comment #7
eaton commentedThe second reason for the #cache property was to prevent the cache from bloating with entries that weren't needed. I think I need to put some time into explaining the interplay of #cache and 'rebuild' and 'storage' -- the results are counter-intuitive if you set #cache = FALSE, then rebuild the form. It'll be cached no matter what you say in the #cache flag.
Also, there's a subtle issue: ONLY things that can be serialized can be placed in $form_state, now. Otherwise you'll get errors on the next display of the form. I ran into that with a SimpleXML object -- aparently that's a known issue with the library.
Comment #8
pwolanin commentedobviously the patch in #6 was meant for a different issue
Comment #9
eaton commentedThis is true. However, fixing this issue is probably not worth the headaches at the moment -- it doesn't break anything, it just results in counter-intuitive behavior when the #cache flag is used. It allows $form_state['rebuild'] and $form_state['storage'] to trigger form caching regardless of the state of the #cache flag. There are good reasons for that, and good reasons why it could work differently, but for now it shouldn't complicate the D6 release.
Comment #10
chx commentedComment #11
fagoI've created two related patches:
* Setting #cache to FALSE shouldn't cache the form: http://drupal.org/node/299672
* fix various problems when using form storage: http://drupal.org/node/302240
regarding this one:
I think caching should be auto-activated on rebuild only when there is some storage. In other cases we could check the #cache property. So eaton's use case can be easily implemented by just setting $form_state['rebuild'].
Comment #12
sunBoth patches mentioned by fago in #11 are committed.
See also #583730: How many ways are there to cache a form?.
I'm not sure I understand this issue. I don't see a grokable summary in here...
Comment #13
sunWon't fix due to #634440: Remove auto-rebuilding magic for $form_state['storage']