<?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>if(is_geek)... &#187; Uncategorized</title>
	<atom:link href="http://www.ifisgeek.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ifisgeek.com</link>
	<description>Look! A New Doot!</description>
	<lastBuildDate>Thu, 03 Sep 2009 04:51:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Blog</title>
		<link>http://www.ifisgeek.com/2007/01/15/blog/</link>
		<comments>http://www.ifisgeek.com/2007/01/15/blog/#comments</comments>
		<pubDate>Tue, 16 Jan 2007 04:29:25 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/blog/</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2007/01/15/blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Secure Logins with Challenge-Response</title>
		<link>http://www.ifisgeek.com/2007/01/14/secure_logins_with_challenge_response/</link>
		<comments>http://www.ifisgeek.com/2007/01/14/secure_logins_with_challenge_response/#comments</comments>
		<pubDate>Mon, 15 Jan 2007 02:12:52 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testbed.ifisgeek.com/tutorials/secure-logins-with-challenge-response/</guid>
		<description><![CDATA[Background
No matter how securely you code your site, someone with a valid password can access that which you mean to keep private. The best solution is, of course, to keep any and all pages that require the input of a password protected using an SSL certificate. In reality, not all sites can afford the luxury [...]]]></description>
			<content:encoded><![CDATA[<h3>Background</h3>
<p>No matter how securely you code your site, someone with a valid password can access that which you mean to keep private. The best solution is, of course, to keep any and all pages that require the input of a password protected using an SSL certificate. In reality, not all sites can afford the luxury of their own SSL certificate. Another, entirely free, method of keeping passwords from being transmitted across the web in clear text is to use a challenge-response system for logins.</p>
<p>The basic idea behind a challenge-response system is that the page requesting a password will have some extra information embedded in it &#8211; information that is unique to that particular login attempt &#8211; which is used to encode the password before it is sent across the network. In this tutorial, we&#8217;ll see how to generate this extra information, called the <em>salt</em> and how to incorporate it into a secure hash using SHA1</p>
<h3>The work upfront</h3>
<p>First of all, we&#8217;ll take a look at things on the client end of things. We will need a javascript implementation of the SHA1 algorithm. I found one as done by a guy named Chris Vaness. I am not sure where I found it, but I did maintain his copyright as requested. Grab it for your own use here: <a href="http://www.ifisgeek.com/js/sha1.js">sha1.js</a>. For CakePHP, place this file in the app/webroot/js directory. All you really need to know about this file is that it defines a function <em>sha1Hash</em> that takes one argument &#8211; the string to hash &#8211; and returns the hashed value.</p>
</p>
<p>Now we need a form for logging in to a site. The html code for a simple login is shown in snippet #1.</p>
<h4>Snippet #1: HTML code for our simplified login.</h4>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;error_message&quot;</span>&gt;</span>The login credentials you supplied could not be recognized. Please try again.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/admin/login&quot;</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span>&gt;</span>Username:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span>
    <span style="color: #009900;">&lt;?php input<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'User/username'</span>, array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'size'</span> <span style="color: #66cc66;">=</span>&gt;</span> 20, 'class' =&gt; 'TextField', 'id'=&gt;'username')); ?&gt;
    <span style="color: #009900;">&lt;?php tagErrorMsg<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'User/username'</span>, <span style="color: #ff0000;">'Username is required.'</span><span style="color: #66cc66;">&#41;</span>?&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span>&gt;</span>Password:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span>    
    <span style="color: #009900;">&lt;?php password<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'User/password'</span>, array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'size'</span> <span style="color: #66cc66;">=</span>&gt;</span> 20, 'class' =&gt; 'TextField', 'id'=&gt;'password')); ?&gt;
    <span style="color: #009900;">&lt;?php tagErrorMsg<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'User/password'</span>, <span style="color: #ff0000;">'Password is required.'</span><span style="color: #66cc66;">&#41;</span>?&gt;</span>
    <span style="color: #009900;">&lt;?php submit<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Login'</span>, array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'class'</span><span style="color: #66cc66;">=</span>&gt;</span>'Button'));?&gt;
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></pre></div></div>

<p>Of course, the code in Snippet #1 is just the login bits of the page, you&#8217;ll want to embed that in a full page (and hopefully pretty it up with some CSS) for production use. In our controller, we&#8217;ll need to generate the salt to embed in the page. Code for doing this is shown in Snippet #2.</p>
<h4>Snippet #2: Adding the salt in the controller.</h4>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> login<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//handle the login - we'll get to this later</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//create the salt by creating an MD5 Hash of the current time</span>
        <span style="color: #000088;">$salt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">//make the salt available to the view</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'special_sauce'</span><span style="color: #339933;">,</span><span style="color: #000088;">$salt</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">//store the salt in the session</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'salt'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$salt</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see, generating the salt and making it available in a variable which we can access in the view is really a trivial matter. A couple of points bear explanation. First of all, why am I using MD5 here when using SHA1 for the hashing itself? Well, this particular use of a hash is simply to generate a random assortment of characters to use as salt, therefore we can use the less secure MD5 algorithm which will run a little faster than SHA1. It really makes no difference, and is more a matter of preference than anything else. For the actual hashes, however, you should use SHA1 as it is more secure. Secondly, you may wonder why I am saving the salt in the session when I have made it available to the view (yes, I am going to be placing it in a hidden form element). The reason for this is to ensure that we use the salt generated here when we do our comparisons later on. If we were to place it in the form element and use that return to check the stored password, an attacker could simply supply the salt he wanted to use in that form element and he could bypass our security. This way, we are protected against clever people like that.</p>
