Answers:
如果要验证当前登录的用户是否有权访问页面,可以使用以下代码:
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
// The user has access to the page in $path.
}
}
$path
是您要检查的页面的路径(例如,node / 1,admin / user / user)。
该代码可在Drupal 6和更高版本中使用,它是menu_execute_active_handler()中使用的代码。
我不建议直接调用访问回调的原因是因为需要将参数传递给该函数。
_menu_check_access()使用的代码如下(Drupal 7):
$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,则传递给访问回调的第二个参数是节点ID等于1的节点的节点对象。
编写处理这些情况的代码也将意味着重复代码。在Drupal中已经存在。即使您重复了该代码,访问回调仍存在问题,即正在根据当前登录的用户检查访问。
如果要检查不是当前登录用户的用户是否可以访问菜单,请首先更改全局变量的值$user
,然后使用我在答案开头报告的代码,然后恢复的值。$user
。有关如何更改全局值的信息$user
,请参见以编程方式模拟其他用户而不会导致当前登录的用户注销。区别在于,不是使用drupal_anonymous_user()返回的值,而是使用user_load()返回的值。
该函数返回的TRUE
是存在参数时传递的路径,当前用户可以访问该路径。因此,如果您正在使用Drupal 7,并且需要检查当前登录用户的访问权限,那么这是最简单的方法:
if (drupal_valid_path('my/path')) {
// Your code here...
}
drupal_valid_path
可以完美地完成工作,并且可以满足这一确切需求。它使用menu_get_item并检查访问。
drupal_valid_path
将无济于事。
\Drupal::service('path.validator')->isValid($path);
-参见API文档
调用在access callback
负责该页面的菜单项中指定的。该菜单项通常是由Drupal调用的实现创建的,hook_menu
并存储在数据库中的某个位置。请注意,hook_menu
实现的模块可能会更改所返回的数据hook_menu_alter
。
请注意,某些模块可能不会将用户作为单独的参数传递(由access arguments
菜单项的键指定),而是可能改为使用全局$user
对象。您将必须为所使用的每个模块进行检查。
检查user_access()
功能。有关每个Drupal版本的指定参数,请参见链接。在Drupal 7-8的文档页面中:
参量
$ string正在检查权限,例如“管理节点”。
$ account(可选)要检查的帐户(如果未使用当前登录的用户)。
返回值
布尔值TRUE(如果当前用户具有所请求的权限)。
Drupal中的所有权限检查都应通过此功能。这样,我们保证行为一致,并确保超级用户可以执行所有操作。
user_access()
并不总是菜单使用的访问回调;即使是这样,您也应该知道需要传递给的访问参数user_access()
。
user_access()
,只是想出OP有权限检查用户是否应该具有访问权限。这不是一个描述性很强的问题
如果需要知道用户是否可以访问特定节点并且正在使用节点访问模块,则可以使用node_access()。(没有节点访问模块,他们只需要“访问内容”权限。)
如果要确定用户是否可以访问由hook_menu()实现定义的任意路径,则可能必须从数据库中检索菜单项并评估其“访问回调”参数。
$node = node_load(123);
$account = user_load(456);
if (node_access("update", $node, $account) === TRUE)
{
print "access";
}