If the builder of a form on a page uses $form_state['storage'] (or happens to inappropriately set $form_state['rebuild']), it will prevent any later form on the page from being able to submit, because $_POST is destroyed.

This seems to be a result of this code in form.inc: 143:

  if (!empty($form_state['rebuild']) || !empty($form_state['storage'])) {
    $form = drupal_rebuild_form($form_id, $form_state, $args);
  }

Or it may be a result of form_state['storage'] inappropriately being set up when the form id is not the same one in the post.

I have attached a complete demo module that simply displays two forms. The upper form happens to set form_state[storage]. As a result, the lower form cannot submit ($_POST is always destroyed before drupal_get_form() is even called on it).

STEPS TO REPRODUCE: Have two forms on one page, with the first one using $form_state[rebuild] in the form building function. The second form will be unable to submit.

EXPECTED BEHAVIOR: Processing a form should not destroy data needed by another ($_POST)

WHAT HAPPENED: Form that uses $form_state['storage'] destroys the other form's $_POST.

Comments

bob.hinrichs’s picture

IMO as well, this is a bug. It has cost me days of work. There is a paradox in which if you want to use the form storage, you cannot set it, nor can you read from formerly-posted data by calling the api to get your form back, without destroying your data in the process. I have tried all kinds of work-arounds.

georgir’s picture

I faced the same problem today. You are completely correct, the problem is that drupal_rebuild_form clears $_POST on line 212 in /includes/form.inc

For now, I am using the following local fix - clear $_POST only if it contains the correct form_id - this way we will make sure we do not affect other forms on the page.
if($_POST['form_id'] == $form_id) $_POST = array();
This fixes the bug OK and can be safely included in future Drupal versions. It isn't clear to me if that line is needed at all, however.
Ideally, if Drupal was properly coded, it should be enough to just clear $form['#post'] (which it does on the next line) so this line can be removed completely.
But just to be on the safe side, I'll leave it to someone smarter than me to decide this.

a9xbqqabtqa6m’s picture

georgir, I am using the exact same fix, and I've seen no side effects.

D7 doesn't clear $_POST like this, so I would assume this is fixed in D7.

rfay’s picture

StatusFileSize
new1014 bytes

I converted the bug demo module to D7 and tested, and this in fact is not a problem in D7. The D7 test module is attached in case we need it for anything later.

sridharpandu’s picture

Five days of searching through the API documentation and the forums I finally found this post. I have exactly the same problem. I have this line in my mm_myform_submit

    $filename = $form_state['storage']['filename']; 
    drupal_set_message($filename); //prints the full path to the file name

and have this line in mm_myform_page_two.

    $filename = $form_state['storage']['filename'];
    drupal_set_message($filename); //doesn't print anything

The $filename is blank. @georgir Just wanted to know where should I include the line of code that you have mentioned.

mdupont’s picture

Status: Active » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.