<?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>JonnyReeves.co.uk &#187; CakePHP</title>
	<atom:link href="http://www.jonnyreeves.co.uk/category/cakephp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonnyreeves.co.uk</link>
	<description>Actionscript, Flash, PHP and stuff</description>
	<lastBuildDate>Mon, 19 Jul 2010 15:36:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>My Development Environment.</title>
		<link>http://www.jonnyreeves.co.uk/2008/11/my-development-environment/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/11/my-development-environment/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 20:49:00 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[fdt]]></category>
		<category><![CDATA[pdt]]></category>
		<category><![CDATA[sendmail]]></category>
		<category><![CDATA[vista]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=63</guid>
		<description><![CDATA[I spend most of my development time sat in Eclipse, I find it funny (or maybe slightly alarming) that only four moths ago I had never ventured near an Integrated Development Environment and spent a lot of time toiling away with a Crimson Editor.  All I can say is that if you haven&#8217;t tried getting [...]]]></description>
			<content:encoded><![CDATA[<p>I spend most of my development time sat in Eclipse, I find it funny (or maybe slightly alarming) that only four moths ago I had never ventured near an Integrated Development Environment and spent a lot of time toiling away with a Crimson Editor.  All I can say is that if you haven&#8217;t tried getting to grips with Eclipse, then now is the time.</p>
<p>As my work is split between programming in PHP and ActionScript, I use Flex Builder as the base for my Eclipse Setup (Flex Builder 3 is built ontop of the Eclipse 3.3 platform).  Flex Builder comes with an ActionScript parser and debugger.  The parser is not as good as <a href="http://fdt.powerflasher.com/">FDT</a> (which I use at work), but is a damn sight cheaper which is always welcome.   Eclipse is incredibly modular and allows you to enhance it&#8217;s basic functionality buy installing components which provide additional perspective and functionality.   I make use of the following:</p>
<ul>
<li><a href="http://wiki.eclipse.org/PDT/Installation#Eclipse_3.3_.2F_Europa_.2F_PDT_1.0">PDT</a> 1.x &#8211; PHP Development Tool, includes code completion and syntax highlighting.</li>
<li><a href="http://subclipse.tigris.org/">Subclipse</a> 1.4 &#8211; SVN Integration for eclipse, essentail for checking in my own code and 3rd party code which I make sure of (Such as the CakePHP Core).  Again, if you&#8217;re not using SVN then you really should!</li>
</ul>
<p>I keep my PHP and ActionScript development seperate by using two Workspaces and swtiching between the two (I do a similar thing at work by having two workspaces for our ActionScript 2 and ActionScript 3 projects at <a href="http://mindcandy.com/">Mindcandy</a>).  To avoid any potential UAC problems in Vista, I make sure that my Workspace is located in my User folder &#8211; this also helps with backups keeping everything in one place.</p>
<p>To back this up, I run a straight forward Apache 2.2, MySQL 5 and PHP 5.2 stack ontop of Windows Vista x64 (Even with UAC turned on!).  I had no problems installing the stack, I just made sure that everything was installed inside my User folder.  (ie: C:\Users\Jonny\Webroot\Apache2-2, etc).  I configure individual vhosts for the projects I work on and point the webroot at my Eclipse Workspace (ie: C:\Users\Jonny\Projects\PHP\Project_Name). This allows me to simulate a webdeploy environment which makes deploying sites to a web server easier.  To complete my local dev setup I setup <a href="http://bfish.xaedalus.net/?p=163">fake sendmail</a> which allows the mail() funcitons inside PHP 5 to be relayed to a remote mail server (very handy! &#8212; again, I was suprised that this worked without a hitch on Vista x64).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/11/my-development-environment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Validating Image Uploads in CakePHP</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/validating-image-uploads-in-cakephp/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/validating-image-uploads-in-cakephp/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 21:17:46 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[libgd]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=53</guid>
		<description><![CDATA[Following on from my article on CakePHP &#8211; Uploaded File Validation in Models, today&#8217;s snippet will show you how to use Cake&#8217;s validation rules to reject invalid images, or images which do not conform to a specified mime-type.  This code relies on the fact that you have LibGD installed on your webserver.

&#60;?php
Class Image extends [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from my article on <a href="http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/">CakePHP &#8211; Uploaded File Validation in Models</a>, today&#8217;s snippet will show you how to use Cake&#8217;s validation rules to reject invalid images, or images which do not conform to a specified <a href="http://en.wikipedia.org/wiki/Internet_media_type">mime-type</a>.  This code relies on the fact that you have <a href="http://www.php.net/manual/en/book.image.php">LibGD</a> installed on your webserver.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> Image <span class="kw2">extends</span> AppModel<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Image&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$validate</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;uploaded_image&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Ensure file uploaded OK.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;valid_upload&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;validateUploadedfile&#8217;</span>, <span class="kw2">false</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;An error occured whilst uploading your image, please try again&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check image is valid / of allowed mime-type</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;valid_image&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;isValidImageFile&#8217;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;The file you have uploaded is not a valid or is unsupported, please try again&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Custom validation rule for uploaded files.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Array $data CakePHP File info.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Boolean $required Is this field required?<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@return Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> validateUploadedFile<span class="br0">&#40;</span><span class="re0">$data</span>, <span class="re0">$required</span> = <span class="kw2">false</span><span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Remove first level of Array ($data['Image']['size'] becomes $data['size'])</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$upload_info</span> = <a href="http://www.php.net/array_shift"><span class="kw3">array_shift</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// No file uploaded.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$required</span> &amp;&amp; <span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8217;size&#8217;</span><span class="br0">&#93;</span> == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check for Basic PHP file errors.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8216;error&#8217;</span><span class="br0">&#93;</span> !== <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Finally, use PHP’s own file validation method.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/is_uploaded_file"><span class="kw3">is_uploaded_file</span></a><span class="br0">&#40;</span><span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8216;tmp_name&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>
&nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp;* Use LibGD to determine if an uploaded file is a valid Image by<br />
&nbsp; &nbsp; &nbsp;* running it&#8217;s mime-type against a list of $valid_mime_types<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;*&nbsp; @param Array $data CakePHP File info<br />
&nbsp; &nbsp; &nbsp;*&nbsp; @return Boolean<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> isValidImageFile<span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Allow these image mime-types, all others will be rejected</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$valid_mime_types</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;image/jpeg&#8217;</span>, <span class="st0">&#8216;image/png&#8217;</span>, <span class="st0">&#8216;image/gif&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = <a href="http://www.php.net/array_shift"><span class="kw3">array_shift</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$filename</span> = <span class="re0">$data</span><span class="br0">&#91;</span><span class="st0">&#8216;tmp_name&#8217;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Catch I/O Errors.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/is_readable"><span class="kw3">is_readable</span></a><span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; failed to read input file: {$filename}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Retrieve the MimeType of Image, if none is returned, it&#8217;s invalid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="re0">$mime_type</span> = <span class="re0">$this</span>-&gt;<span class="me1">getImageMimeType</span><span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; Uploaded file does not have a mime-type&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check the MimeType against the array of valid ones specified above</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/in_array"><span class="kw3">in_array</span></a><span class="br0">&#40;</span><span class="re0">$mime_type</span>, <span class="re0">$valid_mime_types</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; Uploaded image has rejected Mime Type: {$mime_type}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="re0">$this</span>-&gt;__getImageHandleFromFile<span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="coMULTI">/** <br />
&nbsp; &nbsp; &nbsp;* Use LibGD to return an uploaded Image&#8217;s MimeType as a String, FALSE<br />
&nbsp; &nbsp; &nbsp;* on errors or if the file is not an image<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;*&nbsp; @param String $filename Absolute path to file on disc<br />
&nbsp; &nbsp; &nbsp;*&nbsp; @return String Image MimeType of $filename, false on failure<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">function</span> getImageMimeType<span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// If this error is thrown LibGD is not installed on your server.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/function_exists"><span class="kw3">function_exists</span></a><span class="br0">&#40;</span><span class="st0">&#8216;getimagesize&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; LibGD PHP Extension was not found, please refer to http://www.php.net/manual/en/book.image.php&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$result</span> = <a href="http://www.php.net/getimagesize"><span class="kw3">getimagesize</span></a><span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$result</span><span class="br0">&#91;</span><span class="st0">&#8216;mime&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$result</span><span class="br0">&#91;</span><span class="st0">&#8216;mime&#8217;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp;* Returns a LibGD Image Handle for a file specified by $filename<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;*&nbsp; @param String $filename Absolute path to image on disk<br />
&nbsp; &nbsp; &nbsp;*&nbsp; @return LibGD Image Handle on success, FALSE on failure.<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">function</span> __getImageHandleFromFile<span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/is_readable"><span class="kw3">is_readable</span></a><span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; failed to read input file: {$filename}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Retrieve the MimeType of Image, if none is returned, it&#8217;s invalid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="re0">$mime_type</span> = <span class="re0">$this</span>-&gt;<span class="me1">getImageMimeType</span><span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; failed to assertain MimeType of {$filename}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span><span class="re0">$mime_type</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;image/jpeg&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$handle</span> = @imagecreatefromjpeg<span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;image/gif&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$handle</span> = @imagecreatefromgif<span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;image/png&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$handle</span> = @imagecreatefrompng<span class="br0">&#40;</span><span class="re0">$filename</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">default</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; Didn&#8217;t know how to handle MimeType: {$mime_type}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$handle</span> = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$handle</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>As always, comments are welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/validating-image-uploads-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CakePHP &#8211; Activating User Account via Email</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/cakephp-activating-user-account-via-email/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/cakephp-activating-user-account-via-email/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 21:11:20 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[cakephp user activate email]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=42</guid>
		<description><![CDATA[Continuing on from my User Registration with the AuthComponent post I&#8217;m going to cover how to activate user account&#8217;s via email.  Before we get down to the code lets look at a simple use case first.
Activating User Accounts Via Email Use Case
Goal: To confirm that users are registering with a valid email address, force [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing on from my <a href="http://www.jonnyreeves.co.uk/2008/05/user-registration-with-cakephp-12-and-auth-component/">User Registration with the AuthComponent post</a> I&#8217;m going to cover how to activate user account&#8217;s via email.  Before we get down to the code lets look at a simple use case first.</p>
<p><strong>Activating User Accounts Via Email Use Case</strong><br />
<em>Goal</em>: To confirm that users are registering with a valid email address, force them to activate their account before they can log in.</p>
<ol>
<li>User registers for an account, all validations passes and $User->save() has been called</li>
<li>At this point we flag that the user&#8217;s account is pending activation.  An email gets sent to the email address the user registered with.  The email contains a unique activation link</li>
<li>The user recieves the activation email and clicks the activation link</li>
<li>The system (your website) handles the incoming link, checks that the activation link is correct (the hash matches) and marks the user&#8217;s account as &#8220;active&#8221; &#8211; the user can now log in!</li>
<ul>
<li><em>Alternative Path:</em> The activation link is rejected by the system (it&#8217;s invalid / wasn&#8217;t copied correctly) &#8211; we present some helpful information to the user.
	</ull>
</ol>
<p><strong>Time for Some Code!</strong><br />
Okay, let&#8217;s start simple &#8211; the basic User Table we created in the previous article needs to be expanded to include an &#8220;active&#8221; flag (boolean) to indicate if the user&#8217;s account has been activated yet:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="co1">&#8211; Table structure for table `users`</span><br />
<span class="kw1">CREATE TABLE</span> IF <span class="kw3">NOT</span> <span class="kw1">EXISTS</span> `users` <span class="br0">&#40;</span><br />
&nbsp; `id` <span class="kw2">INT</span><span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span> <span class="kw3">AUTO_INCREMENT</span>,<br />
&nbsp; `username` <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">20</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; `password` <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; `email` <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">255</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; `active` <span class="kw2">TINYINT</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span> <span class="kw3">DEFAULT</span> <span class="st0">&#8216;0&#8242;</span>,<br />
&nbsp; `created` <span class="kw2">DATETIME</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; `modified` <span class="kw2">DATETIME</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; <span class="kw1">PRIMARY KEY</span> &nbsp;<span class="br0">&#40;</span>`id`<span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=<span class="kw1">INNODB</span> &nbsp;<span class="kw3">DEFAULT</span> <span class="kw3">CHARSET</span>=latin1;<br />
&nbsp;</div>
<p>Okay, let&#8217;s go ahead and hook this into our Users Controller&#8217;s login() action to stop &#8220;un-activated&#8221; users from loging in (after all, that is the <b>primary goal</b> of performing this work).</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co1">// Note: not all logic is show!</span><br />
uses<span class="br0">&#40;</span>’sanitize’<span class="br0">&#41;</span>;<br />
<span class="kw2">class</span> UsersController <span class="kw2">extends</span> AppController<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = ‘Users’;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$components</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>‘Auth’<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> login<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check for incoming login request.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Use the AuthComponent&#8217;s login action</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">Auth</span>-&gt;<span class="me1">login</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Retrieve user data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$results</span> = <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">find</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;User.username&#8217;</span> =&gt; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;username&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;User.active&#8217;</span><span class="br0">&#41;</span>, <span class="kw2">null</span>, <span class="kw2">false</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check to see if the User&#8217;s account isn&#8217;t active</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$results</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;active&#8217;</span><span class="br0">&#93;</span> == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Uh Oh!</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Session</span>-&gt;<span class="me1">setFlash</span><span class="br0">&#40;</span><span class="st0">&#8216;Your account has not been activated yet!&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Auth</span>-&gt;<span class="me1">logout</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;/users/login&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Cool, user is active, redirect post login</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;/&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span></div>
<p>With this login check in place, we now need to sort out sending out the email which will actually &#8220;activate&#8221; the user&#8217;s account for them.  Before we start with the controller actions, let&#8217;s defined some custom logic in the Model.  As a quick side note, I work to the principle of <a href="http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/">skinny controllers, fat models</a> (and so should you).  What this means, in a nutshell &#8211; is that any logic which relates to a Model (in our case, generating the Confirmation Link) should be done in the Model &#8211; so let&#8217;s do that now.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/models/user.php </span><br />
<span class="co2"># please note that validation logic is not shown</span><br />
<span class="kw2">Class</span> User <span class="kw2">extends</span> AppModel<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = ‘User’;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Creates an activation hash for the current user.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @param Void<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @return String activation hash.<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> getActivationHash<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">id</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">&#40;</span>Security::<span class="me2">hash</span><span class="br0">&#40;</span>Configure::<span class="me2">read</span><span class="br0">&#40;</span><span class="st0">&#8216;Security.salt&#8217;</span><span class="br0">&#41;</span> . <span class="re0">$this</span>-&gt;<span class="me1">field</span><span class="br0">&#40;</span><span class="st0">&#8216;created&#8217;</span><span class="br0">&#41;</span> . <a href="http://www.php.net/date"><span class="kw3">date</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Ymd&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, <span class="nu0">0</span>, <span class="nu0">8</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span></div>
<p>So, incase you didn&#8217;t gather, we can grab a unique Activation Hash for any given user by calling $User->getActivationHash() from inside the controller.  Let&#8217;s just break down what we are doing in the getActivationHash funciton and the reason why we&#8217;re doing it.</p>
<p>When we send the email to the user, we are going to send them a link which they can click on to activate their account.  If we don&#8217;t create unique activation links then users would be able to &#8220;guess&#8221; or craft activation links for other users, for example, if we didn&#8217;t use an activation hash our links may look like this: http://mysite.com/user/activate/jreeves/ &#8211; Hmm, well I know that my username is jreeves, so I could guess pretty easily that /users/activate/dchang is going to active someone elses&#8217; account&#8230; not great.</p>
<p>So, what is getActivationHash doing?  Basically, it&#8217;s taking the datetime of when the user created their account (this will be unique for each user), adding in the Day-Month-Year value (so that activation links only last for 24 hours) and combining the whole shebang with the Security.salt value from CakePHP&#8217;s core.ini and Hashing it (with either MD5 or SHA-1 depending on your Cake&#8217;s settings).  In case you are wondering, this process is called <a href="http://en.wikipedia.org/wiki/Salt_(cryptography)">salting</a> and it makes any unique value (such as a password, or MD5 hash), almost impossible to guess.</p>
<p>Okay, enough talk, let&#8217;s hook this into the register action so that this email gets sent out.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /controllers/users_controller.php</span><br />
<span class="co2"># please note that not all code is shown&#8230;</span><br />
uses<span class="br0">&#40;</span><span class="st0">&#8217;sanitize&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">class</span> UsersController <span class="kw2">extends</span> AppController <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Users&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Include the Email Component so we can send some out :)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$components</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Email&#8217;</span>, <span class="st0">&#8216;Auth&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Allow users to access the following action when not logged in&nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> beforeFilter<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Auth</span>-&gt;<span class="me1">allow</span><span class="br0">&#40;</span><span class="st0">&#8216;register&#8217;</span>, <span class="st0">&#8216;thanks&#8217;</span>, <span class="st0">&#8216;confirm&#8217;</span>, <span class="st0">&#8216;logout&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Auth</span>-&gt;<span class="me1">autoRedirect</span> = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Allows a user to sign up for a new account</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> register<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// See my previous post if this is forgien to you</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;password&#8217;</span><span class="br0">&#93;</span> = <span class="re0">$this</span>-&gt;<span class="me1">Auth</span>-&gt;<span class="me1">password</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;passwrd&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">data</span> = Sanitize::<span class="me2">clean</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Successfully created account &#8211; send activation email&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;__sendActivationEmail<span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">getLastInsertID</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// this view is not show / listed &#8211; use your imagination and inform</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// users that an activation email has been sent out to them.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;/users/thanks&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Failed, clear password field</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;passwrd&#8217;</span><span class="br0">&#93;</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Send out an activation email to the user.id specified by $user_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Int $user_id User to send activation email to<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@return Boolean indicates success<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> __sendActivationEmail<span class="br0">&#40;</span><span class="re0">$user_id</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$user</span> = <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">find</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;User.id&#8217;</span> =&gt; <span class="re0">$user_id</span><span class="br0">&#41;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;User.email&#8217;</span>, <span class="st0">&#8216;User.username&#8217;</span><span class="br0">&#41;</span>, <span class="kw2">null</span>, <span class="kw2">false</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$user</span> === <span class="kw2">false</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span><span class="kw2">__METHOD__</span>.<span class="st0">&quot; failed to retrieve User data for user.id: {$user_id}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Set data for the &quot;view&quot; of the Email</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="st0">&#8216;activate_url&#8217;</span>, <span class="st0">&#8216;http://&#8217;</span> . env<span class="br0">&#40;</span><span class="st0">&#8216;SERVER_NAME&#8217;</span><span class="br0">&#41;</span> . <span class="st0">&#8216;/users/activate/&#8217;</span> . <span class="re0">$user</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;id&#8217;</span><span class="br0">&#93;</span> . <span class="st0">&#8216;/&#8217;</span> . <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">getActivationHash</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="st0">&#8216;username&#8217;</span>, <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;username&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Email</span>-&gt;<span class="me1">to</span> = <span class="re0">$user</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;email&#8217;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Email</span>-&gt;<span class="me1">subject</span> = env<span class="br0">&#40;</span><span class="st0">&#8216;SERVER_NAME&#8217;</span><span class="br0">&#41;</span> . <span class="st0">&#8216; &#8211; Please confirm your email address&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Email</span>-&gt;<span class="me1">from</span> = <span class="st0">&#8216;noreply@&#8217;</span> . env<span class="br0">&#40;</span><span class="st0">&#8216;SERVER_NAME&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Email</span>-&gt;<span class="me1">template</span> = <span class="st0">&#8216;user_confirm&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Email</span>-&gt;<span class="me1">sendAs</span> = <span class="st0">&#8216;text&#8217;</span>; &nbsp; <span class="co1">// you probably want to use both :)&nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">Email</span>-&gt;<span class="me1">send</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span></div>
<p>Okay, now we&#8217;re cooking &#8211; time to create the Email &#8220;views&#8221; which will be sent out with the emails &#8211; in case you are not familiar with the EmailComponent then now would be a good time to <a href="http://book.cakephp.org/view/176/email">refer to the CookBook</a>.  So, let&#8217;s create the plain text email template which will contain the activation link set above:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/views/elements/email/text/user_confirm.ctp</span><br />
<span class="kw2">?&gt;</span><br />
Hey there <span class="kw2">&lt;?</span>= <span class="re0">$username</span> <span class="kw2">?&gt;</span>, we will have you up and running in no <a href="http://www.php.net/time"><span class="kw3">time</span></a>, but first we just need you to confirm your user account by clicking the <a href="http://www.php.net/link"><span class="kw3">link</span></a> below:</p>
<p><span class="kw2">&lt;?</span>= <span class="re0">$activate_url</span> <span class="kw2">?&gt;</span></p>
<p>&nbsp;</p></div>
<p>Phew!  The end is in sight, just one more controller action to hook up (and probably the most important one) &#8211; /users/activate &#8211; I&#8217;m sure you can figure out what this is going to do.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /controllers/user_controller.php</span><br />
<span class="co2"># note that only the activate function is shown&#8230;</span></p>
<p><span class="coMULTI">/**<br />
&nbsp;* Activates a user account from an incoming link<br />
&nbsp;*<br />
&nbsp;* &nbsp;@param Int $user_id User.id to activate<br />
&nbsp;* &nbsp;@param String $in_hash Incoming Activation Hash from the email<br />
*/</span><br />
<span class="kw2">function</span> activate<span class="br0">&#40;</span><span class="re0">$user_id</span> = <span class="kw2">null</span>, <span class="re0">$in_hash</span> = <span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">id</span> = <span class="re0">$id</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">exists</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span><span class="re0">$in_hash</span> == <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">getActivationHash</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Update the active flag in the database</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">saveField</span><span class="br0">&#40;</span><span class="st0">&#8216;active&#8217;</span>, <span class="nu0">1</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Let the user know they can now log in!</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Session</span>-&gt;<span class="me1">setFlash</span><span class="br0">&#40;</span><span class="st0">&#8216;Your account has been activated, please log in below&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;login&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Activation failed, render &#8216;/views/user/activate.ctp&#8217; which should tell the user.</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span></div>
<p>And there we have it, now when your users register they have to confirm their user accounts via Email &#8211; job done!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/cakephp-activating-user-account-via-email/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>CakePHP &#8211; Open_Basedir Restriction in Effect</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/cakephp-open_basedir-restriction-in-effect/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/cakephp-open_basedir-restriction-in-effect/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 21:37:17 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[open_basedir]]></category>
		<category><![CDATA[plesk]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=40</guid>
		<description><![CDATA[Just deployed a CakePHP on a domain running PLESK and dismayed by the fact that your screen is over-flowing with warning about open_basedir restriction in effect?  Fear not, the solution is straight forward (if a little frustrating to track down!)
The problem is caused by this line (line 69, in CakePHP 1.2.0.6311) in /app/webroot/index.php:

ini_set&#40;&#8216;include_path&#8217;, CAKE_CORE_INCLUDE_PATH [...]]]></description>
			<content:encoded><![CDATA[<p>Just deployed a CakePHP on a domain running <a href="http://en.wikipedia.org/wiki/Plesk">PLESK</a> and dismayed by the fact that your screen is over-flowing with warning about open_basedir restriction in effect?  Fear not, the solution is straight forward (if a little frustrating to track down!)</p>
<p>The problem is caused by this line (line 69, in CakePHP 1.2.0.6311) in /app/webroot/index.php:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<a href="http://www.php.net/ini_set"><span class="kw3">ini_set</span></a><span class="br0">&#40;</span><span class="st0">&#8216;include_path&#8217;</span>, CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . <a href="http://www.php.net/ini_get"><span class="kw3">ini_get</span></a><span class="br0">&#40;</span><span class="st0">&#8216;include_path&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp;</div>
<p>Yep, the simple ini_set command &#8211; the clues should start coming in thick and fast that ini_set is causing the problem due to the fact taht open_basedir complains about paths with :&#8217;s in their structure.  (:&#8217;s being the delimiter for automatically included paths).  To fix the problem you can either remove the if logic that calls &#8220;function_exists(&#8217;ini_set&#8217;)&#8221;, or, if you prefer to fix things the corret way, modify the line to remove the final stub:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<a href="http://www.php.net/ini_set"><span class="kw3">ini_set</span></a><span class="br0">&#40;</span><span class="st0">&#8216;include_path&#8217;</span>, CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS<span class="br0">&#41;</span>;<br />
&nbsp;</div>
<p>Good luck, hope that saves someone a headache! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/cakephp-open_basedir-restriction-in-effect/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>CakePHP &#8211; Uploaded File Validation in Models</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 14:56:26 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[file upload]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=37</guid>
		<description><![CDATA[Allowing uploaded files from users in PHP is fraught with danger, however by using CakePHP 1.2 and a little bit of Validation magic we can make things a little safer.
First, lets start by creating a simple upload form where the users will be uploading their files

&#60;?php
# /app/views/story/create.ctp
echo $form-&#62;create&#40;&#8216;Story&#8217;, array&#40;&#8216;action&#8217; =&#62; &#8216;create&#8217;, &#8216;type&#8217; =&#62; &#8216;file&#8217;&#41;&#41;;
echo $form-&#62;input&#40;&#8216;Story.title&#8217;&#41;;
echo [...]]]></description>
			<content:encoded><![CDATA[<p>Allowing uploaded files from users in PHP is fraught with danger, however by using CakePHP 1.2 and a little bit of Validation magic we can make things a little safer.</p>
<p>First, lets start by creating a simple upload form where the users will be uploading their files</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/views/story/create.ctp</span><br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">create</span><span class="br0">&#40;</span><span class="st0">&#8216;Story&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;action&#8217;</span> =&gt; <span class="st0">&#8216;create&#8217;</span>, <span class="st0">&#8216;type&#8217;</span> =&gt; <span class="st0">&#8216;file&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;Story.title&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;Story.contents&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;Artwork.uploaded_image&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;type&#8217;</span> =&gt; <span class="st0">&#8216;file&#8217;</span>, <span class="st0">&#8216;label&#8217;</span> =&gt; <span class="st0">&#8216;Front Artwork&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">end</span><span class="br0">&#40;</span><span class="st0">&#8216;Create Story&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>Nothing particularly special here, just to note that we are specifying &#8220;type&#8221; => &#8220;file&#8221; in the $form::create method &#8211; this makes cake inset the correct &#8216;enc-type&#8217; value in the generated<br />
<form> tag.</p>
<p>So when the user submits this form, they will be pointed towards the create() action in the StoryController, lets have a look at that:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/controllers/story_controller.php</span><br />
uses<span class="br0">&#40;</span><span class="st0">&#8217;sanitize&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">class</span> StoryController <span class="kw2">extends</span> AppController <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Story&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Allows users to create a story with an attached image.<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> create<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Always sanitize user input, except for the filename (which will get borked on Win32 systems)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$uploaded_image</span> = <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;Artwork&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;uploaded_image&#8217;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span> = Sanitize::<span class="me2">clean</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;Artwork&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;uploaded_image&#8217;</span><span class="br0">&#93;</span> = <span class="re0">$uploaded_image</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">Story</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// redirect to the new story.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Session</span>-&gt;<span class="me1">setFlash</span><span class="br0">&#40;</span><span class="st0">&#8216;Your story was created!&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$insert_id</span> = <span class="re0">$this</span>-&gt;<span class="me1">Story</span>-&gt;<span class="me1">getInsertID</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;/stories/view/&#8217;</span> . <span class="re0">$insert_id</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Session</span>-&gt;<span class="me1">setFlash</span><span class="br0">&#40;</span><span class="st0">&#8216;Please correct the errors below&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>Again, nothing unusual here, however, without any data validation we would be opening the application up to attack from malicious users &#8211; they could upload PHP code that could later be executed; for more general reading on the woes of File uploads, see what Chris Shiftlett, author of <a href="http://www.amazon.co.uk/Essential-PHP-Security-Chris-Shiflett/dp/059600656X/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1212331543&#038;sr=8-1">Essential PHP Security</a> <a href="http://shiflett.org/articles/file-uploads">has to say</a>.</p>
<p>So, in order to add some security to Image uploads, we are going to add some simple custom validation rules to the Artwork Model:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/models/artwork.php</span><br />
<span class="kw2">Class</span> Artwork <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Artwork&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$validate</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;uploaded_image&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;valid_upload&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;validateUploadedFile&#8217;</span>, <span class="kw2">false</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;An error occurred whilst uploading&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Custom validation rule for uploaded files.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Array $data CakePHP File info.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Boolean $required Is this field required?<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@return Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> validateUploadedFile<span class="br0">&#40;</span><span class="re0">$data</span>, <span class="re0">$required</span> = <span class="kw2">false</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Remove first level of Array ($data['Artwork']['size'] becomes $data['size'])</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$upload_info</span> = <a href="http://www.php.net/array_shift"><span class="kw3">array_shift</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// No file uploaded.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$required</span> &amp;&amp; <span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8217;size&#8217;</span><span class="br0">&#93;</span> == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check for Basic PHP file errors.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8216;error&#8217;</span><span class="br0">&#93;</span> !== <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Finally, use PHP&#8217;s own file validation method.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/is_uploaded_file"><span class="kw3">is_uploaded_file</span></a><span class="br0">&#40;</span><span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8216;tmp_name&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>Now, before the Data from the form is saved, it will be passed through the custom validation above &#8211; any invalid, or potentially malicious files will be rejected.  This could easily be split into separate validation methods to provide more understandable error messages for your users.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CakePHP, Using CounterCache to keep track of Comments</title>
		<link>http://www.jonnyreeves.co.uk/2008/05/cakephp-using-countercache-to-keep-track-of-comments/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/05/cakephp-using-countercache-to-keep-track-of-comments/#comments</comments>
		<pubDate>Sat, 31 May 2008 18:59:06 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[countercache]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=35</guid>
		<description><![CDATA[CounterCache is one of the new Core Model Behaviors in CakePHP 1.2 and it&#8217;s an absolute life saver for working with hasMany relationships where you want to OrderBy one of the children.
The basic idea behind a CounterCache is to keep tabs on how &#8216;children&#8217; a specific model has, this is best explained in a quick [...]]]></description>
			<content:encoded><![CDATA[<p>CounterCache is one of the new Core Model Behaviors in CakePHP 1.2 and it&#8217;s an absolute life saver for working with hasMany relationships where you want to OrderBy one of the children.</p>
<p>The basic idea behind a CounterCache is to keep tabs on how &#8216;children&#8217; a specific model has, this is best explained in a quick snippet of CakePHP.  In the following example I am going to set up a simple relationship of Users and Comments, however, I want to add the condition that posts must be moderated first as indicated by a `moderated` Boolean field in the MySQL table.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="kw1">IF</span> <span class="kw1">NOT</span> <span class="kw1">EXISTS</span> <span class="st0">`users`</span> <span class="br0">&#40;</span><br />
&nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,<br />
&nbsp; <span class="st0">`username`</span> varchar<span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="st0">`comments_count`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=InnoDB <span class="kw1">DEFAULT</span> CHARSET=latin1;</p>
<p><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="kw1">IF</span> <span class="kw1">NOT</span> <span class="kw1">EXISTS</span> <span class="st0">`comments`</span> <span class="br0">&#40;</span><br />
&nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,<br />
&nbsp; <span class="st0">`user_id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="st0">`message`</span> text <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="st0">`moderated`</span> tinyint<span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#8216;0&#8242;</span>,<br />
&nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=InnoDB <span class="kw1">DEFAULT</span> CHARSET=latin1;<br />
&nbsp;</div>
<h2>Users Model: <b>/app/models/user.php</b></h2>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> User <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;User&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$hasMany</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Comment&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<h3>Comments Model: <b>/app/models/comment.php</b></h3>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> Comment <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Comment&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$actsAs</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;CounterCache&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$belongsTo</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><span class="st0">&#8216;User&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;foreignKey&#8217;</span> =&gt; <span class="st0">&#8216;user_id&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterCache&#8217;</span> =&gt; <span class="st0">&#8216;comments_count&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterScope&#8217;</span> =&gt; <span class="st0">&#8216;moderated = 1&#8242;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>So the magic being introduced here is the CounterCache Behavior,  in the Comments Model (which is included by setting is in the $actsAs variable).  The <strong>&#8216;counterCache&#8217; => &#8216;comments_count&#8217;</strong> value indicates to column on the `belongsTo` table which will contain the count and the <strong>&#8216;counterScope&#8217; => &#8216;moderated = 1&#8242; </strong> tells CounterCache to only increment the count value when this SQL Condition is met (in this case, `moderated` must be true).</p>
<p>Go ahead, build the application, throw some scaffolding into the Controllers and watch in awe as the `comments_count` value increments each time you save a comment where $data['Comment']['moderated'] = 1.  Now, this is all well and good, but in the real world, users won&#8217;t be setting the moderated value, instead you will have a Controller action to approve comments which looks something like this:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> Comment <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Comment&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$actsAs</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;CounterCache&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$belongsTo</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><span class="st0">&#8216;User&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;foreignKey&#8217;</span> =&gt; <span class="st0">&#8216;user_id&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterCache&#8217;</span> =&gt; <span class="st0">&#8216;comments_count&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterScope&#8217;</span> =&gt; <span class="st0">&#8216;moderated = 1&#8242;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Callback for when Cake has performed a save() operation.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param Boolean $created TRUE if save() performed a CREATE<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return Void<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> afterSave<span class="br0">&#40;</span><span class="re0">$created</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="re0">$created</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Kick the counterCache value.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">updateCounterCache</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>You could further tweak this callback to enhance performance, only updating the counterCache when logic dictates it necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/05/cakephp-using-countercache-to-keep-track-of-comments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP Vimeo Helper</title>
		<link>http://www.jonnyreeves.co.uk/2008/05/cakephp-vimeo-helper/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/05/cakephp-vimeo-helper/#comments</comments>
		<pubDate>Mon, 26 May 2008 09:37:01 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Video on the Web]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[vimeo]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=34</guid>
		<description><![CDATA[I&#8217;ve just posted a new Helper over at the bakery to assist with embedding Vidoes from Vimeo.com on your CakePHP site.  The helper grants you access to all configuration flags for the player.  Grab it here, happy baking!
As a side note, whilst fiddling around with this helper I found it interesting to note [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just posted a new Helper over at the <a href="http://bakery.cakephp.org/">bakery</a> to assist with embedding Vidoes from Vimeo.com on your CakePHP site.  The helper grants you access to all configuration flags for the player.  <a href="http://bakery.cakephp.org/articles/view/vimeo-helper">Grab it here</a>, happy baking!</p>
<p>As a side note, whilst fiddling around with this helper I found it interesting to note that Vimeo directly link to the .swf file in their embed code rather than using a Wrapper Script to log incoming embed locations &#8211; I presume they are trawling their Apache logs instead &#8211; still seems a bit backwards&#8230;</p>
<p>VimeoHelper source code after the leap <!-- more --></p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">class</span> VimeoHelper <span class="kw2">extends</span> AppHelper<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Creates Vimeo Embed Code from a given Vimeo Video.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @param String $vimeo_id URL or ID of Video on Vimeo.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @param Array $usr_options VimeoHelper Options Array (see below)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @return String HTML output.<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> getEmbedCode<span class="br0">&#40;</span><span class="re0">$vimeo_id</span>, <span class="re0">$usr_options</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Default options.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$options</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;width&#8217;</span> =&gt; <span class="nu0">400</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;height&#8217;</span> =&gt; <span class="nu0">225</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8217;show_title&#8217;</span> =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8217;show_byline&#8217;</span> =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8217;show_portrait&#8217;</span> =&gt; <span class="nu0">0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;color&#8217;</span> =&gt; <span class="st0">&#8216;00adef&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$options</span> = <a href="http://www.php.net/array_merge"><span class="kw3">array_merge</span></a><span class="br0">&#40;</span><span class="re0">$options</span>, <span class="re0">$usr_options</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Extract Vimeo.id from URL.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">&#40;</span><span class="re0">$vimeo_id</span>, <span class="nu0">0</span>, <span class="nu0">21</span><span class="br0">&#41;</span> == <span class="st0">&#8216;http://www.vimeo.com/&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$vimeo_id</span> = <a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">&#40;</span><span class="re0">$vimeo_id</span>, <span class="nu0">21</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216;&lt;object width=&quot;%s&quot; height=&quot;%s&quot;&gt;&#8217;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8216;width&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8216;height&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="st0">&#8216; &lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span><span class="br0">&#91;</span><span class="br0">&#93;</span> =&nbsp; &nbsp; &nbsp;<span class="st0">&#8216; &lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span><span class="br0">&#91;</span><span class="br0">&#93;</span> =&nbsp; &nbsp; &nbsp;<a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216; &lt;param name=&quot;movie&quot; value=&quot;http://www.vimeo.com/moogaloop.swf?clip_id=%s&amp;amp;server=www.vimeo.com&amp;amp;show_title=%s&amp;amp;show_byline=%s&amp;amp;show_portrait=%s&amp;amp;color=%s&amp;amp;fullscreen=1&quot; /&gt;&#8217;</span>, <span class="re0">$vimeo_id</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8217;show_title&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8217;show_byline&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8217;show_portrait&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8216;color&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216; &lt;embed src=&quot;http://www.vimeo.com/moogaloop.swf?clip_id=%s&amp;amp;server=www.vimeo.com&amp;amp;show_title=%s&amp;amp;show_byline=%s&amp;amp;show_portrait=%s&amp;amp;color=%s&amp;amp;fullscreen=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;%s&quot; height=&quot;%s&quot;&gt;&lt;/embed&gt;&#8217;</span>, <span class="re0">$vimeo_id</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8217;show_title&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8217;show_byline&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8217;show_portrait&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8216;color&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8216;width&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$options</span><span class="br0">&#91;</span><span class="st0">&#8216;height&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$output</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="st0">&#8216;&lt;/object&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">output</span><span class="br0">&#40;</span><a href="http://www.php.net/implode"><span class="kw3">implode</span></a><span class="br0">&#40;</span><span class="re0">$output</span>, <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/05/cakephp-vimeo-helper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User Registration with CakePHP 1.2 and Auth Component</title>
		<link>http://www.jonnyreeves.co.uk/2008/05/user-registration-with-cakephp-12-and-auth-component/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/05/user-registration-with-cakephp-12-and-auth-component/#comments</comments>
		<pubDate>Sat, 24 May 2008 10:54:46 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[auth]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=33</guid>
		<description><![CDATA[With CakePHP 1.2 nearly reaching the RC release, I have started using it as the framework for my own applications.  Once of the new features of 1.2 over 1.1 is the addition of numerous core Components for handling things such as Cookies, Email and Authentication (all of which I rolled myself in 1.1).  Today&#8217;s article [...]]]></description>
			<content:encoded><![CDATA[<p>With <a href="http://cakephp.org/">CakePHP 1.2</a> nearly reaching the RC release, I have started using it as the framework for my own applications.  Once of the new features of 1.2 over 1.1 is the addition of numerous core Components for handling things such as Cookies, Email and Authentication (all of which I rolled myself in 1.1).  Today&#8217;s article is going to focus on the Auth Component and a couple of problems it threw up whilst I was trying to create a simple registration page.</p>
<p>Before starting with the code listings for a simple registation action, a little bit of background as to why I&#8217;m writing this post.  CakePHP 1.2&#8217;s Auth Component will automatically hash the value of $this-&gt;data['User']['password'] &#8211; this is helpful in many ways and allows for a lot of Cake&#8217;s auto-magic, however it can cause problems.  For example, as the passowrd is automatically being hashed into a 40 character value before any other logic is applied, any validation rules in the Model will be ignored (including NOT_EMPTY like checks).  Take this as a hypothetical situation:</p>
<ul>
<li>User goes to /users/register to create a new account</li>
<li></li>
<li>User enters their username and password correctly, they then enter an invalid email address</li>
<li>Controller fails to validate() the invalid email address supplied so takes the user back to the registration page &#8211; Cake helpfully re-populates the form with the values in $this-&gt;data array</li>
<li>This unfortunatley means the user&#8217;s password has been turned into a 40 Character SHA-1 Hash!  If the user fails to notice this fact, fixes their email address and clicks submit then that 40 Character SHA-1 Hash is going to get hashed again &#8211; now the user has no idea what their password is set to &#8211; whoops!</li>
</ul>
<p>Getting around this problem is pretty straight forward, it just requires a little bit of thought &#8211; change the fieldname from password (Which CakePHP 1.2&#8217;s Auth Component will automatically hash) to something else, ie: passwrd.  Now Cake won&#8217;t hash this value, your model&#8217;s validation checks can run and everyone is happy &#8211; just don&#8217;t forget to use AuthComponent::password() to hash this value before storing it.</p>
<h4>User Model Class</h4>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;"> <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;alphanumeric&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <span class="st0">&#8216;alphaNumeric&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;Only the letters A-z and digits 0-9 are allowed&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;length&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;between&#8217;</span>, <span class="nu0">4</span>, <span class="nu0">20</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&quot;Your username must be between 4 and 20 characters long&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;passwrd&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;minLength&#8217;</span>, <span class="nu0">6</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;Your password must be at least 6 characters long&#8217;</span>,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;email&#8217;</span> =&gt; <span class="st0">&#8216;email&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<h4>User Controller Class</h4>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">Auth-&gt;<span class="me1">allow</span><span class="br0">&#40;</span><span class="st0">&#8216;register&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Allows a user to sign up for a new account<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> register<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// If the user submitted the form&#8230;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Turn the supplied password into the correct Hash.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// and move into the &#8216;password&#8217; field so it will get saved.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;password&#8217;</span><span class="br0">&#93;</span> = <span class="re0">$this</span>-&gt;<span class="me1">Auth</span>-&gt;<span class="me1">password</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;passwrd&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Always Sanitize any data from users!</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">data</span> = Sanitize::<span class="me2">clean</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">User</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Use a private method to send a confirmation</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// email to the new user (code not shown)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;__sendConfirmationEmail<span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Success! Redirect to a thanks page.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;/users/thanks&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// The plain text password supplied has been hashed into the &#8216;password&#8217; field so</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// should now be nulled so it doesn&#8217;t get render in the HTML if the save() fails</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;User&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;passwrd&#8217;</span><span class="br0">&#93;</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<h4>User/Register.ctp View</h4>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
&lt;h2&gt;Create an Account&lt;/h2&gt;</p>
<p>
create<span class="br0">&#40;</span><span class="st0">&#8216;User&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;action&#8217;</span> =&gt; <span class="st0">&#8216;register&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;username&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;between&#8217;</span> =&gt; <span class="st0">&#8216;Pick a username&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// Force the FormHelper to render a password field, and change the label.</span><br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;passwrd&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;type&#8217;</span> =&gt; <span class="st0">&#8216;password&#8217;</span>, <span class="st0">&#8216;label&#8217;</span> =&gt; <span class="st0">&#8216;Password&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;email&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;between&#8217;</span> =&gt; <span class="st0">&#8216;We need to send you a confirmation email to check you are human&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">submit</span><span class="br0">&#40;</span><span class="st0">&#8216;Create Account&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">end</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/05/user-registration-with-cakephp-12-and-auth-component/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
