Будет ли перенаправление пользователей в обратном вызове доступа hook_menu иметь нежелательные эффекты?

8

Этот ответ привел к дискуссии о том, как лучше перенаправить пользователя на определенную страницу, если у него не должно быть доступа к странице, к которой он пытается получить доступ.

Один из вариантов - установить для обратного вызова доступа значение 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;
}

Есть ли нежелательные эффекты от перенаправления пользователей в обратном вызове доступа, о которых я не знаю?

Как вы думаете, что является лучшей практикой здесь?

Феликс Ева
источник
добавьте еще одну косую черту в комментарий php в
обратном вызове
5
Я думаю, но не уверен, что если вы добавите этот путь в меню, произойдут некоторые очень странные вещи, потому что обратный вызов доступа используется, чтобы выяснить, может ли пункт меню отображаться для конкретного пользователя.
mpdonadio

Ответы:

6

Я думаю, что вы могли бы сделать это, изменив функцию обратного вызова доставки. Если обратный вызов доступа возвращается 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);
 }

Между прочим, это не проверено, и я никогда ранее не изменял сам обратный вызов доставки.

Энди
источник
Это звучит как интересный подход ...
Феликс Ив
Подтвердил, что это работает. Намного чище, чем перенаправление в обратном вызове доступа. Добавить в hook_menu_alter:$items['player/my_page']['delivery callback'] = 'player_my_page_delivery';
wxactly
3

Я бы не стал делать это в обратном вызове доступа. Если другой разработчик захочет изменить его page_callbackв какой-то момент в будущем, он в конечном итоге почесывает голову, почему обратный вызов не работает, когда вы перенаправляете в обратном вызове доступа.

AWM
источник
Это имеет смысл, и я думаю, что комментарий MPD также имеет смысл.
Феликс Ева