<?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>Shawn McCool</title>
	<atom:link href="http://shawnmccool.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://shawnmccool.com</link>
	<description>a blog about web and game development</description>
	<lastBuildDate>Sat, 30 Jan 2010 07:26:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</title>
		<link>http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/</link>
		<comments>http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 07:25:43 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[screencast]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=438</guid>
		<description><![CDATA[This video covers the development of an admin user management system (CRUD) and includes updates to the authentication system including a method that is used allow only admins into specific sections of the site.


Related posts:<ol><li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This screencast continues a series with the goal of documenting the development of a functionally complete site using PHP with the CodeIgniter framework and jQuery for JavaScript UI Improvements including AJAX interactions.</p>
<p>This video covers the development of an admin user management system (CRUD) and includes updates to the authentication system including a method that is used allow only admins into specific sections of the site.</p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Tip Tracker Android App Released</title>
		<link>http://shawnmccool.com/2009/12/23/tip-tracker-android-app-released/</link>
		<comments>http://shawnmccool.com/2009/12/23/tip-tracker-android-app-released/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 04:19:08 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=430</guid>
		<description><![CDATA[I&#8217;ve released my first Android application.  I decided on something easy for my first app and I have to say.. Android development is incredibly simple.  I think the app turned out really well.  I have multiple upgrades planned including a free version (this version goes for 99 cents).
Upcoming versions will include trending analysis and spreadsheet [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released my first Android application.  I decided on something easy for my first app and I have to say.. Android development is incredibly simple.  I think the app turned out really well.  I have multiple upgrades planned including a free version (this version goes for 99 cents).</p>
<p>Upcoming versions will include trending analysis and spreadsheet export via email.</p>
<p><img src="/files/tiptracker_today.png" alt="" /><img style='padding-left:15px' src="/files/tiptracker_history.png" alt="" /></p>
<p>Sales pitch below:</p>
<p>Servers can gain control of their income with Tip Tracker.</p>
<p>Roughly estimating your income can lead to serious mistakes which result in real financial losses.</p>
<p>This server assistant tool stores the amount of hours worked, tips earned, wages earned, and other income.</p>
<p>Store and analyze your income history.</p>
<div style='width:300px; padding-top:20px;'>
<img src="/files/tiptrackerqr.png" style='float:left; padding-right:8px;' /><br />
Android users can take a picture of this mark to access Tip Tracker on the Android Marketplace.
</div>
<div style='clear:both'>&nbsp;</div>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/12/23/tip-tracker-android-app-released/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Managing Assets with CodeIgniter</title>
		<link>http://shawnmccool.com/2009/11/23/managing-assets-with-codeigniter/</link>
		<comments>http://shawnmccool.com/2009/11/23/managing-assets-with-codeigniter/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 23:16:32 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[reusability]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=390</guid>
		<description><![CDATA[Where do we put those images, anyway?


Related posts:<ol><li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/' rel='bookmark' title='Permanent Link: How to Write a Better Model in CodeIgniter'>How to Write a Better Model in CodeIgniter</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This article discusses the reason behind the base_url() method and the creation of a helper file that will assist in managing images, css files, and more.</p>
<p>PHP code is far from the only content necessary for most web applications.  Most frequently we need to include images, css files, flash files, and many other types of files.  The CodeIgniter framework doesn&#8217;t contain a built-in methodology for asset management, leaving the developer to their own devices when it comes to deciding where to put this content.  Every developer is going to have their own personal preference, and for the most part they&#8217;re equally valid.</p>
<h3>The base_url() method</h3>
<p>Imagine a scenario where you have developed a site that contains user profiles.  Each user profile can have an image.  The code in your view that would display the image may look something like this:</p>
<p>[cc lang="php"]<br />
<img src="/images/profiles/myface.jpg" alt="" /><br />
[/cc]</p>
<p>This works fine until your cool new site is bought up and now your application rests at http://www.bigcompany.com/mycoolsite.  Now, you have to go through all of your code and search/replace &#8220;/images with &#8220;/mycoolsite/images while hoping that you&#8217;ve found everything and that something small won&#8217;t be missed until 500 users have seen it.</p>
<p>Instead, we use the base_url() method for creating absolute links.  base_url() simply outputs the value of the  $config['base_url'] variable that is set in your application/config/config.php file.  Your new code would look like this:</p>
<p>[cc lang="php"]<br />
<img src="<?=base_url()?>images/profiles/myface.jpg&#8221; alt=&#8221;" /><br />
[/cc]</p>
<p>Now, if you need to change the location of your site you can simply update the $config['base_url'] value in your application/config.php and your code will be updated throughout the site.  For this reason it&#8217;s a good idea to use base_url() anywhere that you would use an absolute or relative url that points to your CodeIgniter site.</p>
<p>[cc lang="php"]</p>
<form action="<?=base_url()?>admin/users/edit/72&#8243; method=&#8221;post&#8221;><br />
<a href="<?=base_url()?>admin/pages&#8221;>Manage Pages</a><br />
[/cc]</p>
<h3>The asset_url() function</h3>
<p>We not only have to consider that our application may be moving, we need to consider how we&#8217;re keeping our static assets mobile, things like images, css files, etc.  My method is to create a path_helper that contains a new function, asset_url().</p>
<p>[cc lang="php"]<br />
// application/helpers/path_helper.php<br />
if (!function_exists(&#8216;asset_url&#8217;))<br />
{<br />
	function asset_url()<br />
	{<br />
	    // the helper function doesn&#8217;t have access to $this, so we need to get a reference to the<br />
	    // CodeIgniter instance.  We&#8217;ll store that reference as $CI and use it instead of $this<br />
		$CI =&#038; get_instance();</p>
<p>		// return the asset_url<br />
		return base_url() . $CI->config->item(&#8216;asset_path&#8217;);<br />
	}<br />
}<br />
[/cc]</p>
<p>Then, in either our config.php or in a new configuration file we would add:</p>
<p>[cc lang="php"]<br />
// config.php<br />
$config['asset_path'] = &#8217;system/application/assets/&#8217;;<br />
[/cc]</p>
<p>Now, we just add the path_helper and the configuration file (if you&#8217;re not using config.php) to the autoload.php file.</p>
<p>[cc lang="php"]<br />
// Note that you omit the _helper.php suffix from the filename when loading helpers, it&#8217;s automatically added by CodeIgniter.<br />
$autoload['helper'] = array(&#8216;form&#8217;, &#8216;url&#8217;, &#8216;path&#8217;);</p>
<p>// This line doesn&#8217;t need to be use if you modified the config.php file, as it&#8217;s already loaded for you.<br />
// This line configures application/config/site.cfg to be autoloaded on every page load.<br />
$autoload['config'] = array(&#8217;site&#8217;);<br />
[/cc]</p>
<p>Now that the helper has been created, the configuration updated, and everything set to autoload we&#8217;re ready to use the asset_url() method.  Here&#8217;s the new way of writing image source.</p>
<p>[cc lang="php"]<br />
<img src="<?=asset_url()?>images/profiles/myface.jpg&#8221; alt=&#8221;" /><br />
[/cc]</p>
<p>Now, the asset root folder can be moved anywhere you&#8217;d like and you&#8217;ll be able to easily move these files around.  This can be very useful if users are uploading images to your live site and you wish to view them on your dev site as well.  You could simply update your configuration so that instead of use base_url() it uses http://www.mysite.com/ so that asset requests hit your live site instead of the local development site.</p>
<h3>A Quick Note on Preference</h3>
<p>Naturally, all programmers prefer to do things differently.  Some prefer the asset_url set to &#8216;./&#8217; so that the images/ folder is at the same place as the CodeIgniter system/ folder.  I personally prefer to place assets under the application folder as shown below:</p>
<p>system/application/assets/images<br />
system/application/assets/js<br />
system/application/assets/swf</p>
<p>I am of the opinion that the entirety of a site should be contained within the application/ folder, allowing for the rest of the CodeIgniter structure to be replaced (version upgrade) simply.  It&#8217;s always important to consider the cost of maintaining the site in the future.  It doesn&#8217;t cost any extra time to implement good practices during development but it can be very costly to retrofit a site with similar functionality, especially if there&#8217;s been personnel changes.</p>
<p><strong>The mark of a professional developer is designing and developing with focus on the lifetime cost of the product.</strong></p>
<p>If you have any questions or suggestions please leave a comment.</p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/' rel='bookmark' title='Permanent Link: How to Write a Better Model in CodeIgniter'>How to Write a Better Model in CodeIgniter</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/11/23/managing-assets-with-codeigniter/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Developing a Website with CodeIgniter Part 3: The Login Process</title>
		<link>http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/</link>
		<comments>http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 05:48:51 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[screencast]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=360</guid>
		<description><![CDATA[In this video we utilize the user model that we've created to create a login process for our website. Use use the code igniter form helper, database library, and session library.


Related posts:<ol><li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
<li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This screencast continues a series with the goal of documenting the development of a functionally complete site using PHP with the Code Igniter framework and jQuery for Javascript UI improvements including AJAX interactions.</p>
<p>In this video we utilize the user model that we&#8217;ve created to create a login process for our website. We&#8217;ll use the code igniter form helper, database library, and session library.</p>
<p>I tried something different and recorded the video in HD.  The encoding left the dark background text a bit hard to read, so if I continue to upload HD videos I&#8217;ll switch to using a white background.  Please let me know if you prefer the old resolution or the HD resolution.</p>
<p><a style='text-decoration:none; display:block; float:left' href="http://shawnmccool.com/files/codeignitertutorial-part3.zip"><img src='/files/download.png' border=0/> &nbsp; </a><a href="http://shawnmccool.com/files/codeignitertutorial-part3.zip" style='line-height:60px; color:white; display:block;'>Download the Source Here</a></p>
<p><!--subscribe2--></p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
<li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Why Should I Use CodeIgniter?</title>
		<link>http://shawnmccool.com/2009/10/28/why-should-i-use-code-igniter/</link>
		<comments>http://shawnmccool.com/2009/10/28/why-should-i-use-code-igniter/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 18:33:18 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=354</guid>
		<description><![CDATA[Code Igniter is a PHP development framework.  You can think of it as a PHP web site without content.  Instead it provides a structure and many methods that will be frequently used for most web sites.
So, why should I use Code Igniter instead of just writing my own site from scratch in PHP?
1. [...]


Related posts:<ol><li><a href='http://shawnmccool.com/2009/03/10/code-igniter-at-the-nashville-php-meetup-march-20th/' rel='bookmark' title='Permanent Link: CodeIgniter at the Nashville PHP meetup March 20th.'>CodeIgniter at the Nashville PHP meetup March 20th.</a></li>
<li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/08/29/understand-the-structure-of-code-igniter/' rel='bookmark' title='Permanent Link: Understand the Structure of CodeIgniter'>Understand the Structure of CodeIgniter</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Code Igniter is a PHP development framework.  You can think of it as a PHP web site without content.  Instead it provides a structure and many methods that will be frequently used for most web sites.</p>
<p>So, why should I use Code Igniter instead of just writing my own site from scratch in PHP?</p>
<h3>1. Standardization and Popularity &#8211; Using a popular development framework reduces the development time and consequently cost of initial development and maintenance.</h3>
<p>Hiring good developers is hard and adding developers mid-project is even harder.  Dozens, maybe even hundreds, of hours are spent acclimating new developers to the code base.  By hiring developers who are already familiar with Code Igniter you&#8217;re able to integrate them into the project much more quickly.  Code Igniter is very compartmentalized and finding / modifying various bits of code should be very easy for anyone familiar with the framework.  Initial project development time can be reduced by partially bypassing the need for planning of a custom framework.</p>
<p>Code Igniter is a framework that is widely used and it&#8217;s easy to find developers who are familiar with it.  There are many well made libraries and helpers created by users that will allow developers to integrate functionality into their sites without having to write it all from scratch.  The Code Igniter forums provide a centralized location for developers to get support from other developers.</p>
<h3>2. Loose Coupling and Code Re-usability &#8211; The longer you develop your code base the quicker projects can be completed.</h3>
<p>By keeping your database interactions in libraries and models, your html and display logic in views, and additional methods in helpers and plugins your resulting code becomes modular and is easily reusable on additional projects.  Why rewrite your user authentication system from project to project when you can simply copy your database structure and user model and be done with it?</p>
<p>Code Igniter is written with object oriented PHP.  Object oriented code is significantly less expensive to develop, debug, and maintain.  Programmers can no longer get away with using global variables to pass data around the application and the project quality benefits significantly.</p>
<h3>3. Built in Functionality &#8211; You know those hundred things that you rewrite every time you make a site?  Yea, they&#8217;re already done.</h3>
<p>Code Igniter comes out of the metaphorical box with libraries and helpers that reduce the amount of code a developer will have to write.  Some examples of the functionality that comes bundled in are: benchmarking, html calendar generation, shopping cart management, email sending, file uploading, form validation, ftp transfers, html generation, form generation, internationalization, pagination, session management, trackback management, string / typography manipulation, and more than I can list here.</p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2009/03/10/code-igniter-at-the-nashville-php-meetup-march-20th/' rel='bookmark' title='Permanent Link: CodeIgniter at the Nashville PHP meetup March 20th.'>CodeIgniter at the Nashville PHP meetup March 20th.</a></li>
<li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/08/29/understand-the-structure-of-code-igniter/' rel='bookmark' title='Permanent Link: Understand the Structure of CodeIgniter'>Understand the Structure of CodeIgniter</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/10/28/why-should-i-use-code-igniter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using CodeIgniter&#8217;s Active Record Class to Create Subqueries</title>
		<link>http://shawnmccool.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/</link>
		<comments>http://shawnmccool.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 16:50:34 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[active record]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=344</guid>
		<description><![CDATA[Create abstracted subqueries with Code Igniter's Active Record class.


Related posts:<ol><li><a href='http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/' rel='bookmark' title='Permanent Link: How to Write a Better Model in CodeIgniter'>How to Write a Better Model in CodeIgniter</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
<li><a href='http://shawnmccool.com/2009/03/10/code-igniter-at-the-nashville-php-meetup-march-20th/' rel='bookmark' title='Permanent Link: CodeIgniter at the Nashville PHP meetup March 20th.'>CodeIgniter at the Nashville PHP meetup March 20th.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>A good friend of mine recently asked me how he would create a subquery using Code Igniter&#8217;s Active Record class.  This does present a challenge as Code Igniter&#8217;s Active Record class does not natively support subqueries.</p>
<p>However, if you look into the code for the Database class you&#8217;ll see that CI uses some handy utility methods to compile the SQL for processing.  These methods exist in all Code Igniter drivers (providing the cross platform abstraction that makes Active Record so valuable in the first place).</p>
<p>This algorithm is definitely far from perfect, but it DOES provide some level of abstraction that manually typing your subquery would not.  If you have any questions, concerns, or suggestions feel free to leave them as comments.</p>
<p>[cc lang="PHP"]<br />
// Generate the subquery<br />
$this->db->select(&#8216;count(*)&#8217;);<br />
$this->db->from(&#8216;users&#8217;);</p>
<p>// Render the subquery to a string<br />
$subQuery = $this->db->_compile_select();</p>
<p>// Reset active record<br />
$this->db->_reset_select();</p>
<p>// Generate the primary query and include the subquery<br />
$this->db->select(&#8216;users.id as userId, users.fullname as userName&#8217;);<br />
$this->db->select(&#8220;($subQuery) as userCount&#8221;);<br />
$this->db->where(&#8216;users.status&#8217;, &#8216;active&#8217;);<br />
[/cc]</p>
<p>To break this down into smaller parts:</p>
<p>[cc lang="PHP"]<br />
// Generate the subquery<br />
$this->db->select(&#8216;count(*)&#8217;);<br />
$this->db->from(&#8216;users&#8217;);<br />
[/cc]</p>
<p>This code generates the query: select count(*) from users</p>
<p>[cc lang="PHP"]<br />
// Render the subquery to a string<br />
$subQuery = $this->db->_compile_select();<br />
[/cc]</p>
<p>This code uses Code Igniter&#8217;s Active Record class to generate an abstracted select statement.  Whether we&#8217;re using Oracle, MySQL, or PostgreSQL the statement will be rendered appropriately by Active Record.</p>
<p>[cc lang="PHP"]<br />
// Reset active record<br />
$this->db->_reset_select();<br />
[/cc]</p>
<p>This method is usually called automatically by the Active Record class after a select statement is completed.  This will clear the Active Record cache so that our &#8220;select&#8221;(count(*)) and &#8220;from&#8221;(users) commands will not appear in the NEXT active record statement that we create.</p>
<p>[cc lang="PHP"]<br />
// Generate the primary query and include the subquery<br />
$this->db->select(&#8216;users.id as userId, users.fullname as userName&#8217;);<br />
$this->db->select(&#8220;($subQuery) as userCount&#8221;);<br />
$this->db->where(&#8216;users.status&#8217;, &#8216;active&#8217;);<br />
[/cc]</p>
<p>This code generates a select statement calling back the userID and the userName as well as aliasing the subquery variable string as &#8216;userCount&#8217;.  Using the MySQL driver the SQL that is output is as follows:</p>
<p>[cc lang="SQL"]<br />
SELECT `users`.`id` as userId, `users`.`fullname` as userName, (SELECT count(*) FROM (`users`)) as userCount FROM (`users`) WHERE `users`.`status` = &#8216;active&#8217;<br />
[/cc]</p>
<p>Keep in mind that the developers of Code Igniter did not intend for you to use the _compile_select method.  Therefore, it&#8217;s possible that they may change the functionality in future versions and not bother letting anyone know.  </p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/' rel='bookmark' title='Permanent Link: How to Write a Better Model in CodeIgniter'>How to Write a Better Model in CodeIgniter</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
<li><a href='http://shawnmccool.com/2009/03/10/code-igniter-at-the-nashville-php-meetup-march-20th/' rel='bookmark' title='Permanent Link: CodeIgniter at the Nashville PHP meetup March 20th.'>CodeIgniter at the Nashville PHP meetup March 20th.</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</title>
		<link>http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/</link>
		<comments>http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 00:46:01 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[active record]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=328</guid>
		<description><![CDATA[This video covers the creation of a database table for storing users and the code igniter model class for interacting with it.


Related posts:<ol><li><a href='http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/' rel='bookmark' title='Permanent Link: How to Write a Better Model in CodeIgniter'>How to Write a Better Model in CodeIgniter</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This screencast continues a series with the goal of documenting the development of a functionally complete site using PHP with the Code Igniter framework and jQuery for Javascript UI improvements including AJAX interactions.</p>
<p>This video covers the creation of a database table for storing users and the code igniter model class for interacting with it.</p>
<p>Errata:</p>
<p>I&#8217;ve noticed a few errors in the screencast.  When errors creep up (and they will) I&#8217;ll audit them as they&#8217;re discovered and keep this post up to date.  Errors will also be updated during the following screencast.</p>
<ol>
<li>The UpdateUser method &#8220;set password&#8221; line (line 80) contains the variable $options['userEmail'] instead of $options['userPassword'].</li>
<li>The UpdateUser method is missing the line $this-&gt;db-&gt;where(&#8216;userId&#8217;, $options['userId']);  This should be added before the line that contains $query = $this-&gt;db-&gt;update(&#8216;users&#8217;); (line 84)</li>
<li>The AddUser method&#8217;s default value is set incorrectly (line 48).  It currently shows array(&#8216;userStatus&#8217;, &#8216;active&#8217;) where it should read array(&#8216;userStatus&#8217; =&gt; &#8216;active&#8217;).</li>
</ol>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/' rel='bookmark' title='Permanent Link: How to Write a Better Model in CodeIgniter'>How to Write a Better Model in CodeIgniter</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</title>
		<link>http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/</link>
		<comments>http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 03:29:28 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[screencast]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=323</guid>
		<description><![CDATA[This video briefly covers the establishment of a local development environment and the configuration of Code Igniter.


Related posts:<ol><li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This screencast begins a series with the goal of documenting the development of a functionally complete site using PHP with the Code Igniter framework and jQuery for Javascript UI improvements including AJAX interactions.</p>
<p>This video briefly covers the establishment of a local development environment and the configuration of Code Igniter.</p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
<li><a href='http://shawnmccool.com/2009/11/09/developing-a-website-with-code-igniter-part-3-the-login-process/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 3: The Login Process'>Developing a Website with CodeIgniter Part 3: The Login Process</a></li>
<li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Understand the Structure of CodeIgniter</title>
		<link>http://shawnmccool.com/2009/08/29/understand-the-structure-of-code-igniter/</link>
		<comments>http://shawnmccool.com/2009/08/29/understand-the-structure-of-code-igniter/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 01:41:19 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[screencast]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=315</guid>
		<description><![CDATA[In this screencast I attempt to explain the structure and terminology of the Code Igniter MVC PHP development framework.


Related posts:Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration
CodeIgniter at the Nashville PHP meetup March 20th.
Developing a Website with CodeIgniter Part 4: Admin Site CRUD



Related posts:<ol><li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/03/10/code-igniter-at-the-nashville-php-meetup-march-20th/' rel='bookmark' title='Permanent Link: CodeIgniter at the Nashville PHP meetup March 20th.'>CodeIgniter at the Nashville PHP meetup March 20th.</a></li>
<li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In this screencast I attempt to explain the structure and terminology of the Code Igniter MVC PHP development framework.</p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2009/09/04/developing-a-website-with-code-igniter-part-1-configuration/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration'>Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration</a></li>
<li><a href='http://shawnmccool.com/2009/03/10/code-igniter-at-the-nashville-php-meetup-march-20th/' rel='bookmark' title='Permanent Link: CodeIgniter at the Nashville PHP meetup March 20th.'>CodeIgniter at the Nashville PHP meetup March 20th.</a></li>
<li><a href='http://shawnmccool.com/2010/01/30/developing-a-website-with-codeigniter-part-4-admin-site-crud/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 4: Admin Site CRUD'>Developing a Website with CodeIgniter Part 4: Admin Site CRUD</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/08/29/understand-the-structure-of-code-igniter/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to Write a Better Model in CodeIgniter</title>
		<link>http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/</link>
		<comments>http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 20:29:30 +0000</pubDate>
		<dc:creator>Shawn McCool</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[reusability]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://shawnmccool.com/?p=286</guid>
		<description><![CDATA[Developing using an MVC framework can go a long way towards increasing the reusability and robustness of your code.  In this article I focus on writing model methods for the Code Igniter PHP MVC framework.  The concepts themselves are not specific to Code Igniter, but some of the code will be.
CRUD methods
CRUD is [...]


Related posts:<ol><li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
<li><a href='http://shawnmccool.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/' rel='bookmark' title='Permanent Link: Using CodeIgniter&#8217;s Active Record Class to Create Subqueries'>Using CodeIgniter&#8217;s Active Record Class to Create Subqueries</a></li>
<li><a href='http://shawnmccool.com/2009/11/23/managing-assets-with-codeigniter/' rel='bookmark' title='Permanent Link: Managing Assets with CodeIgniter'>Managing Assets with CodeIgniter</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Developing using an MVC framework can go a long way towards increasing the reusability and robustness of your code.  In this article I focus on writing model methods for the Code Igniter PHP MVC framework.  The concepts themselves are not specific to Code Igniter, but some of the code will be.</p>
<h3>CRUD methods</h3>
<p>CRUD is an acronym that stands for Create, Retrieve, Update, and Delete.  These are the most basic types of interactions that your code will have with a data source.</p>
<p>A few examples:<br />
Create &#8211; adding a user account to your website<br />
Retrieve &#8211; getting a list of available products<br />
Update &#8211; changing a user&#8217;s password or the name of a product<br />
Delete &#8211; removing a user account or product</p>
<p>When writing models you&#8217;ll generally start by creating CRUD methods for each of your logical types of data.  If you&#8217;re writing user authentication (login, logout, forgotten password, account activation) you&#8217;ll want a method to add, update, and delete users along with the ability to pull back the user account information for a single user or for a group of users.</p>
<p>For example:<br />
[cc lang="php"]<br />
function AddUser()<br />
function UpdateUser()<br />
function DeleteUser()<br />
function GetUsers()<br />
[/cc]</p>
<p>Most of the interactions that we have with user accounts can be handled by these four methods.  Instead of creating a model method &#8220;GetActiveUsers&#8221; we can just create a parameter for GetUsers that determines the user status of the returned set, more on this below.</p>
<h3>The Options Array</h3>
<p>Typically parameters for methods are sent in the following manner:<br />
[cc lang="php"]<br />
function AddUser($insertData)<br />
function UpdateUser($userId, $updateData)<br />
function DeleteUser($userId)<br />
function GetUsers($limit, $offset)<br />
[/cc]<br />
Naturally, (especially for GetUsers) we&#8217;ll find more and more parameters to add to our methods.  This not only gets very difficult to read, but can create issues where we have to go back and alter the code that we&#8217;ve already written if we have to tack a new parameter onto the method.</p>
<p>For Example:<br />
[cc lang="php"]<br />
function GetUsers($limit, $offset, $status)<br />
[/cc]</p>
<p>We would also need a singular GetUser($userId) method in addition to the GetUsers method.  This is a problem because we&#8217;re creating multiple versions of the same method.  If we change the way we want information to be returned then we&#8217;d need to change code in two places, the GetUser AND GetUsers methods.</p>
<p>To overcome these issues I propose the usage of an options array, as such:<br />
[cc lang="php"]<br />
function AddUser($options = array())<br />
function UpdateUser($options = array())<br />
function DeleteUser($options = array())<br />
function GetUsers($options = array())<br />
[/cc]<br />
If, in the past, we&#8217;d use GetUsers(5, 5, &#8216;active&#8217;) to return a list of users, we would now use GetUsers(array(&#8216;limit&#8217; => 5, &#8216;offset&#8217; => 5, &#8217;status&#8217; => &#8216;active&#8217;);</p>
<p>Parameters passed using the options array can be sent in any order and can even be completely omitted.  As you need to add functional parameters you simply change the model method and will not have to update code anywhere else.</p>
<h3>Utility Methods</h3>
<p>In order to create properly robust methods we&#8217;re going to need to implement a few common bits of functionality.  Namely, the ability to assign required fields and field defaults.  For example, a required field when adding a user might be userEmail.  For this we create the &#8216;required&#8217; method.<br />
[cc lang="php"]<br />
/**<br />
* _required method returns false if the $data array does not contain all of the keys assigned by the $required array.<br />
*<br />
* @param array $required<br />
* @param array $data<br />
* @return bool<br />
*/<br />
function _required($required, $data)<br />
{<br />
	foreach($required as $field) if(!isset($data[$field])) return false;<br />
	return true;<br />
}<br />
[/cc]<br />
In the &#8216;AddUser&#8217; example our code might look like this:<br />
[cc lang="php"]<br />
/**<br />
* AddUser method creates a record in the users table.<br />
*<br />
* Option: Values<br />
* &#8212;&#8212;&#8212;&#8212;&#8211;<br />
* userEmail			(required)<br />
* userPassword<br />
* userName<br />
* userStatus		active(default), inactive, deleted<br />
*<br />
* @param array $options<br />
*/<br />
function AddUser($options = array())<br />
{<br />
	// required values<br />
	if(!$this->_required(array(&#8216;userEmail&#8217;), $options)) return false;</p>
<p>	// At this point we know that the key &#8216;userEmail&#8217; exists in the $options array.<br />
}<br />
[/cc]</p>
<p>Now our AddUser method will bail out and return false if the &#8216;userEmail&#8217; key was not sent in the options array.  Robust!</p>
<p>Notice that in the PHPdoc block we mention that the default status for newly created users is &#8216;active&#8217;.  Naturally, if we wanted to create an inactive user we would be able to pass the &#8216;userStatus&#8217; parameter with the value inactive.  However, we are lazy and prefer to not have to explicitly declare &#8216;active&#8217;.</p>
<p>Introducing the &#8216;default&#8217; method:<br />
[cc lang="php"]<br />
/**<br />
* _default method combines the options array with a set of defaults giving the values in the options array priority.<br />
*<br />
* @param array $defaults<br />
* @param array $options<br />
* @return array<br />
*/<br />
function _default($defaults, $options)<br />
{<br />
	return array_merge($defaults, $options);<br />
}<br />
[/cc]<br />
That&#8217;s it, this method consists of a single command.  I decided to create a method out of this because I may want to add extra functionality to the defaults method, and don&#8217;t want to have to change every single one of my model methods.</p>
<p>Let&#8217;s go ahead and implement the &#8216;default&#8217; method:<br />
[cc lang="php"]<br />
/**<br />
* AddUser method creates a record in the users table.<br />
*<br />
* Option: Values<br />
* &#8212;&#8212;&#8212;&#8212;&#8211;<br />
* userEmail			(required)<br />
* userPassword<br />
* userName<br />
* userStatus		active(default), inactive, deleted<br />
*<br />
* @param array $options<br />
*/<br />
function AddUser($options = array())<br />
{<br />
	// required values<br />
	if(!$this->_required(array(&#8216;userEmail&#8217;), $options)) return false;</p>
<p>	// default values<br />
	$options = $this->_default(array(&#8216;userStatus&#8217; => &#8216;active&#8217;), $options);<br />
}<br />
[/cc]<br />
// At this point we know that the &#8216;userEmail&#8217; key exists in the $options array and if no &#8216;userStatus&#8217; key existed before, it does now and with the value &#8216;active&#8217;.</p>
<p>These methods go a long way towards making your code more robust while only adding a few lines to each method.</p>
<h3>Active Record</h3>
<p>Many database constructs (MySQL, Oracle, Microsoft SQL, PostgreSQL, etc) use variations of SQL syntax, but they all work a little bit differently. An active record class allows us to create a database query using abstraction.  In other words we are able to create queries that will work on any database construct that our class supports.  They also give the added benefit of allowing us to send bits of the query to the class one by one before executing the query.</p>
<p>A Code Igniter active record query might look something like this:</p>
<p>[cc lang="php"]<br />
$this->db->where(&#8216;userStatus&#8217;, &#8216;active&#8217;);<br />
$this->db->get(&#8216;users&#8217;);<br />
[/cc]</p>
<p>Those two commands will create and execute the query, &#8220;select * from users where userStatus = &#8216;active&#8217;&#8221;</p>
<h3>Putting It All Together</h3>
<p>Using the concepts that we&#8217;ve explored let&#8217;s look at a simple example set CRUD methods.</p>
<p>[cc lang="php"]<br />
/**<br />
* AddUser method creates a record in the users table.<br />
*<br />
* Option: Values<br />
* &#8212;&#8212;&#8212;&#8212;&#8211;<br />
* userEmail			(required)<br />
* userPassword<br />
* userName<br />
* userStatus		active(default), inactive, deleted<br />
*<br />
* @param array $options<br />
*/<br />
function AddUser($options = array())<br />
{<br />
	// required values<br />
	if(!$this->_required(array(&#8216;userEmail&#8217;), $options)) return false;</p>
<p>	// default values<br />
	$options = $this->_default(array(&#8216;userStatus&#8217; => &#8216;active&#8217;), $options);</p>
<p>	// qualification (make sure that we&#8217;re not allowing the site to insert data that it shouldn&#8217;t)<br />
	$qualificationArray = array(&#8216;userEmail&#8217;, &#8216;userName&#8217;, &#8216;userStatus&#8217;);<br />
	foreach($qualificationArray as $qualifier)<br />
	{<br />
		if(isset($options[$qualifier])) $this->db->set($qualifier, $options[$qualifier]);<br />
	}</p>
<p>	// MD5 the password if it is set<br />
	if(isset($options['userPassword'])) $this->db->set(&#8216;userPassword&#8217;, md5($options['userPassword']));</p>
<p>	// Execute the query<br />
	$this->db->insert(&#8216;users&#8217;);</p>
<p>	// Return the ID of the inserted row, or false if the row could not be inserted<br />
	return $this->db->insert_id();<br />
}</p>
<p>/**<br />
* UpdateUser method alters a record in the users table.<br />
*<br />
* Option: Values<br />
* &#8212;&#8212;&#8212;&#8212;&#8211;<br />
* userId			the ID of the user record that will be updated<br />
* userEmail<br />
* userPassword<br />
* userName<br />
* userStatus		active(default), inactive, deleted<br />
*<br />
* @param array $options<br />
* @return int affected_rows()<br />
*/<br />
function UpdateUser($options = array())<br />
{<br />
	// required values<br />
	if(!$this->_required(array(&#8216;userId&#8217;), $options)) return false;</p>
<p>	// qualification (make sure that we&#8217;re not allowing the site to update data that it shouldn&#8217;t)<br />
	$qualificationArray = array(&#8216;userEmail&#8217;, &#8216;userName&#8217;, &#8216;userStatus&#8217;);<br />
	foreach($qualificationArray as $qualifier)<br />
	{<br />
		if(isset($options[$qualifier])) $this->db->set($qualifier, $options[$qualifier]);<br />
	}</p>
<p>	$this->db->where(&#8216;userId&#8217;, $options['userId']);</p>
<p>	// MD5 the password if it is set<br />
	if(isset($options['userPassword'])) $this->db->set(&#8216;userPassword&#8217;, md5($options['userPassword']));</p>
<p>	// Execute the query<br />
	$this->db->update(&#8216;users&#8217;);</p>
<p>	// Return the number of rows updated, or false if the row could not be inserted<br />
	return $this->db->affected_rows();<br />
}</p>
<p>/**<br />
* GetUsers method returns an array of qualified user record objects<br />
*<br />
* Option: Values<br />
* &#8212;&#8212;&#8212;&#8212;&#8211;<br />
* userId<br />
* userEmail<br />
* userStatus<br />
* limit				limits the number of returned records<br />
* offset				how many records to bypass before returning a record (limit required)<br />
* sortBy				determines which column the sort takes place<br />
* sortDirection		(asc, desc) sort ascending or descending (sortBy required)<br />
*<br />
* Returns (array of objects)<br />
* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
* userId<br />
* userEmail<br />
* userName<br />
* userStatus<br />
*<br />
* @param array $options<br />
* @return array result()<br />
*/<br />
function GetUsers($options = array())<br />
{<br />
	// default values<br />
	$options = $this->_default(array(&#8217;sortDirection&#8217; => &#8216;asc&#8217;), $options);</p>
<p>	// Add where clauses to query<br />
	$qualificationArray = array(&#8216;userId&#8217;, &#8216;userEmail&#8217;, &#8216;userStatus&#8217;);<br />
	foreach($qualificationArray as $qualifier)<br />
	{<br />
		if(isset($options[$qualifier])) $this->db->where($qualifier, $options[$qualifier]);<br />
	}</p>
<p>	// If limit / offset are declared (usually for pagination) then we need to take them into account<br />
	if(isset($options['limit']) &amp;&amp; isset($options['offset'])) $this->db->limit($options['limit'], $options['offset']);<br />
	else if(isset($options['limit'])) $this->db->limit($options['limit']);</p>
<p>	// sort<br />
	if(isset($options['sortBy'])) $this->db->order_by($options['sortBy'], $options['sortDirection']);</p>
<p>	$query = $this->db->get(&#8216;users&#8217;);<br />
	if($query->num_rows() == 0) return false;</p>
<p>	if(isset($options['userId']) &amp;&amp; isset($options['userEmail']))<br />
	{<br />
		// If we know that we&#8217;re returning a singular record, then let&#8217;s just return the object<br />
		return $query->row(0);<br />
	}<br />
	else<br />
	{<br />
		// If we could be returning any number of records then we&#8217;ll need to do so as an array of objects<br />
		return $query->result();<br />
	}<br />
}</p>
<p>/**<br />
* DeleteUser method removes a record from the users table<br />
*<br />
* @param array $options<br />
*/<br />
function DeleteUser($options = array())<br />
{<br />
	// required values<br />
	if(!$this->_required(array(&#8216;userId&#8217;), $options)) return false;</p>
<p>	$this->db->where(&#8216;userId&#8217;, $options['userId']);<br />
	$this->db->delete(&#8216;users&#8217;);<br />
}<br />
[/cc]</p>
<p>Here are some examples of how we can use these methods to interact with your database.</p>
<p>Adding a User<br />
[cc lang="php"]<br />
$userId = $this->user_model->AddUser($_POST);</p>
<p>if($userId)<br />
	echo &#8220;The user you have created has been added successfully with ID #&#8221; . $userId;<br />
else<br />
	echo &#8220;There was an error adding your user.&#8221;;<br />
[/cc]</p>
<p>Updating a User<br />
[cc lang="php"]<br />
if($this->user_model->UpdateUser(array(&#8216;userId&#8217; => 3, &#8216;userName&#8217; => &#8216;Shawn&#8217;, &#8216;userEmail&#8217; => &#8216;not telling&#8217;)))<br />
	// The user has been successfully updated<br />
else<br />
	// The user was not updated<br />
[/cc]</p>
<p>User Authentication (Retrieving a Single User)<br />
[cc lang="php"]<br />
$user = $this->user_model->GetUsers(array(&#8216;userEmail&#8217; => $userEmail, &#8216;userPassword&#8217; => md5($userPassword), &#8216;userStatus&#8217; => &#8216;active&#8217;));<br />
if($user)<br />
	// Log the user in<br />
else<br />
	// Sorry, your user / password combination isn&#8217;t correct.<br />
[/cc]</p>
<p>Retrieving a Set of Users<br />
[cc lang="php"]<br />
$users = $this->user_model->GetUsers(array(&#8216;userStatus&#8217; => &#8216;active&#8217;));</p>
<p>if($users)<br />
{<br />
	echo &#8220;Active Users<br />&#8220;;<br />
	foreach($users as $user)<br />
	{<br />
		echo $user->userName . &#8220;<br />&#8220;;<br />
	}<br />
}<br />
else<br />
{<br />
	echo &#8220;There are no active users.&#8221;;<br />
}<br />
[/cc]</p>
<p>Deleting a User<br />
[cc lang="php"]<br />
$this->user_model->DeleteUser(array(&#8216;userId&#8217; => $userId));<br />
[/cc]</p>
<p>I hope that this will continue a dialog on how to better write such commonly reused bits of functionality.  If you have any suggestions or comments please let me know.  I&#8217;d love to hear about the algorithms that you&#8217;ve been designing to handle similar problems.</p>


<p>Related posts:<ol><li><a href='http://shawnmccool.com/2009/09/06/developing-a-website-with-code-igniter-part-2-users-database-table-and-the-user-model/' rel='bookmark' title='Permanent Link: Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model'>Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model</a></li>
<li><a href='http://shawnmccool.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/' rel='bookmark' title='Permanent Link: Using CodeIgniter&#8217;s Active Record Class to Create Subqueries'>Using CodeIgniter&#8217;s Active Record Class to Create Subqueries</a></li>
<li><a href='http://shawnmccool.com/2009/11/23/managing-assets-with-codeigniter/' rel='bookmark' title='Permanent Link: Managing Assets with CodeIgniter'>Managing Assets with CodeIgniter</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://shawnmccool.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
