<?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>Labs &#187; CakePHP</title>
	<atom:link href="http://labs.iamkoa.net/category/cakephp/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.iamkoa.net</link>
	<description>I break it. I fix it. You learn.</description>
	<lastBuildDate>Fri, 09 Jul 2010 02:26:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>First Thing&#8217;s First: Validate</title>
		<link>http://labs.iamkoa.net/2010/07/02/first-things-first-validate/</link>
		<comments>http://labs.iamkoa.net/2010/07/02/first-things-first-validate/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 22:44:43 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/?p=338</guid>
		<description><![CDATA[Have a sweet function written that requires valid variables? Make sure you&#8217;re validating those variables at the top of your function. Validating variables before (as apposed to while) they are used is key in making sure that important logic isn&#8217;t executed using crappy data. Here&#8217;s an example of validating first, then executing: /* The good... [...]]]></description>
			<content:encoded><![CDATA[<p>Have a sweet function written that requires valid variables? Make sure you&#8217;re validating those variables at the top of your function. Validating variables <em>before</em> (as apposed to <em>while</em>) they are used is key in making sure that important logic isn&#8217;t executed using crappy data.</p>
<p>Here&#8217;s an example of validating first, then executing:</p>
<pre class="brush:php">
	/* The good... */
	public function insertNewInvoiceItem($item, $quantity)
	{
		if(!$item instanceof Shop_Item) {
			throw new InvalidArgumentException ('Expecting an item to be an instance of Shop_Item.');
		}

		if(!is_numeric($quantity)) {
			throw new InvalidArgumentException('Quantity is not numeric.');
		}

		// We're good to go. Continue with the function...
	}
</pre>
<p>The method above is also much cleaner than <code>if... else... </code> statements and limits the extra (perhaps useless) work required by your code:</p>
<pre class="brush:php">
	/* The bad... */
	public function insertNewInvoiceItem($item, $quantity)
	{
		if($item instanceof Shop_Item) {
			// Do some $item stuff...

			if(is_numeric($quantity)) {
				// Do some $quantity calculations
			} else {
				// Uh oh, $quantity was bad but we've
				// run some Shop_Item logic already.
			}
		}
		else
		{
			// $item is not part of Shop_Item
		}
	}
</pre>
<p>I used a simple example to demonstrate my point but when this technique is used on more complex logic, it&#8217;s benefits are much more obvious.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2010/07/02/first-things-first-validate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Three Bitchin&#8217; PHP Classes &#8211; Cache, Last.fm API, Time</title>
		<link>http://labs.iamkoa.net/2010/04/21/three-bitchin-php-classes-cache-last-fm-api-time/</link>
		<comments>http://labs.iamkoa.net/2010/04/21/three-bitchin-php-classes-cache-last-fm-api-time/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 07:11:23 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[parse]]></category>
		<category><![CDATA[time]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/?p=77</guid>
		<description><![CDATA[There&#8217;s nothing like the feeling that comes with typing a few lines in a PHP application and letting some included classes take care of the dirty work; you know, the filthy stuff like caching, calling the Last.fm API, purifying timestamps, and handling file uploads. (Dirty, right?) All of the following PHP classes are &#8220;works in [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s nothing like the feeling that comes with typing a few lines in a PHP application and letting some included classes take care of the dirty work; you know, the filthy stuff like <strong>caching</strong>, <strong>calling the Last.fm API</strong>, <strong>purifying timestamps</strong>, and <strong>handling file uploads</strong>. (Dirty, right?)</p>
<p>All of the following PHP classes are &#8220;works in progress&#8221;, but hopefully each is mature enough to find its way into your code. Continue reading to view, download, and use each class.</p>
<p><span id="more-77"></span></p>
<hr />
<h2>Cache &#8211; Output &#038; Object Caching</h2>
<p>Though this class is old (three years), it does the trick, and quickly. <a href="http://www.phpclasses.org/browse/package/3807.html" target="_blank">Dragon Bosnjak</a> wrote this gem, allowing for easy caching of webpage content into a directory (and filename) of your choosing.</p>
<h3>Using Cache Class</h3>
<p>Caching your web content is a breeze! Create a new Cache class by specifying a directory to store the cache file, and surround your webpage content in a <code>while</code> loop, like so:</p>
<pre class="brush:php">
$cache = new Cache("../cache/");

while ($cache->save("filename.cache", 30)) {
	// "30" is the number of seconds the content should remain cached.
	// Your cached content goes here...
 }
</pre>
<h3>Download Cache</h3>
<p>You can download and use this golden-nugget of love by visiting <a href="http://www.phpclasses.org/browse/package/3807.html" target="_blank">PHP Classes</a> &#8211; perhaps the most poorly styled/organized website on the internet, but that&#8217;s another post entirely.</p>
<hr />
<h2>Last.fm API</h2>
<p>If you have yet to discover the hotness of using <a href="http://us2.php.net/oop5.magic" target="_blank">&#8220;Magic Methods&#8221; in PHP</a>, I suggest you read up on how to serve up a magic teapot of greatness using PHP5. These Magic Methods are exactly what I used to create this simple Last.fm API class. The result is the ability to quickly make <em>almost</em> any API call without having to continuously fiddle with API key variables, etc.</p>
<h3>Using Last.fm API Class</h3>
<p>After including the LastFm class file, you need to create a new instance of the <code>LastFm()</code> class.</p>
<pre class="brush:php">
// include class file
include_once('../inc/class.lastfm.php');

// initate LastFm class
$lastfm = new LastFm();
$lastfm->key = "1234567890"; // your LastFm API key
</pre>
<p>Then you can call your LastFm API action using the following conversion:</p>
<p>Let&#8217;s say we want to call <a href="http://www.last.fm/api/show?service=299" target="_blank">User.getTopAlbums</a> with the <strong>user</strong> argument set to <code>bob</code> and the <strong>period</strong> argument set to <code>3month</code>:</p>
<pre class="brush:php">
$lastfm->user_getTopAlbums("user=iamkoa","period=3month");
</pre>
<p>The above PHP code will generate the following API call:</p>
<pre class="brush:html">

http://ws.audioscrobbler.com/2.0/?method=user.getTopAlbums&#038;user=bob&#038;period=3month&#038;api_key=1234567890
</pre>
<h3>Let The Class Parse Things For You&#8230;</h3>
<p>The API call will return, for example, the following XML to Array:</p>
<pre class="brush:php">
Array
(
    [lfm] => Array
        (
            [attr] => Array
                (
                    [status] => ok
                )

            [recenttracks] => Array
                (
                    [attr] => Array
                        (
                            [user] => iamkoa
                            [page] => 1
                            [perPage] => 8
                            [totalPages] => 2777
                        )

                    [track] => Array
                        (
                            [0] => Array
                                (
                                    [artist] => Array
                                        (
                                            [value] => Black Eyed Peas
                                            [attr] => Array
                                                (
                                                    [mbid] => d5be5333-4171-427e-8e12-732087c6b78e
                                                )

                                        )
// etc...
</pre>
<p>To make any Last.fm API call, simply replace the <code>.</code> symbol with an <code>_</code> symbol and include any arguments with a <code>"var=bar"</code> pattern. For example, here&#8217;s how to make a couple calls:</p>
<pre class="brush:php">
// call user.getWeeklyTrackChart
$lastfm->user_getWeeklyTrackChart("user=iamkoa");

// call group.getMembers
$lastfm->group_getMembers("group=groupName");

// etc...
</pre>
<h3>Download Last.fm</h3>
<p><a href="http://labs.iamkoa.net/wp-content/uploads/2010/04/php-class-lastfm-04222010.zip">Download and use the Last.fm PHP class</a>. Please post any enhancements to the class here for others to use.</p>
<hr />
<h2>Time</h2>
<p>Time is a bitch. It&#8217;s always against us. In the case of parsing a date string into a human-friendly string, it&#8217;s even more apparent that time sucks. Hopefully this Time class, though not entirely finished, will help with parsing dates.</p>
<h3>Use it</h3>
<p>It&#8217;s really, really simple to use:</p>
<pre class="brush:php">
$time = new Time();
echo $time->timeAgoInWords($date_string);
</pre>
<p>Depending upon when <code>$date_string</code> is relative to the current time, the above code might print one of the following:</p>
<p><code>"26 July, 2:45 PM", "Yesterday morning", "Today", "Last night", or "28 minutes ago", etc...</code></p>
<p>Editing the class is pretty simple, so I&#8217;ll let all you hackers dig into it for details.</p>
<h3>Download Time</h3>
<p><a href="http://labs.iamkoa.net/wp-content/uploads/2010/04/php-class-time-04222010.zip">Download and use the Time PHP class</a>. Please post any enhancements to the class here for others to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2010/04/21/three-bitchin-php-classes-cache-last-fm-api-time/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Session-Based Flash Messages Look Better (CakePHP)</title>
		<link>http://labs.iamkoa.net/2008/01/13/session-based-flash-messages-look-better-cakephp/</link>
		<comments>http://labs.iamkoa.net/2008/01/13/session-based-flash-messages-look-better-cakephp/#comments</comments>
		<pubDate>Sun, 13 Jan 2008 22:10:53 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[cakephp session messages alert flash]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2008/01/13/session-based-flash-messages-look-better-cakephp/</guid>
		<description><![CDATA[The CakePHP blog tutorial uses a rather archaic method of displaying user messages (like, &#8220;Your post has been saved.&#8220;) that needlessly breaks up the flow of your application. Rather than Cake&#8217;s typical method of displaying flash messages on a separate page (ugly), learn how to seamlessly display the same messages within your application and make [...]]]></description>
			<content:encoded><![CDATA[<p>The CakePHP <a href="http://manual.cakephp.org/appendix/blog_tutorial" target="_blank">blog tutorial</a> uses a rather archaic method of displaying user messages (like, &#8220;<a href='http://labs.iamkoa.net/wp-content/uploads/2008/01/your-post-has-been-saved_1200258861937.png' title='CakePHP Session-Based Messages - Part 3' target='_blank'>Your post has been saved.</a>&#8220;) that needlessly breaks up the flow of your application. Rather than Cake&#8217;s typical method of displaying flash messages on a separate page (ugly), learn how to seamlessly display the same messages <a href='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259770656.png' title='CakePHP Session-Based Messages - Part 4' target='_blank'>within your application</a> and make your users clap with joy.</p>
<p><span id="more-51"></span></p>
<h2>See What I Mean?</h2>
<p>Let me show you exactly what I&#8217;m talking about using some screen shots I took of my own application.</p>
<p>These first two screen shots show the index page and post page of my news application:</p>
<p>(At the moment, nothing is posted on the index page.)<br />
<a href='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259990703.png' title='CakePHP Session-Based Messages - Part 1'><img src='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259990703.thumbnail.png' alt='CakePHP Session-Based Messages - Part 1' /></a></p>
<p>(A typical form allows the user to post a new news article&#8230;)<br />
<a href='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259749609.png' title='CakePHP Session-Based Messages - Part 2'><img src='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259749609.thumbnail.png' alt='CakePHP Session-Based Messages - Part 2' /></a></p>
<p>When we post a new news article, the typical Cake method is to display a flash message on a separate page, forcing the user to temporally leave your application. This method is distracting for the user and makes your application feel broken up. (To return to the news index page, the user is forced to click the &#8220;Your post has been saved&#8221; message.)</p>
<p><a href='http://labs.iamkoa.net/wp-content/uploads/2008/01/your-post-has-been-saved_1200258861937.png' title='CakePHP Session-Based Messages - Part 3'><img src='http://labs.iamkoa.net/wp-content/uploads/2008/01/your-post-has-been-saved_1200258861937.thumbnail.png' alt='CakePHP Session-Based Messages - Part 3' /></a></p>
<p>Instead of the above method, let&#8217;s use the same messages in a Web 2.0 fashion. After a news article is posted, we can automatically redirect the user back to the index page AND display the message on the same page:</p>
<p><a href='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259770656.png' title='CakePHP Session-Based Messages - Part 4'><img src='http://labs.iamkoa.net/wp-content/uploads/2008/01/coco-cms-news_1200259770656.thumbnail.png' alt='CakePHP Session-Based Messages - Part 4' /></a></p>
<p>See what I mean? Allow me to show you how it&#8217;s done&#8230;</p>
<h2>Configure Your Layout</h2>
<p>In order to display the awesome-web-2.0-styled messages, we need to add a line of code to your <code>app/views/layouts/default.thtml</code> page, above the code which displays your layout content:</p>
<pre class="brush:php">
<?php if ($session->check('Message.flash')): $session->flash(); endif; // this line displays our flash messages
   echo $content_for_layout;
?></pre>
<h2>Configure Your Controller</h2>
<p>Next comes the line you must add to your <code>app/controllers/news_controller.php</code> controller to display your message and redirect your user to a particular page:</p>
<pre class="brush:php">
function add() {
// ...
   if ($this->News->save($this->data)) {
      $this->Session->setFlash('Your post has been saved.');
      $this->redirect('/news/index');
     //$this->flash('The News has been saved', '/news/index'); // this was the old way of doing things... yuck
   }
}
</pre>
<h2>All Done!</h2>
<p>Now when a flash message is displayed, it&#8217;ll be placed in a <code>div</code> (directly above the layout content) for easy style manipulation:</p>
<pre class="brush:php">
Your post has been saved.
</pre>
<p>Easy as cake. If you have any questions or suggestions, please post. </p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2008/01/13/session-based-flash-messages-look-better-cakephp/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>CakePHP 1.1 File Upload Plays Rough With PHP 4</title>
		<link>http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/</link>
		<comments>http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 00:23:07 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/</guid>
		<description><![CDATA[Uploading files via CakePHP has been covered a few times on Labs. Based on the feedback, it&#8217;s safe to assume bridging the gap between file uploads and PHP can be tricky. Usually Cake is ready to lend a helpful hand. Not this time. //If you're finding that executing this: //... returns something like this: $this->data:Array [...]]]></description>
			<content:encoded><![CDATA[<p>Uploading files via CakePHP has been covered a <a href="http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/">few</a> <a href="http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/">times</a> on Labs. Based on the feedback, it&#8217;s safe to assume bridging the gap between file uploads and PHP can be tricky. Usually Cake is ready to lend a helpful hand. Not this time.</p>
<p><span id="more-52"></span></p>
<pre class="brush:php">
//If you're finding that executing this:
<?php echo $html->formTag('/' . $params['url']['url'], 'post', array('enctype' => 'multipart/form-data')); ?>
	<?php echo $html->input('Test/title'); ?>
	<?php echo $html->file('Test/file'); ?>
	<?php echo $html->submit('Save'); ?>
</form>

//... returns something like this:
$this->data:Array
(
    [Test] => Array
        (
            [title] => Foo
            [file] => 4tmp/phpHGSjDA
        )
)

//... instead of something like this:
$this->data:Array
(
    [Test] => Array
        (
            [title] => Foo
            [file] => Array
                (
                    [name] => aeo.jpg
                    [type] => image/jpeg
                    [tmp_name] => /tmp/phppM8tfc
                    [error] => 0
                    [size] => 45471
                )
        )
)

//... then you must be as annoyed as I am.
</pre>
<p>The reason why the <code>file</code> form field is returning the tmp name is because CakePHP expects <code>register_globals</code> is OFF.</p>
<h2>Solution One</h2>
<p>Turn off register_globals via .htaccess:</p>
<pre class="brush:php">
#/app/webroot/.htaccess
php_flag register_globals off
</pre>
<h2>Solution Two</h2>
<p>Manually write your HTML form fields without using an input array:</p>
<pre class="brush:php">
// do this
<input type="file" name="file" />
// not this
<?php echo $html->file('Test/file'); ?> // will output:
<input type="file" name="data[Test][test]" />
</pre>
<p>Solution two is a slight pain in the ass, because now that you&#8217;ve eliminated the array within the form input field, you need to do a little extra work in your CakePHP controller. (If there&#8217;s a demand, I&#8217;ll give some examples.)</p>
<p>Hopefully this&#8217;ll clear up Cake&#8217;s messhole.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/12/11/cakephp-11-file-upload-plays-rough-with-php-4/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Simple/Secure Email Class For PHPMailer</title>
		<link>http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/</link>
		<comments>http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/#comments</comments>
		<pubDate>Tue, 27 Nov 2007 23:57:38 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/</guid>
		<description><![CDATA[If you&#8217;re not careful, sending email via PHP is about as safe as cookies at Fat Camp. BKWLD was recently tagged by a spammer who noticed one such insecurity on one of our websites and ended up using our server to send hundreds of emails. It wasn&#8217;t until MediaTemple informed us of this breach that [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re not careful, sending email via PHP is about as safe as cookies at Fat Camp. <a href="http://bkwld.com">BKWLD</a> was recently tagged by a spammer who noticed one such insecurity on one of our websites and ended up using our server to send hundreds of emails. It wasn&#8217;t until <a href="http://mediatemple.net">MediaTemple</a> informed us of this breach that we realized what had happened.</p>
<p>The method most spammers use is called a &#8220;mail injection&#8221;, in that the spammer manipulats the PHP <code>mail()</code> function via a custom form post, etc. I won&#8217;t go into details, as a quick search on Google came up with over 225,000 pages describing this technique &#8211; <a href="http://www.bl0g.co.uk/060214/PHP_mail_Email_Injection_Attack_Allows_Spammers_to_Send_Email/">here</a> <a href="http://www.tonyspencer.com/2005/12/15/email-injection-exploit-through-a-php-contact-form/">are</a> <a href="http://www.securephpwiki.com/index.php/Email_Injection">a</a> <a href="http://www.maravelias.gr/archives/security/28">few</a>.</p>
<p>Getting around these hacks requires detailed validation of your data.Thankfully I&#8217;ve done everything for you using the best PHP email class around, <a href="http://phpmailer.codeworxtech.com/">PHPMailer</a>. My class is called <code>SendMail</code> and it&#8217;s an extension of the PHPMailer class. The result is a powerful script capable of sending email via SMTP or POP3, all without handing over your server to a toothless spammer.</p>
<p><span id="more-48"></span></p>
<blockquote><p>
The SendMail class has been updated. Please view <a href="#updates">the updates</a> before commenting.
</p></blockquote>
<h2>Download The SendMail Class</h2>
<p>Click the link to download the SendMail class and continue reading to learn how to use it.<br />
<a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/sendmail-class-11262007.zip' title='SendMail Class'>Download the SendMail class</a></p>
<h2>Setup</h2>
<p>Setting up the SendMail class is easy-peezie. Simply include the required SendMail variables and call the <code>send()</code> function to send emails:</p>
<pre class="brush:php">
<?php
require("inc/class.sendmail.php");

if($_POST){
    $mail = new SendMail;

    <span class="highlight">$mail->authHosts = array("domain.com");</span>

    $mail->addEmail("name@person.com","Name",);
    $mail->addEmail("name2@person.com","Name2");

    $mail->subject($_POST['subject']);
    $mail->body($_POST['body']);

    $mail->fromName($_POST['from_name']);
    $mail->fromEmail($_POST['from_email']);

    $result = $mail->send();

    if (!$result){
        if(!empty($mail->errors)) {
            $mail->displayErrors($mail->errors,'ol');
        }
    exit();
    }
}

echo "Message was sent successfully";
?>
<form method="post" action="<?=$_SERVER['PHP_SELF']?>">
<input type="text" name="from_email" value="people@info.com" />
<input type="text" name="from_name" value="People" />
<input type="text" name="subject" value="This is a subject" />
<input type="text" name="body" value="Email body goes here." />
<input type="submit" value="Submit" />
</form>
</pre>
<p>For further security, you may implement the <code>authHosts</code> variable as highlighted above. The <code>authHosts</code> array specifies what domains are allowed to send <code>$_POST</code> data. Any domains not listed that attempted to contact the script via <code>$_POST</code> will get a 403 (permission denied) error.</p>
<h2>Further Configuration</h2>
<p>If you need to specify an SMTP host, username, and password, include each variable before calling the <code>send()</code> function. You may also specify the charset and select whether or not HTML should be used in the email by using the respective code below:</p>
<pre class="brush:php">
// ...
$mail = new SendMail;

if($_POST) {

    $mail = new SendMail;

    $mail->authHosts = array("domain.com");

    <span class="highlight">$mail->host = 'mail.domain.com';
    $mail->username = 'root';
    $mail->password = 'pass123';

    $mail->charset = 'utf-8';
    $mail->bodyHtml = "HTML goes in here";</span>

    $mail->addEmail("name@person.com","Name");
    $mail->addEmail("name2@person.com","Name2");

    $mail->subject($_POST['subject']);
    $mail->body($_POST['body']);

    $mail->fromName($_POST['from_name']);
    $mail->fromEmail($_POST['from_email']);

    $mail->Mailer = 'mail';

    $result = $mail->send();

    if (!$result){
        if(!empty($mail->errors)) {
            $mail->displayErrors($mail->errors,'ol');
        }
    exit();
    }
}
// ...
</pre>
<p>When displaying errors via the <code>displayErrors()</code> function, you may choose to use <code>&lt;ul&gt;</code> or <code>&lt;ol&gt;</code> HTML. If you&#8217;d rather receive errors as an array, use <code>$mail-&gt;errors</code> only.</p>
<h2>Fini, Cowboy</h2>
<p>If you need further explanation or would like a better understanding of the code, dig into the <code>inc/class.sendmail.php</code> file. The code is well-commented and should guide you nicely. If it doesn&#8217;t, comment and I&#8217;ll help you myself. For further information on PHPMailer, <a href="http://phpmailer.codeworxtech.com/">go to the official website</a>.</p>
<h2>Updates</h2>
<p><a name="updates"></a><strong>Nov 27, 2007</strong>: The entire SendMail class has been rewritten to better perform as OOP should. The domain security is now optional. All files have been updated for downloading.</p>
<p><strong>Dec 21, 2007</strong>: Select between sending with PHP <code>mail()</code>, SMTP, or POP using <code>Mailer</code> as shown above. All files have been updated for downloading. Eat it up.</p>
<p><strong>Jan 15, 2008</strong>: When sending HTML mail, alternative text sends accordingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/27/a-simplesecure-email-class-for-phpmailer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Custom CakePHP Errors &#8211; A Complete Run Down</title>
		<link>http://labs.iamkoa.net/2007/11/20/custom-cakephp-errors-a-complete-run-down/</link>
		<comments>http://labs.iamkoa.net/2007/11/20/custom-cakephp-errors-a-complete-run-down/#comments</comments>
		<pubDate>Tue, 20 Nov 2007 22:50:46 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/20/custom-cakephp-errors-a-complete-run-down/</guid>
		<description><![CDATA[Taking advantage of custom error documents usually requires tapping on an .htaccess file, as discussed in my previous custom error article. However CakePHP makes for easy custom error handling thanks to a pre-defined Cake system. I&#8217;ll walk you through creating custom error pages, both simple and complex. Basic Errors Creating typical custom error pages in [...]]]></description>
			<content:encoded><![CDATA[<p>Taking advantage of custom error documents usually requires tapping on an <code>.htaccess</code> file, as discussed in <a href="http://labs.iamkoa.net/2007/10/30/custom-404500-errors-via-htaccess/">my previous custom error article</a>. However CakePHP makes for easy custom error handling thanks to a pre-defined Cake system.</p>
<p>I&#8217;ll walk you through creating custom error pages, both simple and complex.</p>
<p><span id="more-47"></span></p>
<h2>Basic Errors</h2>
<p>Creating typical custom error pages in Cake is super easy. Below is a list of files that can be created in the <code>/app/views/errors/</code> folder in order to overwrite the generic error templates located in <code>/cake/libs/view/templates/errors/</code>:</p>
<pre class="brush:php">
# not found #
    error404.thtml

# missing files #
    missing_action.thtml
    missing_component_class.thtml
    missing_component_file.thtml
    missing_connection.thtml
    missing_controller.thtml
    missing_helper_class.thtml
    missing_helper_file.thtml
    missing_layout.thtml
    missing_model.thtml
    missing_scaffolddb.thtml
    missing_table.thtml
    missing_view.thtml

# private &#038; scaffold related errors #
    private_action.thtml
    scaffold_error.thtml
</pre>
<p>The above errors are all fine and dandy, but what if you want to create a custom error to be displayed when a user is denied access to the super secret area of your website?</p>
<h2>Custom Errors</h2>
<p>Custom errors could be used for anything &#8211; to let users know an area is restricted, or perhaps to users know they need to pay you loads of cash in order to use your website. Whatever the reason, Cake can help.</p>
<p><strong>Example:</strong><br />
Let&#8217;s say you want your users to donate before entering your website. For those who haven&#8217;t donated, you want to display an &#8220;error&#8221;.</p>
<p>First create your donation error page as you would any of the errors above, and place it in the typical errors folder:</p>
<pre>
/app/views/errors/donation_error.thtml
</pre>
<p>Next, in order to call your custom error, place the following in your controller of choice:</p>
<pre class="brush:php">
$this->viewPath = 'errors';
$this->render('donation_error');
</pre>
<p>Give yourself a pat on the back. You&#8217;ve done well.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/20/custom-cakephp-errors-a-complete-run-down/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Secure CakePHP via Sessions &amp; Magic (Login / Logout)</title>
		<link>http://labs.iamkoa.net/2007/11/08/secure-cakephp-via-sessions-login-logout/</link>
		<comments>http://labs.iamkoa.net/2007/11/08/secure-cakephp-via-sessions-login-logout/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 20:44:50 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/08/secure-cakephp-via-sessions-login-logout/</guid>
		<description><![CDATA[Making sure a CakePHP application is secure is a total snap thanks to &#8220;sessions&#8221; &#8211; the rock animal of websites. Put on your All-Stars and boot up your MacBook &#8211; I&#8217;m about to go Discovery Channel on your ass. Hopefully by the end of reading this article, you&#8217;ll be able to create a secure CakePHP [...]]]></description>
			<content:encoded><![CDATA[<p>Making sure a CakePHP application is secure is a total snap thanks to &#8220;<a href="http://us.php.net/session">sessions</a>&#8221; &#8211; the rock animal of websites. Put on your All-Stars and boot up your MacBook &#8211; I&#8217;m about to go Discovery Channel on your ass.</p>
<p><span id="more-39"></span></p>
<p>Hopefully by the end of reading this article, you&#8217;ll be able to create a secure CakePHP application. The point is to allow only registered users access to <em>restricted</em> areas of your application without blocking access to <em>all</em> areas of your application.</p>
<h2>Pretext</h2>
<p>We&#8217;ll be creating three sections in order to achieve our goal of total security:</p>
<pre>
1: /app/app_controller.php
2: /app/controllers/users_controller.php
3: /app/views/users/
      -> add.thtml, edit.thtml, index.thtml, login.thtml, logout.thtml
</pre>
<p>As always, <a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/secure-cakephp-sessions-11082007.zip' title='Secure CakePHP via Sessions'>all of these sections can be downloaded</a> so you can follow along.</p>
<h2>1. The app_controller</h2>
<p>Our <code>app_controller.php</code> file will hold the function <code>checkSession</code> which will check session data to make sure a user is logged in. Here&#8217;s the function in its entirety:</p>
<pre class="brush:php">
function checkSession(){

	// fill $username with session data
	$username = $this->Session->read('user');

	// if the $username is empty,
	// send user to login page
	if (!$username){
		$this->redirect('/users/login');
		exit();
	} else {
		// if $username is not empty,
		// check to make sure it's correct
		$results = $this->User->findByEmail($username);

		// if not correct, send to login page
		if(!$results){
			$this->Session->delete('user');
			$this->Session->setFlash('Incorrect session data.');
			$this->redirect('/users/login');
			exit();
		}

		// otherwise set $user variable as users email address
		$this->set('user', $results['User']['email']);
	}
}
/pre>

The commenting throughout the above code is pretty self-explanatory - the session data is checked and validated. Score one for us.
<h2>2. The users_controller</h2>

Of the six functions in <code>users_controller.php</code>, we'll cover the <code>login</code> function. It's purpose is to check user-submitted data against a database, and either set a session (success) or redirect the user to the login page (failure) for another login attempt.
<pre class="brush:php">
function login() {
	$this->set('error', false);
	if ($this->data) {
		// check submitted email address against database
		$results = $this->User->findByEmail($this->data['User']['email']);
		if ($results &#038;&#038; $results['User']['password'] == md5($this->data['User']['password'])) {
			// set "user" session equal to email address
			$this->Session->write('user', $this->data['User']['email']);
			// set "last_login" session equal to users last login time
			$this->Session->write('last_login', $results['User']['last_login']);
			$results['User']['last_login'] = date("Y-m-d H:i:s");
			// save last_login date
			$this->User->save($results);
			$this->redirect('/');
		} else {
			// login data is wrong, redirect to login page
			$this->Session->setFlash('Wrong username / password. Please try again.');
			$this->redirect('/users/login');
		}
	}
}
</pre>
<p>The commented code above should be enough to grasp an understanding of how <code>$this-&gt;Session</code> works. It's a simple CakePHP method of setting/deleting/reading sessions.</p>
<h2>Secure Your Gear</h2>
<p>Now that you've got the code to secure your Cake pages, you need to use it. Call the <code>checkSession</code> function to whenever you'd like to require a user to be logged in.</p>
<pre class="brush:php">
<?php
class ExampleController extends AppController  {
	var $name = "Example";
	var $helpers = array('Html');

	function index() {
		<span class="highlight">// make sure we're logged in</span>
		$this->checkSession();

		// when viewing /app/views/examples/index.thtml
		// the user will be redirected to the login page
		// unless he's logged in, in which case he'll
		// see the page as normal
	}

	function example() {
		// when viewing /app/views/examples/example.thtml
		// everyone (logged in or not) will see this page
	}
}	</code></pre>
<p>But what if you want to secure all the pages in a controller? Simple! Use Cake's <code>beforeFilter</code> function:</p>
<pre class="brush:php">
<?php
class ExampleController extends AppController  {
	var $name = "Example";
	var $helpers = array('Html');

	function beforeFilter() {
		$this->checkSession();
	}

	function index() {
		// when viewing /app/views/examples/index.thtml
		// the user will be redirected to the login page
		// unless he's logged in, in which case he'll
		// see the page as normal
	}

	function example() {
		// when viewing /app/views/examples/example.thtml
		// the user will be redirected to the login page
		// unless he's logged in, in which case he'll
		// see the page as normal
	}
}
</pre>
<h2>Download The Package</h2>
<p>Make sure you grab the complete package to see working examples of this article. A <code>.sql</code> file has been included for easy setup of the required MySQL <code>users</code> table.</p>
<p><a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/secure-cakephp-sessions-11082007.zip' title='Secure CakePHP via Sessions'>Download the 'Secure CakePHP via Sessions' package</a> and consider yourself cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/08/secure-cakephp-via-sessions-login-logout/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Multiple Image Uploads Into Single MySQL Table (CakePHP)</title>
		<link>http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/</link>
		<comments>http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/#comments</comments>
		<pubDate>Wed, 07 Nov 2007 03:00:11 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/</guid>
		<description><![CDATA[The impossible has been done &#8211; uploading multiple images in CakePHP. Find out how easy it is, and why it was never really impossible to begin with. There have been updates to this article. Please make sure you note any changes before commenting. This article assumes you use the CakePHP image upload component I covered [...]]]></description>
			<content:encoded><![CDATA[<p>The impossible has been done &#8211; uploading multiple images in CakePHP. Find out how easy it is, and why it was never really impossible to begin with.</p>
<p><span id="more-35"></span></p>
<blockquote><p>
There have been <a href="#updates">updates</a> to this article. Please make sure you note any changes before commenting.
</p></blockquote>
<blockquote><p>This article assumes you use the <a href="http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/">CakePHP image upload component</a> I covered a while back. If you&#8217;re not using it, you should be.</p></blockquote>
<p>The goal of this article is to explain how to upload multiple photos in CakePHP using a single MySQL table. The images will be uploaded into an <code>uploads</code> folder, while the image names will be stored in a single MySQL table.</p>
<h2>Pretext</h2>
<p>I&#8217;ll assume your upload form is placed in <code>/app/views/images/upload.thtml</code> and your images component sits at <code>/app/controllers/images_controller.php</code>. If you need an example of either file, <a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/multiple-uploads-11062007.zip' title='Multiple Image Uploads (CakePHP)'>download the complete package</a> and follow along.</p>
<h2>Configure Your View</h2>
<p>In order to upload a single image via CakePHP, our view <code>upload.thtml</code> would consist of a single upload field:</p>
<pre><code>&lt;ul&gt;
    &lt;li&gt;
        <span class="highlight">&lt;?php echo $form-&gt;labelTag('Image/images', 'Image:' );?&gt;
        &lt;?php echo $html-&gt;file('Image/filedata');?&gt;</span>
    &lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>But we want the ability to upload multiple images at once, so let&#8217;s adjust our view accordingly:</p>
<pre><code>&lt;ul&gt;
    &lt;li&gt;
        <span class="highlight">&lt;?php echo $form-&gt;labelTag('Image/images', 'Image 1:' );?&gt;
        &lt;?php echo $html-&gt;file('Image/filedata1');?&gt;</span>
    &lt;/li&gt;
    &lt;li&gt;
        <span class="highlight">&lt;?php echo $form-&gt;labelTag('Image/images', 'Image 2:' );?&gt;
        &lt;?php echo $html-&gt;file('Image/filedata2');?&gt;</span>
    &lt;/li&gt;
    &lt;li&gt;
        <span class="highlight">&lt;?php echo $form-&gt;labelTag('Image/images', 'Image 3:' );?&gt;
        &lt;?php echo $html-&gt;file('Image/filedata3');?&gt;</span>
    &lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>All we&#8217;ve done is added more upload fields to our form. Of course we also named them accordingly: <code>filedata</code> followed by a number.</p>
<h2>Dressing Up The Controller</h2>
<p>Next we need to modify our controller (<code>/app/controllers/images_controller.php</code>) to handle the multiple files.</p>
<p>The tricky part comes when we need to store each file name in a single MySQL table called <code>images</code>. We&#8217;ll do this by creating an <code>array</code> of each file name, <code>implode</code> the array, then store the resulting string in MySQL. Sounds confusing, but it&#8217;s not. Read on.</p>
<pre><code>// set the upload destination folder
<span class="highlight">$destination = realpath('../../app/webroot/img/uploads/') . '/';</span>

// number of file form fields
<span class="highlight">$num = 3;</span>

/* take care of image uploads */

<span class="highlight">$array = "";</span>
// loop through each image field
<span class="highlight">for ($i=1; $i&lt;=$num; $i++)
   {
	$file = $this-&gt;data['Image']['filedata'.$i];
	if (!$file['name']) continue;</span>

	// upload image
	<span class="highlight">$result = $this-&gt;Upload-&gt;upload($file, $destination, null, array('type' =&gt; 'resizecrop', 'size' =&gt; array('100', '100'), 'output' =&gt; 'jpg'));</span>

	// error check
	<span class="highlight">if($result || !empty($this-&gt;Upload-&gt;errors)) {</span>

		// there's been an error, delete any uploaded images
		<span class="highlight">if(is_array($array) &amp;&amp; count($array) &gt;= 1) {
			foreach($array as $file) {</span> // delete each file
				<span class="highlight">unlink($destination.$file);
			}
		}</span>

           // display error
		<span class="highlight">$errors = $this-&gt;Upload-&gt;errors;</span>

		// piece together errors
		<span class="highlight">if(is_array($errors)){ $errors = implode("&lt;br /&gt;",$errors); }

		$this-&gt;Session-&gt;setFlash($errors);
		$this-&gt;redirect('/images/upload');
		exit();
	}</span>

	// add the image filename to the $array
	<span class="highlight">if(!is_array($array)){
		$array = array();
		array_push($array, $this-&gt;Upload-&gt;result);
	} else {
		array_push($array, $this-&gt;Upload-&gt;result);
	}

}</span></code></pre>
<p>The <code>for</code> loop above makes sure each form field is properly addressed. The script attempts to upload the data and displays a proper error message if it fails.</p>
<p>The above <code>images_controller.php</code> example is only partially complete. For a complete example, download the complete package below.</p>
<h2>Download The Package</h2>
<p>You can download a working CakePHP example of the files described in this article. The MySQL file needed to create the example <code>images</code> table is included.<br />
<a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/multiple-uploads-11062007.zip' title='Multiple Image Uploads (CakePHP)'>Download the complete &#8216;Multiple Image Uploads (CakePHP)&#8217; package here.</a></p>
<p>Let me know if I&#8217;ve missed anything, or if you need help.</p>
<p><a name="updates"></a></p>
<h2>Updates</h2>
<p><strong>Nov 8th, 2007</strong>: The uploads component (<code>upload.php</code>) has been fixed to correctly handle filetypes.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>3 Hidden CakePHP Functions You Can&#8217;t Live Without, Flay</title>
		<link>http://labs.iamkoa.net/2007/11/01/3-hidden-cakephp-functions-you-cant-live-without-flay/</link>
		<comments>http://labs.iamkoa.net/2007/11/01/3-hidden-cakephp-functions-you-cant-live-without-flay/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 22:18:32 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/11/01/3-hidden-cakephp-functions-you-cant-live-without-flay/</guid>
		<description><![CDATA[CakePHP&#8217;s fattie /cake/lib folder holds many hidden treasures, that although documented in Cake&#8217;s API, lacks examples of use and simple noobie terms like &#8220;howto&#8221;. I&#8217;m here to help, so settle down. Note: In my examples I use each of the functions in a view file (/app/views/), rather than a controller (/app/controllers/) file. I suppose either [...]]]></description>
			<content:encoded><![CDATA[<p>CakePHP&#8217;s fattie <code>/cake/lib</code> folder holds many hidden treasures, that although documented in <a href="http://api.cakephp.org/search.php?query=flay">Cake&#8217;s API</a>, lacks examples of use and simple noobie terms like &#8220;howto&#8221;. I&#8217;m here to help, so settle down.</p>
<p><span id="more-31"></span></p>
<p><strong>Note:</strong> In my examples I use each of the functions in a view file (<code>/app/views/</code>), rather than a controller (<code>/app/controllers/</code>) file. I suppose either one would work, though for these functions, it would probably make more sense to use them in a view.</p>
<h2>Including the Flay class</h2>
<p>In order to use the any one of the following functions in your views, you first need to make sure you include the <code>Flay</code> class. To do so, place the following at the top of the view you wish to use:</p>
<pre><code>&lt;?php
     uses('Flay');
     $flay = new Flay();
?&gt;</code></pre>
<h2>1. fragment</h2>
<p><em>Return a fragment of a text, up to <code>$length</code> characters long, with an ellipsis after it.</em></p>
<pre><code><span class="highlight">Code:</span>
	$text = "&lt;p&gt;This is some example text.&lt;/p&gt;";
	$text = <span class="highlight">$flay-&gt;fragment($text,7);</span>
	echo $text;</code></pre>
<pre><code><span class="highlight">Html Output:</span>
	&lt;p&gt;This is...</code></pre>
<p>The text is fragmented to closely match a character count of <code>7</code> without breaking up any words.</p>
<h2>2. toHtml</h2>
<p><em>Returns given text translated to HTML using the <code>Flay</code> syntax.</em></p>
<pre><code><span class="highlight">Code:</span>
	$text = "&lt;p&gt;This is some example text.&lt;/p&gt;";
	$text = <span class="highlight">$flay-&gt;toHtml($text,null,true);</span>
	echo $text;</code></pre>
<pre><code><span class="highlight">Html Output:</span>
	&lt;p&gt;&lt;p&gt;This is some example text.&lt;/p&gt;&lt;/p&gt;</code></pre>
<p>As you can see, the entire text field is surrounded in a <code>p</code> tag, and the HTML in the <code>$text</code> variable is used as actual HTML.</p>
<pre><code><span class="highlight">Code:</span>
	$text = "&lt;p&gt;This is some example text.&lt;/p&gt;";
	$text = <span class="highlight">$flay-&gt;toHtml($text,null,false);</span>
	echo $text;</code></pre>
<pre><code><span class="highlight">Html Output:</span>
	&lt;p&gt;&amp;lt;p&amp;gt;This is some example text.&amp;lt;/p&amp;gt;&lt;/p&gt;</code></pre>
<p>The entire text field is surrounded in a <code>p</code> tag, but this time the HTML in the <code>$text</code> variable is converted to HTML entities.</p>
<h2>3. colorMark</h2>
<p><em>Returns string with <code>EM</code> elements with color classes added.</em></p>
<pre><code><span class="highlight">Code:</span>
	$text = "&lt;p&gt;This is some example text.&lt;/p&gt;";
	$text = <span class="highlight">$flay-&gt;colorMark(array('some','text'), $text);</span>
	echo $text;</code></pre>
<pre><code><span class="highlight">Html Output:</span>
	&lt;p&gt;This is &lt;em class="yl"&gt;some&lt;/em&gt; example &lt;em class="gr"&gt;text&lt;/em&gt;.&lt;/p&gt;</code></pre>
<p>According to the above, all words equaling <code>some</code> will have an <code>EM</code> element with the class &#8220;yl&#8221;. Where as all words equaling <code>text</code> will have an <code>EM</code> element with the class &#8220;gr&#8221;.</p>
<p>Let me know if I&#8217;ve missed anything.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/11/01/3-hidden-cakephp-functions-you-cant-live-without-flay/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Easy Dynamic Database Connection in CakePHP</title>
		<link>http://labs.iamkoa.net/2007/10/29/easy-dynamic-database-connection-in-cakephp/</link>
		<comments>http://labs.iamkoa.net/2007/10/29/easy-dynamic-database-connection-in-cakephp/#comments</comments>
		<pubDate>Mon, 29 Oct 2007 20:08:04 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/10/29/easy-dynamic-database-connection-in-cakephp/</guid>
		<description><![CDATA[If you&#8217;re like me, you&#8217;re strikingly handsome you create Cake applications on your computer, then upload them for testing (and usage) to a server. It&#8217;s annoying to have to change the /app/config/database.php file for each new testing environment, especially if the same Cake application is being used on multiple machines. Thankfully there&#8217;s a really simple [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me, <strike>you&#8217;re strikingly handsome</strike> you create Cake applications on your computer, then upload them for testing (and usage) to a server. It&#8217;s annoying to have to change the <code>/app/config/database.php</code> file for each new testing environment, especially if the same Cake application is being used on multiple machines.</p>
<p>Thankfully there&#8217;s a <em>really</em> simple way around this crap.</p>
<p><span id="more-27"></span></p>
<p>Simply replace Cake&#8217;s <code>/app/config/database.php</code> file with the following:</p>
<pre><code>&lt;?php
class DATABASE_CONFIG {
	<span class="highlight">#localhost
	var $local = array('driver' =&gt; 'mysql',
		'connect' =&gt; 'mysql_connect',
		'host' =&gt; 'localhost',
		'login' =&gt; 'root',
		'password' =&gt; '',
		'database' =&gt; 'local',
		'prefix' =&gt; '');

	#dev server
	var $dev = array('driver' =&gt; 'mysql',
		'connect' =&gt; 'mysql_connect',
		'host' =&gt; 'mysql.dev.com',
		'login' =&gt; 'dev',
		'password' =&gt; 'password',
		'database' =&gt; 'dev',
		'prefix' =&gt; '');

	#live server
	var $live = array('driver' =&gt; 'mysql',
		'connect' =&gt; 'mysql_connect',
		'host' =&gt; 'mysql.live.com',
		'login' =&gt; 'live',
		'password' =&gt; 'password',
		'database' =&gt; 'live',
		'prefix' =&gt; '');</span>

	#switch between configs
	var $default = array();
	var $test = array();
	function __construct() {

		#wildcard the subdomains
		$host_r = explode('.', $_SERVER['SERVER_NAME']);
		if(count($host_r)&gt;2) while(count($host_r)&gt;2)array_shift($host_r);
		$mainhost = implode('.', $host_r);

		#switch between servers
		switch(strtolower($mainhost)) {
			<span class="highlight">case 'localhost':</span>
				$this-&gt;default = $this-&gt;local;
				break;
			<span class="highlight">case 'dev.com':</span>
				$this-&gt;default = $this-&gt;dev;
				break;
			<span class="highlight">case 'live.com':</span>
				$this-&gt;default = $this-&gt;live;
				break;
			default:
				$this-&gt;default = $this-&gt;local;
		}
	}

	#php 4 compatibility
	function DATABASE_CONFIG() {
		$this-&gt;__construct();
	}
}
?&gt;</code></pre>
<p>The highlighted code beginning with <code>var $local = array('driver' =&gt; 'mysql',</code> corresponds with the <code>case 'localhost':</code> at the bottom.</p>
<h2>A Quick Example</h2>
<p>So let&#8217;s say you have a Cake application running locally on <code>localhost</code> and remotely at <code>mydomain.com</code>, you&#8217;re <code>database.php</code> file would look something like this:</p>
<pre><code>&lt;?php
class DATABASE_CONFIG {
	<span class="highlight">#localhost
	var $local = array('driver' =&gt; 'mysql',
		'connect' =&gt; 'mysql_connect',
		'host' =&gt; 'localhost',
		'login' =&gt; 'root',
		'password' =&gt; '',
		'database' =&gt; 'local',
		'prefix' =&gt; '');

	#live server
	var $live = array('driver' =&gt; 'mysql',
		'connect' =&gt; 'mysql_connect',
		'host' =&gt; 'mysql.mydomain.com',
		'login' =&gt; 'live',
		'password' =&gt; 'password',
		'database' =&gt; 'live',
		'prefix' =&gt; '');</span>

	#switch between configs
	var $default = array();
	var $test = array();
	function __construct() {

		#wildcard the subdomains
		$host_r = explode('.', $_SERVER['SERVER_NAME']);
		if(count($host_r)&gt;2) while(count($host_r)&gt;2)array_shift($host_r);
		$mainhost = implode('.', $host_r);

		#switch between servers
		switch(strtolower($mainhost)) {
			<span class="highlight">case 'localhost':</span>
				$this-&gt;default = $this-&gt;local;
				break;
			<span class="highlight">case 'mydomain.com':</span>
				$this-&gt;default = $this-&gt;live;
				break;
			default:
				$this-&gt;default = $this-&gt;local;
		}
	}

	#php 4 compatibility
	function DATABASE_CONFIG() {
		$this-&gt;__construct();
	}
}
?&gt;</code></pre>
<p>Now when you upload your CakePHP application from your <code>localhost</code> directory to <code>mydomain.com</code>, you won&#8217;t have to fiddle with the <code>database.php</code> file. It&#8217;ll recognize that Cake&#8217;s running on <code>mydomain.com</code> and will adjust the MySQL connection accordingly.</p>
<p>Rock on roll.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/10/29/easy-dynamic-database-connection-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
