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.

CommentFileSizeAuthor
form_cache.patch925 byteseaton

Comments

eaton’s picture

Also, 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...

chx’s picture

Status: Needs review » Closed (won't fix)

I heartily recommend reading up older versions of form.inc. Rebuild always cached.

eaton’s picture

Status: Closed (won't fix) » Needs review

You'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?

eaton’s picture

Title: form['#cache'] no longer respected » form['#cache'] not respected during rebuilds

Changing 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.

chx’s picture

The 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.

eaton’s picture

Status: Needs review » Closed (won't fix)

The 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.

pwolanin’s picture

Status: Closed (won't fix) » Needs review

obviously the patch in #6 was meant for a different issue

eaton’s picture

Status: Needs review » Postponed

This 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.

chx’s picture

Version: 6.x-dev » 7.x-dev
Status: Postponed » Needs work
fago’s picture

I'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'].

sun’s picture

Both 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...

sun’s picture

Status: Needs work » Closed (won't fix)