<p>If anybody is interested, I created a simple unique text field plugin that extends the core text field: <a href="https://github.com/fuel-digital/Craft-Unique-Text-FieldType" rel="noreferrer">https://github.com/fuel-digital/Craft-Unique-Text-FieldType</a>.</p>

CC BY-SA 3.0
2014-11-26T15:58:57.523Z
So did I (github.com/joshangell/craft-unique-value) but yours looks to be much more bulletproof!
Josh Angell
CC BY-SA 3.0
2014-11-26T16:02:13.720Z
I'm sure it could be improved - it's pretty bare bones but does the job.
Russ Back
CC BY-SA 3.0
2016-08-08T10:59:39.090Z
Thanks Russ - this came up as a requirement in a new project... Thanks for contributing to the community!
Matt P
CC BY-SA 3.0
2017-03-01T09:47:05.587Z
Thank you for this plugin. Is this also compatible with Craft v.3?
Panos Spiliotis
CC BY-SA 3.0
2014-11-26T12:10:57.397Z
2014-11-26T12:10:57.397Z
Russ Back
<p>I came up with an answer, but be good to know if there is a better way of doing it:</p>

<pre><code>/**
 * Checks if another entry exists with the given reference
 * 
 * @param  string $value The reference to check
 * @return bool
 */
private function referenceExists($value)
{
    $existing = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry)-&gt;first(array(
        $this-&gt;model-&gt;getAttribute('handle') =&gt; $value
    ));

    return ($existing &amp;&amp; $existing-&gt;getAttribute('id') != $this-&gt;element-&gt;getAttribute('id'));
}

/**
 * Validates the field values is unique
 *
 * @param mixed $value
 * @return true|string|array
 */
public function validate($value)
{
    return ($this-&gt;referenceExists($value)) ? $this-&gt;model-&gt;getAttribute('name') . Craft::t(' must be unique') : true;
}
</code></pre>

CC BY-SA 3.0
2014-11-25T16:10:09.127Z
Am confused now as to whether that referenceExists() method should be in the plugin's service rather than the fieldtype too...
Russ Back
CC BY-SA 4.0
2021-09-29T19:31:42.337Z
As of Craft 3.7.x (maybe earlier) the check needs to be slightly adjusted. Now you need to compare the existing entries `id` with the elements `canonicalId`, because under some circumstances you could run into the issue that you compare an entry id with a draft id.
medoingthings
CC BY-SA 3.0
2014-11-25T15:41:22.763Z
2014-11-25T15:41:22.763Z
Russ Back
<p>I have a custom field type which I need to be unique. So far I have this:</p>

<pre><code>/**
 * Validates the field values is unique
 *
 * @param mixed $value
 *
 * @return true|string|array
 */
public function validate($value)
{
    $existingEntryCount = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry)-&gt;total(array(
        $this-&gt;model-&gt;getAttribute('handle') =&gt; $value
    ));

    return ($existingEntryCount) ? $this-&gt;model-&gt;getAttribute('name') . Craft::t(' must be unique') : true;
}
</code></pre>

<p>This works in that it returns an error if any entry is found with the value submitted, however I need to restrict the search so that it excludes the current entry from the search query.</p>

<plugin-development><custom-fieldtype>
Validating a field value is unique
# Validating a field value is unique

(Asked by: username_0 on 2014-11-25)

I have a custom field type which I need to be unique. So far I have this:
/**
 * Validates the field values is unique
 *
 * @param mixed $value
 *
 * @return true|string|array
 */
public function validate($value)
{
    $existingEntryCount = craft()->elements->getCriteria(ElementType::Entry)->total(array(
        $this->model->getAttribute('handle') => $value
    ));

    return ($existingEntryCount) ? $this->model->getAttribute('name') . Craft::t(' must be unique') : true;
}

This works in that it returns an error if any entry is found with the value submitted, however I need to restrict the search so that it excludes the current entry from the search query.

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

---

## 2 answers

### Answer by username_0 on 2014-11-25. Score: 4 | Accepted answer

I came up with an answer, but be good to know if there is a better way of doing it:
/**
 * Checks if another entry exists with the given reference
 * 
 * @param  string $value The reference to check
 * @return bool
 */
private function referenceExists($value)
{
    $existing = craft()->elements->getCriteria(ElementType::Entry)->first(array(
        $this->model->getAttribute('handle') => $value
    ));

    return ($existing && $existing->getAttribute('id') != $this->element->getAttribute('id'));
}

/**
 * Validates the field values is unique
 *
 * @param mixed $value
 * @return true|string|array
 */
public function validate($value)
{
    return ($this->referenceExists($value)) ? $this->model->getAttribute('name') . Craft::t(' must be unique') : true;
}

> **Comments:**
> **username_0**: Am confused now as to whether that referenceExists() method should be in the plugin's service rather than the fieldtype too...  
> **username_4**: As of Craft 3.7.x (maybe earlier) the check needs to be slightly adjusted. Now you need to compare the existing entries `id` with the elements `canonicalId`, because under some circumstances you could run into the issue that you compare an entry id with a draft id.  

---

### Answer by username_0 on 2014-11-26. Score: 5

If anybody is interested, I created a simple unique text field plugin that extends the core text field: <https://github.com/fuel-digital/Craft-Unique-Text-FieldType>.

> **Comments:**
> **username_1**: So did I (github.com/joshangell/craft-unique-value) but yours looks to be much more bulletproof!  
> **username_0**: I'm sure it could be improved - it's pretty bare bones but does the job.  
> **username_2**: Thanks Russ - this came up as a requirement in a new project... Thanks for contributing to the community!  
> **username_3**: Thank you for this plugin. Is this also compatible with Craft v.3?  

---

