Validate "at least one attribute required"?

What's the best practice to validate, that at least one of a model's attributes is present? I need this for a report filter, where the user has to specify at least one filter criterium before the report is generated.

You may write a new validator or extend the existing CRequiredValidator (preferred).

If you extend CRequiredValidator, you may override the validate() method like the following:



public function validate($object,$attributes=null)


{


     $count=$this->countErrors($object->errors);


     parent::validate($object,$attributes);


     $n=count($this->attributes);


     if($this->countErrors($object->errors)-$count===$n)


     {


         $object->clearErrors();


         $object->addError(...);


     }


}


[/code]

Cool, thanks.

I just don't understand why you use $this->countErrors() (which doesn't exist) instead of a simple count().

I've changed your proposal a little and it seems to work now. The way you described it, it would keep the errors from the RequireValidator on success. Not sure, if the clone() is to expensive, though.

<?php


class RequireOneValidator extends CRequiredValidator {





    public function validate($object,$attributes=null)


    {


        $clone=clone($object);


        $before=count($clone->errors);


        parent::validate($clone,$attributes);


        $after=count($clone->errors);


        $count=count($this->attributes);


        if (($after-$before)===$count)


        {


            $attributes=$this->attributes;


            $first=array_shift($attributes);


            $message=$this->message!==null?$this->message:Yii::t('yii','At least one attribute is required.');


            $object->addError($first,$message);


            foreach($attributes as $a)


                $object->addError($a,'');


        }


    }





}


You may also just be able to do a simple:

if (!empty($_POST['User'])) {

//do stuff with it

}

normally you might use isset() instead of !empty().  Not totally sure if it would work though because i'm not totally sure how empty() works on arrays

Yes, the above solution might be a little “fat”. :) But i wanted all attributes to get highlighted in the form and only have one error message, so having a validator for this seemed useful. Feel free to optimize ;).