Как в hook_menu настроить права доступа?

Главные вкладки

Аватар пользователя shlop shlop 18 декабря 2017 в 16:50

Здравствуйте, подскажите пожалуйста. В общем есть у меня модуль, который создает страницу.
И есть определенная роль "оператор", и вот собственно мой вопрос в том, как сделать так, что бы эта страница была доступна только роли "оператор" ? Заранее благодарю за ответ.

<?php
function webformizi_menu() {
    
$items = array();
    
$items['newselect'] = array(
        
'title' => 'Новая поверка',
        
'page callback' => 'main_funct'//Отрисовка стр.
        
'type'=> MENU_NORMAL_ITEM,
    );
    return 
$items;
}
?>

Лучший ответ

Аватар пользователя ivnish ivnish 18 декабря 2017 в 16:54

Вы правильно ключевые слова выбрали. Проверяйте в access callback какая роль у пользователя. Всё это легко гуглится

Комментарии

Аватар пользователя ivnish ivnish 18 декабря 2017 в 16:54

Вы правильно ключевые слова выбрали. Проверяйте в access callback какая роль у пользователя. Всё это легко гуглится

Аватар пользователя shlop shlop 18 декабря 2017 в 17:33

Ну собственно решил проблему вот такой функцией:
Данная страница доступна только для администратора, и роли оператора.

<?php
function module_access() {
    global 
$user;
    
$Array $user->roles;
    if(
in_array("Оператор",$Array) || in_array("administrator",$Array)) {
        return 
TRUE;
    }
    else {
        return 
FALSE;
    }
}
?>

Которая находиться в access callback в hook_menu

<?php
function webformizi_menu() {
    
$items = array();
    
$items['newselect'] = array(
        
'title' => 'Новая поверка',
        
'page callback' => 'main_funct'//Отрисовка стр.
        
'access callback' => 'module_access',
        
'type'=> MENU_NORMAL_ITEM,
    );
    return 
$items;
}
?>
Аватар пользователя ХулиGUN ХулиGUN 18 декабря 2017 в 18:27

Я могу, конечно, ошибаться, но in_array это тот же цикл по массиву и тогда в вашем module_access() получается 2 обхода одного и того же массива.
Гораздо быстрее отработало что-то типа:

<?php
foreach($roleArray as $role) {
  if (
$role == 'administrator' || $role == 'Оператор') {
      return 
true;
  }
}
return 
false;
?>

В таком случае будет всего 1 проход по циклу и то не до конца, если найдёт совпадения.
А так, как массив ролей юзера, опять же если мне не изменяет память, от "меньших" к "большим", то рациональней было бы массив предварительно развернуть
<?php array_reverse($userRoles?>

Аватар пользователя gun_dose gun_dose 18 декабря 2017 в 19:55

Где там два прохода? И с каких пор foreach стал быстрее, чем специализированные функции работы с массивами?

Аватар пользователя ХулиGUN ХулиGUN 18 декабря 2017 в 21:43

gun_dose wrote:

И с каких пор foreach стал быстрее, чем специализированные функции работы с массивами?

Я ж писал
Я wrote:

Я могу, конечно, ошибаться, но in_array это тот же цикл по массиву

Если это не так, то объясни мне, как работает in_array?

Аватар пользователя gun_dose gun_dose 18 декабря 2017 в 22:26

Нада смотреть в исходниках пхп. Но поскольку сам цикл в in_array написан на более быстром, чем пхп языке, то должен быть быстрее. Ну да ладно, опустим момент скорости. Где там два цикла то?

Аватар пользователя ХулиGUN ХулиGUN 18 декабря 2017 в 22:25

gun_dose wrote:

Где там два прохода?

Первый проход проверяет оператора, второй - администратора.
Алексей, будьте любезны объяснить чем именно кроме слова "специализированная" foreach отличается от in_array

Bumble , + 1. Ещё лучше решение:
<?php  return (isset($user->roles[$rid1]) || isset($user->roles[$rid2]) ) ?>

Аватар пользователя ХулиGUN ХулиGUN 18 декабря 2017 в 22:43

gun_dose wrote:

за один проход можно решить через array_intersect

опять же судя из ссылки Антона $user->roles - массив, где ключами выступают айдишники ролей.
То есть для интерсекта нужно составить сперва соответствующий массив для оператора и администратора, и потом проверить длину чтобы вернуть булево значение. Как по мне через isset проще, короче и понятнее

Аватар пользователя gun_dose gun_dose 18 декабря 2017 в 22:46

Через иссет нельзя проверить две роли сразу.

А вообще, по-правильному нужно проверять не роли, пермишены.

Аватар пользователя fairrandir fairrandir 19 декабря 2017 в 10:00

Вот просто спасибо. А я дурак всю жизнь проверял через

<?php
isset($var1) && isset($var2)
?>

Теперь чувствую себя полным идиотом.

Аватар пользователя ХулиGUN ХулиGUN 18 декабря 2017 в 22:49

gun_dose wrote:

Даже взгуглить не поленился:

Ну и? При строгой типизации - одинаковое время выполнения. При нестрогой in_array чуть быстрее. При чём в примере при нахождении элемента foreach не прерывает цикл)))