Follow-up from #579366-40: How many ways are there to redirect after form submission?. If a form builder callback or hook_form_alter() implementation sets a value for one of the $form_state keys that appears in form_state_keys_no_cache(), then this value gets used when the form isn't cached, but gets dropped when it is cached. So, for example, whether a form can set $form_state['redirect'] within a hook_form_alter() is coupled to whether $form_state['cache'] is set. This makes no sense. We either need to restrict form_state_keys_no_cache() to be used only when caching from drupal_rebuild_form(), or if we're gonna use it during all form caching as we do now, then we need to also remove the same keys during a cache miss. This patch implements the latter.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rfay’s picture

subscribe. Thanks, effulgentsia.

Dries’s picture

This is a nice clean-up that improves consistency. At the same time, it might be puzzling, as people might find that their fields got 'eaten'?

effulgentsia’s picture

At the same time, it might be puzzling, as people might find that their fields got 'eaten'?

I agree, Let's consider the keys in question:

  • always_process
  • must_validate
  • rebuild
  • redirect
  • no_redirect
  • temporary

Which of these would a developer expect to be able to set from a form builder callback or a hook_form_alter()? Of those, for which (if any) does it make sense for the behavior to be different depending on whether the form was retrieved from cache or not? For the latter question, I think only 'temporary' could fit that bill. 'always_process' is an odd one in that it is somewhat incompatible with form caching anyway (its purpose is for simple GET forms where you don't want to pass things like 'form_build_id' in the query string). But for the other four, I think we really need to ask the question of whether we intend to allow developers to set them during a form builder callback / hook_form_alter() or not. If yes, we need to remove them from form_state_keys_no_cache(). If no, we need to document that clearly, so people aren't puzzled by their $form_state settings getting 'eaten'.

effulgentsia’s picture

For anyone becoming concerned that the Form API was in danger of becoming understandable, here's a patch that adds a little more ugliness relative to the original one. It adjusts for #3.

effulgentsia’s picture

Issue tags: +D7 Form API challenge

While this issue isn't critical, it touches on deep enough FAPI internals that I think it deserves the "D7 Form API challenge" tag, lest we forget about it.

sun’s picture

Nice code/docs ratio :)

Patch makes sense; not sure whether we can teach and transfer the same information in less words though.

sun’s picture

Indeed quite hard to explain. Nevertheless, tried to shorten those docs. RTBC if you're OK with it.

Dries’s picture

Status: Needs review » Fixed

I re-read sun's version and it looked good to me. Committed to CVS HEAD.

sun’s picture

Thanks. Though re-reading this today, I could understand if eff slowly walks out of the room to tape is head and get that rambo knife ready to rumble..

*meshutsup*

fago’s picture

I wonder whether we should do this cleanup only when we check for the cache vs anytime? In which cases we should *not* do the cleanup?

As of now the code doesn't do the cleanup the first time the form is built, what makes a different form state for the form processing / after build handlers.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

c960657’s picture

This left the code out of sync with the documentation. See #1493222: Documentation incorrectly says that $form_state['redirect'] can be set from form builder function for follow-up.