<?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>Wed, 03 Mar 2010 03:29:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0-alpha</generator>
		<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>
<blockquote><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></blockquote>
<blockquote><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></blockquote>
<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>
<blockquote><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></blockquote>
<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>
<blockquote><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></blockquote>
<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><code>&lt;?php
   if ($session-&gt;check('Message.flash')): $session-&gt;flash(); endif; <span class="highlight">// this line displays our flash messages</span>
   echo $content_for_layout;
?&gt;</code></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><code>function add() {
...
   if ($this-&gt;News-&gt;save($this-&gt;data)) {
      $this-&gt;Session-&gt;setFlash('Your post has been saved.');
      $this-&gt;redirect('/news/index');
      <span class="highlight">//$this-&gt;flash('The News has been saved', '/news/index'); // this was the old way of doing things... yuck</span>
   }
}</code></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><code>&lt;div id="flashMessage" class="message"&gt;Your post has been saved.&lt;/div&gt;</code></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:
&#60;?php echo $html-&#62;formTag('/' . $params['url']['url'], 'post', array('enctype' =&#62; [...]]]></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><code><span class="highlight">If you're finding that executing this:</span>
&lt;?php echo $html-&gt;formTag('/' . $params['url']['url'], 'post', array('enctype' =&gt; 'multipart/form-data')); ?&gt;
	&lt;?php echo $html-&gt;input('Test/title'); ?&gt;
	&lt;?php echo $html-&gt;file('Test/file'); ?&gt;
	&lt;?php echo $html-&gt;submit('Save'); ?&gt;
&lt;/form&gt;

<span class="highlight">... returns something like this:</span>
$this-&gt;data:Array
(
    [Test] =&gt; Array
        (
            [title] =&gt; Foo
            [file] =&gt; 4tmp/phpHGSjDA
        )
)

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

... then you must be as annoyed as I am.</code></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><code>#/app/webroot/.htaccess
php_flag register_globals off</code></pre>
<h2>Solution Two</h2>
<p>Manually write your HTML form fields without using an input array:</p>
<pre><code>-- do this --
&lt;input type="file" name="file" /&gt;
-- not this --
&lt;?php echo $html-&gt;file('Test/file'); ?&gt; // will output: &lt;input type="file" name="data[Test][test]" /&gt;</code></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><code>&lt;?php
require("inc/class.sendmail.php");

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

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

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

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

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

    $result = $mail-&gt;send();

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

echo "Message was sent successfully";
?&gt;

&lt;form method="post" action="&lt;?=$_SERVER['PHP_SELF']?&gt;"&gt;
    &lt;input type="text" name="from_email" value="people@info.com" /&gt;&lt;br /&gt;
    &lt;input type="text" name="from_name" value="People" /&gt;&lt;br /&gt;
    &lt;input type="text" name="subject" value="This is a subject" /&gt;
    &lt;input type="text" name="body" value="Email body goes here." /&gt;
    &lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;</code></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><code>...
$mail = new SendMail;

if($_POST) {

    $mail = new SendMail;

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

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

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

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

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

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

    $mail-&gt;Mailer = 'mail';

    $result = $mail-&gt;send();

    if (!$result){
        if(!empty($mail-&gt;errors)) {
            <span class="highlight">$mail-&gt;displayErrors($mail-&gt;errors,'ol');</span>
        }
    exit();
    }
}
...</code></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 Cake is super [...]]]></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><code><span class="highlight"># not found #</span>
    error404.thtml

<span class="highlight"># missing files #</span>
    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

<span class="highlight"># private &amp; scaffold related errors #</span>
    private_action.thtml
    scaffold_error.thtml</code></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><code>/app/views/errors/donation_error.thtml</code></pre>
