Die Formularumleitung funktioniert nicht, wenn "Ziel" in der URL enthalten ist

20

In einem meiner Formulare versuche ich, eine festzulegen, $form_state['redirect']damit das Formular an dieses Ziel gesendet wird, nachdem der Benutzer auf eine der Aktionsschaltflächen geklickt hat.

Wenn ich $form_state['redirect']die Umleitung vor und nach dem Hinzufügen überprüfe, ist sie vor und nach dem Hinzufügen NULL und enthält das richtige Array. So richte ich die Umleitung ein:

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

Ich möchte das Ziel aus dem Formular erhalten, das der Benutzer zum nächsten Pfad anzeigt (aus diesem Grund rufe ich auf drupal_get_destination(), der ein Array mit 'destination' => 'some/path/here'inside zurückgibt .

Da sich bereits ein Ziel im Pfad des aktuellen Formulars befindet, wird das Formular anscheinend an dieses Ziel weitergeleitet, unabhängig davon, was ich in meinen eigenen Formularübermittlungs-Handler eingegeben habe (siehe obigen Code). Ich habe sogar versucht, drupal_goto () zu verwenden, und das hat den Benutzer auch nicht umgeleitet.

Geerlingguy
quelle

Antworten:

27

Wenn ein Formular verarbeitet wird, wird der Wert von $form_state['redirect']an den eigenen Parameter gesendet drupal_goto()und drupal_goto()immer vorgezogen .$_GET['destination']$path

Der Vollständigkeit halber hatten Sie in Drupal 6 etwas Pech, ohne Ihre eigenen Header in hook_exit():

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

In Drupal 7 hook_drupal_goto_alter()wurde für diesen speziellen Anwendungsfall Folgendes hinzugefügt:

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

Eine weitere Option für Drupal 7, die näher an drupal_get_destination() Ihren Vorstellungen liegt, ist das Zurücksetzen des statischen Caches in Ihrem Submit-Handler mithilfe von 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();
}

Da Sie drupal_get_destination()unmittelbar nach dem Zurücksetzen aufrufen , ist Drupal der Zielparameter für den Rest des Seitenaufbaus, einschließlich des Aufrufs , glücklicherweise nicht bewusst drupal_goto().

Hinweis: Ich habe den Code zum Definieren geändert, $form_state['redirect']weil Sie die Variable niemals überschreiben möchten: Andere Submit-Handler haben möglicherweise ihre eigenen Weiterleitungen definiert. Drupal verwendet immer das letzte Element im Array. Wenn Sie also foo/barden Zielparameter (und jede andere bis zu diesem Punkt definierte Umleitung) überschreiben möchten , muss es das letzte Element sein.


quelle
Perfekt und sehr gute Erklärung. Ich habe tatsächlich ein bisschen mehr gefunden, indem ich den Fluss eines verarbeiteten Formulars durchgearbeitet habe - drupal_goto () ist letztendlich der Grund, warum meine einfache Umleitung nicht funktioniert hat. Ich musste auch $ _GET ['destination'] überschreiben.
Geerlingguy
Vielen Dank! Dies ist in der Tat sehr klarstellend.
Silberdistel
4

Vielen Dank dafür, aber aus irgendeinem Grund hat das nicht funktioniert, als ich es ausprobiert habe. Ich habe einen schwerwiegenden Fehler erhalten - die in der obigen Beispielantwort gesendeten Daten erfüllen nicht die Anforderungen vondrupal_goto()

Es mag sein, dass diese Antwort ziemlich alt ist, aber ich konnte sie stattdessen zum Laufen bringen:

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();

}

Ich weiß, dass dies gegen diese Notiz verstößt:

Sie möchten die Variable niemals überschreiben. Möglicherweise haben andere Submit-Handler ihre eigenen Weiterleitungen definiert.

In diesem Fall möchten Sie die Variable jedoch unbedingt überschreiben. Sie würden diesen Wert nicht festlegen, wenn Sie die festgelegten Werte anderer Module nicht ignorieren möchten. Auch ich denke du musst wegen dem Wegdrupal_goto() mit dem Abfrageparameter arbeiten. Dies kann auch der Grund sein, warum die ursprüngliche Antwort schwerwiegende Fehler auf meiner Website verursachte.

tmsimont
quelle
Diese Antwort hat mir geholfen zu erkennen, dass $form_state['redirect']Sie unter bestimmten Umständen die WSOD vollständig überschreiben möchten oder eine WSOD mit konkurrierenden Weiterleitungen erhalten.
tyler.frankenstein
-2

set form #action

global $base_path;
$form['#action'] = $base_path . '/node/'.$form_state['node']->nid.'/mytab';
rémy
quelle
-1 Ich denke , ruft drupal_goto()in hook_node_insert()die Dinge vermasseln (weil drupal_goto()Anrufe drupal_exit()von den neuen Knoten zu verhindern gespeichert werden).
Andy
true - in einem node_insert-Hook .. (hat die Antwort bearbeitet)
rémy
1
Dies gibt keine Umleitung aus, wenn OP darum bittet, sondern sendet das Formular an einen anderen Pfad.
Andy