gpt4 book ai didi

drupal - 如何使用 hook_menu_alter() 来操作路径访问控制

转载 作者:行者123 更新时间:2023-12-01 06:59:41 24 4
gpt4 key购买 nike

/**
* Implementation of hook_menu_alter().
*/
function joke_menu_alter(&$callbacks) {
// If the user does not have 'administer nodes' permission,
// disable the joke menu item by setting its access callback to FALSE.
if (!user_access('administer nodes')) {
$callbacks['node/add/joke']['access callback'] = FALSE;
// Must unset access arguments or Drupal will use user_access()
// as a default access callback.
unset($callbacks['node/add/joke']['access arguments']);
}
}

以上功能来自亲开发drupal。我不能很好地理解它。为什么我必须取消设置访问参数 (unset($callbacks['node/add/joke']['access arguments']);) ?

谢谢你。

最佳答案

整个例子看起来很糟糕。简而言之,一个笑话。首先,让我回答您的问题,然后我将继续解释为什么您不应该在实践中遵循该示例。

来自includes/menu.inc:

if (!isset($item['access callback']) && isset($item['access arguments'])) {
// Default callback.
$item['access callback'] = 'user_access';
}

当您不再需要访问回调时取消设置访问回调(毕竟现在依赖于 bool 值)可防止 Drupal 路由系统中过于聪明的逻辑在 user_access() 中受到影响。只是为了它有事可做。

现在,为什么这是糟糕的代码。
hook_menu()hook_menu_alter()两者都在缓存清除时运行(更具体地说,在重建菜单路由系统时)。这意味着无论哪个用户访问站点以重建菜单的权限都将被硬编码到菜单路由行为中。这是一个非常糟糕和不一致的安排。

如果要根据权限阻止对路径的访问,则需要将回调更改为将测试该权限的内容。然后当菜单被重建时,它会在每次页面加载时检查新的回调函数,看看当前用户是否应该被授予权限。

一个简单的例子可能如下所示:
/**
* Implementation of hook_menu_alter().
*/
function joke_menu_alter(&$items) {
$items['node/add/joke']['access callback'] = 'user_access';
$items['node/add/joke']['access arguments'] = array('administer nodes');
}

现在我们有一个函数,它采用 node/add/joke 路径并声明唯一重要的是用户是否拥有 administer nodes允许。当然,这比示例的明显意图要有限一些,即保留现有的访问控制,但也要求用户拥有 administer nodes允许。

这也是可以修复的,但更复杂。从 Spaces 借用一些概念项目:
/**
* Implementation of hook_menu_alter().
*/
function joke_menu_alter(&$items) {
$path = 'node/add/joke';
$items[$path]['access arguments'][] = $items[$path]['access callback'];
$items[$path]['access callback'] = 'joke_menu_access';
}

function joke_menu_access() {
$args = func_get_args();
$access_callback = array_pop($args);
$original_access = call_user_func_array($access_callback, $args);
return $original_access && user_access('administer nodes');
}

我们已经成功地将原始访问回调封装在一个新的访问回调中,我们可以向其中添加我们需要的任何附加逻辑。

请注意,在最后两个函数示例中,我使用了 $path变量以保持代码简单。我也分开了 $original_access到它自己的线路并先检查,实际上我会检查 user_access()首先,它几乎肯定会比原始访问回调中发生的任何事情都具有更高的性能。

关于drupal - 如何使用 hook_menu_alter() 来操作路径访问控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5124584/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com