<?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"
	>

<channel>
	<title>JonnyReeves.co.uk</title>
	<atom:link href="http://www.jonnyreeves.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonnyreeves.co.uk</link>
	<description>Actionscript, Flash, PHP and stuff</description>
	<pubDate>Sun, 19 Oct 2008 11:14:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>The State of Logging in ActionScript 3</title>
		<link>http://www.jonnyreeves.co.uk/2008/10/the-state-of-logging-in-actionscript-3/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/10/the-state-of-logging-in-actionscript-3/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 11:14:45 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[ActionScript 3]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=62</guid>
		<description><![CDATA[I&#8217;ve been looking at Logging Frameworks in ActionScript 3 over the past few days and I&#8217;m afraid that I&#8217;m slightly at a loss as for which approach is the best to take.  There are a few Logging Frameworks out there, but Adobe has kindly supplied an intrinic Logging Framework, however, it&#8217;s not without it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking at Logging Frameworks in ActionScript 3 over the past few days and I&#8217;m afraid that I&#8217;m slightly at a loss as for which approach is the best to take.  There are a few Logging Frameworks out there, but Adobe has kindly supplied an intrinic Logging Framework, however, it&#8217;s not without it&#8217;s shortcomings.</p>
<p>The biggest problem that I&#8217;ve come up against is that there is no easy way to set the Category for the Log.  The Flex Logging Framework allows you to set the category of the log when you retrieve the ILogger instance.  This can in turn be used by the Log Filtering system to specify which categories you would like to log.  Ideally you set the category String to be the name of the Class you are currently Logging, however, due to the rather shaky reflection tools avaliable, there&#8217;s no easy way to automatically get the name of the current Class.  To compound the problem even further, getQualifiedClassName returns illegal characters (The semi-colon seperating the Package and the Class Name) and Flex Logging Framework will throw and Illegal Arguments error if you try and use it as the category name.  So, in order to have automatic categories generated, we have to do a bit of a curly shuffle with a StackTrace and a Helper Method</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package uk.<span class="me1">co</span>.<span class="me1">jonnyreeves</span>.<span class="me1">logging</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">logging</span>.<span class="me1">ILogger</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">logging</span>.<span class="me1">ILoggingTarget</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> mx.<span class="me1">logging</span>.<span class="kw3">Log</span>;&nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">utils</span>.<span class="me1">getQualifiedClassName</span>;&nbsp; &nbsp; &nbsp; &nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Flex Logger Helper, automatically returns the Category Name when used inside<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* a Class.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @author jonny reeves<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> Logger <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns an instance of Flex Logger with the correct category name for the calling Class<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return ILogger instance with the correct category set for the calling Class.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw3">static</span> <span class="kw2">function</span> getLogger<span class="br0">&#40;</span><span class="br0">&#41;</span> : ILogger<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="kw2">var</span> category : <span class="kw3">String</span> = <span class="st0">&quot;&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; category = getCallerFromStackTrace<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="kw1">return</span> <span class="kw3">Log</span>.<span class="me1">getLogger</span><span class="br0">&#40;</span>category<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; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Triggers a StackTrace and extracts the calling method from it, neat.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw3">static</span> <span class="kw2">function</span> getCallerFromStackTrace<span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw3">String</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="kw2">var</span> callerMethod : <span class="kw3">String</span> = <span class="st0">&quot;&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> nullArray : <span class="kw3">Array</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">// Pop a StackTrace by creating a RunTime error.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">try</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; nullArray.<span class="kw3">push</span><span class="br0">&#40;</span><span class="st0">&quot;whoops&quot;</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="kw3">catch</span> <span class="br0">&#40;</span><span class="kw3">e</span> : <span class="kw3">Error</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="kw2">var</span> stackTrace : <span class="kw3">String</span> = <span class="kw2">new</span> <span class="kw3">Error</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getStackTrace</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="br0">&#125;</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">// Extract the ClassName from the StackTrack</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>stackTrace != <span class="kw2">null</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="kw2">var</span> parts : <span class="kw3">Array</span> = <span class="kw2">new</span> <span class="kw3">Array</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; stackTrace.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="br0">&#41;</span>.<span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parts = stackTrace.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">&quot;&nbsp; &nbsp; &nbsp; at &quot;</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="kw1">if</span> <span class="br0">&#40;</span>parts<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> != <span class="kw2">null</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">&#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">// Handle Both Class Init and internal method cases</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &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>parts<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>.<span class="kw3">indexOf</span><span class="br0">&#40;</span><span class="st0">&quot;$cinit&quot;</span><span class="br0">&#41;</span> != <span class="nu0">-1</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="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callerMethod = parts<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">&quot;$cinit&quot;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callerMethod = parts<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">&quot;/&quot;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &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="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; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> getCategoryNameFor<span class="br0">&#40;</span>callerMethod<span class="br0">&#41;</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; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Helper method which takes an ActionScript 3 Formatted Class Name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* and replaces the semi-colons seperating the package and Class name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* with a Single Period for use as teh Flex Logging Category name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param qualifiedClassName<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return String Legal Flex Logging Category String<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw3">static</span> <span class="kw2">function</span> getCategoryNameFor<span class="br0">&#40;</span>qualifiedClassName : <span class="kw3">String</span><span class="br0">&#41;</span> : <span class="kw3">String</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="kw1">return</span> qualifiedClassName.<span class="kw3">indexOf</span><span class="br0">&#40;</span><span class="st0">&quot;::&quot;</span><span class="br0">&#41;</span> &gt; <span class="nu0">-1</span> ? qualifiedClassName.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">&quot;::&quot;</span><span class="br0">&#41;</span>.<span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span> : qualifiedClassName;<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>
<p>This can now be used inside any Class you wish to Log by delcaring a private, static instance of ILogger, for example:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package uk.<span class="me1">co</span>.<span class="me1">jonnyreeves</span>.<span class="me1">logging</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> LoggingExample<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Instance of the Flex Logging Framework via the Logger Helper Class which will<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* automatically set the Category name to uk.co.jonnyreeves.logging.LoggingExample<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw3">static</span> <span class="kw2">var</span> Logger : ILogger = Logger.<span class="me1">getLogger</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* You can now log away, don&#8217;t forget to initialise your Flex Logger Instance (Log) first<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* by setting the Target Publisher (not shown).<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> LoggingExample<span class="br0">&#40;</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; Logger.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;Hello World!&quot;</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 />
&nbsp;</div>
<p>Although this is helpful it still does not address a couple of other fundimental issues:</p>
<ul>
<li>The output from the Flex Logging Framework does not include the enclosing method or line number from which the error was triggered (although this information can extracted from a StackTrace and automatically appended to the Logged Message by the Publisher).</li>
<li>The Flex Logging Framework does not intelligently handle datatypes - unfortunatley we can only passing String&#8217;s to Flex Logger - however, we can get around this by making use of 3rd Party Consoles such as Thunderbolt (which also, helpfully includes a LoggingTarget).</li>
<li>Although the Flex Logging Framework allows you to supply a custom Filters Array (and this can even be updated at runtime), it does not appear to include a simple way to configure this via an external XML configuration file.  However, I&#8217;m fairly confident that I can role my own (just a shame that I have to!)</li>
</ul>
<p>I&#8217;m going to be working on the three points above over the next few days and see if I can come up with a solution which stays as faithful to the intrinsic Logging framework as possible but allows the flexibility of some of the other Loggers out there (Luminic Box, XRay, etc).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/10/the-state-of-logging-in-actionscript-3/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Flash on the Beach 2008 - Tuesday Write Up</title>
		<link>http://www.jonnyreeves.co.uk/2008/10/flash-on-the-beach-2008-tuesday-write-up/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/10/flash-on-the-beach-2008-tuesday-write-up/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 10:34:24 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[ActionScript 2]]></category>

		<category><![CDATA[flash]]></category>

		<category><![CDATA[fotb]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=61</guid>
		<description><![CDATA[I went down to the Flash on the Beach 08 conference yesterday, here&#8217;s some of the notes that I wrote up on the train back:
Creating The Next Generation Happy Meal Toy
Julain Dolce
Julian is lead Developer for Fuel Industies, a creative agency that worked on a large scale campaign for the fast food chain McDonalds.  [...]]]></description>
			<content:encoded><![CDATA[<p>I went down to the <a href="http://flashonthebeach.com/">Flash on the Beach</a> 08 conference yesterday, here&#8217;s some of the notes that I wrote up on the train back:</p>
<h2><strong>Creating The Next Generation Happy Meal Toy</strong></h2>
<p><em>Julain Dolce</em></p>
<p>Julian is lead Developer for <a href="http://www.fuelindustries.com/">Fuel Industies</a>, a creative agency that worked on a large scale campaign for the fast food chain McDonalds.  The project was a rich multimedia experience centred on <a href="http://www.fuelindustries.com/casestudies/fairiesanddragons/">magical fairies and dragons</a>.  The application was delivered on CD which was bundled with Happy Meals.  The campaign proved very successful pushing over 80 million units in 30 countries.  He began his presentation with a brief overview of the product (marred somewhat by the fact the projector was not playing ball and he had to show it to the audience from the screen of his 15” Macbook).</p>
<p>Julian&#8217;s project had several key requirements which were taken into consideration during the initial planning stage:</p>
<ul>
<li> App. must be Cross Platform (Win32 and Mac OS)</li>
<li> Installed from a CD, with no internet access required</li>
<li> Handle multiple windows (for performance) and alpha transparency</li>
</ul>
<p>This ruled out Adobe Air 1.0 as it can&#8217;t be installed solely from a CD, it also has issues with full frame transparency.  As a result they settled on a mixture of <a href="http://www.multidmedia.com/software/zinc/">MDM Zinc 3</a> and <a href="http://www.screentime.com/software/mprojector/">mProjector</a>.  They also used <a href="http://bitrock.com/products_installbuilder_overview.html">Install Builder</a>, which is a Cross Platform (Win32, Linux and Mac) installation creator.  Their main Flash tools were FDT and Eclipse, they made use of SVN and constructed a couple of custom tools in C# using <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation">WPF on Win32</a></p>
<p>Julian’s team ended up building most of their application in ActionScript 2, Julain cited this was because of a lack of a mature ActionScript 3 development environment when the project was started in the summer of 2007.  They used SVN to keep code versioned, Mantis to track bugs and took advantage of an automated build process to get the builds out to testers.  They also kept Excel spreadsheets for each library asset which detailed file locations, settings (offsets, alpha, and compression ratios for all Cell animations, sounds and linkageid&#8217;s, etc.</p>
<p>The team made use of JSFL, which can be used to create custom scripts inside Adobe CS Applications - one such example was the ability to apply an affect to the selected symbols in the Document&#8217;s Library.</p>
<p>Their major testing problem was performance bound - using fullscreen alpha transparency bought things to a crawl and meant click events went unnoticed on slower machines - as a result they split the animations down into separate transparent windows which moved across the stage (the user’s desktop).  They used LocalConnection calls to get these panels to talk to each other and sync up.</p>
<p>Although the project appeared to go smoothly and was obviously successful, Julian did admit to one major failing.  In the time between sending the CD&#8217;s off for pressing in China and the returned product - Mac OS X 10.5 shipped - and unfortunately, their application did not work on it - whoops.</p>
<h2>Adobe Town Hall Meeting</h2>
<p><em>Richard Galvan, Mike Downey, Paul Betlem, Lee Brimelow and Matt Millar.</em></p>
<p>The second talk of the day consisted of 5 members of the Adobe Team - 3 platform evangelists and two Flash Player engineers.  The group asked questions asked by the audience.  I managed to ask a question in the session:</p>
<p>&#8220;The company I work for are currently porting a large scale AS2 project to AS3 and were disheartened by the lack of support and tools made available by Adobe to assist in this.  By using the Proxy class we have managed to create shims for most the intrinsic AS2 classes, but I Would like to know why Adobe did not do this and release it to the community.&#8221;</p>
<p>Their reply wasn’t what I was hoping for (but was to be expected).  I was told that Actionscript 3 was designed to target new customers and that they wanted to add as many features as possible to the language. I’m not quite sure what to infer from this seeing as AS2 obviously had a massive user base.  The group did, however, acknowledge that the lack of community support in the transition from AS2 to AS3 was a problem (although, again, made no indication that any tools would be forthcoming) .  They rounded off my question by assuring that ASVM1 Content (AS1 and 2 SWFs) would continue to be usable in Flash Player releases in the future.</p>
<p>Another interesting question that was asked was about the support for Dynamic Runtime Languages to script the published flash applications and allow greater control at runtime.  The team responded by saying that a new project - FLACC (FLAsh C++) is in the works which will allows C++ code to run natively inside the Flash Player. This could lead to other language interpreters being made available and will prove a very powerful tool for ActionScript developers.</p>
<p>Adobe also confirmed that Flash 10 is being worked on for the iPhone - but Apple has not confirmed it will be approved.  Flash Player 10 will include the new unloadAndStop() method to help with Garbage Collection when unloading external content in the Player and that there is no AS4 on the cards - instead they will work on improving AS3 whilst pushing ECMAScript 4 forwards (they hinted that Private Constructors might be coming back)</p>
<p>After the Session I spoke to an Adobe Flash Player engineer, Matt Millar.  I told him about our Library Linkage Problem where Child Objects placed on the stage in frame 2 (or greater) are not linked to the Display Chain on the first tick.  Whilst I was asking this question, another developer stepped in and claimed it was a major problem for his team.  I gave Matt my business card and the told me he would be in touch - I&#8217;m hoping that this will be fixed before FP 10 is released, but I am not holding my breath!</p>
<h2>Grant Skinner</h2>
<p><em>Things every ActionScript developer should know.</em></p>
<p>Grant is a well revered programmer in the ActionScript community, <a href="http://gskinner.com/blog/">his Blog</a> provides an excellent resource and he heads up his own <a href="http://gskinner.com/site2_5/">development team</a>.  Grant&#8217;s talk was aimed at developers of all skill levels, but focused mainly on the grass roots.  Grant gave an interesting presentation which, in his words, he wished someone had given to him 5 years ago - I&#8217;m not sure I can agree it was as life changing as Grant made out - but that may be in part due to the best practices which Mind Candy&#8217;s dev team strives towards ;)</p>
<p>Grant started off by assuring the audience that were no right answers in programming - don’t be driven to fake absolutes, although there are no definitive right answers there are plenty of wrong ones!  Code is art, Grant stressed, learn the rules before you can start to break them and don’t get hooked on Design Patterns – they’re not the answer to everything.</p>
<p>Grant then proceeded to lay down some programming fundamentals - Enforce code standards as it makes inheriting files easier.  Think of code like <a href="http://en.wikipedia.org/wiki/Lego">Lego</a>, not <a href="http://en.wikipedia.org/wiki/Play-Doh">Playdoh</a>.  If you are building a space ship in Playdoh and want to change the engine you have to pull it all apart - with Lego you can take apart and reassemble with ease - your code should be like this too.  Code flows down in specialisation - at the very top of the Object stack is the Main Application Controller which includes very specific logic for this one particular app - however as you move outwards, objects should become more generic and reusable.  When working with reusable code, remember inside looking out - prefer composition and event dispatching over tight coupling and inheritance.</p>
<p>Grant also recommended the use of Service delegates to act as a layer between Server Side logic and Controller Logic in Flash, that way, the server side logic can change with only the one class needing modification on the Flash side.</p>
<p>Moving towards Flash Player specifics, Grant told the audience to always keep learning - read every API you can - you don&#8217;t have to specialise but at least know what FP10 is capable of.  Also remember that AS3 needs you to be very particular about Garbage Collection - always create destructors in your AS3 objects to handle this in one place.</p>
<p>Grant bought up the concept of using Timeline based Event dispatching.  His example was a simple graphical dialogue box (like we use in Moshi), where the box just dispatches events when it finished tweening in / out - that way Classes using this Timeline code / Library Linage just need to register for its events removing any form of tight coupling.  Grant proceeded to talk about he makes use of JSFL to create custom Panels and &#8220;Graphical Objects&#8221;  - a single click from the command line laid out all the frames, labels and AS3 timeline code for creating a Graphical Button (including the Linkage name!)</p>
<p>Finally, Grant reminded the audience that we are blessed to have the Flash IDE - we can create prototype and concepts in seconds - get out there an experiment!</p>
<p>You can view Grant&#8217;s <a href="http://gskinner.com/talks/thingseveryflash/">slides for his presentation</a> over on his site - note that you will need <a href="http://labs.adobe.com/downloads/flashplayer10.html">Flash Player 10 beta</a> installed as he makes use of the new 3D features present</p>
<h2>Platform Jujitsu</h2>
<p><em>Lee Brimelow</em></p>
<p>Lee (who runs <a href="http://theflashblog.com/">theflashblog.com</a>) came back in the afternoon to evangelise about the new CS4 platform, showing us some of the new features available across the entire product line (Flash CS4, Flex Builder 4 and Flash Player 10).  He started off his speech by outlining that Flash Developers much be proficient in 5 main areas:</p>
<ul>
<li> Motion and Video</li>
<li> Visual Design (using Photoshop and Illustrator)</li>
<li> Object Orientated ActionScript</li>
<li> Flash and Flash IDE&#8217;s</li>
<li> Server Side Integration</li>
</ul>
<p>With the introduction out of the way, Lee went on to talk about some of the new features in Flash Player 10.  First up was native 3D - this provides full antialiased 3D inside with AS3, and, as it&#8217;s intrinsic to the player, it&#8217;s very fast!  Lee stressed that this was meant to compliment, not replace more mature and capable 3D engines like PaperVision (but mentioned that there were plenty of new API&#8217;s that those guys would be hooking in to to speed things up).  To accompany this, the drawing API has received an overhaul to allow drawing and manipulating programmatically generated 3D Objects</p>
<p>Next up was Adobe&#8217;s Advanced Text Engine - this is in the form of an AS3 API which Lee described as bewildering to anyone except &#8220;Text Nerds&#8221; - he said it provided an incredible amount of control - so much so that they were planning to release a CS4 component shortly after release which would allow &#8220;normal people&#8221; to harness it&#8217;s power - he did however say that this component would not ship with CS4.</p>
<p>Flash Player 10 will incorporate a host of &#8220;tweaks&#8221; including true Hardware Acceleration which will improve the speed of Video and Bitmap Manipulation (Filters, Pixel Bender operations).  Local file access will be included (but will require user prompts), the previously mentioned unloadAndStop() method will be added and the new <a href="http://www.mikechambers.com/blog/2008/08/19/using-vectors-in-actionscript-3-and-flash-player-10/">Vector datatype</a> for strongly typed Arrays.</p>
<p>One of the new features that Lee was getting excited about was <a href="http://www.kaourantin.net/2008/05/adobe-pixel-bender-in-flash-player-10.html">Pixel Bender</a> - this allows image processing with shaders and filters and looked very interesting.  Lee showed a custom demo where he <a href="http://theflashblog.com/?p=386">created his own filter</a> in HLSL (High Level Shader Language - which looked a bit like C#).  One of the most exciting things about Pixel Bender is the fact that it is threaded separately from Flash Player - Lee said that complex calculations could be passed off to the Pixel Bener to allow for Mutli Threading in Flash Applications - if this is true, and it&#8217;s as easy as Lee hinted then this will be a major break through for Flash Player and will be immensely useful for <a href="http://www.moshimonsters.com/">complex Flash Apps</a>.</p>
<p>Lee proceeded to talk about Adobe Air 1.5 and Flex Builder 4, neither of which sounded very exciting - alough Flex 4 will feature (yet another) XML based language for handling graphics in Flex.</p>
<p>Finally, Lee showed us some of the features of the new Flash CS4 IDE including live previews of 3d Images.  The Flash Properties Panel now includes a new Z property alongside the traditional x and y which allows you to move symbols in space (away from the camera) - he whipped up a simple, live demonstration of this which was very impressive, however, he insisted the really cold 3D features would only be available via AS3 scripting.  He wrapped up his Flash CS4 presentation by mentioning that the Flash IDE ActionScript Panel had not been touched in this release - in his own words - fail.</p>
<h2>The Best 8 to 12 Hours of My Life</h2>
<p><em>Robert Hodgin</em></p>
<p>The day ended with a visual presentation by <a href="http://www.flight404.com/">Robert Hodgin</a> who specialises in Audio Visualisation code - whilst not ActionScript based, his visuals provided some inspiring ideas and concepts along with a recommendation that the audience branch out and try a hit of &#8216;cid if they haven&#8217;t had the privilege.</p>
<p><a href="http://www.flight404.com/_videos/magnetosphere/index.html">Magneto Visulisation of Trentemoller&#8217;s Miss You</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/10/flash-on-the-beach-2008-tuesday-write-up/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu Netboot install with Windows (PXE)</title>
		<link>http://www.jonnyreeves.co.uk/2008/09/ubuntu-netboot-install-with-windows-pxe/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/09/ubuntu-netboot-install-with-windows-pxe/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 15:59:48 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=60</guid>
		<description><![CDATA[I&#8217;m the proud owner of a Dell X200 Laptop, which, due to it&#8217;s compact form factor (incredible seeing as it dates back to 2003!) lacks a CD-Rom and Floppy Disc Drive.  This makes installing operating systems a bit of a chore and seeing how my USB Pen Drive packed in at the weekend, the only [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m the proud owner of a Dell X200 Laptop, which, due to it&#8217;s compact form factor (incredible seeing as it dates back to 2003!) lacks a CD-Rom and Floppy Disc Drive.  This makes installing operating systems a bit of a chore and seeing how my USB Pen Drive packed in at the weekend, the only install method I had avaliable to me was a NetBoot install via PXE (Preboot Executing Environment).</p>
<p>Usually this is a pretty straight forward afair, but I had a bit of a problem - may laptop would only find the TFTP server if it was directly wired to it via a crossover cable (no doubt my POS Speedlink router was partly to blame).  After a couple of hours of faffing I finally managed to get a succesfull install with the following steps:</p>
<ol>
<li>Download a copy of <a href="http://tftpd32.jounin.net/tftpd32_download.html">TFTP32 for Windows</a></li>
<li>Directly wire your laptop to your desktop pc (which is running the TFTP server) with a crossover cable</li>
<li>Follow the Ubuntu <a href="https://help.ubuntu.com/community/Installation/WindowsServerNetboot">Windows Server Netboot Wiki Entry</a> to get the TFTP Server configured - make sure you set everything up to point towards your Router.  (ie: My router defaults to 192.168.1.254, so I set that as the gateway and gave the DHCP Server in TFTP32 a sensible range of IP Addresses to serve out.<a href="https://help.ubuntu.com/community/Installation/WindowsServerNetboot"><br />
</a></li>
<li>When the laptop boots via PXE, follow the guide right up to the Network interface seletion (should be just after the Keyboard layout).</li>
<li>At this point, unplug the cross over cable and wire the laptop directly into the router, wait a couple of seconds for it to autosense the connection and then proceed with the Ubuntu install - it should discover your router and recieve a new IP Address via DHCP</li>
<li>Sit back and smile as your laptop succesfully downloads the required packages from the ubuntu archives.</li>
</ol>
<p>Hope this helps someone out there</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/09/ubuntu-netboot-install-with-windows-pxe/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Typesafe Enums in ActionScript 2</title>
		<link>http://www.jonnyreeves.co.uk/2008/07/typesafe-enums-in-actionscript-2/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/07/typesafe-enums-in-actionscript-2/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 09:24:07 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[ActionScript 2]]></category>

		<category><![CDATA[actionscript]]></category>

		<category><![CDATA[as2]]></category>

		<category><![CDATA[enum]]></category>

		<category><![CDATA[events]]></category>

		<category><![CDATA[oo]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=59</guid>
		<description><![CDATA[Typesafe Enums are perfect when you want to get the message across loud and clear, with no room for error.  The classic use for an Enum is handling events, to give some context I&#8217;ll demonstrate how you could handle events without using an Enum:

/**
&#160;* This example method will send an event back to a [...]]]></description>
			<content:encoded><![CDATA[<p>Typesafe <a href="http://en.wikipedia.org/wiki/Enumerated_type">Enums</a> are perfect when you want to get the message across loud and clear, with no room for error.  The classic use for an Enum is handling events, to give some context I&#8217;ll demonstrate how you could handle events without using an Enum:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="coMULTI">/**<br />
&nbsp;* This example method will send an event back to a Registered Listener, in this<br />
&nbsp;* case we&#8217;re going to inform the listener that we have loaded our data and <br />
&nbsp;* are ready for use.<br />
&nbsp;*<br />
&nbsp;* &nbsp; &nbsp; &nbsp;@param Void<br />
&nbsp;* &nbsp; &nbsp; &nbsp;@return Void<br />
*/</span><br />
<span class="kw3">private</span> <span class="kw2">function</span> __onLoadComplete<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">Void</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// This forms the basis of the event we are going to send.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> eventObject:<span class="kw3">Object</span> = <span class="kw2">new</span> <span class="kw3">Object</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Populate our eventObject with its type &amp; the event message to send</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; eventObject.<span class="kw3">type</span> = <span class="st0">&#8216;ModelEvent&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; eventObject.<span class="me1">event</span> = <span class="st0">&#8216;data_loaded&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// And send the object via mx.events.EventDispatcher</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">dispatchEvent</span><span class="br0">&#40;</span>eventObject<span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>The listener object (in this case, a Controller), will then have a similar method for handling callbacks, again, without using an enum we would be left to switch on a string, something like this:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="coMULTI">/**<br />
&nbsp;* Example function, showing us registering the event listener to the Model with<br />
&nbsp;* a delegated callback to the __onModelEvent() function.<br />
&nbsp;*<br />
&nbsp;*&nbsp; &nbsp; &nbsp; @param Void<br />
&nbsp;*&nbsp; &nbsp; &nbsp; @return Void<br />
*/</span><br />
<span class="kw3">private</span> <span class="kw2">function</span> registerModel<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; model.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">&quot;modelEvent&quot;</span>, Delegate.<span class="me1">create</span><span class="br0">&#40;</span><span class="kw3">this</span>, __onModelEvent<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></p>
<p>
<span class="coMULTI">/**<br />
&nbsp;* Callback method which was registered at the same time as adding the eventListener<br />
&nbsp;* this method handles incoming events from registered models<br />
&nbsp;*<br />
&nbsp;*&nbsp; &nbsp; &nbsp; @param Object event object dispatched from registered model.<br />
&nbsp;*&nbsp; &nbsp; &nbsp; @return Void<br />
*/</span><br />
<span class="kw3">private</span> <span class="kw2">function</span> __onModelEvent<span class="br0">&#40;</span>event:<span class="kw3">Object</span><span class="br0">&#41;</span>:<span class="kw3">Void</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>event.<span class="me1">event</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;data_loaded&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">trace</span> <span class="br0">&#40;</span><span class="st0">&#8216;Controller::__onModelEvent &#8212; Data Loaded!&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;</p>
<p>&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; <span class="kw3">trace</span> <span class="br0">&#40;</span><span class="st0">&#8216;Controller::__onModelEvent &#8212; Unkown Model State recieved: &#8216;</span> + event.<span class="me1">event</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; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>Obviously this approach works, but it can lead to some quite obvious, yet tricky to find errors.   For example, what if I set the value of eventObject.state to &#8216;Data_Loaded&#8217;, or mashed the keyboard and entered &#8216;data_laoded&#8217;?  Of course, both these problems can be spotted (the trace() on default will help you debug typos, and a `event.state.toLowerCase()` would help with the first problem, but what about when other people are working with the code - how will they be able to tell which states are available to them, this is especially true if there are multiple listeners to modelEvents, maybe all the state&#8217;s aren&#8217;t show in each switch() - now we&#8217;re starting to see the bigger issue - one of software design.  Wouldn&#8217;t it be great if we could bring all the Model State messages into one place?</p>
<p>Say hello to the ModelEvent Enum Class:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="coMULTI">/**<br />
&nbsp;* ModelEvent.as<br />
&nbsp;* John Reeves, http://www.jonnyreeves.co.uk/<br />
&nbsp;* May 2008<br />
&nbsp;*<br />
&nbsp;* Typesafe Event dispatched from Models.<br />
*/</span><br />
<span class="kw2">class</span> ModelEvent<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> <span class="kw3">_name</span>:<span class="kw3">String</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> _level:<span class="kw3">Number</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Private Constructor for creating ModelEvent instances. &nbsp;This stops developers<br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; * creating their own ModelEvent&#8217;s in the code, instead we encourage people<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* to create Static Model Events below:<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">function</span> ModelEvent<span class="br0">&#40;</span><span class="kw3">name</span>:<span class="kw3">String</span>, <span class="kw3">level</span>:<span class="kw3">Number</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="kw3">this</span>.<span class="kw3">_name</span> = <span class="kw3">name</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>._level = <span class="kw3">level</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Static Events Models can Send.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">static</span> <span class="kw3">public</span> <span class="kw2">var</span> DATA_LOADED:ModelEvent = <span class="kw2">new</span> ModelEvent<span class="br0">&#40;</span><span class="st0">&#8216;DATA_LOADED&#8217;</span>, <span class="nu0">1</span><span class="br0">&#41;</span>;&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">static</span> <span class="kw3">public</span> <span class="kw2">var</span> DATA_ERROR:ModelEvent = <span class="kw2">new</span> ModelEvent<span class="br0">&#40;</span><span class="st0">&#8216;DATA_ERROR&#8217;</span>, <span class="nu0">2</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the ModelEvent object for the given ModelEvent String<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @param mediaType the MediaType&#8217;s name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @return the MediaType object<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span>&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw3">static</span> <span class="kw2">function</span> forName<span class="br0">&#40;</span>ModelEvent:<span class="kw3">String</span><span class="br0">&#41;</span>:ModelEvent<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><span class="br0">&#40;</span>ModelEvent<span class="br0">&#91;</span>ModelEvent.<span class="kw3">toUpperCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span> <span class="kw3">instanceof</span> ModelEvent<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> ModelEvent<span class="br0">&#91;</span>ModelEvent.<span class="kw3">toUpperCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</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 />
&nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the current ModelEvent&#8217;s name as a String<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> getName<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">String</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">this</span>.<span class="kw3">_name</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the current ModelEvent&#8217;s Level as a Number<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> getLevel<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">Number</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">this</span>._level;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Compares an incoming ModelEvent (x) to the current Object.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @param ModelEvent x Incoming ModelEvent Object to perform comparison on.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; @return Boolean true if it matches<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> equals<span class="br0">&#40;</span>x:ModelEvent<span class="br0">&#41;</span>:<span class="kw3">Boolean</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>x.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> == <span class="kw3">this</span>.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &amp;&amp; x.<span class="me1">getLevel</span><span class="br0">&#40;</span><span class="br0">&#41;</span> == <span class="kw3">this</span>.<span class="me1">getLevel</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="kw1">return</span> <span class="kw2">true</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> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>&nbsp; &nbsp; &nbsp; &nbsp;<br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>This class is used a little differently to most others.  As the constructor is set to private, we don&#8217;t expect developers to be creating instances of ModelEvent&#8217;s in their own code (so in the case of the Model&#8217;s __onLoadComplete() function which was shown above, we wouldn&#8217;t other developers using the new keyword to create their own instance of ModelEvent).  Instead, we expect developers to access the pre-defined ModelStates via the <strong>static</strong> public properties defined inside the class, let&#8217;s show a quick example and revisit our Model&#8217;s onLoadComplete method:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="coMULTI">/**<br />
&nbsp;* Now we will update this method to use the ModelEvent Enum class.<br />
&nbsp;*<br />
&nbsp;* &nbsp; &nbsp; &nbsp;@param Void<br />
&nbsp;* &nbsp; &nbsp; &nbsp;@return Void<br />
*/</span><br />
<span class="kw3">private</span> <span class="kw2">function</span> __onLoadComplete<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">Void</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// This forms the basis of the event we are going to send.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> eventObject:<span class="kw3">Object</span> = <span class="kw2">new</span> <span class="kw3">Object</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Populate our eventObject with its type &amp; the state message to send, </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// this time instead of setting state as a String, we set it to be on the </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// ModelEvent&#8217;s static properties.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; eventObject.<span class="kw3">type</span> = <span class="st0">&#8216;ModelEvent&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; eventObject.<span class="me1">event</span> = ModelEvent.<span class="me1">DATA_LOADED</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// And send the object via mx.events.EventDispatcher</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">dispatchEvent</span><span class="br0">&#40;</span>eventObject<span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>That was straight forward - an now we don&#8217;t have to worry about typo&#8217;s or mixing the case, any mistakes at this point will be caught by the Compiler when you build the swf.  Okay, that&#8217;s cool, but how do we handle recieving the events in the Controller?  Even easier!</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="coMULTI">/**<br />
&nbsp;* Callback method, this time update to handle the incoming ModelEvent<br />
&nbsp;*<br />
&nbsp;*&nbsp; &nbsp; &nbsp; @param Object event object dispatched from registered model.<br />
&nbsp;*&nbsp; &nbsp; &nbsp; @return Void<br />
*/</span><br />
<span class="kw3">private</span> <span class="kw2">function</span> __onModelEvent<span class="br0">&#40;</span>event:<span class="kw3">Object</span><span class="br0">&#41;</span>:<span class="kw3">Void</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// extract the ModelEvent Enum from the event Object</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> event:ModelEvent = event.<span class="me1">event</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Use the ModelEvent::equals method to perform comparison</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">equals</span><span class="br0">&#40;</span>ModelEvent.<span class="me1">DATA_LOADED</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="kw3">trace</span> <span class="br0">&#40;</span><span class="st0">&#8216;Controller::__onModelEvent &#8212; Data Loaded!&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>Of course, if you prefer you could switch based on event.getLevel() with the case statements performing comparisons on ModelEvent.DATA_LOADED.getLevel();</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/07/typesafe-enums-in-actionscript-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CNET TV Videos</title>
		<link>http://www.jonnyreeves.co.uk/2008/07/cnet-tv-videos/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/07/cnet-tv-videos/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 08:45:07 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[ActionScript 2]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=58</guid>
		<description><![CDATA[I&#8217;ve recently been slaving away on Version 4 of the CNET Video Player.  Today is the official launch of the new player and it would appear everything has gone smoothly.  The player features numerous enhancements over the previous version including a full XSPF playlist, XML Configuration, Support for related content at the end [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently been slaving away on Version 4 of the <a href="http://videos.cnet.co.uk/">CNET Video Player</a>.  Today is the official launch of the new player and it would appear everything has gone smoothly.  The player features numerous enhancements over the previous version including a full <a href="http://xspf.org">XSPF playlist</a>, XML Configuration, Support for related content at the end of playback and off site embedding (with full metrics).</p>
<p><center><br />
<!-- Start CNET Embed Player -->
<div style="width: 400px; overflow: hidden;"><object type="application/x-shockwave-flash" data="http://www.cnet.co.uk/embed/39039360" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="400" height="265" allowfullscreen="true"><param name="allowScriptAccess" value="always"/><param name="movie" value="http://www.cnet.co.uk/embed/39039360"/><param name="loop" value="false"/><param name="allowFullScreen" value="true"/><param name="quality" value="high"/><param name="bgcolor" value="#dddddd" /></object>
<div style="width: 400px; height: 26px; background-color: #dddddd; overflow: hidden;">
<ul style="text-align: left; margin: 5px 0; padding: 2px; font-size: 10px; font-family: arial; color: #999;">
<li style="list-style: none; float: left; margin-right: 5px;"><a href="http://videos.cnet.co.uk/39039360.htm" style="color: #fff; display: inline;">Sony Ericsson W760i</a></li>
<li style="list-style: none; float: left; margin-right: 5px;"><strong>|</strong></li>
<li style="list-style: none; float: left;"><a href="http://videos.cnet.co.uk/" style="color: #fff; display: inline;">More videos from CNET.co.uk</a></li>
</ul>
</div>
</div>
<p><!-- Finish CNET Embed Player --><br />
</center></p>
<p>I will try and give a more detailed write up of some of the component features at a later date, but for now it&#8217;s back to work rolling out the rest of the enhancements to the video page!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/07/cnet-tv-videos/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Actionscript - Loading Acute and UTF-8 Characters from XML into Dynamic Text with Flash</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/actionscript-acute-utf-8-data-xml-flash/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/actionscript-acute-utf-8-data-xml-flash/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 09:17:32 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[ActionScript 2]]></category>

		<category><![CDATA[actionscript]]></category>

		<category><![CDATA[acute]]></category>

		<category><![CDATA[dynamic text]]></category>

		<category><![CDATA[flash]]></category>

		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=54</guid>
		<description><![CDATA[Writing flexible applications in Flash is easy, (/me points in the direction of my XML Configuration Class) and there&#8217;s few reasons why all your text strings should not be read in at run time to allow for easy internationalization.
However, one pitfall to be aware of is trying to use Acutes and other &#8220;non-latin&#8221; characters in [...]]]></description>
			<content:encoded><![CDATA[<p>Writing flexible applications in Flash is easy, (/me points in the direction of my <a href="http://www.jonnyreeves.co.uk/2008/06/actionscript-20-configuration-class/">XML Configuration Class</a>) and there&#8217;s few reasons why all your text strings should not be read in at run time to allow for easy internationalization.</p>
<p>However, one pitfall to be aware of is trying to use Acutes and other &#8220;non-latin&#8221; characters in dynamic text fields (é, etc).  I was having a problem when these characters were not only not showing up, but all characters after the acute were being truncated!  Here&#8217;s my configuration XML:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span> <span class="re2">?&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;configuration<span class="re2">&gt;</span></span></span><br />
&nbsp;<span class="sc3"><span class="re1">&lt;textValue<span class="re2">&gt;</span></span></span>armén<span class="sc3"><span class="re1">&lt;/textValue<span class="re2">&gt;</span></span></span><br />
&nbsp;<span class="sc3"><span class="re1">&lt;/configuration<span class="re2">&gt;</span></span></span><br />
&nbsp;</div>
<p><em>Side Note: Flash Player 9 appears to ignore the <a href="http://www.w3schools.com/XML/xml_encoding.asp">XML Encoding</a> value specified in XML files, however it&#8217;s good practice to adhere to web standards, so make sure your XML&#8217;s encoding is set to UTF-8</em></p>
<p>The next obvious set is to ensure that you embedding all the required glyphs in your .fla file, you do this by clicking on the <em>Embed&#8230;</em> button for your Dynamic Textfield - make sure you embed all the Latin characters you need and then specify the acutes and other UTF-8 characters seperatley in the &#8220;include these characters:&#8221; textbox:</p>
<p><img src="http://www.jonnyreeves.co.uk/wp-content/uploads/2008/06/flash-character-embedding.gif" alt="The Character Embedding Dialouge in Flash CS3" title="flash-character-embedding" width="500" height="283" class="aligncenter size-full wp-image-55" /></p>
<p>Now this is where the problem comes in - when I try to compile and run this flash movie, instead of getting the text <em>armén</em> in my textfield, I get <em>arm</em> with both the acute (é) and any trailing characters truncated (in some cases (as in the screen shot below), I even get some of the trailing XML&#8230; eek!)</p>
<p><img src="http://www.jonnyreeves.co.uk/wp-content/uploads/2008/06/utf-8-dynamic-text-error1.jpg" alt="The UTF-8 Text String \&quot;armén\&quot; is breaking the layout" title="utf-8-dynamic-text-error1" width="442" height="334" class="aligncenter size-full wp-image-57" /></p>
<p>After a bit of head scratching I finally managed to track down the problem: The XML file must be saved as UTF-8 encoding!  (d&#8217;oh!)  However, in tracking down the problem I also discovered another workaround using <a href="http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary723.html">System.useCodepage</a>.  Setting this value to &#8216;true&#8217; in the first frame of your actionscript will force flash to ignore the character encoding of the XML document.</p>
<p>Hope this saves someone some time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/actionscript-acute-utf-8-data-xml-flash/feed/</wfw:commentRss>
		</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 - 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 - 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>
		</item>
		<item>
		<title>Holiday Photography</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/holiday-photography/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/holiday-photography/#comments</comments>
		<pubDate>Sun, 15 Jun 2008 08:20:39 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[photography]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=48</guid>
		<description><![CDATA[I&#8217;m back from a week long holiday in the bay of Elounda, Crete.  During my stay I took about 200 pictures using my trusty Samsung i6 my favourite of which were taken on the Island of Spinalonga which served as a leprosy colony until 1957, the following pic was snapped looking back towards Plaka.

The [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m back from a week long holiday in the bay of <a href="http://maps.google.co.uk/maps?f=q&#038;hl=en&#038;geocode=&#038;q=crete&#038;ie=UTF8&#038;ll=35.276806,25.729465&#038;spn=0.044214,0.062485&#038;t=h&#038;z=14">Elounda, Crete</a>.  During my stay I took about 200 pictures using my trusty <a href="http://www.digicamreview.co.uk/samsung_digimax_i6_review.htm">Samsung i6</a> my favourite of which were taken on the <a href="http://en.wikipedia.org/wiki/Spinalonga">Island of Spinalonga</a> which served as a leprosy colony until 1957, the following pic was snapped looking back towards Plaka.</p>
<p style="text-align: center;"><a href='http://www.jonnyreeves.co.uk/wp-content/uploads/2008/06/lonely-tree-spinalonga.jpg'><img src="http://www.jonnyreeves.co.uk/wp-content/uploads/2008/06/ssl20297.png" alt="A sole tree on the Island of Spinalonga, Crete" title="Lonely Tree, Spinalonga" width="500" height="242" class="aligncenter" /></a></p>
<p>The following picture was taken in the town of <a href="http://maps.google.co.uk/maps?f=q&#038;hl=en&#038;geocode=&#038;q=crete&#038;ie=UTF8&#038;t=h&#038;ll=35.188378,25.721295&#038;spn=0.002639,0.003905&#038;z=18&#038;iwloc=addr">Aghios Nikolaos</a>, which features a large central lake / dock which is famed for being bottomless and surrounded by restaurants.  This particular flower was found all around Crete and looked like a giant dandelion - the &#8220;ball&#8221; was comprised of hundreds of blue spikes.  I took this particular picture in response to a Chris&#8217; own picture, <a href="http://chris-beaumont.com/blog/2008/06/01/hyperactive-bumble-bee/">Drunken Bumble Bee</a> to which mine pales in comparison!</p>
<p style="text-align: center;"><a href='http://www.jonnyreeves.co.uk/wp-content/uploads/2008/06/mr-bee.jpg'><img src="http://www.jonnyreeves.co.uk/wp-content/uploads/2008/06/mr-bee-thumbnail.jpg" alt="A bee on a plant in Aghios Nikolaos" title="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/holiday-photography/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CakePHP - 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; - 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) - we present some helpful information to the user.
	</ull>
</ol>
<p><strong>Time for Some Code!</strong><br />
Okay, let&#8217;s start simple - 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 - is that any logic which relates to a Model (in our case, generating the Confirmation Link) should be done in the Model - 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/ - 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 - 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 - 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; - 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 - time to create the Email &#8220;views&#8221; which will be sent out with the emails - 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) - /users/activate - 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 - job done!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/cakephp-activating-user-account-via-email/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CakePHP - 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 - 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>
		</item>
	</channel>
</rss>
