整個例子似乎壞了。總之,一個笑話。首先,讓我回答你的問題,然後我會繼續解釋爲什麼你不應該在實踐中遵循這個例子。
從包括/ menu.inc:
if (!isset($item['access callback']) && isset($item['access arguments'])) {
// Default callback.
$item['access callback'] = 'user_access';
}
解封訪問回調,當你不再需要他們(靠一個布爾值,畢竟現在)防止過度聰明的邏輯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');
}
現在我們有一個函數,使用節點/添加/笑話路徑並宣佈只事情,重要的是,是否用戶有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()
,因爲它幾乎可以肯定比原始訪問回調中發生的任何事情都更有效。
我只是想增加一個謝謝,即使投票後,不僅告訴OP如何,但爲什麼*!哦,我希望有一個加10當答案深入。 – Richard 2013-09-04 14:45:26