<p>With our form defined and our salt available we need to write some javascript to process the user input before sending it to the server. Specifically, we are going to take the entered password, run the SHA1 algorithm on it, concatenate the resulting hash with the salt and run the algorithm on it again. Following that process we write our new password value into the password field and let the form submit. Javascript to accomplish this is shown in Snippet #3.</p>
<h4>Snippet #3: Javascript transform_login function</h4>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> transform_login<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> password <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'password'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> salt <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'special_sauce'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> hashed_pass <span style="color: #339933;">=</span> sha1Hash<span style="color: #009900;">&#40;</span>password<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> hashed_and_salted_pass <span style="color: #339933;">=</span> hashed_pass <span style="color: #339933;">+</span> salt<span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> salted_hash_pass_hash <span style="color: #339933;">=</span> sha1Hash<span style="color: #009900;">&#40;</span>hashed_and_salted_pass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'password'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> salted_hash_pass_hash<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This new javascript function requires that we make some changes to our login code, as shown in Snippet #4.</p>
<h4>Snippet #4: Modfied login form.</h4>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/sha1.js&quot;</span> <span style="color: #000066;">language</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/login.js&quot;</span> <span style="color: #000066;">language</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;?php if <span style="color: #66cc66;">&#40;</span>$error<span style="color: #66cc66;">&#41;</span>: ?&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;error_message&quot;</span>&gt;</span>The login credentials you supplied could not be recognized. Please try again.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
<span style="color: #009900;">&lt;?php endif; ?&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/admin/login&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span><span style="color: #66cc66;">&#41;</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span>&gt;</span>Username:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span>
        <span style="color: #009900;">&lt;?php echo $html-&gt;</span>input('User/username', array('size' =&gt; 20, 'class' =&gt; 'TextField', 'id'=&gt;'username')); ?&gt;
        <span style="color: #009900;">&lt;?php echo $html-&gt;</span>tagErrorMsg('User/username', 'Username is required.')?&gt;
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span>&gt;</span>Password:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span>
        <span style="color: #009900;">&lt;?php echo $html-&gt;</span>password('User/password', array('size' =&gt; 20, 'class' =&gt; 'TextField', 'id'=&gt;&quot;password&quot;)); ?&gt;
        <span style="color: #009900;">&lt;?php echo $html-&gt;</span>tagErrorMsg('User/password', 'Password is required.')?&gt;
        <span style="color: #009900;">&lt;?php echo $html-&gt;</span>submit(&quot;Login&quot;, array('class'=&gt;'Button', 'onclick'=&gt;&quot;Javascript:return transform_login();&quot;)); ?&gt;
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;special_sauce&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;special_sauce&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'&lt;?php echo $special_sauce; ?&gt;</span></span>'&gt;
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span>
<span style="color: #009900;">&lt;?php if <span style="color: #66cc66;">&#40;</span>$error<span style="color: #66cc66;">&#41;</span>: ?&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">language</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;javascript&quot;</span>&gt;</span>
        document.getElementById('password').value = &quot;&quot;;
        document.getElementById('username').value = &quot;&quot;;
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;?php endif; ?&gt;</span></pre></div></div>

