How can I add custom validation rules to my plugin settings? I have a plugin that needs to perform some custom validation on one of its settings. How would I go about doing that?
The gist is, you will need to give your plugin a dedicated Settings model class, where you will have complete control over its validation rules and errors.

Here’s how to set that up:


Create a new Model class whose defineAttributes() method is based on your plugin's current defineSettings() method.



class Foo_SettingsModel extends BaseModel
{
    protected function defineAttributes()
    {
        return array(
            'settingName' =&gt; AttributeType::String,
            // ...
        );
    }
}

Give your plugin a getSettingsModel() function (instead of defineSettings()), which will return a new instance of your settings model.

class FooPlugin extends BasePlugin
{
    // ...

    protected function getSettingsModel()
    {
        return new Foo_SettingsModel();
    }
}



To perform the actual validation, you have two options:


Create a custom validator class (see the ones in craft/app/validators/ for examples), and make your plugin’s rules() method include it:

class FooPlugin extends BasePlugin
{
    // ...

    public function rules()
    {
        $rules = parent::rules();
        $rules[] = array('settingName', 'Craft\Foo_CustomValidatorClassName');

        return $rules;
    }
}

Override your plugin’s validate() method and just perform the validation directly from there:

class FooPlugin extends BasePlugin
{
    // ...

    public function validate($attributes = null, $clearErrors = true)
    {
        $validates = parent::validate($attributes, $clearErrors);

        if ($attributes === null || in_array('settingName', $attributes))
        {
            // Perform custom validation here
            // ...

            if (!$settingNameValidates)
            {
                $this-&gt;addError('settingName', 'Error message');
                $validates = false;
            }
        }

        return $validates;
    }
}



Finally, the last thing you’ll need to ensure is that your plugin’s settings template is actually showing the error messages associated with this setting:

{{ forms.textField({
    ...
    errors: info.getErrors('settingName')
}) }}