PHPCMS 後台支援角色權限控制,可限制特定角色存取特定欄目。但預設左側選單仍會顯示所有欄目名稱,即便用戶無權存取,造成介面混淆與操作困擾。需修改選單生成邏輯,依權限動態過濾選單項目。
?mod=phpcms&file=menu&action=get_menu_list&menuid=4admin/menu.inc.php 的 get_menu_list 方法$m->get_child($menuid) 取得子選單,直接 JSON 輸出case 'get_menu_list':
$data = $m->get_child($menuid);
$data = str_charset(CHARSET, 'utf-8', $data);
$max = array_slice($data, -1);
$data['max'] = $max[0]['menuid'];
$data = json_encode($data);
if (PHP_OS < 5.0) header('Content-type: text/html; charset=utf-8');
echo $data;
break;
case 'get_menu_list':
$data = $m->get_child($menuid);
// 遍歷選單項目,檢查欄目管理權限
foreach ($data as $k => $val) {
// 僅處理欄目類型選單 (keyid 格式: catid_XX)
if (!empty($data[$k]['keyid']) && substr($data[$k]['keyid'], 0, 5) == 'catid') {
// catid_0 為根節點,保留
if ($data[$k]['keyid'] == 'catid_0') {
continue;
}
// 提取欄目 ID
$catid = str_replace("catid_", "", $data[$k]['keyid']);
// 檢查管理權限
$allow_manage = $priv_role->check('catid', $catid, 'manage');
// 無權限則移除選單項目
if (!$allow_manage) {
unset($data[$k]);
}
}
}
$data = str_charset(CHARSET, 'utf-8', $data);
$max = array_slice($data, -1);
$data['max'] = $max[0]['menuid'];
$data = json_encode($data);
if (PHP_OS < 5.0) header('Content-type: text/html; charset=utf-8');
echo $data;
break;
| 程式碼片段 | 用途 |
|---|---|
substr($keyid, 0, 5) == 'catid' | 識別欄目類型選單項目(區分模組、功能等其他類型) |
str_replace("catid_", "", $keyid) | 從 catid_123 格式提取數字 ID |
$priv_role->check('catid', $catid, 'manage') | 呼叫權限類別檢查當前角色是否有該欄目管理權限 |
unset($data[$k]) | 從陣列移除無權限項目,不影響 JSON 編碼輸出 |
menu_{roleid}_{menuid})view、edit、delete 等細粒度權限// 前端 AJAX 請求加入快取參數
$.ajax({
type: 'get',
url: '?mod=phpcms&file=menu&action=get_menu_list&menuid=' + id,
cache: true, // 啟用瀏覽器快取
dataType: 'json',
success: function(json) {
// 渲染選單邏輯
}
});
admin/menu.inc.php 會影響系統升級,建議透過模組擴充或 Hook 機制實現$priv_role 需確認已正確載入(通常在控制器建構子中初始化)