Erreur «Le formulaire est devenu obsolète»

12

J'ai une forme de nœud en plusieurs étapes. À mi-chemin du formulaire via une boîte de dialogue contextuelle, l'utilisateur est invité à se connecter s'il ne s'est pas connecté auparavant.

Lors de la connexion réussie lors de la prochaine page du formulaire de noeud, j'obtiens cette erreur de validation:

Le formulaire est devenu obsolète. Copiez tout travail non enregistré dans le formulaire ci-dessous, puis rechargez cette page.

Je comprends que c'est parce que drupal_validation_form()vérifie $form['#token']et $form_state['values']['form_token']sont les mêmes.

Comment puis-je éviter cela, car il s'agit d'un cas d'utilisation spécial (et ce n'est pas une contrefaçon par certains éléments externes).

Une entrée sur ce front?

quête
la source
1
Il est peut-être trop tard pour répondre, mais j'ai encouragé le même problème. J'ai trouvé un problème avec $ form ["# token"] = drupal_get_token ($ form ['# form_id']); quand je prépare mon $ form.
1
J'étais en train de coder en dur un formulaire dans une page et j'avais besoin d'ajouter le jeton. En ajoutant <input name='form_token' type='hidden' value='<?php print drupal_get_token('MY_FORM_ID'); ?>'>le formulaire a pu se soumettre correctement.
Thirdender

Réponses:

2

Votre message m'a sauvé d'une grave misère. Je ne sais pas trop comment cette connexion a été établie, mais votre message m'a amené à un petit changement dans le code de mon module. Il était facile de comprendre pourquoi l'erreur "Le formulaire est devenu obsolète" se produisait cependant maintenant. Alors, voyez si cela pourrait vous rafraîchir la tête et vous aider dans votre cas.

Ma page admin / mymod avait un élément de menu configuré qui comprenait les éléments suivants.

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

Dans mymod_main($op = '')Je construis sous condition une des 2 formes mais chaque construction est bien sûr une nouvelle forme, par exemple $build['mymod_admin'] = drupal_get_form('mymod_admin')ou $build['mymod_delete'] = drupal_get_form('mymod_delete').

Pas de problème lors du premier chargement de la page admin / mymod et l'appel de mymod_admin. Mais lorsque le bouton d'envoi créé dans mymod_admin est cliqué, mymod_delete est appelé et crée son formulaire. Il y a l'erreur "Le formulaire est devenu obsolète" qui a ruiné le traitement du formulaire. Le correctif consiste simplement à utiliser mymod_main()comme rappel de page.

Maintenant, il n'y a pas de croisement de formulaires lorsque la page admin / mymod se recharge pour chacun des formulaires car il n'y a pas de formulaire de départ du rappel manu, puis le deuxième formulaire défini dans $build.

Randy Skretka
la source
Pouvez-vous expliquer votre «correctif», je pense que j'ai le même problème mais je ne comprends pas ce que vous entendez par «---» et «+++», merci
iain maitland
Cela signifie que le rappel de page a été modifié mymod_main().
kiamlaluno
0

L'erreur signifie que les form_tokenbesoins ne sont pas valides et doivent être régénérés. Il s'agit essentiellement d'un champ de formulaire masqué (généralement utilisé pour se protéger contre les contrefaçons intersites).

Normalement, un élément de jeton est automatiquement ajouté à chaque formulaire Drupal par drupal_prepare_form(), vous n'avez donc généralement pas à en ajouter un vous-même, sauf si vous écrivez votre propre code.

Si vous essayez de programmer un formulaire de plusieurs pages, vous devrez probablement recréer le jeton sur chaque soumission en utilisant drupal_get_token(), par exemple, comme indiqué ici :

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

En ce qui concerne la solution de contournement pour forcer la régénération du jeton de formulaire dans form_alter, vérifiez l'exemple suivant:

/**
 * 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'),
      );
    }
}

Dépannage

  • Vérifiez si votre formulaire n'est pas codé en dur, sinon ajoutez le jeton comme suggéré par @thirdender :

    <input name='form_token' type='hidden' value='<?php print drupal_get_token('MY_FORM_ID'); ?>'>
  • Vérifiez si l'erreur se produit sur votre formulaire, comme cela pourrait se produire sur un autre formulaire (par exemple, formulaire dans le formulaire).

  • Déboguer drupal_valid_token().
Kenorb
la source