web-dev-qa-db-ja.com

「宛先」がURLにある場合、フォームリダイレクトが機能しない

私のフォームの1つで、_$form_state['redirect']_を設定して、ユーザーがアクションボタンの1つをクリックした後にフォームがその宛先に移動するようにしています。

リダイレクトを追加する前と後の両方で_$form_state['redirect']_を検査すると、適切な配列が含まれる前と後にNULLになります。リダイレクトを設定する方法は次のとおりです。

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

ユーザーが表示しているフォームから次のパスへの宛先を保持したいので(drupal_get_destination()を呼び出すと、内部に_'destination' => 'some/path/here'_を含む配列が返されます。

現在のフォームのパスにはすでに宛先があるため、自分のフォーム送信ハンドラーに何を配置しても、フォームはその宛先にリダイレクトされるようです(上記のコードを参照)。 drupal_goto()を使用しても、ユーザーはリダイレクトされませんでした。

19
geerlingguy

フォームが処理されると、_$form_state['redirect']_の値が drupal_goto() に送信され、drupal_goto()は常に_$_GET['destination']_を独自の_$path_パラメータ。

完全を期すために、Drupal 6では、 hook_exit() に独自のヘッダーを設定せずに、少し運が悪かった:

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

Drupal 7、に hook_drupal_goto_alter() がこの特定のユースケースに追加されました:

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

Drupal 7のもう1つのオプションは、実行したいことにより近いものですが、 drupal_get_destination() の静的キャッシュをリセットして、 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();
}
_

リセット直後にdrupal_get_destination()を呼び出すため、Drupalは、drupal_goto()を呼び出す場合も含めて、ページビルドの残りの宛先パラメーターを認識しません。

注:変数を上書きしたくないため、_$form_state['redirect']_を定義するためのコードを変更しました。他の送信ハンドラが独自のリダイレクトを定義している可能性があります。 Drupalは常に配列のlast項目を使用するので、_foo/bar_で宛先パラメーター(およびその他すべて)をオーバーライドする場合その時点までに定義されたリダイレクト)、それは最後でなければなりません。

27
user7

ありがとうございましたが、何らかの理由で試してもうまくいきませんでした。致命的なエラーが発生しました-上記の回答例で送信されたデータはdrupal_goto()の要件を満たしていません

この答えはかなり古いためかもしれませんが、代わりにこれで動作させることができました:

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

}
_

これはこのメモに違反しています。

変数を上書きしたくない場合:他の送信ハンドラーが独自のリダイレクトを定義している場合があります。

ただし、この場合は必ず変数を上書きする必要があります。他のモジュールの設定値を無視したくない場合を除いて、この値を設定することはありません。また、drupal_goto()がクエリパラメータを処理する方法が原因であると思います。これが、元の回答が私のサイトで致命的なエラーをスローした理由でもあります。

4
tmsimont