yii : how to display the different menu(s) by user role?
Solution 1
If you're using RBAC you can set the 'visible' param of CMenu items depending on the users privileges, for example;
$this->widget('zii.widgets.CMenu',array(
'items'=>array(
array(
'label'=>'Home',
'url'=>array('site/index'),
),
array(
'label'=>'HR',
'url'=>array('/hr/index'),
'visible'=>Yii::app()->user->checkAccess('hr')
),
array(
'label'=>'Accounts',
'url'=>array('/account/index'),
'visible'=>Yii::app()->user->checkAccess('account')
),
array(
'label'=>'Operations',
'url'=>array('/operations/index'),
'visible'=>Yii::app()->user->checkAccess('operations')
),
),
);
This way users will only be able to see the items in the menu if they have access privileges for that area.
[EDIT]
As per simaremare's comment below, you can force caching of this query beyond the current request by extending CWebUser
. Firstly, set your user to run through your new class (we'll call it TWebUser
), so in your main.php config file;
'components'=>array(
'user'=>array(
...
'class'=>'TWebUser',
...
),
...
),
Now we need to create TWebUser
to cache these beyond the current request (which is what CWebUser
does (source code):
class TWebUser extends CWebUser
{
private $_access=array();
public function checkAccess($operation,$params=array(),$allowCaching=true)
{
if($allowCaching && $params===array() && isset($this->_access[$operation]))
return $this->_access[$operation];
$cache = Yii::app()->session['checkAccess'];
if($allowCaching && !$this->getIsGuest() && isset($cache[$operation]) && time() - $cache[$operation]['t'] < 1800)
{
$checkAccess = $cache[$operation]['p'];
} else {
$checkAccess = Yii::app()->getAuthManager()->checkAccess($operation,$this->getId(),$params);
if($allowCaching && !$this->getIsGuest())
{
$access = isset($cache) ? $cache : array();
$access[$operation] = array('p'=>$checkAccess, 't'=>time());
Yii::app()->session['checkAccess'] = $access;
}
}
return $this->_access[$operation] = $checkAccess;
}
}
Now your access results will be set for the whole session. This does mean that if you edit the RBAC permissions for a given account, they'll have to log out and log in again to see the new changes reflected in the browser.
I hope that helps! I'm sure I found this workaround from someone else (probably on SO), but I can't find the original post to give them credit.
Solution 2
You would wrap an if-statement around the menu-items that you may or may not want to show.
In the if-statement, you would have to test whether the user qualifies to see your menu-items.
For example:
<?php if (Yii::app()->user->isGuest): ?>
<?php $this->widget('zii.widgets.CMenu',array(
'items'=>array(
array(
'label'=>'this menu item visible only for Guests (not logged in)',
'url'=>array('/site/index')),
),
)); ?>
<?php endif; ?>
Thu Ra
Updated on June 26, 2022Comments
-
Thu Ra almost 2 years
Q : How can I show display different menu(s) by user role?
Description : the app has many roles. e.g HR manager, Account Manager, Operating Manager, Employee, Operator, ...., etc. I used rights and yii-user modules to create those roles. Those roles have different functions. So the app will show different menu for different user's role after logged in. Now, I can lock the function for different user. e.g when HR manger logged in, he/she can't route to other function of user role. But I don't know how to show the HR Menu for Hr Manager, only.
I am not a newbie for yii. but I'm a newbie for those modules (rihgts and yii-user).
-
Thu Ra over 11 yearsThank for you help. Yes, I knew this isGuest. but I've different role name at authitem tbl, e.g HR Manager. My problem is I don't know how to check HR Manager role. I tried isHRManager, but it is not working. And I tried Authenticated as isAuthenticated, but it is not working also. How can I check other role as isGuest?
-
simaremare about 11 yearsthis will do query everytime doing checkAccess(), this seems not efficient.
-
Stu about 11 yearsHi @simaremare, that's a good point, the default user class (
CWebUser
) only caches these results for the current request, I've added an update that's a bit more efficient. -
Sarvar N almost 10 yearswell explained, thanks. It gives me more idea about customizing RBAC.