<p>As you can see, we have added code to include the sha1.js and login.js files which contain our sha1 functions and login function transform_login. We have also inserted our hidden value with the salt in it, called <em>special_sauce</em> here. Finally, we have added an <em>onclick</em> to the submit button to call the javascript function and transform our password. This should be everything we need on the client end of things.</p>
<h3>The login process in the controller</h3>
<p>Earlier, in Snippet #2, we passed over the code in the controller that actually handles the processing of the login. Now it is time to revisit the controller and finish off our secure login. The goal here is to replicate the actions taken in the javascript function <em>transform_login</em> and compare the results of the server-side transform and that done on the client end.</p>
<p>Since we embedded the salt in the login form using a hidden form value, that value will be available to us here in the controller. We never want to use that value, however, because we can never be sure of the source of any information coming to us from a web form. It is very easy to construct a duplicate form which submits faulty information in an attempt to gain access to a secured system. What we will do is take the password from the user&#8217;s database record and the salt stored in the session and put that information through the same transformations as we did on the client side. If the values match then we know the user entered the right password and can be granted access. Snippet #5 contains the full code of the final controller method.</p>
<h4>Snippet #5: Completed controller login code.</h4>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> login<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// If a has submitted form data:</span>
     <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
     <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$someone</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">User</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findByUsername</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'data'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'User'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         <span style="color: #666666; font-style: italic;">//the password from the database           </span>
         <span style="color: #000088;">$password</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$someone</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'User'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">//the salt value from the session</span>
         <span style="color: #000088;">$salt</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'salt'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">//hash the password</span>
         <span style="color: #000088;">$hashed_password</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sha1</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">//add the salt to the hashed password</span>
         <span style="color: #000088;">$salted_and_hashed_password</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$hashed_password</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$salt</span><span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">//salt the salted and hashed password</span>
         <span style="color: #000088;">$salted_hash_pass_hash</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sha1</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$salted_and_hashed_password</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         <span style="color: #666666; font-style: italic;">//do our comparison</span>
         <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$salted_hash_pass_hash</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'data'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'User'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>
              <span style="color: #666666; font-style: italic;">// This means they were the same. We can now build some basic</span>
              <span style="color: #666666; font-style: italic;">// session information to remember this user as 'logged-in'.</span>
              <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'User'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$someone</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'User'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
              <span style="color: #666666; font-style: italic;">// Now that we have them stored in a session, forward them on</span>
              <span style="color: #666666; font-style: italic;">// to a landing page for the application.</span>
              <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/logged_in/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #009900;">&#125;</span>
         <span style="color: #666666; font-style: italic;">// Else, they supplied incorrect data:</span>
         <span style="color: #b1b100;">else</span>
         <span style="color: #009900;">&#123;</span>
             <span style="color: #666666; font-style: italic;">//Remember the $error var in the view? Let's set that to true:</span>
             <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'error'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #009900;">&#125;</span>
     <span style="color: #009900;">&#125;</span>
     <span style="color: #b1b100;">else</span>
     <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$salt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'special_sauce'</span><span style="color: #339933;">,</span><span style="color: #000088;">$salt</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'salt'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$salt</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Summary and Caveats</h3>
