13

I have a multistep node form. Half way through the form through a popup dialog user is asked to login if they have not logged in prior.

Upon successful login when proceeding with next page of the node form, I get this validation error:

The form has become outdated. Copy any unsaved work in the form below and then reload this page.

I understand it is because drupal_validation_form() verifies $form['#token'] and $form_state['values']['form_token'] are the same.

How do I avoid this, as this is a special use case (and it's not forgery by some external stuffs).

Any input on this front?

2
  • 1
    Maybe it's too late for answer but i've encourted the same problem. I've found an issue with $form["#token"]=drupal_get_token($form['#form_id']); when i prepare my $form.
    – user7430
    Commented May 16, 2012 at 21:18
  • 1
    I was actually hard-coding a form into a page, and needed to add the token. By adding <input name='form_token' type='hidden' value='<?php print drupal_get_token('MY_FORM_ID'); ?>'> the form was able to submit properly.
    – thirdender
    Commented May 28, 2014 at 15:43

2 Answers 2

2

Your post just saved me from serious misery. Don't quite know how that connection was made but your post lead me to a small change in my module code. Easy to understand why the "The form has become outdated" error was occurring now though. So see if this might jog your thoughts and help for your case.

My page admin/mymod had a menu item set up that included the following.

'page callback' => 'drupal_get_form', 
'page arguments' => 'mymod_main',

In mymod_main($op = '') I am conditionally building one of 2 forms but each build is of course a new form, e.g. $build['mymod_admin'] = drupal_get_form('mymod_admin') or $build['mymod_delete'] = drupal_get_form('mymod_delete').

No problem when the page admin/mymod first loaded and mymod_admin is called. But when the submit button created in mymod_admin is clicked then mymod_delete is called and creates it's form. There comes the "The form has become outdated" error that ruined the form processing. The fix is simply to use mymod_main() as page callback.

Now there is no crossing up of forms when the admin/mymod page reloads for each of the forms as there is not a starting form from the manu callback and then the second form defined in $build.

2
  • Can you explain your 'fix', i think i have the same issue but I don't understand what you mean with '---' and '+++', thank you Commented Jul 16, 2014 at 1:10
  • It means the page callback was changed to be mymod_main().
    – avpaderno
    Commented Jul 16, 2014 at 2:45
1

The error means that form_token needs is invalid and needs to be regenerated. This is basically a hidden form field (generally used to protect against cross-site forgeries).

Normally a token element is automatically added to each Drupal form by drupal_prepare_form(), so you don't generally have to add one yourself, unless you're writing your own code.

If you're trying to program some multi-page form, you probably need to re-generate the token on each submit using drupal_get_token(), e.g. as shown here:

$form_state['input']['form_token'] = drupal_get_token($form['#token']);

As for workaround to force regeneration of form token in form_alter, check the following example:

/**
 * Implements hook_form_alter().
 */
function mymodule_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id === 'your_form_entityform_edit_form' && !empty($form_state['input']['form_id'])) {
      $form_id = $form_state['input']['form_id'];
      $form ['#token'] = $form_id;
      $form ['form_token'] = array(
        '#id' => drupal_html_id('edit-' . $form_id . '-form-token'),
        '#type' => 'token',
        '#default_value' => drupal_get_token($form['#token']),
        '#parents' => array('form_token'),
      );
    }
}

Troubleshooting

  • Double check if your form is not hardcoded, otherwise add the token as suggested by @thirdender:

    <input name='form_token' type='hidden' value='<?php print drupal_get_token('MY_FORM_ID'); ?>'>
    
  • Check if the error happens on your form, as it could on other form (e.g. form within the form).

  • Debug drupal_valid_token().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.