<p>Completely untested and this whole pattern feels hacky to me, but something like this should work:</p>

<p>From your field type:</p>

<pre><code>public function validate($value)
{
    if(is_array($value) &amp;&amp; $value['type'] != '')
    {
        // Validate the field type.
        $errors = parent::validate($value);

        if (!is_array($errors))
        {
            $errors = array();
        }

        $linkModel = $this-&gt;_valuetToModel($value);

        // Validate the model.
        $validated = $linkModel-&gt;validate();

        return $validated &amp;&amp; empty($errors) ? true : array_merge($linkModel-&gt;getAllErrors(), $errors);
    }

    return true;
}
</code></pre>

<p>From your model:</p>

<pre><code>public function validate($attributes = null, $clearErrors = true)
{
    switch($this-&gt;type)
    {
        case('email'):
            if( !filter_var($this-&gt;value, FILTER_VALIDATE_EMAIL) )
            {
                $this-&gt;addError('value', Craft::t('Please enter a valid email address.'));
            }
            break;

        ....

    }

    return !$this-&gt;hasErrors();
}
</code></pre>

CC BY-SA 3.0
2015-09-23T20:17:25.527Z
The validate() function in the model or the fieldtype class??
Sam Hibberd
CC BY-SA 3.0
2015-09-23T21:04:53.680Z
So you want to validate the fieldtype as well as a model from the field type and return the combined validation results?
Brad Bell
CC BY-SA 3.0
2015-09-23T21:06:14.130Z
Yep that's the requirement here, assuming there's not a better way?
Sam Hibberd
CC BY-SA 3.0
2015-09-23T21:08:03.870Z
Thinking about it, might it be better to validate the  fieldtype input pre populate model? Seems like an unnecessary step.
Sam Hibberd
CC BY-SA 3.0
2015-09-23T21:14:10.460Z
Updated answer.
Brad Bell
CC BY-SA 3.0
2015-09-23T19:47:33.887Z
2015-09-23T21:13:52.183Z
2015-09-23T21:13:52.183Z
Brad Bell
<p>How can you ensure that the base fieldtype validation (required etc) and error messages are still applied when validating $value via the validate($value) function??</p>

<p>Validate method in fieldtype class:</p>

<pre><code>public function validate($value)
{
    if(is_array($value) &amp;&amp; $value['type'] != '')
    {
        $linkModel = $this-&gt;_valuetToModel($value);
        $validated = $linkModel-&gt;validate();
        return $validated ? true : $linkModel-&gt;getAllErrors();
    }
    return true;
}
</code></pre>

<p>Validate method of custom model that the fieldtype populates and returns to the template:</p>

<pre><code>public function validate($attributes = null, $clearErrors = true)
{
    switch($this-&gt;type)
    {
        case('email'):
            if( !filter_var($this-&gt;value, FILTER_VALIDATE_EMAIL) )
            {
                $this-&gt;addError('value', Craft::t('Please enter a valid email address.'));
            }
            break;

        case('tel'):
            $regexp = '/^[0-9+\(\)#\.\s\/ext-]+$/';
            if(!filter_var($this-&gt;value, FILTER_VALIDATE_REGEXP, array('options' =&gt; array('regexp' =&gt; $regexp))))
            {
                $this-&gt;addError('value', Craft::t('Please enter a valid telephone.'));
            }
            break;

        case('custom'):
            if(!filter_var($this-&gt;value, FILTER_VALIDATE_URL))
            {
                $this-&gt;addError('value', Craft::t('Please enter a valid url.'));
            }
            break;

        case('entry'):
            if($this-&gt;value == '')
            {
                $this-&gt;addError('value', Craft::t('Please select an entry.'));
            }
            break;

        case('asset'):
            if($this-&gt;value == '')
            {
                $this-&gt;addError('value', Craft::t('Please select an asset.'));
            }
            break;

        case('category'):
            if($this-&gt;value == '')
            {
                $this-&gt;addError('value', Craft::t('Please select a category.'));
            }
            break;
        // default:
        //     Craft::dd(parent::validate($attributes, null));
        //     $this-&gt;addError('value', Craft::t('Please select a sdfasdfsd.'));
        //     break;
    }

    return !$this-&gt;hasErrors();
}
</code></pre>

<plugin-development><custom-fieldtype><validation>
Base fieldtype validation working with model validation?
# Base fieldtype validation working with model validation?

(Asked by: username_0 on 2015-09-23)

How can you ensure that the base fieldtype validation (required etc) and error messages are still applied when validating $value via the validate($value) function??
Validate method in fieldtype class:
public function validate($value)
{
    if(is_array($value) && $value['type'] != '')
    {
        $linkModel = $this->_valuetToModel($value);
        $validated = $linkModel->validate();
        return $validated ? true : $linkModel->getAllErrors();
    }
    return true;
}

Validate method of custom model that the fieldtype populates and returns to the template:
public function validate($attributes = null, $clearErrors = true)
{
    switch($this->type)
    {
        case('email'):
            if( !filter_var($this->value, FILTER_VALIDATE_EMAIL) )
            {
                $this->addError('value', Craft::t('Please enter a valid email address.'));
            }
            break;

        case('tel'):
            $regexp = '/^[0-9+\(\)#\.\s\/ext-]+$/';
            if(!filter_var($this->value, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => $regexp))))
            {
                $this->addError('value', Craft::t('Please enter a valid telephone.'));
            }
            break;

        case('custom'):
            if(!filter_var($this->value, FILTER_VALIDATE_URL))
            {
                $this->addError('value', Craft::t('Please enter a valid url.'));
            }
            break;

        case('entry'):
            if($this->value == '')
            {
                $this->addError('value', Craft::t('Please select an entry.'));
            }
            break;

        case('asset'):
            if($this->value == '')
            {
                $this->addError('value', Craft::t('Please select an asset.'));
            }
            break;

        case('category'):
            if($this->value == '')
            {
                $this->addError('value', Craft::t('Please select a category.'));
            }
            break;
        // default:
        //     Craft::dd(parent::validate($attributes, null));
        //     $this->addError('value', Craft::t('Please select a sdfasdfsd.'));
        //     break;
    }

    return !$this->hasErrors();
}

**Tags:** plugin-development, custom-fieldtype, validation

---

## 1 answers

### Answer by username_1 on 2015-09-23. Score: 1

Completely untested and this whole pattern feels hacky to me, but something like this should work:
From your field type:
public function validate($value)
{
    if(is_array($value) && $value['type'] != '')
    {
        // Validate the field type.
        $errors = parent::validate($value);

        if (!is_array($errors))
        {
            $errors = array();
        }

        $linkModel = $this->_valuetToModel($value);

        // Validate the model.
        $validated = $linkModel->validate();

        return $validated && empty($errors) ? true : array_merge($linkModel->getAllErrors(), $errors);
    }

    return true;
}

From your model:
public function validate($attributes = null, $clearErrors = true)
{
    switch($this->type)
    {
        case('email'):
            if( !filter_var($this->value, FILTER_VALIDATE_EMAIL) )
            {
                $this->addError('value', Craft::t('Please enter a valid email address.'));
            }
            break;

        ....

    }

    return !$this->hasErrors();
}

> **Comments:**
> **username_0**: The validate() function in the model or the fieldtype class??  
> **username_1**: So you want to validate the fieldtype as well as a model from the field type and return the combined validation results?  
> **username_0**: Yep that's the requirement here, assuming there's not a better way?  
> **username_0**: Thinking about it, might it be better to validate the  fieldtype input pre populate model? Seems like an unnecessary step.  
> **username_1**: Updated answer.  

---

