Search code examples
phpyii-extensionsyiiyii-components

How filter my user list by status ? - Yii


I use Yii Framework and I want to filter by status my users list. The status is defined by a number:

  • 0 : enabled
  • 1 : banned
  • 2 : disabled

Therefore display the correct status I use a function itemAlias​() :

public static function itemAlias($attribute, $value=null) {

    $_items = array(
        'status' => array(
            '0' => Yii::t("status", 'Enabled'),
            '1' => Yii::t("status", 'Banned'),
            '2' => Yii::t("status", 'Disabled'),
        ),
    );

    if (isset($value))
        return isset($_items[$attribute][$value]) ? $_items[$attribute][$value] : false;
    else
        return isset($_items[$attribute]) ? $_items[$attribute] : false; 
 }

So when viewing users I have good status is displayed (for example : "Enabled"), but when I want to filter by status I have to filter with 1, 2 or 3.

I wanted to know if it was possible to filter by status (active, banned, disabled)?


Solution

  • Of course it is possible. You can create scopes like:

    public function scopes()
    {
       return array(
           'enabled' => array(
              'condition' => 'status=0',
           ),
           'banned' => array(
              'condition' => 'status=1',
           ),
       );
    }
    

    Then in your query you'd have something like:

    $activeUsers = User::model()->enabled()->findAll();
    $bannedUsers = User::model()->banned()->findAll();
    

    Also, you can have named scopes:

    public function statusIs($status)
    {
        // you can accept a status string here and translate it in an integer, your choice.
        return $this->getDbCriteria()->mergeWith(array(
           'condition' => 'status = '.(int)$status
        ));
    }
    

    And use it in your query like:

    User::model()->statusIs(0)->findAll();// get all enabled
    

    Also, using scopes you can query your related models as well, something like:

    Posts::model()->with('users:enabled')->findAll();
    

    should work too.

    Just take a look at http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes and see more.

    L.E:

    public function getStatuses()
    {
       return array(
          '0' => Yii::t("status", 'Enabled'),
          '1' => Yii::t("status", 'Banned'),
          '2' => Yii::t("status", 'Disabled'),
       );
    }
    
    public function getStatusesDropDown(array $htmlOpts = array())
    {
       return CHtml::activeDropDownList($this, 'status', $this->getStatuses(),$htmlOpts);
    }
    

    Now that you have the drop down code, in your CActiveForm, or any other form you show this status drop down like:

    echo $model->getStatusesDropDown();
    

    When you select a status from the drop down and you submit the form, the input named YourModel[status] will be submitted. This will have a value of 0 or 1 or 2. Next, in you search() method, you have to:

    public function search()
    {
        $criteria = new CDbCriteria;
        [...]
        if ($this->status !== null && (int)$this->status >= 0) {
           $criteria->compare('status', (int)$this->status);
        }
        [...]
    }
    

    And that's pretty much it.