<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Scott Nelle.com &#187; CodeIgniter</title>
	<atom:link href="http://www.ScottNelle.com/category/codeigniter/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ScottNelle.com</link>
	<description>Scott Nellé&#039;s Personal Site</description>
	<lastBuildDate>Tue, 08 Nov 2011 04:02:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Extending CodeIgniter&#8217;s Validation Library To Check For Unique Values</title>
		<link>http://www.ScottNelle.com/41/extending-codeigniters-validation-library/</link>
		<comments>http://www.ScottNelle.com/41/extending-codeigniters-validation-library/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 02:01:38 +0000</pubDate>
		<dc:creator>Scott Nelle</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.scottnelle.com/?p=41</guid>
		<description><![CDATA[Updated August 29, 2010: I&#8217;ve updated this post to be compatible with the latest version of CodeIgniter. It&#8217;s currently compatible with 1.7.0 and later. If you are still running on an older version and want the old version of this &#8230; <a href="http://www.ScottNelle.com/41/extending-codeigniters-validation-library/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p class="update"><strong>Updated August 29, 2010:</strong> I&#8217;ve updated this post to be compatible with the latest version of CodeIgniter. It&#8217;s currently compatible with 1.7.0 and later. If you are still running on an older version and want the old version of this code to match let me know; I will send it to you. When I updated the post I also reset the discussion since most of it was specific to the old code.</p>
<p class="update"><strong>February 15, 2011</strong> <a href="#comment-12903">Calvin Froedge rightly notes in the comments</a> that with the release of CodeIgniter 2.0 the old PHP-4-compatible constructor style no longer works. The code below is updated to reflect that. He also has some thoughts about internationalization with language files and storing the visitor&#8217;s language in the session variables. This should be back-compatible with old versions CodeIgniter as long as you&#8217;re running PHP 5 on your server.</p>
<p>I&#8217;m working on small web application and I&#8217;m building it with CodeIgniter.  Like most web applications, mine requires user registration and login.  And like most login systems, mine is happiest if each user has a unique username.  While the CodeIgniter validation library is pretty robust, it doesn&#8217;t come with a function for checking a value to see if it is unique or if it already exists in the database.  Fortunately there are a couple of ways to remedy that.</p>
<p>The first way is outlined in the <a href="http://codeigniter.com/user_guide/libraries/form_validation.html#callbacks">documentation for the validation library</a> under the heading &#8220;Callbacks: Your own Validation Functions.&#8221;  I tried this and it works well, but it requires you to write the functions in your controller or model.  I thought that looked messy and I wanted something a little more streamlined, so I decided to extend the validation library with my own function.  Extending CodeIgniter&#8217;s libraries is pretty easy.  Here&#8217;s what I came up with&#8211;I&#8217;ll explain the important lines afterward:</p>
<pre><code>
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * MY_Form_validation Class
 *
 * Extends Form_Validation library
 *
 * Adds one validation rule, "unique" and accepts a
 * parameter, the name of the table and column that
 * you are checking, specified in the forum table.column
 *
 * Note that this update should be used with the
 * form_validation library introduced in CI 1.7.0
 */
class MY_Form_validation extends CI_Form_validation {

	function __construct()
	{
	    parent::__construct();
	}

	// --------------------------------------------------------------------

	/**
	 * Unique
	 *
	 * @access	public
	 * @param	string
	 * @param	field
	 * @return	bool
	 */
	function unique($str, $field)
	{
		$CI =&amp; get_instance();
		list($table, $column) = explode('.', $field, 2);

		$CI-&gt;form_validation-&gt;set_message('unique', 'The %s that you requested is unavailable.');

		$query = $CI-&gt;db-&gt;query("SELECT COUNT(*) AS dupe FROM $table WHERE $column = '$str'");
		$row = $query-&gt;row();
		return ($row-&gt;dupe &gt; 0) ? FALSE : TRUE;
	}
}
?&gt;
</code></pre>
<p>Save the above code as system/application/libraries/MY_Form_validation.php and you&#8217;re ready to go. You can now add the &#8220;unique&#8221; rule to your existing validation, like so:</p>
<pre><code>
$this-&gt;form_validation-&gt;set_rules('username','User Name','required|min_length[5]|unique[users.username]');
$this-&gt;form_validation-&gt;set_rules('emailaddress','Email Address','required|valid_email|unique[users.email]');
</code></pre>
<p>This will check the values that entered for <code>username</code> and <code>emailaddress</code> to make sure they don&#8217;t already exist in the <code>username</code> and <code>email</code> fields in your table called <code>users</code>.  The general format for the rule, then, is : <code>unique[table.column]</code>.  This matches the SQL syntax for specifying fields when field names are ambiguous.  Pretty cool.</p>
<p>So here&#8217;s what&#8217;s going on in each of the important lines.</p>
<pre><code>
$CI =&amp; get_instance();
</code></pre>
<p>This creates a reference to the CodeIgniter super object and allows you to use it&#8217;s functions in your library.  <a href="http://www.codeignitor.com/user_guide/general/creating_libraries.html">See the user guide for an explanation</a> (under the heading &#8220;Utilizing CodeIgniter Resources within Your Library.&#8221;)</p>
<pre><code>
list($table, $column) = explode('.', $field, 2);
</code></pre>
<p>This line parses out the table name and column name.  Note that it only returns 2 strings.  This way you can specify something like <code>unique[users.email.address]</code>, which would check the users table for a column called email.address.  In mysql periods are allowed in field names but not table names, and the validation rule reflects that.</p>
<pre><code>
$CI-&gt;form_validation-&gt;set_message('unique', 'The %s that you requested is unavailable.');
</code></pre>
<p>This line sets the error message in case the value isn&#8217;t unique. <code>%s</code> will be replaced by the field description you enter in your validation fields.  This would be better off in a language file, but for ease of use I&#8217;ve stuck it right in the library.  CodeIgniter allows you to replace entire language files but not simply extend them with a single line.  If that changes in the future I&#8217;ll revisit my decision.</p>
<pre><code>
$query = $CI-&gt;db-&gt;query("SELECT COUNT(*) AS dupe FROM $table WHERE $column = '$str'");
$row = $query-&gt;row();
</code></pre>
<p>Here&#8217;s where it checks the database to make sure your field is unique.  In the query I assigned the row count to the keyword &#8220;dupe&#8221; (for duplicate.)  I wanted to use &#8220;exists&#8221; or &#8220;match&#8221; but both are protected words in mysql.  Oh well. Note the use of <code>$CI-&gt;db-&gt;query</code> instead of <code>$this-&gt;db-&gt;query</code>.  That&#8217;s explained in the documentation link earlier in this post.</p>
<pre><code>
return ($row-&gt;dupe &gt; 0) ? FALSE : TRUE;
</code></pre>
<p>Finally, this line returns the result of the validation check.  In case you&#8217;re not accustomed to using ternary operators, here it is as an if/else:</p>
<pre><code>
if ($row-&gt;dupe &gt; 0)
{
	return FALSE; // a match was found, validation fails
}
else
{
	return TRUE; // value is unique, validation passed
}
</code></pre>
<p>So there you have it.  A quick extension to CodeIgniter&#8217;s validation library that allows you to check your database for unique values.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ScottNelle.com/41/extending-codeigniters-validation-library/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
	</channel>
</rss>