<p>That&#8217;s really all there is to securing your logins with a challenge-response system. Of course, if you have an SSL certificate available to you, using it would be in your best interests. There is, however, nothing stopping you from using both at the same time. You can never have too much security.</p>
<p>A few words of warning, however. This is not intended to be a complete solution for your login needs. There are several aspects of a login system that have been overlooked in the name of brevity. Not the least of these are validating required fields and protecting all input fields from SQL Injection vulnerablilities. This only provides you with the means of obscuring password data in transit over public networks. I recommend that you do your research up front on a complete solution to prevent getting burned by something simple you may have overlooked.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2007/01/14/secure_logins_with_challenge_response/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementing Single Table Inheritance in CakePHP</title>
		<link>http://www.ifisgeek.com/2007/01/14/implementing_single_table_inheritance_in_cakephp/</link>
		<comments>http://www.ifisgeek.com/2007/01/14/implementing_single_table_inheritance_in_cakephp/#comments</comments>
		<pubDate>Mon, 15 Jan 2007 02:05:05 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testbed.ifisgeek.com/implementing-single-table-inheritance-in-cakephp/</guid>
		<description><![CDATA[Single Table Inheritance is on of the coolest features of Ruby on Rails. Unfortunately, it is one feature that has not made its way into CakePHP. With a little bit of work, however, you can implement it for yourself. It should be noted, however, that this is by  no means a complete solution. What [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ifisgeek.com/blog_entries/show/the_joys_of_single_table_inheritance">Single Table Inheritance</a> is on of the coolest features of Ruby on Rails. Unfortunately, it is one feature that has not made its way into CakePHP. With a little bit of work, however, you can implement it for yourself. It should be noted, however, that this is by  no means a complete solution. What follows works for me in my applications but does not cover all possible scenarios. This tutorial is in the same table as my blog entries so you are seeing the methods below in action but your mileage may vary. </p>
<h4>An Example Scenario</h4>
<p>To best illustrate this method we will need an example scenario to work with. As I mentioned in my blog entry on <a href="http://www.ifisgeek.com/blog_entries/show/the_joys_of_single_table_inheritance">Single Table Inheritance</a>, it is particularly helpful when creating a site like Digg. For our example, let&#8217;s consider building a site called Excavate. Our requirements are rather simple: a site for people to input links with descriptions. Once a link has been entered it will be considered an &quot;upcoming&quot; entry. Once enough members (only people who have signed up can view and excavate upcoming items) excavate an item it gets green-lighted and becomes a &quot;current&quot; entry. We will store both types of entry in one database table.</p>
<h4>The Database Bits</h4>
<p>The basic information we need for both kinds of entry is the same: a title, a description, a url, an author name, an author email address, and a created date. A current posting will also require the date which it was green-lighted to order the postings chronologically. To these required fields we will be adding a type field which will hold a reference to which object the record references, upcoming or current. Snippet 1 shows the SQL code for creating our table in MySQL.</p>
<h4>Snippet #1: SQL Code for our entries table.</h4>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`entries`</span> <span style="color: #66cc66;">&#40;</span> 
    <span style="color: #ff0000;">`id`</span> int<span style="color: #66cc66;">&#40;</span>11<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span> 
    <span style="color: #ff0000;">`title`</span> varchar<span style="color: #66cc66;">&#40;</span>255<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> 
    <span style="color: #ff0000;">`description`</span> text <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> 
    <span style="color: #ff0000;">`url`</span> var char<span style="color: #66cc66;">&#40;</span>255<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
    <span style="color: #ff0000;">`author_name`</span> varchar<span style="color: #66cc66;">&#40;</span>255<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
    <span style="color: #ff0000;">`author_email`</span> varchar<span style="color: #66cc66;">&#40;</span>255<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
    <span style="color: #ff0000;">`created`</span> datetime <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
    <span style="color: #ff0000;">`greenlit`</span> datetime <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
    <span style="color: #ff0000;">`type`</span> varchar<span style="color: #66cc66;">&#40;</span>255<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'BlogEntry'</span><span style="color: #66cc66;">,</span>
    <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#41;</span>
    ENGINE<span style="color: #66cc66;">=</span>MyISAM <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>latin1;</pre></div></div>

<p>There are a few things to check with your database code to ensure that everything will function smoothly. First of all, ensure that your `created` field is called created. CakePHP will automagically handle setting this value for you when you are saving your model. Secondly, ensure that you do not set any model-specific fields to NOT NULL. If, for example, we had set the `greenlit` field to be NOT NULL we would run into troubles when saving an upcoming object, as that object has not been greenlit yet.</p>
<h4>The Models</h4>
<p>Now that we have the database table in place to hold our data it is time to write the Model classes for our two objects. We will need to add several variable to the models and override several methods from the parent class AppModel. Let&#8217;s start by looking at the Current model.</p>
<h4>Snippet #2: Class definition and variables<br />
for the Current Model.</h4>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> <span style="color: #990000;">Current</span> <span style="color: #000000; font-weight: bold;">extends</span> AppModel
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Current'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//single table inheritance vars</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__table</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'entries'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Current.id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.title'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Current.description'</span><span style="color: #339933;">,</span> 
<span style="color: #0000ff;">'Current.author_name'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Current.author_email'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Current.created'</span><span style="color: #339933;">,</span>
<span style="color: #0000ff;">'Current.greenlit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__type_field</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'type'</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first variable we need to define is $name. This is required in CakePHP if you are using PHP4 but not in PHP5. Nevertheless, we will be using it as it will make many things we are going to do much easier. Ensure that the value of this variable matches exactly the name of your class. The next variable $__table contains the name of the database table in which we are storing our objects. $__fields is an array containing a list of the fields that belong to this model. Note that each field is prefixed with the name of the class it belongs to &#8211; even though the name of the table is not Current this will work because the queries created by CakePHP will have FROM `entries` AS `Current` to make everything play nicely. Also of note is the fact that we are not specifying that the type field is a part of the model &#8211; this is because it is not. The type field determines which model a record is but we will be handling that automatically and so do not need to manipulate the field directly. Finally, we place the name of the field in which we are storing our type into the variable $__type_field.</p>
<div class="right_cutout">
<h4>Associations?</h4>
<p>What about using associations in our models? Using associations with Single Table Inheritance works the same way as it would in ordinary circumstances. Other models would reference the Current and Upcoming models as if they were regular models. For example, we might have two other models in play: Comment and Author. In Author we would have Current and Upcoming listed in the $hasMany array and in Comment we would have Current and Upcoming listed in the $belongsTo array. Within Current and Upcoming we would reference other models in the same way. The only thing to watch out for is that you specify the model name in the $__fields array. So, if we had a table of authors our Current $__fields array would contain &#8216;Author.name&#8217; if we wanted to pull in the author&#8217;s name.</p></div>
<p>With the above variables in place, we can turn our attention to the methods we need to override. Any methods which involve reading or writing records need to be modified to take our changes into account. For my particular needs, I have found that I needed to override <em>__construct, findAll, findCount, findAllThreaded</em> and <em>save</em>. <em>__construct</em> is modified to supply the tablename to the <em>__construct</em> method of AppModel and, as such, is the simplest modification we will be making. The modifications to the <em>save</em> method are a little more significant by equally easy to accomplish. All that needs doing is to add a reference to the type field and its value to the $data variable before passing it to the parent.</p>
<p>The data retrieval methods <em>findAll, findCount</em> and <em>findAllThreaded</em> require a little more work than the fields detailed above. There are two things that need to be done here: modify the conditions to include a reference to the value of the type field and check for the fields being queried. The latter requires a little more explanation. Since we are storing the information for both objects in one table there are certain fields which belong to one model but not to the other. We need to make sure that we are only grabbing the fields that belong to the model in question. In our example, we need to check that we are not querying the greenlit field if we are querying for an Upcoming model. If the fields are not being queried specifically and $fields is null, then we will substitute our $__fields array for $fields to only return that which belongs to this model. Snippet #3 contains the completed code for our Current model.</p>
<h4>Snippet #3: Complete definition for the Current Model.</h4>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> <span style="color: #990000;">Current</span> <span style="color: #000000; font-weight: bold;">extends</span> AppModel
<span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Current'</span><span style="color: #339933;">;</span>
&nbsp;
     <span style="color: #666666; font-style: italic;">//single table inheritance vars</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__table</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'entries'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Current.id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.title'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.description'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.author_name'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.author_email'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.created'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Current.greenlit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__type_field</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'type'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span><span style="color: #000088;">$ignore_table</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ds</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$table</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__table<span style="color: #339933;">;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span><span style="color: #000088;">$table</span><span style="color: #339933;">,</span><span style="color: #000088;">$ds</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> findAll<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$limit</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> 1<span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conditions</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; AND &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #b1b100;">AS</span> <span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">,</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Field &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$field</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; does not exist in Model &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
         <span style="color: #009900;">&#125;</span>
&nbsp;
         <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">findAll</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span><span style="color: #339933;">,</span> <span style="color: #000088;">$limit</span><span style="color: #339933;">,</span> <span style="color: #000088;">$page</span><span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> findCount<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span> <span style="color: #339933;">=</span> 0<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conditions</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; AND &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">findCount</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> findAllThreaded<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sort</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__table <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conditions</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; AND &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #b1b100;">AS</span> <span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">,</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Field &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$field</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; does not exist in Model &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">findAllThreaded</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sort</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$validate</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fieldList</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$validate</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fieldList</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Snippet #4 contains the complete code for our Upcoming Model. Notice that it does not reference the greenlit field whereas the Current Model did.</p>
<h4>Snippet #4: Complete definition for the Upcoming Model.</h4>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Upcoming <span style="color: #000000; font-weight: bold;">extends</span> AppModel
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Upcoming'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//single table inheritance vars</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__table</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'entries'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Upcoming.id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Upcoming.title'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Upcoming.description'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Upcoming.author_name'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Upcoming.author_email'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Upcoming.created'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$__type_field</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'type'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span><span style="color: #000088;">$ignore_table</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #000088;">$ds</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$table</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__table<span style="color: #339933;">;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span><span style="color: #000088;">$table</span><span style="color: #339933;">,</span><span style="color: #000088;">$ds</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> findAll<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$limit</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> 1<span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conditions</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; AND &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #b1b100;">AS</span> <span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">,</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Field &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$field</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; does not exist in Model &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">findAll</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span><span style="color: #339933;">,</span> <span style="color: #000088;">$limit</span><span style="color: #339933;">,</span> <span style="color: #000088;">$page</span><span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> findCount<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span> <span style="color: #339933;">=</span> 0<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conditions</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; AND &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">findCount</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$recursive</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> findAllThreaded<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sort</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__table <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$conditions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conditions</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; AND &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = '&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #b1b100;">AS</span> <span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #339933;">,</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__fields<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Field &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$field</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; does not exist in Model &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">findAllThreaded</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$conditions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fields</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sort</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>    
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$validate</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fieldList</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>__type_field<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$validate</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fieldList</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see, aside from the values of the variables at the top, these two models are nearly identical for our simple example. In a real system you would likely add other methods to your models to handle more than just the simplest of situations. An example here would be for the green-lighting process. A method in the Upcoming model which sets the value of the greenlit field and changes the type field to &#8216;Current&#8217; would effectively change the model of the record and have it show up where needed. I&#8217;ll leave that code as an exercise.</p>
<p>Given the fact that the modified methods are the same in both models, this method lends itself to scaffolding quite easily. One of these days I am going to look into modifying / extending the CakePHP script bake.php to allow for scaffolding Single Table Inheritance models. If someone has a chance to do this before I do, please drop me a line!</p>
<h4>Controllers and Views</h4>
<p>With the database table and Model classes taken care of it is time to look at the Controllers and Views. What needs to be done specially to handle the Single Table Inheritance? Nothing! This is the realy beauty of a setup like this, you make your changes at the Database and Model levels but your controllers and views are handled like they are for any other models. As far as you are concerned when writing the controllers and views, there are two database tables &#8211; one for Upcoming and one for Current &#8211; and you can handle them as you would normally.</p>
<h4>Caveats</h4>
<p>As I mentioned at the beginning of this, not every scenario will be covered by this method. Depending on your needs you may need to override more or less methods from AppModel. I am currently using this on two projects in addition to on this site. If anyone else manages to get some use out of it or if you have any questions/comments/error reports, please feel free to leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2007/01/14/implementing_single_table_inheritance_in_cakephp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tutorials</title>
		<link>http://www.ifisgeek.com/2007/01/14/tutorials/</link>
		<comments>http://www.ifisgeek.com/2007/01/14/tutorials/#comments</comments>
		<pubDate>Mon, 15 Jan 2007 02:01:45 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testbed.ifisgeek.com/tutorials/</guid>
		<description><![CDATA[This is where I will link all of my tutorials.
Implementing Single Table Inheritance In CakePHP
Secure Logins With Challenge-Response
]]></description>
			<content:encoded><![CDATA[<p>This is where I will link all of my tutorials.</p>
<p><a title="Implementing Single Table Inheritance In CakePHP [Tutorial]" href="http://www.ifisgeek.com/tutorials/implementing_single_table_inheritance_in_cakephp/">Implementing Single Table Inheritance In CakePHP</a></p>
<p><a title="Secure Logins With Challenge-Response [Tutorial]" href="http://www.ifisgeek.com/tutorials/secure_logins_with_challenge_response/">Secure Logins With Challenge-Response</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2007/01/14/tutorials/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My new car keeps getting better</title>
		<link>http://www.ifisgeek.com/2006/10/28/my_new_car_keeps_getting_better/</link>
		<comments>http://www.ifisgeek.com/2006/10/28/my_new_car_keeps_getting_better/#comments</comments>
		<pubDate>Sat, 28 Oct 2006 06:48:28 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/2006/10/28/my_new_car_keeps_getting_better/</guid>
		<description><![CDATA[We just got a new car: a Dodge Caliber. There are many amazing things about this car, enough that I&#8217;ll devote a whole posting to it once I have some pictures to go along with it. One thing I wanted to mention, however, was something I noticed on the drive home from the movies tonight. [...]]]></description>
			<content:encoded><![CDATA[<p>We just got a new car: a Dodge Caliber. There are many amazing things about this car, enough that I&#8217;ll devote a whole posting to it once I have some pictures to go along with it. One thing I wanted to mention, however, was something I noticed on the drive home from the movies tonight. The radio can display song and artist information for FM stations. Yes, as I am driving I can hit the info button and it will show me the name of the song playing and the artist. This blew my mind! Amazing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2006/10/28/my_new_car_keeps_getting_better/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seen Saw III</title>
		<link>http://www.ifisgeek.com/2006/10/28/seen_saw_iii/</link>
		<comments>http://www.ifisgeek.com/2006/10/28/seen_saw_iii/#comments</comments>
		<pubDate>Sat, 28 Oct 2006 06:43:30 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/2006/10/28/seen_saw_iii/</guid>
		<description><![CDATA[This evening Lindsay and I went to see Saw III with some friends. I have to say I found it rather disappointing. The twists and turns that were so excellent in the first two movies are there. The story is quite strong and the ending was very well done. So, what was wrong with it? [...]]]></description>
			<content:encoded><![CDATA[<p>This evening Lindsay and I went to see Saw III with some friends. I have to say I found it rather disappointing. The twists and turns that were so excellent in the first two movies are there. The story is quite strong and the ending was very well done. So, what was wrong with it? Everything else.</p>
<p>The entire story could have been told in half of a movie but it was stretched to a whole one. If you&#8217;ve heard that this movie has much more gore than the previous two, you have not been misled. I am all for gore in a horror movie, but in tis one it felt unnecessarily tacked on. Long portions of the movie between gory scenes were just too drawn out. One example is the story of the character named Jeff. The movie leaves his story to tell other aspects and it feels like an eternity before the focus returns to him. As such, there is very little to make me care about him or his situation. The first two movies did a much better job of telling different stories or different angles on stories without making any of those stories suffer. In the third, however, the movie as a whole suffers.</p>
<p>I recommend this movie if you are a fan of horror flicks. Just don&#8217;t expect anything as good as the previous two.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2006/10/28/seen_saw_iii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>About</title>
		<link>http://www.ifisgeek.com/2006/10/25/about/</link>
		<comments>http://www.ifisgeek.com/2006/10/25/about/#comments</comments>
		<pubDate>Thu, 26 Oct 2006 04:26:30 +0000</pubDate>
		<dc:creator>jread</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/about/</guid>
		<description><![CDATA[Jeff Read is the creator / evil genius behind ifisgeek.com. Originally from Sydney, Nova Scotia he currently calls Saskatoon, Saskatchewan his home. A Programmer/Analyst by day and a Programmer by night he enjoys well-commented code, and long walks on the beach with his wife.
]]></description>
			<content:encoded><![CDATA[<p><img align="left" style="margin-right: 10px" alt="Jeff Read" id="image46" title="Jeff Read" src="http://www.ifisgeek.com/wp-content/uploads/2007/01/jeffread.jpg" />Jeff Read is the creator / evil genius behind ifisgeek.com. Originally from Sydney, Nova Scotia he currently calls Saskatoon, Saskatchewan his home. A Programmer/Analyst by day and a Programmer by night he enjoys well-commented code, and long walks on the beach with his wife.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2006/10/25/about/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Directions</title>
		<link>http://www.ifisgeek.com/2006/10/25/new_directions/</link>
		<comments>http://www.ifisgeek.com/2006/10/25/new_directions/#comments</comments>
		<pubDate>Wed, 25 Oct 2006 18:38:42 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/2006/10/25/new_directions/</guid>
		<description><![CDATA[It has been quite a while since I last posted anything here, and for that I apologize. Life has been terribly busy in the last while. Work has been eating up a lot of my time &#8211; overtime is great for the bank account but not so good for the blog. Added to the time [...]]]></description>
			<content:encoded><![CDATA[<p>It has been quite a while since I last posted anything here, and for that I apologize. Life has been terribly busy in the last while. Work has been eating up a lot of my time &#8211; overtime is great for the bank account but not so good for the blog. Added to the time being consumed by work, Lindsay and I renovated our family room, a task which kept my main computer offline for a little over a week. Once I get the photo galleries on this site up and running I&#8217;ll post some pictures of the new and improved family room.</p>
<p>With all that has been going on I found myself getting very angry very easily, all of the time. Stress has a way of doing that to a person. Since that realisation, I have been working on learning to be more Zen. Reading a few books on the subject has helped a great deal. My stress levels have become more manageable and I can actually start considering taking on some more again.</p>
<p>Additionally, a few things are changing which could very well indicate that this is a good time in my life to initiate changes. I just sold my car and placed a deposit on a new Dodge Caliber. The Passat was a great car but we are finding an increasing need for more space. the Caliber has the dual benefit of lots of storage space and of being a very cool car. Also, when Lindsay and I were getting married I said I wanted two good years of marital bliss before we even consider the idea of having kids. Well, 2 years is coming up in July and I am not happy with where I am. I want to be in good shape and healthy before we have kids because making drastic changes to my health and routine after that will be impossible &#8211; well, making drastic changes will likely be par for the course but making conscious drastic changes will probably be more difficult.</p>
<p>Another change is my friend Ralph got himself a new job. With that he&#8217;ll be leaving Cover-All and he&#8217;s looking to make some changes in his life too. Such changes on my part will no doubt be a little easier if I know someone going through similar changes at the same time &#8211; especially if we can turn it all into some kind of competition <img src='http://www.ifisgeek.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So, what does this mean for my blog? Well, I should be making more frequent entries. There should also be more entries about my life and such with perhaps less tech/geek entries. Maybe less geek, not likely but possible. I am also going to abandon development on this blogging engine. It was a great project for learning CakePHP but such development these days takes away from the time I have to create content. Look for this site to become powered by WordPress in the near future. I will still keep a copy of this codebase on my development machine so I will continue to write tutorials for CakePHP and anything esle I can think of. Such development will not be readily apparent on this site in the future, however, unless I start writing WordPress plugins.</p>
<p>Wish me luck as I start down this new road. It is said that even the longest journey starts with a single step and for me, on this site, that first step is this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2006/10/25/new_directions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webstats Is A Spectator Sport</title>
		<link>http://www.ifisgeek.com/2006/08/31/webstats_is_a_spectator_sport/</link>
		<comments>http://www.ifisgeek.com/2006/08/31/webstats_is_a_spectator_sport/#comments</comments>
		<pubDate>Fri, 01 Sep 2006 02:22:51 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/2006/08/31/webstats_is_a_spectator_sport/</guid>
		<description><![CDATA[I have recently started submitting links to my site to various other sites such as the CakePHP wiki, the google group for CakePHP and digg. Almost immediately I started seeing a significant increase in the traffic to my site. I use Google Analytics to track these metrics, and I have to admit, I have become [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently started submitting links to my site to various other sites such as the <a href="http://www.testbed.ifisgeek.com/%5C%22http://wiki.cakephp.org%5C%22">CakePHP wiki</a>, <a href="http://www.testbed.ifisgeek.com/%5C%22http://groups.google.com/group/cake-php%5C%22">the google group for CakePHP</a> and <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.digg.com%5C%22">digg</a>. Almost immediately I started seeing a significant increase in the traffic to my site. I use Google Analytics to track these metrics, and I have to admit, I have become addicted. Checking these stats is, to a geek like me, what watching sports must be like to a jock. I submit a tutorial to another site, submit it at different times and watch the effect it has on my traffic. It is really fascinating. It is through this micro-obsession that I have discovered two absolutely killer sites.</p>
<p>The first of these isn&#8217;t really a site. Well, it is but that isn&#8217;t the important part of it. This morning I noticed that all of a sudden 30% of the traffic I received over the past week was attributed to a site called <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.stumbleupon.com%5C%22">stumbleupon.com</a>. This happened overnight. Last night going to bed the major contributer to my traffic was groups.google.com at about 21% of total traffic. Then this morning a site I had never heard of rocketed to 30%. I <em>had</em> to check this site out.</p>
<p>What StumbleUpon turned out to be is the homepage for a browser plug-in. Think of it as digg for every single page you browse to. You can register your vote, either thumbs-up or thumbs-down on any page. You can also click the Stumble button in the SU toolbar and be taken to a random page that matches your interests (you choose some categories of interest when initially configuring the toolbar). So far, the choices have been quite accurate. The very first page I <em>stumbled</em> to was killer. It has to be the best music site I have ever visited.</p>
<p>By far I have found the best way to learn of new bands that appeal to me is talking to friends. I mention a band I like, they say they like them too and, hey, have you ever heard <em>these</em> guys? <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.pandora.com/%5C%22">Pandora Internet Radio</a> has harnessed this power in a website. You go there, enter the name of a band you like and an Internet radio station is configured for you full of bands that are similar in nature to the one you already like. The first band I tried was Orson, my current favourite, but alas, they are still only big in Britain and weren&#8217;t found in the db. Next I tried Brand New, another favourite of mine. I have been listening to songs for the past half hour inspired by my like of Brand New and I have yet to hear a bad one. This works seriously well. Try it out, you won&#8217;t be disappointed!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2006/08/31/webstats_is_a_spectator_sport/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Joys of Single Table Inheritance</title>
		<link>http://www.ifisgeek.com/2006/08/19/the_joys_of_single_table_inheritance/</link>
		<comments>http://www.ifisgeek.com/2006/08/19/the_joys_of_single_table_inheritance/#comments</comments>
		<pubDate>Sat, 19 Aug 2006 23:07:05 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/2006/08/19/the_joys_of_single_table_inheritance/</guid>
		<description><![CDATA[CakePHP started as a PHP port of the Rails framework (please read the sidebar if you are unfamiliar with Ruby on Rails) but has grown into its own, in my opinion, most excellent project. Cake has the benefit of being based on PHP which is still, I believe, the most popular web programming language out [...]]]></description>
			<content:encoded><![CDATA[<p>CakePHP started as a PHP port of the Rails framework (please read the sidebar if you are unfamiliar with <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.rubyonrails.org%5C%22">Ruby on Rails</a>) but has grown into its own, in my opinion, most excellent project. Cake has the benefit of being based on PHP which is still, I believe, the most popular web programming language out there. One thing that I have found Cake lacking in comparison to Ruby on Rails is Single Table Inheritance.</p>
<div class="right_cutout">
<h4>Ruby on Rails?</h4>
<p>If you have been living under a rock for the past year, you have probably never heard of <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.rubyonrails.org%5C%22">Ruby on Rails</a>. The rest of you know that Rails is a web application development framework, built using the Ruby programming language, that makes the development of richly functional web apps so easy it is enjoyable. Personally, I have played with Ruby on Rails a bit and been very impressed with it. I do not, however, use it for any of my development. Why? Primarily because of the low number of web hosts that offer support for it. My own webhost, <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.dreamhost.com/r.cgi?193898%5C%22">Dreamhost</a>, <em>does</em> support it but I can never be sure that my client&#8217;s favourite host will.</div>
<p>Single Table Inheritance is a method of using one database table to hold the information of multiple objects. For example, if you had tutorials and blog entries that had basically the same fields and were going to be treated in basically the same manner, you could store them all in one table and use Single Table Inheritance to have them treated differently in your application. This is, in fact, what I have done with this site. (see my tutorial <a href="http://www.ifisgeek.com/tutorials/show/implementing_single_table_inheritance_in_cakephp">Implementing Single Table Inheritance in CakePHP</a> for information on how to accomplish this with CakePHP).</p>
<p>You may be wondering why we would want to bother with this when it is just as easy to create two tables and scaffold them seperately. In this case, yes, you are correct. Let&#8217;s take a look at another example which might shed some more light on the power of Single Table Inheritance. Let&#8217;s take a look at a site like <a href="http://www.testbed.ifisgeek.com/%5C%22http://www.digg.com%5C%22">Digg</a>. With this site there are two types of entry that can be viewed: those on the front page and those that are &#8220;Upcoming&#8221;. They are identical except for the fact that one has been given the &#8220;green-light&#8221; (in the case of Digg, an algorithm determines this based on popularity and time and any number of other factors) and the other has not. If we were creating a site like this using Ruby on Rails or CakePHP <em>without</em> Single Table Inheritance, we would have two almost identical tables and the process of &#8220;green-lighting&#8221; would involve deleting a post from one table (upcoming) and inserting it into another (current).</p>
<p>With Single Table Inheritance, however, we can have everything in one table with an added field which specifies the type of object we are dealing with: Upcoming or Current. In this setup, &#8220;green-lighting&#8221; is as simple as changing the type field on the record. So, with Single Table Inheritance we get the benefit of having everything in one table and the benefits of being able to programmatically treat each as a different object. We can have entirely different methods of displaying, adding, editing or deleting the two even though they are held in the same table.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2006/08/19/the_joys_of_single_table_inheritance/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
