【问题标题】:Yii: Use a different scope based on user roleYii:根据用户角色使用不同的范围
【发布时间】:2014-04-05 00:00:50
【问题描述】:

我有两个级别的管理员可以创建和更新用户,“管理员”和“经理”。

在我的用户 _form.php 中,我有一个“user_type”下拉列表,其中包含我的帐户级别。

我想限制管理员创建“管理员”帐户,并且显然在用户更新自己的记录时完全隐藏下拉列表。

a) 有没有办法使用 rules() 来控制这种行为? b) 我考虑创建一个名为“hideAdmin”的范围,如下所示:

'hideAdmin' => array(
   'condition' => 'user_type != "Admin"',
),

然后在我的模型中创建一个名为“scopeToUse()”的公共方法,如下所示:

    public function scopeToUse() {
        $scope = 'hideAdmin()';
        if(Yii::app()->authManager->checkAccess('Admin', Yii::app()->user->id)) {
            $scope = 'orderAsc()';
        } 
        return $scope;
    }

最后,像这样创建我的下拉列表。

<?php echo $form->dropDownList($model,'user_type_id',
   CHtml::listData(UserType::model()->scopeToUse()->findAll(),'id','user_type')); ?>

我希望 'scopeToUse()' 会返回范围名称并且它会起作用,但我最终还是得到了这个:

Fatal error: Call to a member function findAll() on a non-object

你知道正确的方法吗?

编辑

我最终从@Rafay-Zia-Mir 那里得到了启发,并在我的用户类中创建了一个新方法来检查权限并返回适当的 CHtml::listData 以及我想要的范围。不完全是我想要的,但最终结果是一样的,它使我不会在我的视图中放置太多代码,它允许我使用我的范围而不是重复选择标准。

这是代码:

    public function userTypeDropdown() {
        if(Yii::app()->authManager->checkAccess('Admin',Yii::app()->user->id)) {
            $listData = CHtml::listData(UserType::model()->findAll(),'id','user_type');
        } else {
            $listData = CHtml::listData(UserType::model()->hideAdmin()->findAll(),'id','user_type');
        };
        return $listData;
    }

【问题讨论】:

  • 显然 scopeToUse() 不是一个对象,这就是您收到此错误的原因。
  • findAll 是 CActiveRecord 基类的一个方法,但您正在为函数调用它
  • 对,我只是不确定如何让它工作。如果我执行 UserType::model()->hideAdmin()->findAll... 它可以工作。那么我如何才能在正确的范围内进行管道传输呢?
  • 其实我无法理解你的问题。您想根据当前用户的角色在下拉菜单中显示项目吗?如果当前用户不是管理员,那么隐藏下拉菜单?这就是你想要的吗?
  • 是的。所以我创建了 2 个作用域来处理它,以及 UserType 模型中的一个方法。我只希望该方法返回适当的范围名称,理想情况下是通过一个变量而不是多个返回(返回 UserType::model()->hideAdmin() 有效,其中 hideAdmin() 是范围的名称)。

标签: php yii scopes


【解决方案1】:

好的,实际上您可以通过在视图代码中使用 If 语句来执行此操作。你可以这样做

<?php 
          if(Yii::app()->authManager->checkAccess('Admin', Yii::app()->user->id)) {
         ?>
         <?php $criteria=new CDbCriteria();
             $criteria->condition="NOT user_type=Admin";
                echo $form->dropDownList($model,'user_type_id',
                    CHtml::listData(UserType::model()->findAll($criteria),'id','user_type')); ?>

         <?php } ?>

如果用户只是管理员,则下拉菜单将显示。
编辑:如果您想使用函数调用来获取它,那么您可以使用它。

public function scopeToUse() {
        if(Yii::app()->authManager->checkAccess('Admin', Yii::app()->user->id)) {
            $this->getDbCriteria()->mergeWith(array(
        'condition' => 'NOT user_type="Admin"',
         'order'=>'id ASC'
    ));

        } 
        return $this;
    }

那么你可以使用 use

<?php  echo $form->dropDownList($model,'user_type_id',
                        CHtml::listData(UserType::model()->scopeToUse()->findAll(),'id','user_type')); ?>

【讨论】:

  • 谢谢。这是我将在我的视图中隐藏使用表单更新电子邮件和密码的普通用户的下拉列表,但是我想过滤下拉列表,以便“经理”无法将任何人分配为“管理员”。在我的应用中,“管理员”是一种超级用户。
  • 好的,那么您要根据什么标准过滤 droprDown? “经理不能将任何人指定为管理员”谁是任何人?谁是管理员权限的正确用户?
  • 就是在上面定义的范围内。 'hideAdmin' => 数组('条件' => 'user_type != "Admin"', ),
  • @McB,告诉我UserType的属性是什么?我问是因为 UserType::model()->findAll() 将返回表中的所有记录。你希望 dropDown 中的记录的 user_type 不是 admin 吗?
  • 我知道我可以使用标准或通过输入 2 行下拉代码(一个 IF 管理员,另一个 IF 经理)来做到这一点。我只是想弄清楚是否有办法使用我已经创建的范围而不是新的 CDbCriteria 对象。
猜你喜欢
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 2013-11-30
  • 2018-07-12
  • 1970-01-01
  • 2015-07-22
  • 2016-04-07
相关资源
最近更新 更多