web-dev-qa-db-fra.com

La redirection de formulaire ne fonctionne pas si la «destination» est dans l'URL

Dans l'un de mes formulaires, j'essaie de définir un $form_state['redirect'] Afin que le formulaire accède à cette destination après que l'utilisateur a cliqué sur l'un des boutons d'action.

Si j'inspecte $form_state['redirect'] Avant et après avoir ajouté la redirection, elle est NULL avant et après contient le tableau approprié. Voici comment je configure la redirection:

$form_state['redirect'] = array(
  'my/custom/path/' . $nid,
  array('query' => drupal_get_destination()),
);

Je veux conserver la destination du formulaire que l'utilisateur visualise au chemin suivant (c'est pourquoi j'appelle drupal_get_destination(), qui retourne un tableau avec 'destination' => 'some/path/here' À l'intérieur.

Il semble que, parce qu'il y a déjà une destination dans le chemin du formulaire actuel, le formulaire redirige vers cette destination, peu importe ce que j'ai mis dans mon propre gestionnaire de soumission de formulaire (voir le code ci-dessus). J'ai même essayé d'utiliser drupal_goto () et cela n'a pas redirigé l'utilisateur non plus.

19
geerlingguy

Lorsqu'un formulaire est traité, la valeur de $form_state['redirect'] Est envoyée à drupal_goto() et drupal_goto() favorise toujours $_GET['destination'] Par rapport à son propre paramètre $path.

Par souci d'exhaustivité, dans Drupal 6, vous n'avez pas eu de chance sans définir vos propres en-têtes dans hook_exit() :

function mymodule_exit($destination = NULL) {
  $my_destination = 'foo/bar';
  header('Location: ' . url($my_destination));
  exit;
}

Dans Drupal 7, hook_drupal_goto_alter() a été ajouté pour ce cas d'utilisation spécifique:

function mymodule_drupal_goto_alter(&$path, &$options, &$http_response_code) {
  $path = 'foo/bar';
}

Une autre option pour Drupal 7, qui est plus proche de ce que vous voulez faire, est de réinitialiser le cache statique pour drupal_get_destination() dans votre gestionnaire de soumission en utilisant drupal_static_reset() :

function mymodule_form_submit($form, &$form_state) {
  // See note
  $form_state['redirect'][] = drupal_get_destination();
  $form_state['redirect'][] = 'foo/bar';

  unset($_GET['destination']);
  drupal_static_reset('drupal_get_destination');
  drupal_get_destination();
}

Puisque vous appelez drupal_get_destination() immédiatement après la réinitialisation, Drupal ignore parfaitement le paramètre de destination pour le reste de la construction de la page, y compris lorsqu'il appelle drupal_goto().

Remarque: J'ai changé le code pour définir $form_state['redirect'] Parce que vous ne voulez jamais écraser la variable: d'autres gestionnaires de soumission ont peut-être défini le leur redirige. Drupal utilisera toujours l'élément dernier dans le tableau, donc si vous voulez que foo/bar Remplace le paramètre de destination (et toutes les autres redirections définies jusque-là), il doit être le dernier.

27
user7

Merci pour cela, mais pour une raison quelconque, cela n'a pas fonctionné lorsque je l'ai essayé. J'ai eu une erreur fatale - les données envoyées dans l'exemple de réponse ci-dessus ne satisfont pas aux exigences de drupal_goto()

C'est peut-être parce que cette réponse est plutôt ancienne, mais j'ai pu le faire fonctionner avec ceci à la place:

function mymodule_form_submit($form, &$form_state) {


  $form_state['redirect'] = array(
    'foo/bar', array(
      'query' => drupal_get_destination()
    )
  );

  unset($_GET['destination']);
  drupal_static_reset('drupal_get_destination');
  drupal_get_destination();

}

Je sais que cela viole cette note:

vous ne voulez jamais écraser la variable: d'autres gestionnaires de soumission ont peut-être défini leurs propres redirections.

Mais, dans ce cas, vous voulez vraiment écraser la variable. Vous ne définiriez pas cette valeur à moins que vous ne vouliez ignorer les valeurs définies d'autres modules. En outre, je pense que vous devez le faire en raison de la façon dont drupal_goto() fonctionne avec le paramètre de requête. C'est peut-être aussi la raison pour laquelle la réponse originale lançait des erreurs fatales sur mon site.

4
tmsimont