Answers.Body: <p>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.</p>
  
  <p>Here’s how to set that up:</p>
  
  <ol>
  <li><p>Create a new Model class whose defineAttributes() method is based on your plugin's current defineSettings() method.</p>
  
  
  
  <pre class="lang-php prettyprint-override"><code>class Foo_SettingsModel extends BaseModel
  {
      protected function defineAttributes()
      {
          return array(
              'settingName' =&gt; AttributeType::String,
              // ...
          );
      }
  }
  </code></pre></li>
  <li><p>Give your plugin a getSettingsModel() function (instead of defineSettings()), which will return a new instance of your settings model.</p>
  
  <pre class="lang-php prettyprint-override"><code>class FooPlugin extends BasePlugin
  {
      // ...
  
      protected function getSettingsModel()
      {
          return new Foo_SettingsModel();
      }
  }
  </code></pre></li>
  </ol>
  
  <p>To perform the actual validation, you have <strong>two options</strong>:</p>
  
  <ol>
  <li><p>Create a custom validator class (see the ones in craft/app/validators/ for examples), and make your plugin’s rules() method include it:</p>
  
  <pre class="lang-php prettyprint-override"><code>class FooPlugin extends BasePlugin
  {
      // ...
  
      public function rules()
      {
          $rules = parent::rules();
          $rules[] = array('settingName', 'Craft\Foo_CustomValidatorClassName');
  
          return $rules;
      }
  }
  </code></pre></li>
  <li><p>Override your plugin’s validate() method and just perform the validation directly from there:</p>
  
  <pre class="lang-php prettyprint-override"><code>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;
      }
  }
  </code></pre></li>
  </ol>
  
  <p>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:</p>
  
  <pre class="lang-twig prettyprint-override"><code>{{ forms.textField({
      ...
      errors: info.getErrors('settingName')
  }) }}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-06-16T21:28:06.623Z
Answers.Text: I am trying to do this for a fieldtype that matches input against a regex (`PlainTextFieldType` plus input has to match the regex).
  
  It has a `function validate` which checks that the input matches the regex when you try to save an entry with this field type. Now I need a new validation to check that the regex to match against is valid, which should prevent you from saving the field. Does that use the same `function validate`?
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-06-17T04:07:02.727Z
Answers.Text: I'm closer. There are two `validate` functions. The one in `...FieldType.php` that validates entries with this field type, and the one in `...SettingsModel.php` that validates the actual field type.
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-06-24T16:17:52.127Z
Answers.Text: @MarionNewlevant If you're still having trouble, it's probably worth posting a new question about it.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-01-18T09:34:43.277Z
Answers.Text: I had to change `extends Plugin` to `extends BasePlugin` and `extends Model` to `extends BaseModel` to get this to work - otherwise I was getting errors.
Answers.UserDisplayName: Phil Gyford
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-06-15T13:19:11.980Z
Answers.LastActivityDate: 2018-01-31T20:15:55.473Z
Answers.LastEditDate: 2018-01-31T20:15:55.473Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>I have a plugin that needs to perform some custom validation on one of its settings. How would I go about doing that?</p>
  
Tags: <plugin-development><validation>
Title: How can I add custom validation rules to my plugin settings?
ThreadText: # How can I add custom validation rules to my plugin settings?
  
  (Asked by: username_0 on 2015-06-15)
  
  I have a plugin that needs to perform some custom validation on one of its settings. How would I go about doing that?
  
  **Tags:** plugin-development, validation
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2015-06-15. Score: 7 | Accepted answer
  
  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:
  
  1. Create a new Model class whose defineAttributes() method is based on your plugin's current defineSettings() method.
  
     ```php
     class Foo_SettingsModel extends BaseModel
     {
         protected function defineAttributes()
         {
             return array(
                 'settingName' => AttributeType::String,
                 // ...
             );
         }
     }
  
     ```
  2. Give your plugin a getSettingsModel() function (instead of defineSettings()), which will return a new instance of your settings model.
  
     ```php
     class FooPlugin extends BasePlugin
     {
         // ...
  
         protected function getSettingsModel()
         {
             return new Foo_SettingsModel();
         }
     }
  
     ```
  
  To perform the actual validation, you have **two options**:
  
  1. Create a custom validator class (see the ones in craft/app/validators/ for examples), and make your plugin’s rules() method include it:
  
     ```php
     class FooPlugin extends BasePlugin
     {
         // ...
  
         public function rules()
         {
             $rules = parent::rules();
             $rules[] = array('settingName', 'Craft\Foo_CustomValidatorClassName');
  
             return $rules;
         }
     }
  
     ```
  2. Override your plugin’s validate() method and just perform the validation directly from there:
  
     ```php
     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->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:
  
  ```twig
  {{ forms.textField({
      ...
      errors: info.getErrors('settingName')
  }) }}
  
  ```
  
  > **Comments:**
  > **username_1**: I am trying to do this for a fieldtype that matches input against a regex (`PlainTextFieldType` plus input has to match the regex).  It has a `function validate` which checks that the input matches the regex when you try to save an entry with this field type. Now I need a new validation to check that the regex to match against is valid, which should prevent you from saving the field. Does that use the same `function validate`?  
  > **username_1**: I'm closer. There are two `validate` functions. The one in `...FieldType.php` that validates entries with this field type, and the one in `...SettingsModel.php` that validates the actual field type.  
  > **username_0**: @username_1 If you're still having trouble, it's probably worth posting a new question about it.  
  > **username_2**: I had to change `extends Plugin` to `extends BasePlugin` and `extends Model` to `extends BaseModel` to get this to work - otherwise I was getting errors.  
  
  ---
  
  