Вы не указали, какую версию Drupal вы используете. Более подробная информация о вашей цели также будет полезна; в наиболее распространенных случаях Drupal автоматически обрабатывает доступ к меню.
Дилан Тэк
Ответы:
25
Если вы хотите проверить, есть ли у вошедшего в систему пользователя доступ к странице, вы можете использовать следующий код:
if($router_item = menu_get_item($path)){if($router_item['access']){// The user has access to the page in $path.}}
$path это путь к странице, которую вы хотите проверить (например, узел / 1, администратор / пользователь / пользователь).
Причина, по которой я не предлагаю напрямую вызывать обратный вызов доступа, заключается в том, что аргументы, которые необходимо передать этой функции.
$arguments = menu_unserialize($item['access_arguments'], $map);// As call_user_func_array is quite slow and user_access is a very common// callback, it is worth making a special case for it.if($callback =='user_access'){
$item['access']=(count($arguments)==1)? user_access($arguments[0]): user_access($arguments[0], $arguments[1]);}
elseif (function_exists($callback)){
$item['access']= call_user_func_array($callback, $arguments);}
Код, который должен быть как можно более универсальным, напрямую не обрабатывает пользовательский объект. Это означает, что невозможно заменить объект пользователя для текущего пользователя, вошедшего в систему, другим объектом пользователя.
Код должен быть достаточно универсальным для обработки определений меню, таких как следующие:
$items['node/add/'. $type_url_str]= array('title'=> $type->name,'title callback'=>'check_plain','page callback'=>'node_add','page arguments'=> array($type->type),'access callback'=>'node_access','access arguments'=> array('create', $type->type),'description'=> $type->description,'file'=>'node.pages.inc',);
$items['node/%node']= array('title callback'=>'node_page_title','title arguments'=> array(1),// The page callback also invokes drupal_set_title() in case// the menu router's title is overridden by a menu link. 'page callback'=>'node_page_view','page arguments'=> array(1),'access callback'=>'node_access','access arguments'=> array('view',1),);
В обоих определениях аргументы доступа не включают объект пользователя, и в этом случае node_access () использует объект пользователя для текущего пользователя, вошедшего в систему. Во втором случае одним из аргументов является объект узла, полученный из URL; например, если URL-адрес example.com/node/1, то второй аргумент, переданный обратному вызову доступа, является объектом узла для узла с идентификатором узла, равным 1.
Написание кода, который обрабатывает эти случаи, также будет означать дублирование кода уже существует в Drupal. Даже если вы продублировали этот код, все равно будет проблема обратных вызовов доступа, которые проверяют доступ по отношению к вошедшему в данный момент пользователю.
Если вы хотите проверить, может ли пользователь, не являющийся в данный момент вошедшим в систему пользователем, получить доступ к меню, сначала измените значение глобальной переменной $user, используйте код, который я сообщил в начале моего ответа, а затем восстановите значение $user, Чтобы узнать, как изменить значение global $user, вы можете увидеть, как программно выдает себя за другого пользователя, не вызывая текущего пользователя, вошедшего в систему . Разница в том, что вместо использования значения, возвращаемого от drupal_anonymous_user () , вы используете значение, возвращаемое из user_load () .
Функция возвращает TRUEпуть, переданный в качестве аргумента, и текущий пользователь имеет к нему доступ. Итак, если вы работаете над Drupal 7 и вам нужно проверить доступ к текущему вошедшему в систему пользователю, это самый простой способ:
if(drupal_valid_path('my/path')){// Your code here...}
В D7 drupal_valid_pathотлично справляется со своей задачей и делает это именно для этого. Он использует menu_get_item и также проверяет доступ.
Weboide
Это правда, но это работает только для текущего пользователя. Если вы хотите узнать, может ли какой-либо другой пользователь получить доступ к пути, вам drupal_valid_pathэто не поможет.
Эндрю Шульман
@ AndrewSchulman Не думаю, что для этого есть API, но вы можете временно переключать пользователей.
peterpoe
В Drupal 8 это переместилось \Drupal::service('path.validator')->isValid($path);- см. Документацию
Gogowitsch
3
Вызовите тот, access callbackкоторый указан в пункте меню, который отвечает за страницу. Этот пункт меню обычно создается Drupal, вызывающим реализацию, hook_menuи сохраняется где-то в базе данных. Помните, что возвращаемые данные hook_menuмогут быть изменены модулем реализации hook_menu_alter.
Помните, что некоторые модули могут не передавать пользователя в качестве отдельного аргумента (как указано access argumentsключом пункта меню), но вместо этого могут использовать глобальный $userобъект. Вы должны будете проверить это для каждого модуля, который вы используете.
Этот метод может использоваться, чтобы узнать, разрешен ли доступ к странице другому пользователю, кроме действующего пользователя.
Освальд
1
Вызов обратного вызова доступа не так прост, как вызов любой другой функции, так как обратный вызов доступа требует определенных аргументов; смотрите _menu_check_access () , которая является функцией, которая проверяет, есть ли у текущего вошедшего в систему пользователя доступ к меню.
kiamlaluno
2
Проверьте user_access()функцию. Смотрите ссылку на указанные параметры для каждой версии Drupal. Со страницы документации для Drupal 7-8:
параметры
$ string Разрешение, такое как «администрировать узлы», проверяется на наличие.
$ account (необязательно) Аккаунт, который нужно проверить, если не указан, использовать вошедшего в систему пользователя.
Возвращаемое значение
Boolean TRUE, если текущий пользователь имеет запрошенное разрешение.
Все проверки прав доступа в Drupal должны проходить через эту функцию. Таким образом, мы гарантируем согласованное поведение и гарантируем, что суперпользователь может выполнять все действия.
user_access () предназначен для проверки, имеет ли пользователь определенный «тип» разрешений. Что нужно, если пользователь может получить доступ к определенному «пути»; например, если пользователь может получить доступ к «узлу / 12»?
Фарзан
Ну как вы определяете, когда у пользователя есть разрешение или нет? Я бы предположил, что на странице разрешений есть опция, которую вы либо проверили, либо нет, чтобы разрешить определенные роли
Laxman13
user_access()не всегда обратный вызов доступа, используемый меню; даже если бы это было так, вы должны знать аргументы доступа, которые вам нужно передать user_access().
kiamlaluno
Я знаю, что это не всегда user_access(), просто решил, что у ОП есть разрешение проверить, есть ли у пользователя доступ. Не очень описательный вопрос
Laxman13
Несмотря на то, что user_access не может проверить доступ к определенному пути, я думаю, что использование user_access всегда, когда это возможно, лучший способ проверить доступ. Хороший ответ @ Laxman13 +1.
AyeshK
2
Если вам нужно знать, может ли пользователь получить доступ к определенному узлу и использует ли модуль доступа к узлу, вы можете использовать node_access () . (без модуля доступа к узлу им просто нужно разрешение «доступ к содержимому».)
Если вы хотите выяснить, может ли пользователь получить доступ к произвольному пути, который определен реализацией hook_menu (), вам, возможно, придется извлечь пункт меню из базы данных и оценить его параметр «обратный вызов доступа».
Ответы:
Если вы хотите проверить, есть ли у вошедшего в систему пользователя доступ к странице, вы можете использовать следующий код:
$path
это путь к странице, которую вы хотите проверить (например, узел / 1, администратор / пользователь / пользователь).Код работает в Drupal 6 и более поздних версиях, и он используется из menu_execute_active_handler () .
Причина, по которой я не предлагаю напрямую вызывать обратный вызов доступа, заключается в том, что аргументы, которые необходимо передать этой функции.
Код, используемый _menu_check_access (), следующий (Drupal 7):
Код, который должен быть как можно более универсальным, напрямую не обрабатывает пользовательский объект. Это означает, что невозможно заменить объект пользователя для текущего пользователя, вошедшего в систему, другим объектом пользователя.
Код должен быть достаточно универсальным для обработки определений меню, таких как следующие:
В обоих определениях аргументы доступа не включают объект пользователя, и в этом случае node_access () использует объект пользователя для текущего пользователя, вошедшего в систему. Во втором случае одним из аргументов является объект узла, полученный из URL; например, если URL-адрес example.com/node/1, то второй аргумент, переданный обратному вызову доступа, является объектом узла для узла с идентификатором узла, равным 1.
Написание кода, который обрабатывает эти случаи, также будет означать дублирование кода уже существует в Drupal. Даже если вы продублировали этот код, все равно будет проблема обратных вызовов доступа, которые проверяют доступ по отношению к вошедшему в данный момент пользователю.
Если вы хотите проверить, может ли пользователь, не являющийся в данный момент вошедшим в систему пользователем, получить доступ к меню, сначала измените значение глобальной переменной
$user
, используйте код, который я сообщил в начале моего ответа, а затем восстановите значение$user
, Чтобы узнать, как изменить значение global$user
, вы можете увидеть, как программно выдает себя за другого пользователя, не вызывая текущего пользователя, вошедшего в систему . Разница в том, что вместо использования значения, возвращаемого от drupal_anonymous_user () , вы используете значение, возвращаемое из user_load () .источник
Попробуйте drupal_valid_path () .
Функция возвращает
TRUE
путь, переданный в качестве аргумента, и текущий пользователь имеет к нему доступ. Итак, если вы работаете над Drupal 7 и вам нужно проверить доступ к текущему вошедшему в систему пользователю, это самый простой способ:источник
drupal_valid_path
отлично справляется со своей задачей и делает это именно для этого. Он использует menu_get_item и также проверяет доступ.drupal_valid_path
это не поможет.\Drupal::service('path.validator')->isValid($path);
- см. ДокументациюВызовите тот,
access callback
который указан в пункте меню, который отвечает за страницу. Этот пункт меню обычно создается Drupal, вызывающим реализацию,hook_menu
и сохраняется где-то в базе данных. Помните, что возвращаемые данныеhook_menu
могут быть изменены модулем реализацииhook_menu_alter
.Помните, что некоторые модули могут не передавать пользователя в качестве отдельного аргумента (как указано
access arguments
ключом пункта меню), но вместо этого могут использовать глобальный$user
объект. Вы должны будете проверить это для каждого модуля, который вы используете.источник
Проверьте
user_access()
функцию. Смотрите ссылку на указанные параметры для каждой версии Drupal. Со страницы документации для Drupal 7-8:источник
user_access()
не всегда обратный вызов доступа, используемый меню; даже если бы это было так, вы должны знать аргументы доступа, которые вам нужно передатьuser_access()
.user_access()
, просто решил, что у ОП есть разрешение проверить, есть ли у пользователя доступ. Не очень описательный вопросЕсли вам нужно знать, может ли пользователь получить доступ к определенному узлу и использует ли модуль доступа к узлу, вы можете использовать node_access () . (без модуля доступа к узлу им просто нужно разрешение «доступ к содержимому».)
Если вы хотите выяснить, может ли пользователь получить доступ к произвольному пути, который определен реализацией hook_menu (), вам, возможно, придется извлечь пункт меню из базы данных и оценить его параметр «обратный вызов доступа».
источник
источник