yii: как отображать разные меню в зависимости от роли пользователя?

В: Как я могу отображать разные меню в зависимости от роли пользователя?

Описание: приложение имеет много ролей. например, менеджер по персоналу, менеджер по работе с клиентами, операционный менеджер, сотрудник, оператор, .... и т. д. Я использовал права и модули yii-user для создания этих ролей. Эти роли имеют разные функции. Таким образом, приложение будет отображать разные меню для разных ролей пользователей после входа в систему. Теперь я могу заблокировать функцию для разных пользователей. например, когда менеджер по персоналу вошел в систему, он / она не может перейти к другой функции роли пользователя. Но я не знаю, как показать только меню HR для Hr Manager.

Я не новичок в yii. но я новичок в этих модулях (rihgts и yii-user).


person Thu Ra    schedule 13.09.2012    source источник


Ответы (2)


Если вы используете RBAC, вы можете установить 'видимый' параметр элементов CMenu в зависимости от привилегий пользователя, например;

$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')
        ),
    ),
);

Таким образом, пользователи смогут видеть элементы в меню только в том случае, если у них есть права доступа к этой области.

[ИЗМЕНИТЬ]

Согласно комментарию simaremare ниже, вы можете принудительно кэшировать этот запрос за пределы текущего запроса, расширив CWebUser. Во-первых, настройте своего пользователя для запуска вашего нового класса (мы назовем его TWebUser), поэтому в вашем конфигурационном файле main.php;

'components'=>array(
    'user'=>array(
        ...
        'class'=>'TWebUser',
        ...
    ),
    ...
),

Теперь нам нужно создать TWebUser для их кэширования помимо текущего запроса (что и делает CWebUser (исходный код):

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;
    }
}

Теперь ваши результаты доступа будут установлены для всей сессии. Это означает, что если вы отредактируете разрешения RBAC для данной учетной записи, им придется выйти из системы и войти снова, чтобы увидеть новые изменения, отраженные в браузере.

Надеюсь, это поможет! Я уверен, что нашел этот обходной путь от кого-то другого (вероятно, на SO), но я не могу найти исходный пост, чтобы отдать им должное.

person Stu    schedule 14.09.2012
comment
это будет выполнять запрос каждый раз при выполнении checkAccess(), это кажется неэффективным. - person simaremare; 14.02.2013
comment
Привет @simaremare, это хороший момент, пользовательский класс по умолчанию (CWebUser) кэширует эти результаты только для текущего запроса, я добавил обновление, которое немного более эффективно. - person Stu; 14.02.2013
comment
хорошо объяснил, спасибо. Это дает мне больше информации о настройке RBAC. - person Sarvar Nishonboyev; 26.07.2014

Вы бы обернули оператор if вокруг пунктов меню, которые вы можете или не хотите показывать.

В операторе if вам нужно будет проверить, имеет ли пользователь право видеть ваши пункты меню.

Например:

<?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; ?>
person Ivo Renkema    schedule 13.09.2012
comment
Спасибо за помощь. Да, я знал, что это Гость. но у меня другое имя роли в таблице авторизации, например, менеджер по персоналу. Моя проблема в том, что я не знаю, как проверить роль менеджера по персоналу. Я пробовал isHRManager, но он не работает. И я пробовал Authenticated as isAuthenticated, но он тоже не работает. Как я могу проверить другую роль как isGuest? - person Thu Ra; 14.09.2012