web-dev-qa-db-ja.com

hook_form_alter()でリダイレクトを実行するにはどうすればよいですか?

ユーザーがログインしたときに、特定の役割を持つユーザーを別のページにリダイレクトしたい。 Drupal 7では、drupal_goto()hook_user_login()を使用してリダイレクトを行い、hook_module_implements_alter()を使用してモジュールはリストの最後にあるため、他のすべてが実行される可能性があります。

Drupal 8では、コントローラーの外部でリダイレクトを実行することは、サポートされているユースケースではないようです。

そのページでは、gngnにも同じ問題があり、RedirectResponseを手動で生成して送信します。

問題は、私が見ると、send()はリクエストを終了せず、ページには2つのHTMLドキュメントがあることです。「リダイレクト先...」ページの後に、そこにあったページが続きます。そもそも。これはセキュリティ上の問題になる可能性があります。

johnvbはこれに注意し、exit()の後にsend()への呼び出しを挿入します。

おそらく何か便利なことがindex.phpの$kernel->terminate()呼び出しで行われており、exit()を呼び出すことでバイパスされています。

Drupal 7では、drupal_goto()drupal_exit()を呼び出してこの問題を処理しました。

drupal_goto()が削除されました は、リクエストフローを中断する必要があるモジュールがHTTP例外をスローする必要があることを示していますが、「リダイレクト」例外はありません。

ユーザーログインもリダイレクトを行うため、上記のdrupal_goto()変更レコードリンクで提案されているように、リダイレクトURLを変更する方法もあります。ただし、そのアプローチでは、すべてのリクエストで私のメソッドが呼び出されることになり、私がやっていることはめちゃくちゃ無駄に見えます。

Drupal 8)でhook_form_alter()からリダイレクトを実行するにはどうすればよいですか?

2
Claw
use Drupal\Core\Form\FormStateInterface;

/** 
 * Implements hook_form_FORM_ID_alter().
 */
function [MODULENAME]_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Alter login form and add own custom submit handler.
  $form['#submit'][] = '_[MODULENAME]_user_login_form_submit';

  // Not all forms pay attention to $form['#submit'][]. For these
  // try adding your submit hook to the #submit for the specific
  // button.  e.g.,
  $form['actions']['submit']['#submit'][] = '_[MODULENAME]_user_login_form_submit';
}

/**
 * Custom submit handler for login form.
 */
function _[MODULENAME]_user_login_form_submit($form, FormStateInterface $form_state) {
  // Set redirect to login form.
  $form_state->setRedirect('custom.redirect_callback');
}
5
harsh_behl_0007

ログイン後にユーザーをリダイレクトする方法はいくつかあります。前の回答と同様に、hook_form_FORM_ID_alter()を実装して追加の送信関数を追加することで実行できますが、hook_user_login関数も使用できます。

いくつかのURLを生成するパラメーターを持ついくつかのルートにリダイレクトするには(Symfony\Component\Validator\Constraints\Url class reference を使用):

$form_state->setRedirectUrl(new Url('route_name', ['route' => 'parameters'])); 

あるルートにリダイレクトするには:

$form_state->setRedirect('route_name', ['route' => 'parameters']);

また、Symfony\Component\HttpFoundation\RedirectResponse、たとえば、ユーザーをカスタムユーザーページにリダイレクトする場合:

function your_module_user_login($account) {
    global $base_url;
    $redirect = new RedirectResponse($base_url .'/your-url/'.$account->uid->value);
    $redirect->send();

}
0
Andrew Nim

Drupal 8)で、フォームの送信後にリダイレクトを設定する正しい方法は、次の手順に従います。

別の方法としては、redirect.destinationサービスを使用します。この場合、Drupal 8でも、hook_user_login()を使用できます。

_function mymodule_user_login(UserInterface $account) {
  \Drupal::destination()->set($url_destination_as_string);
}
_

RedirectDestination::set() のドキュメントには、次のように書かれています:

すべてのレンダリングですべての宛先呼び出しをオーバーライドするために、このメソッドが使用されることはめったにありません。たとえば、ビューはこのメソッドを使用します。

補足として、ログイン後にユーザーをリダイレクトする正しい方法は、Drupal 7で)、次のようなコードを使用しています。

_function mymodule_user_login(&$edit, $account) {
  $edit['redirect'] = $path_to_redirect_users_to;
}
_

これは、フックが受け取る_&$edit_パラメーターが、ログインフォーム送信ハンドラーに渡される_$form_state_パラメーターであるため機能します。

_function user_login_submit($form, &$form_state) {
  global $user;
  $user = user_load($form_state['uid']);
  $form_state['redirect'] = 'user/' . $user->uid;
  user_login_finalize($form_state);
}

function user_login_finalize(&$edit = array()) {
  global $user;
  watchdog('user', 'Session opened for %name.', array(
    '%name' => $user->name,
  ));

  // Update the user table timestamp noting user has logged in.
  // This is also used to invalidate one-time login links.
  $user->login = REQUEST_TIME;
  db_update('users')
    ->fields(array(
    'login' => $user->login,
  ))
    ->condition('uid', $user->uid)
    ->execute();

  // Regenerate the session ID to prevent against session fixation attacks.
  // This is called before hook_user in case one of those functions fails
  // or incorrectly does a redirect which would leave the old session in place.
  drupal_session_regenerate();
  user_module_invoke('login', $edit, $user);
}
_
0
kiamlaluno