web-dev-qa-db-ja.com

hook_menuのアクセスコールバックでユーザーをリダイレクトすると、望ましくない影響がありますか?

この答え は、ユーザーがアクセスしようとしているページにアクセスできない場合に、ユーザーを特定のページにリダイレクトする最良の方法についての議論につながりました。

1つのオプションは、アクセスコールバックをtrueに設定してから、ページコールバックでユーザーをリダイレクトすることです。これは有効なようですが、ページコールバックでアクセス機能とページ作成機能を混在させていると思います。

例えば。

function hook_menu() {
    $items['player/my_page'] = array(
        'title' => t('My Page'), // note this is a required parameter
        'access callback' => TRUE,
        'page callback' => 'some_function',
    );
    return $items;
}

function some_function() {
    global $user;   
    if(!$user->uid) { // here checking if the user is logged in but could be checking for a specific permission or field value
        $dest = drupal_get_destination();
        drupal_goto('user/login', $dest); // this remembers where the user is coming from
    }
    // carry on building rest of page
}

別のオプションは、ユーザーがアクセス権を持っているかどうかをチェックする関数を呼び出すようにアクセスコールバック関数を設定することですが、falseを返す代わりに、ユーザーを別のページにリダイレクトします。アクセスロジックとページ作成ロジックを分離しているので、これは良いことです。ただし、アクセスコールバックの目的はブール値を返すことなので、これはユーザーをリダイレクトすることでそのロジックを壊しています。

例えば。

function hook_menu() {
    $items['player/my_page'] = array(
        'title' => t('My Page'), // note this is a required parameter
        'access callback' => 'check_access',
        'page callback' => 'some_function',
    );
    return $items;
}

function check_access() {
    global $user;
    // here checking if the user is logged in but could be checking for a specific permission or field value
    if(!$user->uid) {
        $dest = drupal_get_destination();
        drupal_goto('user/login', $dest);
    }
    return TRUE;
}

私が知らないアクセスコールバックでユーザーをリダイレクトすることによる望ましくない影響はありますか?

ここでのベストプラクティスは何だと思いますか?

8
Felix Eve

これは、デリバリーコールバック関数を変更することで実現できると思います。アクセスコールバックがFALSEを返す場合、それが配信コールバックに渡されます。特定のページでのみこのリダイレクト動作が必要な場合は、hook_menu()またはhook_menu_alter()を使用して、それらのページのみの配信コールバックを変更できます。動作をグローバルにしたい場合は、hook_page_delivery_callback_alter()を使用して変更できます。

これが配信コールバックの例です。

function custom_deliver_html_page($page_callback_result) {
  if ($page_callback_result === MENU_ACCESS_DENIED) {
    drupal_goto('<front>');
  }
  drupal_deliver_html_page($page_callback_result);
 }

ところで、これはテストされておらず、私自身が以前に配信コールバックを実際に変更したことはありません。

6
Andy

アクセスコールバックでは行いません。別の開発者が将来的にpage_callbackを変更したい場合、アクセスコールバックでリダイレクトしているときにコールバックが機能しない理由について頭を悩ますことになります。

3
awm