1
votes

I have a drop down list where users can select their timezone on a form. On submit, I'm looking for the best way to validate the timezone input field using Yii rules.

I'm able to get an array of timezones in PHP using the following:

DateTimeZone::listIdentifiers(DateTimeZone::ALL)

The values are like this (an indexed key with a timezone value):

Array([0]=>'Pacific/Midway',[1]=>'Pacific/Niue',...);

My select box looks like this:

<select name="timezone" id="timezone">
 <option value="Pacific/Midway">Pacific/Midway (GMT-11:00)</option>
 <option value="Pacific/Niue">Pacific/Niue (GMT-11:00)</option>
 ...
</select>

I tried the following:

public function rules() {
  return array(
    array('timezone','in','range'=>DateTimeZone::listIdentifiers(DateTimeZone::ALL)),
    array(timezone','required'),
  );
} // rules()

But it never validates, I think because the the range is a multidimensional array and in order for range to work it needs to be just an array of values like array('value1','value2'); Is that true?

Is there a better approach?

1

1 Answers

1
votes

Best way is to create custom validator class, some example (untested, tune/fix to your needs):

class CountryValidator extends CValidator
{
    /**
     * Validates the attribute of the object.
     * If there is any error, the error message is added to the object.
     * @param CModel $object the object being validated
     * @param string $attribute the attribute being validated
     */
    protected function validateAttribute($object,$attribute)
    {
        $ids = DateTimeZone::listIdentifiers(DateTimeZone::ALL);
        if(!in_array($object->$attribute, $ids))
        {
            $this->addError($object,$attribute,'Wrong time zone selected!');
        }
    }
}

Then use it in your model:

/**
 * @return array validation rules for model attributes.
 */
public function rules()
{
    return array(
       array('timezone', 'alias.to.CountryValidator'),
    );
}

This method has very important advantage: Like other validator it is reusable, and does not mess your model code.