yii2权限控制rbac之菜单menu最详细教程
前面我们在博文 yii2搭建完美后台并实现rbac权限控制实例教程中完美实现了yii2的后台搭建和rbac权限控制,如果你还没有实现,请先看上文再回来参考本文,因为本文是在上文的基础上进行完善和补充。
先认个错,罪过了,你将要看的这篇教程是菜单权限的扩展,如果你的菜单出不来,很是建议你参考 yii2 rbac权限控制详细操作步骤
部分小伙们纷纷反映,最后菜单menu怎么控制权限呀,看不懂,搞不定,而且你那貌似没搞完,瞎忽悠!确实没那么全,今天看我们如何实现菜单完美权限化。先罗列下主要讲的内容,不需要的没必要看下去,只为分享给有需要的人。
- 利用menu表添加菜单
- 左侧菜单结果adminlte完美呈现
- 菜单前面自定义icon小图标并呈现
- 如何控制菜单的显示或者隐藏
- 多控制器激活当前菜单
- 页面操作按钮没权限的不做显示
- gridview中也只显示有操作权限的按钮
嗯,差不多就这么多,如果你还有其他的有关权限控制菜单的需求,请下方留言,咱们共同交流。
先看图预览下大致效果,不然怎么激起你们好学的心。
首先我们先访问路由页面 /admin/route/index ,尽可能的把左侧的全部选中,移动到右侧,最后记得给当前用户分配相关的可访问权限哦。
接下来访问菜单列表 /admin/menu/index 点击添加菜单,如果这个时候你没有访问权限,你可以修改配置文件的 as access 项 allowActions选项为 “*”,暂时允许当前用户访问任意权限,记得一定要在添加完权限的时候去掉 as access 的设置,不然权限失效了可别回来找我。
这里我们先填写上图中标红的四个字段
举个例子:我们要添加一级菜单"权限管理"
名称请填写"权限管理",因为是一级菜单,父级名称请留空,路由我们这里选择"/admin/default/index",注意了,这里要添加的路由,一定要是路由页面 /admin/route/index右侧罗列出来的。
映射,其实就是排序高低的问题,比如说我添加了两个菜单,映射值为1的就在上面 值为2的就在1的下面,我们这里填写数字1。
"数据"这一项我们后面再说。
按照刚刚介绍的这种方式添加吧,举一个添加二级菜单"权限控制"的例子
只需要把父级名称这里填写我们刚刚添加成功的一级名称"权限管理"即可。其他照旧。不会操作的多看两遍,这里最好把权限管理的几个菜单全部添加完毕,因为接下来我们需要而且你可以多练练手。
到此我们已经会添加菜单了。
我们来看下一步,利用我们之前搭建的后台框架进行展现。
use mdm\admin\components\MenuHelper; echo dmstr\widgets\Menu::widget( [ 'options' => ['class' => 'sidebar-menu'], 'items' => MenuHelper::getAssignedMenu(Yii::$app->user->id), ] );
是不是很简单,What?我的怎么没有dmstr这玩意,不好意思,已经说的很多遍,需要先看上文再有这个菜单的结合。
ok,刷新页面看看你的菜单,虽然我们还没完全实现我们想要的功能,不过到此你应该能看到你的菜单展现了。
接下来将进入我们的重点以及难点,我们要实现菜单前面的小图标且完成菜单可隐藏控制。
还记得我们一开始创建菜单的时候,唯一没进行填写的选项"数据"吗?
以“博客管理”这个二级菜单为例,我们在“数据”这一项这样填写
{"icon": "book", "visible": true}
截图如下
这句话是什么意思呢?注意这个"数据"项我们填写的是一段json代码,这里我们现在只定制了两个key: icon和visible,icon是菜单小图标,可选项参考这里,visible是“显示”的意思,可以显示或者隐藏菜单项。我们刚刚也说了,这两个key是我们自己定制的,既然如此,那我们自然也需要写程序实现相应的功能。
找到菜单输出的地方(left.php),我们对mdm\admin\components\MenuHelper::getAssignedMenu方法完善一下。代码如下:
use mdm\admin\components\MenuHelper; <?php $callback = function($menu){ $data = json_decode($menu['data'], true); $items = $menu['children']; $return = [ 'label' => $menu['name'], 'url' => [$menu['route']], ]; //处理我们的配置 if ($data) { //visible isset($data['visible']) && $return['visible'] = $data['visible']; //icon isset($data['icon']) && $data['icon'] && $return['icon'] = $data['icon']; //other attribute e.g. class... $return['options'] = $data; } //没配置图标的显示默认图标,默认图标大家可以自己随便修改 (!isset($return['icon']) || !$return['icon']) && $return['icon'] = 'circle-o'; $items && $return['items'] = $items; return $return; }; //这里我们对一开始写的菜单menu进行了优化 echo dmstr\widgets\Menu::widget( [ 'options' => ['class' => 'sidebar-menu'], 'items' => MenuHelper::getAssignedMenu(Yii::$app->user->id, null, $callback), ] ); ?>
可以看出我们已经完美的实现了给菜单添加小图标和设置菜单隐藏的问题。如果你有其他的属性需要进行配置,可以自行扩展。
关于多控制器的激活,什么意思呢?我来阐述两句。
比如说我们现在要访问的菜单,其路由是/test/index,如果正常激活菜单的话,当我们访问/test/*的时候,其对应的左侧菜单自然会处于激活状态,但是,我们想要的一种效果是,当访问/test2/*(注意哦,这里是test2另外一个控制器)的时候我们也想要激活当前菜单/test/index怎么办好呢?为了文章的阅读性更强,该问题属于后期增添的,如果你有兴趣,请移步yii2左侧菜单子级无法高亮的问题参考。
现在,我们还有两个任务仍待完成,要完成接下来的两个任务,为了大家的方便,建议你的项目可以自定义配置gii模版,不支持自定义gii模板的可以参考自定义gii模版 当你发现我们后面需要做的功能,我觉得你会赞叹我们这里的操作。
为了方便操作,我们这里增加一个测试表test,我们先用未做修改的gii模版生成一份model+curd。我们先把test/*的所有权限分配给当前登录的用户,并添加一条数据。打开/test我们可以正常看到下面的截图,注意图中的两个标记。
然后我们打开test/index.php文件,对标记的两个地方进行如下修改
use mdm\admin\components\Helper; <?php //没有创建权限不显示按钮 if(Helper::checkRoute('create')) { echo Html::a('Create Test', ['create'], ['class' => 'btn btn-success']); } ?> <?= GridView::widget([ // ...... 'columns' => [ // ...... [ 'class' => 'yii\grid\ActionColumn', 'template' => Helper::filterActionColumn('{view}{update}{delete}'), ], ], ]); ?>
现在我们刷新下页面/test再看看,好像没什么变化嘛。别急,我们现在撤销当前用户的/test/*、 /test/create 权限和/test/update权限,然后你再刷新下页面看看效果,我们截图看看。
也就是说我们没有权限的按钮消失了,当你手动访问/test/create的时候你会发现也会提醒你没有权限。
如果你的gii模板是自定义的,相信你会迅速在其生成的模板中所有的操作上添加权限控制的,是不是很happy?
最后,我们的菜单menu关于权限控制的讲解基本也就结束了,长篇大论,仔细回想起来也没多少东西,倒是希望能帮到你一二