<?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>Michael Wales</title>
	<atom:link href="http://www.michaelwales.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.michaelwales.com</link>
	<description>Senior Developer Michael Wales, featuring articles on web development (PHP, Python and Ruby), industry highlights and open source software releases.</description>
	<lastBuildDate>Fri, 12 Mar 2010 02:41:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ErkanaAuth Now Hosted on Bitbucket</title>
		<link>http://www.michaelwales.com/2010/03/erkanaauth-now-hosted-on-bitbucket/</link>
		<comments>http://www.michaelwales.com/2010/03/erkanaauth-now-hosted-on-bitbucket/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 02:41:08 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[authorization library]]></category>
		<category><![CDATA[Bitbucket]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[ErkanaAuth]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=140</guid>
		<description><![CDATA[
As the entire CodeIgniter community runs over to Mercurial and Bitbucket, thanks to EllisLab&#8217;s huge announcement earlier today it seemed only fitting to get ErkanaAuth hosted over there as soon as possible.
Honestly, I&#8217;ve been wanting to do something like this for a lot of my open-source work for a long time; I just keep putting [...]]]></description>
			<content:encoded><![CDATA[<p class="aligncenter"><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/erkanaauth-banner.png" alt="ErkanaAuth" title="ErkanaAuth" /></p>
<p>As the entire <a href="http://www.codeigniter.com/" title="CodeIgniter">CodeIgniter</a> community runs over to <a href="http://mercurial.selenic.com/" title="Mercurial">Mercurial</a> and <a href="http://www.bitbucket.org" title="Bitbucket">Bitbucket</a>, thanks to <a href="http://codeigniter.com/news/ellislab_moves_to_mercurial_assembla_bitbucket_codeigniter_2.0_baking/" title="CodeIgniter 2.0.0 Baking">EllisLab&#8217;s huge announcement earlier today</a> it seemed only fitting to get ErkanaAuth hosted over there as soon as possible.</p>
<p>Honestly, I&#8217;ve been wanting to do something like this for a lot of my open-source work for a long time; I just keep putting it off. I love the distributed environment for collaborating on projects like this, because you guys probably have a lot of great ideas for this library! Now, you can contribute as well!</p>
<p>Go ahead: <a href="http://bitbucket.org/walesmd/codeigniter-erkana-auth/" title="Bitbucket: CodeIgniter Erkana Auth">check out the repository</a>, fork it, make some changes and send me pull requests so I can look over them. You can check out my <a href="http://www.michaelwales.com/2010/02/erkanaauth-version-2-0a/" title="Michael Wales: ErkanaAuth Version 2.0a">original post for my thoughts</a> in where I see this library headed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/03/erkanaauth-now-hosted-on-bitbucket/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CodeIgniter 2.0 and Mercurial Transition</title>
		<link>http://www.michaelwales.com/2010/03/codeigniter-2-0-and-mercurial-transition/</link>
		<comments>http://www.michaelwales.com/2010/03/codeigniter-2-0-and-mercurial-transition/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 19:03:35 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=133</guid>
		<description><![CDATA[EllisLab has just announced they have transitioned away from Subversion to Mercurial and are hosting the CodeIgniter 2.0 source on Bitbucket.
I did a quick glance through the source and here are some of the things I immediately noticed in CodeIgniter 2.0 (this isn&#8217;t a comprehensive list, just what I find the most exciting):

Scaffolding has finally [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ellislab.com/" title="EllisLab">EllisLab</a> has <a href="http://codeigniter.com/news/ellislab_moves_to_mercurial_assembla_bitbucket_codeigniter_2.0_baking/" title="CodeIgniter 2.0 Baking">just announced</a> they have transitioned away from Subversion to Mercurial and are hosting the <a href="http://bitbucket.org/ellislab/codeigniter/" title="CodeIgniter 2.0 on Bitbucket">CodeIgniter 2.0 source on Bitbucket</a>.</p>
<p>I did a quick glance through the source and here are some of the things I immediately noticed in CodeIgniter 2.0 (this isn&#8217;t a comprehensive list, just what I find the most exciting):</p>
<ul>
<li>Scaffolding has finally been completely removed.</li>
<li>The <samp>codeigniter</samp> directory has been renamed to <samp>core</samp> and houses most of the absolute necessities. [<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/core/">source</a>]</li>
<li>System-wide plugins are gone (they were mostly worthless to begin with).</li>
<li>There&#8217;s a new Javascript library that features a driver system, similar to the database libraries. <a href="http://www.jquery.com/" title="jQuery">jQuery</a> is currently supported but expect to see more. [<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/libraries/Javascript.php">source</a>]</li>
<li>A driver library has been added, to assist developer in creating their own driver-backed libraries. [<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/libraries/Driver.php">source</a>]</li>
<li>You can now enable/disable individual sections of the profiler (it&#8217;s also it&#8217;s own class, rather than being part of the output library).[<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/libraries/Profiler.php">source</a> | <a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/application/config/profiler.php">source</a>]</li>
<li>There&#8217;s a new security library that features CSRF protection and becomes the new home for XSS filtering. [<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/libraries/Security.php">source</a>]</li>
<li>The Input, Upload and XML-RPC libraries have received new features and make use of the security library.</li>
<li>The Cookie helper now utilizes the Input class. [<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/helpers/cookie_helper.php">source</a>]</li>
<li>The application directory now contains a <samp>third_party</samp> directory, I presume would take the place of the old plugins directory. [<a href="http://bitbucket.org/ellislab/codeigniter/src/tip/system/application/third_party/">source</a>]</li>
</ul>
<p>I&#8217;m most excited about the new Security library but can&#8217;t wait to see how this release shapes up! What are you most looking forward to in CodeIgniter 2.0?</p>
<p><strong>Edit:</strong> <a href="http://philsturgeon.co.uk/news/2010/03/codeigniter-2" title="Phil Sturgeon: CodeIgniter 2">Phil Sturgeon</a> and <a href="http://www.haughin.com/2010/03/11/codeigniter-2-critical-changes-implications/" title="Elliot Haughin: CodeIgniter 2 Critical Changes Implications">Elliot Haughin</a> have provided their run-downs of CodeIgniter changes as well. One of the biggest changes I missed was the fact that CodeIgniter 2.0.0 functionality is not guaranteed to work in PHP4 and by CodeIgniter 2.1.0, legacy features will no longer be guaranteed to work in PHP4 either.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/03/codeigniter-2-0-and-mercurial-transition/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Updating Simpla for Today&#8217;s Wordpress</title>
		<link>http://www.michaelwales.com/2010/02/updating-simpla-for-todays-wordpress/</link>
		<comments>http://www.michaelwales.com/2010/02/updating-simpla-for-todays-wordpress/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 13:00:19 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Simpla]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=112</guid>
		<description><![CDATA[Simpla, the theme you see here was released just over 4 years ago. Since that time Wordpress has deprecated a number of its template tags &#8211; the functions theme developers use to bring Wordpress&#8217; functionality into their designs.
I took it upon myself to run through this theme, looking for any of the deprecated functions and [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/simpla.png" alt="Simpla" title="Simpla" width="300" height="225" class="alignright" /><a href="http://ifelse.co.uk/archives/2006/02/21/simpla-theme-released/" title="If..Else Log: Simpla Theme Released">Simpla</a>, the theme you see here was released just over 4 years ago. Since that time <a href="http://www.wordpress.org/" title="Wordpress">Wordpress</a> has deprecated a number of its template tags &#8211; the functions theme developers use to bring Wordpress&#8217; functionality into their designs.</p>
<p>I took it upon myself to run through this theme, looking for any of the deprecated functions and replacing them with their updated versions. Although the theme still works, today, with these deprecated functions that functionality could cease at any moment.</p>
<p>Surprisingly, the majority of the theme has withstood the test of time. I only notice two issues: the <code>get_settings()</code> tag in <samp>header.php</samp> and the <code>wp_list_cats</code> tag in <samp>sidebar.php</samp>.</p>
<p>The two snippets below reflect the altered portions of the code, bringing Simpla in-line with Wordpress 2.9.2 (although I believe the actual deprecation took place many, many versions ago).</p>
<p>In the header, <code>get_settings()</code> is used to make the title of the blog link back to the home page. This snippet makes use of the new <code>get_option()</code> function, which allows us to provide a default value in the second parameter (I just hard-coded in what my blog URL should be) which would be used in-case this option went mysteriously missing from our database. For an added bonus, I&#8217;ve included the <a href="http://microformats.org/wiki/rel-home" title="Microformats.org: rel=&quot;home%quot;">rel=&#8221;home&#8221; microformat</a> as well.</p>
<script src="http://gist.github.com/316446.js"></script><noscript><pre><code class="gist">&lt;div id=&#8221;header&#8221;&gt;<br />
&lt;h1&gt;&lt;a href=&#8221;<?php echo get_option('home', 'http://www.michaelwales.com/'); ?>/&#8221; rel=&#8221;home&#8221;&gt;<?php bloginfo('name'); ?>&lt;/a&gt;&lt;/h1&gt;<br />
&lt;p class=&#8221;description&#8221;&gt;<?php bloginfo('description'); ?>&lt;/p&gt;<br />
&lt;/div&gt;</code></pre></noscript>
<p>Our sidebar was using the <code>wp_list_cats()</code> function. We&#8217;re going to replace that with the newer <code>wp_list_categories()</code> function. We&#8217;ll pass this function a string of arguments, which will allow us to display the number of posts within each category and suppress the default heading and <code>&lt;ul&gt;&lt;/ul&gt;</code> wrapper that the function places around the list (since we&#8217;re using our own header).</p>
<script src="http://gist.github.com/316452.js"></script><noscript><pre><code class="gist">&lt;h2&gt;Categories&lt;/h2&gt;<br />
&lt;ul&gt;<br />
<?php wp_list_categories('show_count=1&#038;title_li'); ?><br />
&lt;/ul&gt;</code></pre></noscript>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/updating-simpla-for-todays-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protecting Controllers with ErkanaAuth</title>
		<link>http://www.michaelwales.com/2010/02/protecting-controllers-with-erkanaauth/</link>
		<comments>http://www.michaelwales.com/2010/02/protecting-controllers-with-erkanaauth/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 02:37:22 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[authorization library]]></category>
		<category><![CDATA[ErkanaAuth]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=81</guid>
		<description><![CDATA[
ErkanaAuth, although in a very alpha form, is simple to use and already extremely powerful. Protecting a portion of your website behind the authentication system is as easy as one-line, a call to the library&#8217;s required() method.
In this example, we are protecting an entire controller behind the authentication library:
When a method within this controller is [...]]]></description>
			<content:encoded><![CDATA[<p class="aligncenter"><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/erkanaauth-banner.png" alt="ErkanaAuth" title="ErkanaAuth" width="696" height="230" /></p>
<p><a href="http://www.michaelwales.com/2010/02/erkanaauth-version-2-0a/" title="ErkanaAuth">ErkanaAuth</a>, although in a very alpha form, is simple to use and already extremely powerful. Protecting a portion of your website behind the authentication system is as easy as one-line, a call to the library&#8217;s <code>required()</code> method.</p>
<p>In this example, we are protecting an entire controller behind the authentication library:</p>
<script src="http://gist.github.com/296829.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>class Transactions extends Controller {</p>
<p>  function Transactions() {<br />
    parent::Controller();<br />
    $this->erkana_auth->required();<br />
  }</p>
<p>  // index()<br />
  // List all a user&#8217;s transactions<br />
  function index() {<br />
    $this->load->view(&#8216;transactions&#8217;);<br />
  }</p>
<p>}</code></pre></noscript>
<p>When a method within this controller is called, the user&#8217;s session will be validated. If the user has not authenticated they will then be forwarded to your application&#8217;s <code>accounts</code> controller, where your login and user creation methods should reside.</p>
<p>To protect individual methods, just call the <code>required()</code> method in the first line of the method you want to protect.</p>
<script src="http://gist.github.com/296834.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>class Transactions extends Controller {</p>
<p>  function Transactions() {<br />
    parent::Controller();<br />
  }</p>
<p>  // index()<br />
  // List all a user's transactions<br />
  function index() {<br />
    $this->erkana_auth->required();<br />
    $this->load->view(&#8216;transactions&#8217;);<br />
  }</p>
<p>}</code></pre></noscript>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/protecting-controllers-with-erkanaauth/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Delegating OpenID to Your Google Account</title>
		<link>http://www.michaelwales.com/2010/02/delegating-openid-to-your-google-account/</link>
		<comments>http://www.michaelwales.com/2010/02/delegating-openid-to-your-google-account/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 13:57:04 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[OpenID]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=96</guid>
		<description><![CDATA[Earlier this morning I made a complaint on Twitter concerning how OpenID URLs are typically long and hard to remember &#8211; I was specifically referring to Google&#8217;s OpenID URLs. Sure, there are other providers available, and to be perfectly honest I have accounts with some of the more popular (Wordpress, Yahoo, etc.), but my Google [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/openid-please.png" alt="OpenID" title="OpenID" width="250" height="250" class="alignright" />Earlier this morning I made a <a href="http://twitter.com/walesmd/status/9676277160" title="Twitter: Michael Wales">complaint on Twitter</a> concerning how OpenID URLs are typically long and hard to remember &#8211; I was specifically referring to Google&#8217;s OpenID URLs. Sure, there are other providers available, and to be perfectly honest I have accounts with some of the more popular (Wordpress, Yahoo, etc.), but my Google account is the one provider that gets used on a daily basis.</p>
<p><a href="http://twitter.com/cdharrison/status/9676339232" title="Twitter: Chris Harrison">Chris Harrison brought me back on track</a> telling me I should just use my own domain as my OpenID provider. Honestly, this required more effort than I wanted to exert but I started looking around for simpler solutions. As it turns out, there are two meta tags you can add to the header of your site (<code>openid.server</code> and <code>openid.delegate</code>) that will essentially &#8220;forward&#8221; any OpenID requests to your OpenID provider. This would allow me to make a quick change on my domain, not worry about maintaining the software that actually serves as the provider, yet still reap all the benefits.</p>
<p>Unfortunately, Google doesn&#8217;t support the <code>openid.delegate</code> meta tag&#8230;</p>
<p>Fortunately, one of Google&#8217;s very own <a href="http://code.google.com/p/google-app-engine-samples/" title="Google App Engine Demos">App Engine demos</a> does serve as an OpenID provider and allows you to delegate to their server. App Engine also allows developers to easily include authentication in their application by simply using the user&#8217;s Google Account &#8211; which is exactly what this demo application does. The end result: I authenticate with my Google Account to this App Engine demo and it serves up OpenID authentication on my domain&#8217;s behalf.</p>
<p>Check out the <a href="http://openid-provider.appspot.com/" title="Google App Engine: OpenID Provider">OpenID Provider demo</a> and login to your account. After you&#8217;ve logged in the application will tell you what your OpenID URL is, which you could use on sites like <a href="http://www.stackoverflow.com/" title="StackOverflow">StackOverflow</a> to authenticate. If, on the other hand, you want to use your own domain as your OpenID URL, take this information, edit the HTML meta tags below, and toss them into the header of your very own website:</p>
<script src="http://gist.github.com/315719.js"></script><noscript><pre><code class="gist">&lt;meta name=&#8221;openid.server&#8221; href=&#8221;http://openid-provider.appspot.com/[USERNAME]&#8221; /%gt;<br />
%lt;meta name=&#8221;openid.delegate&#8221; href=&#8221;http://openid-provider.appspot.com/[USERNAME]&#8221; /%gt;</code></pre></noscript>
<p><strong>Edit:</strong> As <a href="http://ericharrison.info/" title="Eric Harrison">Eric Harrison</a> and <a href="http://notsorelevant.com/" title="Carsten Pötter">Carsten Pötter</a> mention within the comments, Google now supports OpenID on your individual profile pages. Check out <a href="http://www.abstractioneer.org/2009/12/openid-delegation-for-googles-op.html" title="John Panzer: OpenID Delegation for Google">John Panzer&#8217;s</a> tutorial.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/delegating-openid-to-your-google-account/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Basic Pattern Matching Form Validation in CodeIgniter</title>
		<link>http://www.michaelwales.com/2010/02/basic-pattern-matching-form-validation-in-codeigniter/</link>
		<comments>http://www.michaelwales.com/2010/02/basic-pattern-matching-form-validation-in-codeigniter/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 18:03:21 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[form validation]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=86</guid>
		<description><![CDATA[CodeIgniter comes with an excellent Form Validation library right out of the box. This library features a number of validation and preparation functions that are executed on posted form fields when the run() method is called. If you need additional functionality, it is also very easy to add your own validation/preparation functions to your application, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/regex.jpg" alt="Regular Expressions" title="Regular Expressions" width="200" height="200" class="alignright" /><a href="http:/www.codeigniter.com/" title="CodeIgniter">CodeIgniter</a> comes with an excellent <a href="http://codeigniter.com/user_guide/libraries/form_validation.html" title="CodeIgniter User Guide: Form Validation">Form Validation</a> library right out of the box. This library features a number of validation and preparation functions that are executed on posted form fields when the <code>run()</code> method is called. If you need additional functionality, it is also very easy to add your own validation/preparation functions to your application, without modifying any of the underlying CodeIgniter codebase.</p>
<p>If you have a decent level of experience with Microsoft&#8217;s Excel, you may have had to develop a custom cell format from time to time. This basic format syntax provides a very loose, but functional, method of defining the format of the input you expect. In this tutorial, we&#8217;ll define a new form field validation rule (called <code>matches_pattern</code>) that excepts one argument that will define the pattern we want the user&#8217;s input to match. Our goal is to make something very simple to use, but moderately powerful, so we&#8217;re going to stay away from having to use regular expressions within our validation rules. Instead, we&#8217;ll create a set of replacement characters to use within our rules instead: <code>#</code> to represent a number, <code>?</code> to represent an alphabetical character and <code>~</code> to represent any character.</p>
<p>These characters will allow us to validate a user&#8217;s input matches specific cases. For instance, phone numbers could be forced to match <code>(###) ###-####</code> or a date field could be forced to match <code>##-##-####</code> (MM-DD-YYYY).</p>
<p>The first step in extending CodeIgniter&#8217;s Form Validation library is to create our own Form Validation class within our applications <samp>libraries/</samp> directory. By default, the prefix for your own extending classes is <samp>MY_</samp>, so we&#8217;ll create <samp>libraries/MY_Form_validation.php</samp> and stub out the following code:</p>
<script src="http://gist.github.com/314719.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>class MY_Form_validation extends CI_Form_validation {</p>
<p>  function MY_Form_validation() {<br />
    parent::CI_Form_validation();<br />
  }</p>
<p>  // matches_pattern()<br />
  // Ensures a string matches a basic pattern<br />
  // # numeric, ? alphabetical, ~ any character<br />
  function matches_pattern($str, $pattern) {<br />
  }<br />
}</code></pre></noscript>
<p>We've now extended the default Form Validation library and we have a function, called <code>matches_pattern()</code> that we can call from our <code>set_rules()</code> method. Let's start fleshing out this method and translating our characters into their regular expression equivalents:</p>
<script src="http://gist.github.com/314739.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>class MY_Form_validation extends CI_Form_validation {</p>
<p>  function MY_Form_validation() {<br />
    parent::CI_Form_validation();<br />
  }</p>
<p>  // matches_pattern()<br />
  // Ensures a string matches a basic pattern<br />
  // # numeric, ? alphabetical, ~ any character<br />
  function matches_pattern($str, $pattern) {<br />
    $characters = array(<br />
      '#', '?', '~'<br />
    );</p>
<p>    $regex_characters = array(<br />
      '[0-9]', '[a-zA-Z]', '.'<br />
    );</p>
<p>    $pattern = str_replace($characters, $regex_characters, $pattern);<br />
    if (preg_match('/^' . $pattern . '$/', $str)) return TRUE;<br />
    return FALSE;<br />
  }<br />
}</code></pre></noscript>
<p>We're now using <code>str_replace()</code> to translate our special characters into their regular expression equivalents. Finally, we run through <code>preg_match()</code> and return a boolean as to whether the user input (<code>$str</code>) matches. You may wonder why we're just not returning the value of <code>preg_match()</code>. Unfortunately, <code>preg_match()</code> returns a <samp>1</samp> or <samp>0</samp> (at least on my development server) and CodeIgniter expects an explicit boolean, therefore we run it through the conditional really quick.</p>
<p>Our last step is escaping some of the standard regular expression special characters. In regular expressions, characters like <samp>(</samp>, <samp>)</samp>, <samp>[</samp> and many others have special meanings. We don't want to make use of these special meanings within our patterns though; if our patterns contains an <samp>(</samp> we literally want to match on that character (rather than capturing a successful match). We'll implement this by modifying our character arrays and replacing these special characters with their escaped versions:</p>
<script src="http://gist.github.com/314747.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>class MY_Form_validation extends CI_Form_validation {</p>
<p>  function MY_Form_validation() {<br />
    parent::CI_Form_validation();<br />
  }</p>
<p>  // matches_pattern()<br />
  // Ensures a string matches a basic pattern<br />
  // # numeric, ? alphabetical, ~ any character<br />
  function matches_pattern($str, $pattern) {<br />
    $characters = array(<br />
      '[', ']', '\\', '^', '$',<br />
      '.', '|', '+', '(', ')',<br />
      '#', '?', '~'            // Our additional characters<br />
    );</p>
<p>    $regex_characters = array(<br />
      '\[', '\]', '\\\\', '\^', '\$',<br />
      '\.', '\|', '\+', '\(', '\)',<br />
      '[0-9]', '[a-zA-Z]', '.' // Our additional characters<br />
    );</p>
<p>    $pattern = str_replace($characters, $regex_characters, $pattern);<br />
    if (preg_match('/^' . $pattern . '$/', $str)) return TRUE;<br />
    return FALSE;<br />
  }<br />
}</code></pre></noscript>
<p>The final step in this process is to define the error message that is reported when our validation function returns <code>FALSE</code>. This is done by defining your own language file within your application at <samp>language/english/form_validation_lang.php</samp>. The content within this file will be appended to CodeIgniter default <samp>form_validation_lang.php</samp> file:</p>
<script src="http://gist.github.com/314751.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>$lang['matches_pattern'] = "The %s field does not match the required pattern.";</code></pre></noscript>
<p>The <code>%s</code> within this language definition will be replaced by the field name in which you include this rule. To use our new rule, we just append it to the rule set for any of our fields within our controller:</p>
<script src="http://gist.github.com/314757.js"></script><noscript><pre><code class="gist"><?php</p>
<p>$this->form_validation->set_rules('due_date', 'due date', 'trim|required|matches_pattern[##-##-####]');<br />
$this->form_validation->set_rules('phone_number', 'phone number', 'trim|required|matches_pattern[(###) ###-####]');</code></pre></noscript>
<p>It's very easy to create your own validation rules. If you find yourself writing callback functions to do the same things over and over, consider bringing that function out into your own Form Validation library. The <code>matches_pattern()</code> function we wrote here provides an easy-to-use, yet simple, way to match a specific pattern - just remember to inform your users of what that pattern is! If you wanted, you could an include another <code>%s</code> within your language definition that would insert the specific pattern in the error message.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/basic-pattern-matching-form-validation-in-codeigniter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Suggest an Article Topic, GetSatisfaction Implemented</title>
		<link>http://www.michaelwales.com/2010/02/suggest-an-article-topic-getsatisfaction-implemented/</link>
		<comments>http://www.michaelwales.com/2010/02/suggest-an-article-topic-getsatisfaction-implemented/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 19:22:05 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[GetSatisfaction]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=74</guid>
		<description><![CDATA[Is there a topic you want me to write an article on? Today&#8217;s your lucky day! I&#8217;ve added the GetSatisfaction Skribit widget to the right-hand border of this page.
A quick click of the widget will allow you to submit ideas, a question, a problem or give me some head-bloating praise. Feel free to use and [...]]]></description>
			<content:encoded><![CDATA[<p>Is there a topic you want me to write an article on? Today&#8217;s your lucky day! I&#8217;ve added the <del><a href="http://www.getsatisfaction.com/" title="GetSatisfaction">GetSatisfaction</a></del> <ins><a href="http://www.skribit.com/" title="Skribit">Skribit</a></ins> widget to the right-hand border of this page.</p>
<p>A quick click of the widget will allow you to submit ideas, a question, a problem or give me some head-bloating praise. Feel free to use and abuse but remember this is a public means of communication, if you need to contact me privately you can always email at <a href="mailto:webmaster@michaelwales.com" title="Email Michael Wales">webmaster@michaelwales.com</a>.</p>
<p><strong>Edit:</strong><br />
<a href="http://cdharrison.com" title="Web Designer: Chris Harrison">Chris Harrison</a> pointed out <a href="http://www.skribit.com/" title="Skribit">Skribit</a> to me and it is much better suited for this purpose.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/suggest-an-article-topic-getsatisfaction-implemented/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Dropping Support for IE6</title>
		<link>http://www.michaelwales.com/2010/02/google-dropping-support-for-ie6/</link>
		<comments>http://www.michaelwales.com/2010/02/google-dropping-support-for-ie6/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 19:30:31 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Microsoft]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=64</guid>
		<description><![CDATA[As web developers we typically fulfill a number of roles: developer, designer, marketing, SEO. Of all these roles nothing is more frustrating than the designer role, primarily due to the evil that is Internet Explorer 6. Thankfully, Google has taken a stance, primarily fueled by the recent Chinese attacks, and IE6 is going down.
Last week, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/browsers.jpg" alt="Web Browsers" title="Web Browsers" width="140" height="135" class="alignright" />As web developers we typically fulfill a number of roles: developer, designer, marketing, SEO. Of all these roles nothing is more frustrating than the designer role, primarily due to the evil that is Internet Explorer 6. Thankfully, <a href="http://www.google.com/" title="Google">Google</a> has taken a stance, primarily fueled by the <a href="http://arstechnica.com/tech-policy/news/2010/01/furious-google-throws-down-gauntlet-to-china-over-censorship.ars" title="Ars Technica: Furious Google Throws Down Gauntlet to China Over Censorship">recent Chinese attacks</a>, and IE6 is going down.</p>
<p>Last week, on the <a href="http://googleenterprise.blogspot.com/" title="Official Google Enterprise Blog">Official Google Enterprise Blog</a>, the Senior Product Manager of Google Apps announced that as early as March 2010 Google will start phasing out support for older browsers. The official lineup Google recommends consists of Internet Explorer 7.0+, Mozilla Firefox 3.0+, Google Chrome 4.0+ and Safari 3.0+.</p>
<p>Google also sent an email to all <a href="http://www.google.com/a/" title="Google Apps for Domains">Google Apps for Domains</a> administrators yesterday that clarified some concerns people had: this isn&#8217;t just for the enterprise users. Users of the standard GMail and Google Calendar will see functionality dropping off on older browsers as well. This really shouldn&#8217;t come as a surprise. As developers, would you expect Google to maintain two separate codebases, one of which has inherent flaws that consistently introduces security vulnerabilities? I didn&#8217;t think so&#8230;</p>
<p>Is this the nail in the coffin that is Internet Explorer 6? I think so! With such a drastic change from one of the industry leaders, a company most people couldn&#8217;t dream of living without in this day, older browsers have no choice but to die off. Most people using IE6, or various other older browsers, aren&#8217;t doing so by choice &#8211; they are in enterprise environments in which they are not able to upgrade. These companies are now being told by one of the largest providers of software they use on a daily basis, <strong>the time is now</strong>! If more companies, and even developers like us, took a stand like Google is we would see an end to the 8+ year browser lifecycle that IE6 has enjoyed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/google-dropping-support-for-ie6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ErkanaAuth Version 2.0a</title>
		<link>http://www.michaelwales.com/2010/02/erkanaauth-version-2-0a/</link>
		<comments>http://www.michaelwales.com/2010/02/erkanaauth-version-2-0a/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 16:57:49 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[authorization library]]></category>
		<category><![CDATA[BSD license]]></category>
		<category><![CDATA[ErkanaAuth]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=43</guid>
		<description><![CDATA[
In November 2007 I released an authentication library for CodeIgniter named ErkanaAuth. It was very simple to use since it just provided a few methods to make authentication simpler for you &#8211; it didn&#8217;t hijack the entire process. The post announcing that library, and the code, has long since been lost but you can still [...]]]></description>
			<content:encoded><![CDATA[<p class="aligncenter"><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/erkanaauth-banner.png" alt="ErkanaAuth" title="ErkanaAuth" width="696" height="230" /></p>
<p>In November 2007 I released an authentication library for <a href="http://www.codeigniter.com/" title="CodeIgniter">CodeIgniter</a> named ErkanaAuth. It was very simple to use since it just provided a few methods to make authentication simpler for you &#8211; it didn&#8217;t hijack the entire process. The post announcing that library, and the code, has long since been lost but you can still read the original post thanks to <a href="http://web.archive.org/web/20071111145023/http://www.michaelwales.com/2007/10/erkana-codeigniter-authorization-library/" title="Wayback Machine: Michael Wales - Erkana CodeIgniter Authorization Library">Archive.org&#8217;s Wayback machine</a>.</p>
<p>Recently, I&#8217;ve taken on a personal project of a rather grand-scale and have started factoring out the authentication logic into a library of it&#8217;s own, which I am referring to as ErkanaAuth 2.0. I am now releasing the library in its current state which is <strong>vastly unfinished</strong>! Nonetheless, I would love to hear your thoughts on the direction the library is headed and features you would like to see.</p>
<p>I don&#8217;t think I can reiterate this enough at this point in time, this is <strong>hardcore alpha</strong> &#8211; I should have called this <em>ErkanaAuth Version 2.0ha-dont-fucking-use-me-in-production-code</em>. I mean, in theory you could use this, and if its a library you want to use in future applications I strongly encourage you to give it a go. The authentication mechanism is secure but the library as a whole is sorely lacking in features at this point and is pretty hard-coded to a strict environment.</p>
<h4>Features</h4>
<ul>
<li>Authentication via username or email address and password.</li>
<li>Account creation using username or email address as unique identifier.</li>
<li>Locking of controllers/methods to logged-in users in one line.</li>
<li>Passwords are hashed with a salt prior to storing in the database.</li>
<li>User token stored in session is a hashed representation of the user&#8217;s ID and their password hash. Encrypting the session cookie via CodeIgniter&#8217;s <samp>config/config.php</samp> file adds another layer of security against altered session data.</li>
</ul>
<h4>Planned Features</h4>
<ul>
<li>Exponential delay on failed login attempts.</li>
<li>Group-based authorization system.</li>
<li>Require email validation on account creation.</li>
<li>Optional Captcha on account creation.</li>
<li>Linking of Facebook / Twitter authentication to Erkana Auth Account.</li>
<li>Forgotten password resets.</li>
<li>Extensive account API for building of authentication administration panels.</li>
<li>Extensive group API for building of authorization administration panels.</li>
</ul>
<h4>Installation</h4>
<p>The downloadable package includes a number of directories and files within those directories. It is advised to extract the archive in a temporary location, ensure there are no naming conflicts with your current application and then move the directories into your CodeIgniter application&#8217;s directory. The most common naming conflict will be with the <samp>models/account.php</samp> file. The list of files included are:</p>
<ul>
<li><samp>helpers/erkana_auth_helper.php</samp></li>
<li><samp>language/english/erkana_auth_lang.php</samp></li>
<li><samp>libraries/Erkana_auth.php</samp></li>
<li><samp>models/account.php</samp></li>
<li><samp>sql/1-create_accounts_email.sql</samp></li>
<li><samp>sql/1-create_accounts_username.sql</samp></li>
</ul>
<p>After installing the library within your application directory you must decide whether your application will authenticate based on username/password or email/password and run the correct SQL file on your database schema. This file will create a table named <code>accounts</code>, the statement run by <samp>sql/1-create_accounts_email.sql</samp> is:</p>
<script src="http://gist.github.com/294774.js"></script><noscript><pre><code class="gist">CREATE TABLE IF NOT EXISTS `accounts` (<br />
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,<br />
  `email` varchar(120) NOT NULL,<br />
  `password_hash` varchar(40) NOT NULL,<br />
  `salt` varchar(7) NOT NULL,<br />
  `last_login` timestamp NOT NULL DEFAULT &#8216;0000-00-00 00:00:00&#8242;,<br />
  `created_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,<br />
  PRIMARY KEY (`id`),<br />
  UNIQUE KEY `email` (`email`)<br />
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;</code></pre></noscript>
<p>If you run <samp>sql/1-create_accounts_username.sql</samp> the following statement will be executed:</p>
<script src="http://gist.github.com/294777.js"></script><noscript><pre><code class="gist">CREATE TABLE IF NOT EXISTS `accounts` (<br />
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,<br />
  `username` varchar(20) NOT NULL,<br />
  `password_hash` varchar(40) NOT NULL,<br />
  `salt` varchar(7) NOT NULL,<br />
  `last_login` timestamp NOT NULL DEFAULT &#8216;0000-00-00 00:00:00&#8242;,<br />
  `created_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,<br />
  PRIMARY KEY (`id`),<br />
  UNIQUE KEY `email` (`email`)<br />
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;</code></pre></noscript>
<h4>Usage</h4>
<p>ErkanaAuth aims to be as simple as possible in its usage. As of this version, this is primarily due to the limited scope of its functionality, but the overall feel for the library will differ as little as possible from what can be seen as of now. Many of the limitations on the library (i.e., strict naming of form fields) will be corrected as development continues.</p>
<p>ErkanaAuth does not assist in the creation of any front-end related code (i.e., user registration forms, login forms) at this time. ErkanaAuth simply provides a powerful set of methods to be used within your controllers to assist in getting an authentication system up and running as quickly as possible. Additionally, there is a helper function to display useful error messages to your users for invalid form submissions.</p>
<h5>Creating a User</h5>
<p>The <code>create_account()</code> method accepts a single string parameter of either <code>email</code> (default) or <code>username</code>, which should reflect the authentication mechanism you opted for during the installation and execution of the SQL file earlier. This method will return <code>TRUE</code> or <code>FALSE</code> if the user was created and can be used similarly as to how the standard <code>form_validation</code> library is used.</p>
<p>The library currently requires the following form fields to be present with the corresponding rulesets:</p>
<ul>
<li><code>email</code>: Only if you select the email authentication mechanism (<code>required|max_length[120]|valid_email|trim</code>)</li>
<li><code>username</code>: Only if you select the username authentication mechanism (<code>required|min_length[4]|max_length[20]|trim</code>)</li>
<li><code>password</code>: Always required (<code>required|matches[passwordconf]</code>)</li>
<li><code>passwordconf</code>: Always required (<code>required</code>)</li>
</ul>
<p>The controller method that displays and processes your account creation form should call the <code>create_account()</code> method and redirect on <code>TRUE</code>, otherwise loading the view file that contains your account creation form. In the following example, the user is redirected to <code>accounts/index()</code> which would display our login form.</p>
<script src="http://gist.github.com/294795.js"></script><noscript><pre><code class="gist">// create()<br />
// Creates a user<br />
function create() {<br />
	if ($this->erkana_auth->create_account(&#8216;email&#8217;)) {<br />
		redirect(&#8216;accounts&#8217;);<br />
	}</p>
<p>	$this->load->view(&#8216;accounts/create&#8217;);<br />
}<br />
</code></pre></noscript>
<h5>Validating a User&#8217;s Login Credentials</h5>
<p>The <code>validate_login()</code> method accepts a single string parameter of either <code>email</code> (default) or <code>username</code>, which should reflect the authentication mechanism you opted for during the installation and execution of the SQL file earlier. This method will return <code>TRUE</code> or <code>FALSE</code> if the credentials are valid and can be used similarly as to how the standard <code>form_validation</code> library is used.</p>
<p>The library currently requires the following form fields to be present:</p>
<ul>
<li><code>email</code>: Only if you select the email authentication mechanism</li>
<li><code>username</code>: Only if you select the username authentication mechanism</li>
<li><code>password</code>: Always required</li>
</ul>
<p>The controller method that displays and processes your login form should call the <code>validate_login()</code> method and redirect on <code>TRUE</code>, otherwise loading the view file that contains your login form. In the following example, the user is redirected to <code>announcements/index()</code> which would display a &#8220;dashboard&#8221; like page and only be accessible to logged in users.</p>
<script src="http://gist.github.com/294803.js"></script><noscript><pre><code class="gist">// index()<br />
// Displays the login screen<br />
function index() {<br />
	if ($this->erkana_auth->validate_login(&#8216;email&#8217;)) {<br />
		redirect(&#8216;announcements&#8217;);<br />
	}</p>
<p>	$this->load->view(&#8216;accounts/index&#8217;);<br />
}<br />
</code></pre></noscript>
<h5>Validating a User&#8217;s Logged-in Status at Page Load</h5>
<p>The <code>required()</code> method provides a simple, one-line, way to validate a user&#8217;s session and ensure the user is logged into a valid account. This line should be placed within the constructor of any controller class you would like to complete protect or as the first line of a method you would like to protect. The following example is a controller named <code>Announcements</code> that currently only has its <code>index()</code> method protected. Any other methods added to this controller would not be protected without either moving the <code>required()</code> method to the constructor or placing a call to the <code>required()</code> method within the controller methods themselves.</p>
<script src="http://gist.github.com/294808.js"></script><noscript><pre><code class="gist"><?php if (!defined('BASEPATH')) exit('No direct script access allowed.');</p>
<p>class Announcements extends Controller {</p>
<p>	function Announcements() {<br />
		parent::Controller();<br />
	}</p>
<p>	// index()<br />
	// List of announcements<br />
	function index() {<br />
		$this->erkana_auth->required();</p>
<p>		echo &#8216;Logged in&#8217;;<br />
	}</p>
<p>}</code></pre></noscript>
<h5>Displaying Errors on Invalid Form Submissions</h5>
<p>The library includes a helper with the function <code>authentication_errors()</code> to assist in displaying errors upon form submission. This function will return all errors, delimited by a <code><br /></code>. If there are no errors, <code>NULL</code> is returned. In the following example, we are displaying a login form that will display errors at the top of the form if any exist from prior submission attempts:</p>
<script src="http://gist.github.com/294816.js"></script><noscript><pre><code class="gist"><?php echo form_open('accounts/index') . PHP_EOL; ?><br />
<?php if (authentication_errors()): ?></p>
<p class="error"><?php echo authentication_errors(); ?></p>
<p><?php endif; ?></p>
<p><label for="account-email">Your email address:</label></p>
<input type="text" id="account-email" name="email" />
<p><label for="account-password">Your password:</label></p>
<input type="password" id="account-password" name="password" />
<input type="submit" value="Login" />
<p><?php echo form_close() . PHP_EOL; ?></code></pre></noscript>
<h4>Technical Details</h4>
<p>During account creation an alphanumeric string is randomly generated to serve as the user&#8217;s salt. This salt is then hashed with the user&#8217;s password and the resulting hash is stored in the database to validate against.</p>
<p>On a login attempt, the database is queried for a record based on your authentication mechanism (email or username). That record is then compared against the user submitted data for validation. On a successful validation, session variables are stored consisting of the record&#8217;s <code>id</code> and a hash of the record&#8217;s <code>id</code> field and <code>password_hash</code> field.</p>
<p>When a user visits a protected page the session is first checked for the variables that are set by a successful login. If these session variables exist, the database is queried for the record identified. If this record exists, the session is further validated by comparing the stored hash of the record&#8217;s <code>id</code> and <code>password_hash</code> with the data that is stored in the record.</p>
<h4>Download</h4>
<p><a href="http://www.michaelwales.com/wp-content/uploads/2010/02/erkana_auth-2.0a.zip">Erkana Auth 2.0a is available for download</a>. At this early stage of development a version control repository has not been made publicly available. In the future, Subversion and Git repositories will be made available.</p>
<h4>License</h4>
<p>ErkanaAuth 2.0a is licensed under the BSD License as defined by the <a href="http://creativecommons.org/licenses/BSD/">Human-Readable Creative Commons Deed</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/erkanaauth-version-2-0a/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Packt Publishing&#8217;s CodeIgniter 1.7 Review</title>
		<link>http://www.michaelwales.com/2010/02/packt-publishings-codeigniter-1-7-review/</link>
		<comments>http://www.michaelwales.com/2010/02/packt-publishings-codeigniter-1-7-review/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 10:00:45 +0000</pubDate>
		<dc:creator>Michael Wales</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[packt publishing]]></category>

		<guid isPermaLink="false">http://www.michaelwales.com/?p=30</guid>
		<description><![CDATA[In mid-December I was asked by Packt Publishing to read and review their latest CodeIgniter book, ingeniously titled CodeIgniter 1.7, by Jose Argudo and David Upton. As you all know, my blog has been down for quite some time; although, I read the book (and subsequently gave it away to a friend), I am just [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.michaelwales.com/wp-content/uploads/2010/02/packtpub-codeigniter.jpg"><img src="http://www.michaelwales.com/wp-content/uploads/2010/02/packtpub-codeigniter-243x300.jpg" alt="Pack Publishing: CodeIgniter 1.7" title="Packt Publishing: CodeIgniter 1.7" width="122" height="150" class="alignright" /></a>In mid-December I was asked by <a href="http://www.packtpub.com/" title="Packt Publishing">Packt Publishing</a> to read and review their latest CodeIgniter book, ingeniously titled <a href="http://www.packtpub.com/improve-coding-productivity-with-codeigniter-1-7?utm_source=michaelwales.com&#038;utm_medium=bookrev&#038;utm_content=blog&#038;utm_campaign=mdb_001849" title="Packt Publishing: CodeIgniter 1.7"><em>CodeIgniter 1.7</em></a>, by Jose Argudo and David Upton. As you all know, my <a href="http://www.michaelwales.com/2010/02/blog-back-up-and-running/" title="Michael Wales: Blog Back Up and Running">blog has been down</a> for quite some time; although, I read the book (and subsequently gave it away to <a href="http://blog.johnpantoja.com/" title="Web Developer: John Pantoja">a friend</a>), I am just now able to write the promised review.</p>
<p>This book targets the absolute beginner developer and it does an adequate job filling the niche, as previous CodeIgniter books on the market are drastically outdated. Unfortunately, I don&#8217;t feel this book differentiates itself significantly from the well-written <a href="http://www.codeigniter.com/user_guide/" title="CodeIgniter User Guide">CodeIgniter User Guide</a> and many people who buy this book will feel as if they have been cheated out of $36.</p>
<p>Chapters 1-3 explain what frameworks are, what CodeIgniter can do for you, how to get up and running with CodeIgniter and the basics of the MVC development pattern. It&#8217;s not until Chapter 4 that we discover some truly unique CodeIgniter content with the Active Record pattern, but it doesn&#8217;t last as we drop back to some pretty basic HTML material in Chapter 5 as we build out some forms.</p>
<p>The rest of the book does a very good job of reiterating the content outlined in the user guide, ranging from sessions and security to the XML-RPC library. There&#8217;s even a bit of content on the Cart library which is a welcome addition since it&#8217;s relatively new.</p>
<p>The shining star for this book though is Chapter 7, <em>CodeIgniter and Objects</em>. Argudo and Upton do an amazing job describing the CodeIgniter super-global object, as well as explaining copying by reference in plain English. Unfortunately, it just kind of creeps up on you out of nowhere with very little lead in or warning that <strong>shit&#8217;s about to get deep</strong>. It&#8217;s a worthy addition to the book though and serves its purpose in separating the &#8220;restating the easy stuff from the user guide&#8221; from the &#8220;restating the object oriented stuff from the user guide&#8221; sections of the book.</p>
<p>All in all, if you feel as if you need the user guide read off to you in plain English, by all means buy this book. There&#8217;s nothing else on the market today that will explain virtually every aspect of the framework to you as a beginner. If you&#8217;re comfortable in reading and understanding the user guide, possibly with a bit of help from the <a href="http://www.codeigniter.com/forums/" title="CodeIgniter Forums">CodeIgniter Forums</a>, you&#8217;re going to want to pass.</p>
<p>Last but not least, this is one of the few books whose eBook version actually provides a legitimate value (other than just being a good option for the broke audience). If you fall between the two aforementioned groups (i.e., you are comfortable with the user guide but you don&#8217;t quite understand the CodeIgniter object model or how to best write your own libraries) <strong>buy the eBook now</strong>. You&#8217;re going to save some money and Chapters 7-9 and 15 are well worth the $28 price tag.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.michaelwales.com/2010/02/packt-publishings-codeigniter-1-7-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
