北哥這篇文講解yii2許可權擴充套件(yii2-admin) - 下部

阿北哥ya發表於2017-08-08

繼續上一篇,我們接著說yii2-admin中的menu。

傳送門

Menu

接下來說一下選單,我想這也是大家都很在意的一塊。我們期望得到一種結果,當一個角色登陸後,ta只會看到和自己相關的選單。

看看yii2-admin如何去實現~

為了更清晰的使用和理解,我們先構造一個許可權系統作為例子,如圖。

許可權結構
許可權結構

話說選單也是需要配置的,開啟yii2-admin的Menu,然後建立能被yii2-admin控制的選單。

新建選單表單
新建選單表單

一個一個說吧

  • ① 選單的名字,這個不用多說了
  • ② 父級,如果沒有不用填寫,有則寫父級選單名字
  • ③ Route,這個是重要的,這些就是我們納入了yii2-admin體系的路由列表,比如我本次的goods下的action
  • ④ 排序,同級選單的排序,按照所填數字從小向大升序來。
  • ⑤ 資料,這裡留坑,即將填。

我們新建瞭如下單的選單

選單結構
選單結構

現在我們已經有了帶角色功能的選單,現在開始在檢視中使用它。

使用選單

好在yii2-admin提供了一個方法來獲得某個角色的選單陣列

use mdm\admin\components\MenuHelper;
MenuHelper::getAssignedMenu(Yii::$app->user->id)複製程式碼

我們使用MenuHelper來獲得登入會員的角色選單,它返回一個多維陣列,如下面程式碼這樣。

[
    [
        'label' => $menu['name'], 
        'url' => [$menu['route']],
        'items' => [
            [
                'label' => $menu['name'], 
                'url' => [$menu['route']]
            ],
            ....
        ]
    ],
    [
        'label' => $menu['name'], 
        'url' => [$menu['route']],
        'items' => [
            [
                'label' => $menu['name'], 
                'url' => [$menu['route']]
            ]
        ]
    ],
    ....
]複製程式碼

這個你熟悉吧,yii2的nav掛件需要的陣列格式。

來實戰下,在goods/index檢視寫如下程式碼

use mdm\admin\components\MenuHelper;
\yii\helpers\VarDumper::dump(MenuHelper::getAssignedMenu(Yii::$app->user->id),10,true);die();複製程式碼

下面我們分別用 abei(master-role角色)和abei-kefu(kefu-role角色)登入,看看效果。

很好很好
很好很好

很高興,從結果驗證了yii2-admin很聰明的按照角色返回選單陣列了。

ok,現在我們回過頭來說新建選單時候的那個Data區域,我現在有個需求,剛才我建立了名字為goods、goods-index、goods-create的選單,但是我不想這樣顯示,我希望在瀏覽器上的顯示為“商品管理”、“商品列表”、“新建商品”。

用Data區域就可以實現此目的。

當然核心是用yii2-admin對MenuHelper::getAssignedMenu返回的選單陣列進行格式化的功能,那開始吧,只需在goods/index的檢視裡增加一個回撥函式,如下

use mdm\admin\components\MenuHelper;
$callback = function($menu){
    $data = $menu['data'];
    return [
        'label' => $data ? $data : $menu['name'],
        'url' => [$menu['route']],
        'items' => $menu['children']
    ];
};

$items = MenuHelper::getAssignedMenu(Yii::$app->user->id, null, $callback);
\yii\helpers\VarDumper::dump($items,10,true);die();複製程式碼

其中的$menu['data']就是我們填寫的值,當然其實這個區域可以填寫更多複雜的東東(比如一句PHP語句)。我的邏輯很簡單,對於每一個選單項,如果有設定data值,則用data值替代name成為顯示的label,否則還是用name;

看看結果吧

data還可以做更多
data還可以做更多

又學會了一點點,繼續往下,到現在我們得到了一個陣列,下面來做一個實際效果,將這個陣列弄到yii2的選單中

// view/goods/index
use mdm\admin\components\MenuHelper;
use yii\bootstrap\Nav;
$callback = function($menu){
    $data = $menu['data'];
    return [
        'label' => $data ? $data : $menu['name'],
        'url' => [$menu['route']],
        'items' => $menu['children']
    ];
};

$items = MenuHelper::getAssignedMenu(Yii::$app->user->id, null, $callback);

echo Nav::widget(['items'=>$items]);複製程式碼

alt
alt

好,就是我想要的。到此刻我們構造出了一個二維的選單,當然多維也是一樣的邏輯,這裡還要說一個地方。

getAssignedMenu

要說的是這個函式的第二個引數,預設為null,獲取整個選單結構,當我們為其傳遞一個選單節點的時候,則可以獲得該節點的子選單。

但是要注意的是:引數值是節點選單的ID,而不是name,這點要切記。

另一種情況

我們前面是通過登陸會員得到對應選單陣列然後渲染,在世界上還有一種情景就是一個完整的選單就放到那裡,會員登陸後篩選出自己的部分。

好在yii2-admin也可以幫我們實現,我們來code下。

use mdm\admin\components\Helper;

//    完整的選單
$menuItems = [
    ['label' => '', 'url' => ['/site/index']],
    ['label' => 'About', 'url' => ['/site/about']],
    ['label' => 'Contact', 'url' => ['/site/contact']],
    ['label' => '商品管理', 'items' => [
        ['label' => '商品列表', 'url' => ['/goods/index']],
        ['label' => '新建商品', 'url' => ['/goods/create']],
    ]]
];

$menuItems = Helper::filter($menuItems);

echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    'items' => $menuItems,
]);複製程式碼

我們通過Helper::filter函式對其進行了篩選,看看結果

結果符合預期
結果符合預期

從結果你應該能知道,這是一次非常嚴格的篩選,首先要根據yii2-admin設定的menu匹配,然後你還要有許可權的才會顯示,很嚴格。

關於Helper::checkRoute

從上面的例子我們知道在檢視裡主要靠 mdm\admin\components\Helper 來搞定這些事情,它還提供了一個checkRoute,引數是一個路由,用來判斷當前會員是否對某個路由有許可權,比如如下程式碼

use mdm\admin\components\Helper;

if(Helper::checkRoute('/goods/delete')){
       //...
}複製程式碼

到此刻位置,yii2-admin關於menu的使用就完事了,當然細節還有不少,以後慢慢慢說

關於按鈕

當我們使用GridView的時候,一般最後一列都是一對action按鈕,那麼不同的角色對這些按鈕可能操作許可權是不同的,yii2-admin也為我們提供了這個場景的篩選,見程式碼

use mdm\admin\components\Helper;

'columns' => [
    ...
    [
        'class' => 'yii\grid\ActionColumn',
        'template' => Helper::filterActionColumn('{view}{delete}{posting}'),
    ]
]複製程式碼

對,使用 Helper::filterActionColumn就可以,當然你在GridView的buttons裡用Helper::checkRoute來判斷我也沒意見,喜歡哪個用哪個。

總結下

到此刻為止,我們用3篇把yii2-admin官方的文件 + 一點小例子就算說完了,算是一個入門級的中文文件,接下來我們會對這個擴充套件那些細節配置及實際使用中的情景進行解說,明天繼續聊。


簽名檔
簽名檔

相關文章