mdmsoft / yii2-admin

Auth manager for Yii2 (RBAC Manager)
GNU General Public License v3.0
1.16k stars 577 forks source link

Display menu items based on role with rule #236

Open nlrooat opened 8 years ago

nlrooat commented 8 years ago

Hi,

I'm having a role X with rule Y. User Z has role X assigned. There is a menu-item M with a route R that is linked to the role X. Now, when rule Y returns false, X cannot access R (Yii::$app->user->can('R') returns false). When rule Y returns true, X can access R. This is as expected.

My problem is that the menu-item M is always displayed for user Z, no matter the result of Y. Is there a (clean) way to hide menu-item M for user Z when Y returns false?

Thanks for your input!

mdmunir commented 8 years ago

Are you using MenuHelper::getAssignedMenu()? Currently MenuHelper::getAssignedMenu() not check for rule. Try using Helper::filter().

user mdm\admin\components\Helper;

$menuItems = [
    ['label' => 'Home', 'url' => ['/site/index']],
    ['label' => 'About', 'url' => ['/site/about']],
    ['label' => 'Contact', 'url' => ['/site/contact']],
    ['label' => 'Login', 'url' => ['/user/login']],
    [
        'label' => 'Logout (' . \Yii::$app->user->identity->username . ')',
        'url' => ['/user/logout'],
        'linkOptions' => ['data-method' => 'post']
    ],
    ['label' => 'App', 'items' => [
        ['label' => 'New Sales', 'url' => ['/sales/pos']],
        ['label' => 'New Purchase', 'url' => ['/purchase/create']],
        ['label' => 'GR', 'url' => ['/movement/create', 'type' => 'receive']],
        ['label' => 'GI', 'url' => ['/movement/create', 'type' => 'issue']],
    ]]
];

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

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

It will filter menu items base on role and rule. You can also check for individual route.

user mdm\admin\components\Helper;

if(Helper::checkRoute('delete')){
    echo Html::a(Yii::t('rbac-admin', 'Delete'), ['delete', 'id' => $model->name], [
            'class' => 'btn btn-danger',
            'data-confirm' => Yii::t('rbac-admin', 'Are you sure to delete this item?'),
            'data-method' => 'post',
        ]);
}
nlrooat commented 8 years ago

Are you using MenuHelper::getAssignedMenu()? Currently MenuHelper::getAssignedMenu() not check for rule. Try using Helper::filter().

You are right, I was using MenuHelper::getAssignedMenu(). Now I have the following code:

$items = MenuHelper::getAssignedMenu(Yii::$app->user->id);
$items = Helper::filter($items);
echo Nav::widget([
        'options' => ['class' => 'navbar-nav navbar-left'],
        'items' => $items,
]);

Problem now is that $items is an empty array after executing $items = Helper::filter($items);. Any ideas? Thanks for your help!

P.S. noticed a small typo (2 times) in your comment: 'user' instead of 'use'.

nlrooat commented 8 years ago

Found it, small mistake of swapping arguments. In Helper::filterRecursive() method, the line

$allow = static::checkRoute($userId, $item['url'][0]);

should be

$allow = static::checkRoute($item['url'][0], $userId);
mdmunir commented 8 years ago

https://github.com/mdmsoft/yii2-admin/blob/master/components/Helper.php#L181

nlrooat commented 8 years ago

Thanks, I see you already fixed it. I'm testing with version ~2.0, since I'm testing for a production environment. Any idea when this fix will be released in a stable version?

nordkite commented 8 years ago

If you are using RBAC.

['label' => Yii::t('menu', 'Menu item'), 'url' => ['/controller/index'], 'visible' => Yii::$app->user->can('role')],
epulgaron commented 6 years ago

If you are using RBAC.

['label' => Yii::t('menu', 'Menu item'), 'url' => ['/controller/index'], 'visible' => Yii::$app->user->can('role')],

i'm usig you solution but it doesnt work as i expected, if i use 'visible' => Yii::$app->user->can('role')], doesnt show anything but if i write 'visible' => !Yii::$app->user->can('role')] work as i expected, but i doesnt look right, could you throw some light please. thx

Prvnbp commented 5 years ago

If you are using RBAC.

['label' => Yii::t('menu', 'Menu item'), 'url' => ['/controller/index'], 'visible' => Yii::$app->user->can('role')],

I have 3 role one menu wants to show both role means how can i set using RBAC