<p>Next, in order to call your custom error, place the following in your controller of choice:</p>
<pre><code>$this-&gt;viewPath = 'errors';
$this-&gt;render('donation_error');</code></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 application. [...]]]></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><code><span class="highlight">1:</span> /app/app_controller.php
<span class="highlight">2:</span> /app/controllers/users_controller.php
<span class="highlight">3:</span> /app/views/users/
      -&gt; add.thtml, edit.thtml, index.thtml, login.thtml, logout.thtml</code></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><code>function checkSession(){

	<span class="highlight">// fill $username with session data</span>
	$username = $this-&gt;Session-&gt;read('user');

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

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

		<span class="highlight">// otherwise set $user variable as users email address</span>
		$this-&gt;set('user', $results['User']['email']);
	}
}</code></pre>
<p>The commenting throughout the above code is pretty self-explanatory &#8211; the session data is checked and validated. Score one for us.</p>
<h2>2. The users_controller</h2>
<p>Of the six functions in <code>users_controller.php</code>, we&#8217;ll cover the <code>login</code> function. It&#8217;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.</p>
<pre><code>function login() {
	$this-&gt;set('error', false);
	if ($this-&gt;data) {
		<span class="highlight">// check submitted email address against database</span>
		$results = $this-&gt;User-&gt;findByEmail($this-&gt;data['User']['email']);
		if ($results &amp;&amp; $results['User']['password'] == md5($this-&gt;data['User']['password'])) {
			<span class="highlight">// set "user" session equal to email address</span>
			$this-&gt;Session-&gt;write('user', $this-&gt;data['User']['email']);
			<span class="highlight">// set "last_login" session equal to users last login time</span>
			$this-&gt;Session-&gt;write('last_login', $results['User']['last_login']);
			$results['User']['last_login'] = date("Y-m-d H:i:s");
			<span class="highlight">// save last_login date</span>
			$this-&gt;User-&gt;save($results);
			$this-&gt;redirect('/');
		} else {
			<span class="highlight">// login data is wrong, redirect to login page</span>
			$this-&gt;Session-&gt;setFlash('Wrong username / password. Please try again.');
			$this-&gt;redirect('/users/login');
		}
	}
}</code></pre>
<p>The commented code above should be enough to grasp an understanding of how <code>$this-&gt;Session</code> works. It&#8217;s a simple CakePHP method of setting/deleting/reading sessions.</p>
<h2>Secure Your Gear</h2>
<p>Now that you&#8217;ve got the code to secure your Cake pages, you need to use it. Call the <code>checkSession</code> function to whenever you&#8217;d like to require a user to be logged in.</p>
<pre><code>&lt;?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-&gt;checkSession();

		<span class="highlight">// 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</span>
	}

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

	function beforeFilter() {
		$this-&gt;checkSession();
	}

	function index() {
		<span class="highlight">// 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</span>
	}

	function example() {
		<span class="highlight">// 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</span>
	}
}	</code></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 &#8216;Secure CakePHP via Sessions&#8217; 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 a while [...]]]></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 one [...]]]></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 way [...]]]></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>
		<item>
		<title>Image Upload Component (CakePHP)</title>
		<link>http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/</link>
		<comments>http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 23:40:17 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/</guid>
		<description><![CDATA[Thanks to some fine work by Ben Borowski, uploading images in CakePHP is easy as kicking your kids. I&#8217;ve used this component for quite a few projects. It&#8217;s safe to say that it rules.
Learn how to use it, love it, code it.


There have been updates to this article. Please make sure you note any changes [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to some fine work by <a href="http://www.typeoneerror.com/">Ben Borowski</a>, uploading images in CakePHP is easy as kicking your kids. I&#8217;ve used this component for quite a few projects. It&#8217;s safe to say that it rules.</p>
<p>Learn how to use it, love it, code it.</p>
<p><span id="more-19"></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 covers uploading one image at a time. To learn how to upload multiple images at once, see the <a href="http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/">Multiple Image Uploads Into Single MySQL Table (CakePHP) </a> article.
</p></blockquote>
<h2>Dropping The Knowledge (pretext)</h2>
<p>Using the upload component is super simple and allows for optional input to customize the resulting image.</p>
<pre><code>/*
  * upload
  * - handle uploads of any type
  *		@ file - a file (file to upload) $_FILES[FILE_NAME]
  *		@ path - string (where to upload to)
  *		@ name  [optional] - override the default file name
  *		@ rules [optional] - how to handle file types
  *			- rules['type'] = string ('resize','resizemin','resizecrop','crop')
  *			- rules['size'] = array (x, y) or single number
  *			- rules['output'] = string ('gif','png','jpg')
  *			- rules['quality'] = integer (quality of output image)
  *		@ allowed [optional] - allowed filetypes array
  *			- default: array ('jpg','jpeg','gif','png')
  *	ex:
  * 	<span class="highlight">$result = $this-&gt;Upload-&gt;upload($file, 'uploads', null, array('type' =&gt; 'resizecrop', 'size' =&gt; array('400', '300'), 'output' =&gt; 'jpg'));</span>
  *
  */</code></pre>
<p>Each value should be self explanatory. If you need further explanation, post a comment and we&#8217;ll go through it together.</p>
<h2>1. Download Upload Component &#038; Create Upload Dir</h2>
<p>Download the following zip file, extract it, and place <code>upload.php</code> in your <code>/app/controllers/components/</code> directory.<br />
<a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/uploads-component-11062007.zip' title='CakePHP Image Upload Component'>Download the complete image upload component here.</a></p>
<p>Now create an &#8216;uploads&#8217; directory in <code>/app/webroot/img/uploads/</code> and make sure to give the directory 777 (writable by all) permissions.</p>
<h2>2. Prepare Your Controller</h2>
<p>Next we&#8217;ll slap the necessary code in place to handle a single image upload. (To upload multiple images at once, <a href="http://labs.iamkoa.net/2007/11/06/multiple-image-uploads-into-single-mysql-table-cakephp/">check out this article</a>.)</p>
<pre><code>class ImagesController extends AppController {

	var $name = 'Images';
	var $helpers = array('Html', 'Form');
	<span class="highlight">var $components = array('Upload');</span>

function upload() {

	if (empty($this-&gt;data)) {
		$this-&gt;render();
	} else {
		$this-&gt;cleanUpFields();

		// set the upload destination folder
		<span class="highlight">$destination = realpath('../../app/webroot/img/uploads/') . '/';</span>

		// grab the file
		<span class="highlight">$file = $this-&gt;data['Image']['filedata'];</span>

		// upload the image using the upload component
		<span class="highlight">$result = $this-&gt;Upload-&gt;upload($file, $destination, null, array('type' =&gt; 'resizecrop', 'size' =&gt; array('400', '300'), 'output' =&gt; 'jpg'));</span>
		<span class="highlight">
		if (!$result){
			$this-&gt;data['Image']['filedata'] = $this-&gt;Upload-&gt;result;
		} else {
			// display error
			$errors = $this-&gt;Upload-&gt;errors;

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

			$this-&gt;Session-&gt;setFlash($errors);
			$this-&gt;redirect('/images/upload');
			exit();
		}
		if ($this-&gt;Image-&gt;save($this-&gt;data)) {
			$this-&gt;Session-&gt;setFlash('Image has been added.');
			$this-&gt;redirect('/images/index');
		} else {
			$this-&gt;Session-&gt;setFlash('Please correct errors below.');
			unlink($destination.$this-&gt;Upload-&gt;result);
		}</span>
	}
}</code></pre>
<p><small>* Highlighted code represents things relating to the upload class. The rest is default Cake code.</small></p>
<h2>3. Create Your View</h2>
<p>In the appropriate view controller (in this case, <code>/app/views/images/upload.thtml</code>), use the following code to insert a file upload field:</p>
<pre><code>&lt;?php echo $form-&gt;labelTag('Image/images', 'Image:' );?&gt;
&lt;?php echo $html-&gt;file('Image/filedata');?&gt;</code></pre>
<p>This will create the following HTML:</p>
<pre><code>&lt;label for="Image"&gt;Image:&lt;/label&gt;
&lt;input type="file" name="data[Image][filedata]" id="ImageFiledata" /&gt;	</code></pre>
<h2>Complete The Package</h2>
<p>To make things easy, I&#8217;ve included all the above files in a single download. <a href='http://labs.iamkoa.net/wp-content/uploads/2007/11/uploads-component-11062007.zip' title='CakePHP Image Upload Component'>Get the complete CakePHP image upload package here.</a></p>
<p>If you have issues, comment. I&#8217;m happy to help.<br />
<a name="updates"></a></p>
<h2>Updates</h2>
<p><strong>Nov 8th, 2007</strong>: The uploads component (<code>upload.php</code>) has been modified to correctly handle filetypes.</p>
<p><strong>Nov 6th, 2007</strong>: Errors are now gracefully displayed. An <code>allowed</code> variable has been added to the upload component regarding allowed filetypes. A <code>.sql</code> file has been included for easy setup of the <code>images</code> MySQL table.</p>
<p><strong>Jan 16th, 2008</strong>: <del datetime="2008-01-24T17:15:14+00:00">Thanks to <em>Ruben</em>, a small <code>$fileType</code> glitch was discovered&#8230; and fixed. Thanks Ruben!</del> <strong>Jeff</strong> correctly pointed out that Ruben&#8217;s &#8220;fix&#8221; was actually an unneeded glitch. The component has been reverted to working form.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Create Downloadable iCal Events via Cake</title>
		<link>http://labs.iamkoa.net/2007/09/07/create-downloadable-ical-events-via-cake/</link>
		<comments>http://labs.iamkoa.net/2007/09/07/create-downloadable-ical-events-via-cake/#comments</comments>
		<pubDate>Sat, 08 Sep 2007 02:31:33 +0000</pubDate>
		<dc:creator>Koa</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[iCal]]></category>

		<guid isPermaLink="false">http://labs.iamkoa.net/2007/09/07/create-downloadable-ical-events-via-cake/</guid>
		<description><![CDATA[iCal just plain rules. Though it&#8217;s not a super-detailed, completely all-knowing calendar application, it&#8217;s the most user friendly offline event tracker to date. (The best online calendar is Google Calendar, hands down.)
Allowing your loyal, web-savvy fans to download iCal files (enabling them to instantly add events to their iCal program), or subscribing to iCal feeds [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.apple.com/macosx/features/ical/" target="_blank">iCal</a> just plain rules. Though it&#8217;s not a super-detailed, completely all-knowing calendar application, it&#8217;s the most user friendly offline event tracker to date. (The best online calendar is <a href="http://calendar.google.com" target="_blank">Google Calendar</a>, hands down.)</p>
<p>Allowing your loyal, web-savvy fans to download iCal files (enabling them to instantly add events to their iCal program), or subscribing to iCal feeds (allowing their iCal program to update the users calendar whenever they chose &#8211; much like RSS) can bring a smile to even the pickiest of web surfers.</p>
<p><span id="more-7"></span><br />
Here&#8217;s the guts of a typical iCal file we&#8217;ll call <code>theevent.vcs</code>:
<pre><code>BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DURATION:PT1H
SEQUENCE:4
URL;VALUE=URI:http://www.thehotfreaks.com/
DTSTART;TZID=US/Pacific:20070914T210000
DTEND;TZID=US/Pacific:20070914T210000
SUMMARY: Art
DESCRIPTION: Crazy Sexy Rainbow
END:VEVENT
END:VCALENDAR</code></pre>
<p>I&#8217;ll let you figure out what every variable means. For now, let&#8217;s cut the crap and dive into the good stuff.</p>
<p><strong>CREATE DOWNLOADABLE ICAL EVENTS VIA CAKEPHP WITH THREE FILES:</strong></p>
<p>To create a file based on a particular event, open the CakePHP controller associated with your needs. Since I&#8217;m creating an iCal file based off an event, my controller is called <code>events_controller.php</code> &#8211; your controller might vary.</p>
<p>In the controller, create a function called <code>ical</code>, like so:
<pre><code>function ical($id = null) {
   // use ical layout
   <span class="highlight">$this-&gt;layout = "ical";</span>

   if (!$id || !$this-&gt;Event-&gt;read(null,$id)) {
      $this-&gt;Session-&gt;setFlash('Invalid id for Event.');
      $this-&gt;redirect('/events/index');
      exit();
   }

   $this-&gt;set('theEvent', $this-&gt;Event-&gt;read(null,$id));
}</code></pre>
<p>Then create a new layout (in your <code>views/layouts/</code> folder) called <code>ical.thtml</code>. Place the following junk inside it:
<pre><code>&lt;?php
   $Filename = "TheEvent.vcs";
   header("Content-Type: text/x-vCalendar");
   header("Content-Disposition: inline; filename=$Filename");
   echo $content_for_layout;
?&gt;</code></pre>
<p>The <code>$Filename</code> variable above can be changed to whatever you like as long as it maintains a <code>.vcs</code> ending.</p>
<p>Then in your <code>views/events/</code> folder, add the <code>ical.thtml</code> view:
<pre><code>BEGIN:VCALENDAR
VERSION:1.0
BEGIN:VEVENT
DURATION:PT1H
SEQUENCE:4
URL;VALUE=URI:&lt; ? php echo $theEvent['Event']['website']. "\n"; ?&gt;
DTSTART;TZID=US/Pacific:&lt; ? php echo date("Ymd\THi00", strtotime($theEvent['Event']['event_date']))."\n"; ?&gt;
DTEND;TZID=US/Pacific:&lt; ? php echo date("Ymd\THi00", strtotime($theEvent['Event']['event_date']))."\n"; ?&gt;
SUMMARY:&lt; ? php echo $theEvent['Event']['summary']."\n"; ?&gt;
DESCRIPTION:&lt; ? php echo $theEvent['Event']['description']."\n" ?&gt;
END:VEVENT
END:VCALENDAR</code></pre>
<p>DONE. Now surf to <code>/events/ical/[id-of-event]/</code> and you should have a magical iCal file begin downloading. Life is good.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.iamkoa.net/2007/09/07/create-downloadable-ical-events-via-cake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
