<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Another Cake Baker</title>
	<atom:link href="http://lemoncake.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://lemoncake.wordpress.com</link>
	<description>My forays into the Kitchen</description>
	<lastBuildDate>Mon, 19 Dec 2011 08:11:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='lemoncake.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Another Cake Baker</title>
		<link>http://lemoncake.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://lemoncake.wordpress.com/osd.xml" title="Another Cake Baker" />
	<atom:link rel='hub' href='http://lemoncake.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Extending ACL to per field</title>
		<link>http://lemoncake.wordpress.com/2007/10/10/extending-acl-to-per-field/</link>
		<comments>http://lemoncake.wordpress.com/2007/10/10/extending-acl-to-per-field/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 23:40:29 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[acl]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/10/10/extending-acl-to-per-field/</guid>
		<description><![CDATA[In some recent comments I was asked how I would expand ACL to incorporate rights at a per field level. I can see how this would be useful, although in my opinion it would become too unweidly for the admin to assign rights. It would be easier for the administrators to have multiple actions/views with [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=32&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In some <a href="http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/#comment-394">recent comments</a> I was asked how I would expand ACL to incorporate rights at a per field level.  I can see how this would be useful, although in my opinion it would become too unweidly for the admin to assign rights.  It would be easier for the administrators to have multiple actions/views with the appropriate fields in them. I will outline both methods and there relative merits.</p>
<h2>ACL per Field</h2>
<p>The complex and ugly part of this method is the administration interface.  The actual creation of ACO&#8217;s and access control can be done quite elgantly in Cake using a behaviour.  All this requires is that in Model::afterSave() each fields ACO is created.  Similarly for access control, in Model::afterFind() loop over each field, check the current users permissions and then unset the fields that are restricted.</p>
<p><strong>Advantages</strong></p>
<ul>
<li>This method allows very fine grained control.  Each record will have it&#8217;s fields able to be restricted independantly of other records of the same model</li>
<li>When access rules change, views and actions don&#8217;t</li>
</ul>
<p><strong>Disadvantages</strong></p>
<ul>
<li>Greater ACL overhead</li>
<li>ACO table grows much faster with respect to number of model records.</li>
<li>Views bedome more complex (logic to test which fields are available)</li>
<li>Unweidly managment interface</li>
</ul>
<h2>Actions per Rols</h2>
<p>This method creates seperate actions/views based on the current users role, similar to the way admin_ works.  There are two options with this method.  Seperate actions and views per role, or seperate views only through $this-&gt;render($role.&#8217;_&#8217;.$action).  Personally I would use the seperate views only as this does not require creating Route rules &#8211; yes I am lazy <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Advantages</strong></p>
<ul>
<li>Simplified logic. One extra line per action and no extra ACL overhead.</li>
<li>Simplified management</li>
<li>Field control at the Model level, not record level</li>
</ul>
<p><strong>Disadvantages</strong></p>
<ul>
<li>Field access must be determined at design time</li>
<li>When rights change, so do views</li>
</ul>
<h2>Conclusion</h2>
<p>While the first method provide far greater control over field rights at a record level, I feel that it is overkill and not worth the extra ACL and database overhead.  In my experience, per user per record per field control has never been required.  The simplified view switch method provides more than enough control for the majority of applications.  </p>
<p>I find that access control is usually defined before implementation, and rarely changes while in production. This makes the trade of simplified code and management with the need to update files in the event of rights changes worth while.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/32/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/32/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=32&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/10/10/extending-acl-to-per-field/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>What I&#8217;ve learnt over the last two months</title>
		<link>http://lemoncake.wordpress.com/2007/09/19/what-ive-learnt-over-the-last-two-months/</link>
		<comments>http://lemoncake.wordpress.com/2007/09/19/what-ive-learnt-over-the-last-two-months/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 12:45:55 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/09/19/what-ive-learnt-over-the-last-two-months/</guid>
		<description><![CDATA[The last two months have been pretty hectic for me. I work full-time and also foolishly decided to do a full work load at university this semester as well. I found that the two don&#8217;t go togethter so well. Funny that. So I have learn&#8217;t the hard way that time managment is a skill and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=31&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The last two months have been pretty hectic for me.  I work full-time and also foolishly decided to do a full work load at university this semester as well.  I found that the two don&#8217;t go togethter so well. Funny that.  So I have learn&#8217;t the hard way that time managment is a skill and is a very hard skill to master.</p>
<p>Here are just a couple of other random things I have found out over the last few weeks:</p>
<ul>
<li>Outlook Addins are a pain to develop &#8211; in managed code at least.  I hear using unmanaged Win32 API is actually easier</li>
<li>Multiply that by 10 when  deploying your addin in a terminal services environment</li>
<li>Never &#8220;port&#8221; an Access &#8220;application&#8221; to .NET.  It is best to start from scratch and do it properly</li>
<li>Organising a group university assignment is a project in and of itself</li>
<li>Dragging yourself out of bed at 5 in the morning to go for a run eventually gets easier</li>
<li>Puppies are the cutest thing, but also the most annoying thing. Although I have taught her to sit</li>
</ul>
<p>The good news is that I am starting a rather large CakePHP project very soon, so expect to see some more regular Cake posts in the near future.</p>
<p>Oh and dont forget to check out the new CakePHP Podcast &#8220;<a href="http://live.cakephp.org">The Show</a>&#8220;.  Put a voice to those Cake characters we all know.  The podcast has a good vibe to it and is actually really informative, e.g. I didn&#8217;t know that Cake 1.2 can handle XML natively in models.  Jeff does a good job of interviewing Nate and gwoo in the pilot about the new features in the upcoming 1.2 version.  </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/31/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/31/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=31&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/09/19/what-ive-learnt-over-the-last-two-months/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Update on DbAcl ticket #2976</title>
		<link>http://lemoncake.wordpress.com/2007/08/27/update-on-dbacl-ticket-2976/</link>
		<comments>http://lemoncake.wordpress.com/2007/08/27/update-on-dbacl-ticket-2976/#comments</comments>
		<pubDate>Mon, 27 Aug 2007 01:14:59 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[acl]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/08/27/update-on-dbacl-ticket-2976/</guid>
		<description><![CDATA[Wow &#8211; ask and you shall recieve. Not long after I posted this, changset 5588 implemented Simons patch. One of the things that I have noticed about DbAcl, and other people have mentioned it as well on the Google Group, is that apart from not handling non-unique aliases very well, DbAcl node lookup will fail [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=29&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><ins datetime="2007-08-27T09:28:58+00:00">Wow &#8211; ask and you shall recieve. Not long after I posted this, <a href="https://trac.cakephp.org/changeset/5588">changset 5588</a> implemented Simons patch.</ins></p>
<p>One of the things that I have noticed about DbAcl, and other people have mentioned it as well on the Google Group, is that apart from not handling non-unique aliases very well, DbAcl node lookup will fail if the url does not have the full path in the ACO tree.  </p>
<p>For example, consider the following tree.</p>
<pre>ROOT
|_ controller1
|_ controller 2
  |_action 1</pre>
<p>If you then access http://localhost/controller1/ everything is fine.  But when you try to access  http://localhost/controller1/action1 you will get errors from DbAcl something like:<br />
<code>Warning (512): DB_ACL::check() - Failed ACO node lookup in permissions check.</code></p>
<p>Ok so just put all the actions in the database was my first solution. That is until I realised that something like /posts/view/id is going to need an ACO for every id, which seems a bit overkill. </p>
<p>What I would like is for non-existent children ACOs to automatically inherit from the parent and so on.  Obviously this is only suitable for ACOs based on urls.</p>
<p><a href="http://blog.jails.fr/cakephp/">Simon Jaillet</a> has submitted a new patch to the the CakePHP Trac Ticket <a href="https://trac.cakephp.org/ticket/2976">#2976</a>. Simon describes his reasons for creating the patch in his <a href="http://blog.jails.fr/cakephp/index.php?post/2007/08/15/AuthComponent-and-ACL">post</a> and goes on to describe his own ACL implementation.</p>
<p>The patch that Simon has submitted resolves the inheritence problem. Simon also submitted an updated test case that contains tests specifically for non-existent children.  I have tested this patch against the updated test cases and on some actual applications and I highly recommend updating to the latest svn trunk (5588 at time of update).<del datetime="2007-08-27T09:31:38+00:00">applying this patch &#8211; at least until it makes it into the core.  Which I sincerely hope that it does.</del></p>
<p>Kudos to Simon Jaillet, you are my new Acl hero having solved the inheritence problem for me.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/29/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/29/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=29&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/08/27/update-on-dbacl-ticket-2976/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Vendors in CakePHP</title>
		<link>http://lemoncake.wordpress.com/2007/08/08/vendors-in-cakephp/</link>
		<comments>http://lemoncake.wordpress.com/2007/08/08/vendors-in-cakephp/#comments</comments>
		<pubDate>Wed, 08 Aug 2007 10:44:32 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/08/08/vendors-in-cakephp/</guid>
		<description><![CDATA[While looking around just now I found a post complaining about vendors for not working like regular Cake magic includes such as the association variables. This is from the original post But I become strange when I tried to attach some personal library. They develop a shit name “vendor” to connect external library. This is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=28&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While looking around just now I found a post complaining about vendors for not working like regular Cake magic includes such as the association variables.</p>
<p>This is from the <a href="http://reazulk.wordpress.com/2007/07/10/stupid-cakephp-and-stupid-vendor-technique">original post </a></p>
<blockquote><p><em>But I become strange when I tried to attach some personal library. They develop a shit name “vendor” to connect external library. This is really bad news because they just attach this file with the script and if you have attached a class you have to call the class to make object.</em></p></blockquote>
<p>They then go on to complain that they can&#8217;t use Cakes database functions in their libraries.  If you are writing code &#8220;libraries&#8221; specifically for CakePHP then it should probably be a Component, Behaviour or Helper.</p>
<p>The reason vendors() is the way it is is because Cake makes no assumptions about 3rd party classes or libraries.  </p>
<p>For example: vendors(&#8216;my_library&#8217;) will load my_library.php but there my not be a MyLibrary class in the file.  In fact there may not even be any classes in there. Therefore Cake cannot automagically create a $this-&gt;MyLibrary variable.</p>
<p>When using vendors() you are left to use the library the old fashioned php way. i.e load, instatiate, use.  </p>
<p>Cake makes things easy but it cannot support every configuration in every third party library.  Sometimes you just have to do it yourself.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/28/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/28/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=28&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/08/08/vendors-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Multi-record Forms</title>
		<link>http://lemoncake.wordpress.com/2007/08/06/multi-record-forms/</link>
		<comments>http://lemoncake.wordpress.com/2007/08/06/multi-record-forms/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 12:31:51 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[n00b tip]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/08/06/multi-record-forms/</guid>
		<description><![CDATA[One question that comes up time and again on the Google Group is &#8220;How do I make a single form for more than one record?&#8221;, which I call multi-record forms. Multi-record forms have a repeated section in the form for multiple entries of the same data. The example that I am going to use is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=27&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One question that comes up time and again on the Google Group is &#8220;How do I make a single form for more than one record?&#8221;, which I call multi-record forms.  Multi-record forms have a repeated section in the form for multiple entries of the same data. The example that I am going to use is an Author with many Books.</p>
<p>In CakePHP this technique will be most commonly used with hasMany associations. Note that this technique is not specific to CakePHP but the code and conventions used are.</p>
<h3>Building the Form</h3>
<p>Our example form consists of an Authors name, date of birth and up to 5 book records with title,  year of publication and publisher.</p>
<p>Here is the view.</p>
<pre>&lt;form action="&lt;?= $html-&gt;url('/authors/add'); ?&gt;" method="post"&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Author Details&lt;/legend&gt;
    &lt;?= $form-&gt;input('Author.name'); ?&gt;
    &lt;?= $form-&gt;input('Author.dob', array('type' =&gt; 'date')); ?&gt;
  &lt;/fieldset&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Books Published&lt;/legend&gt;
    &lt;?php for ($i=0; $i&lt;5; $i++) : ?&gt;
    &lt;fieldset&gt;
      &lt;legend&gt;Book&lt;?= $i; ?&gt;&lt;/legend&gt;
      &lt;label for="BookTitle&lt;?= $i; ?&gt;"&gt;Title&lt;/label&gt; &lt;input type="text" name="data[Book][&lt;?= $i; ?&gt;][title]" id="BookTitle&lt;?= $i; ?&gt;" /&gt;
      &lt;?= $form-&gt;error('Book.'.$i.'.title'); ?&gt;&lt;br /&gt;
      &lt;label for="BookPublication&lt;?= $i; ?&gt;"&gt;Publication Year&lt;/label&gt; &lt;input type="text" name="data[Book][&lt;?= $i; ?&gt;][publication]" id="BookPublication&lt;?= $i; ?&gt;" /&gt;
      &lt;?= $form-&gt;error('Book.'.$i.'.publication'); ?&gt;&lt;br /&gt;
      &lt;label for="BookPublisher&lt;?= $i; ?&gt;"&gt;Publisher&lt;/label&gt; &lt;input type="text" name="data[Book][&lt;?= $i; ?&gt;][publisher]" id="BookPublisher&lt;?= $i; ?&gt;" /&gt;
      &lt;?= $form-&gt;error('Book.'.$i.'.publisher'); ?&gt;
    &lt;/fieldset&gt;
    &lt;?php endfor; ?&gt;
  &lt;/fieldset&gt;
&lt;/form&gt;</pre>
<p>The first fieldset is the Author details and is a constructed like a regular form.  The Books Published fieldset contains 5 sub-fieldsets that are created by a loop.  </p>
<p>Each sub-fieldset contains inputs with names in the format:<br />
<code>name="data[ModelName][index][fieldName]"</code><br />
<strong>N.B. </strong>Notice that there are no quotes surrounding the text in the square brackets.</p>
<h3>Using existing Data</h3>
<p>For an edit page the majority of the view would be the same.  The loop would change to:</p>
<pre>&lt;?php for ($i=0; $i&lt;count($this-&gt;data['Book']); $i++) : ?&gt;
&lt;fieldset&gt;
  &lt;legend&gt;Book&lt;?= $i; ?&gt;&lt;/legend&gt;
  &lt;input type="hidden" name="data[Book][&lt;?= $i; ?&gt;][id]" id="BookId&lt;?= $i; ?&gt;" value="&lt;?= $this-&gt;data['Book'][$i]['id']; ?&gt;" /&gt;
  &lt;label for="BookTitle&lt;?= $i; ?&gt;"&gt;Title&lt;/label&gt; &lt;input type="text" name="data[Book][&lt;?= $i; ?&gt;][title]" id="BookTitle&lt;?= $i; ?&gt;" value="&lt;?= $this-&gt;data['Book'][$i]['title']; ?&gt;" /&gt;
  &lt;?= $form-&gt;error('Book.'.$i.'.title'); ?&gt;&lt;br /&gt;
  &lt;label for="BookPublication&lt;?= $i; ?&gt;"&gt;Publication Year&lt;/label&gt; &lt;input type="text" name="data[Book][&lt;?= $i; ?&gt;][publication]" id="BookPublication&lt;?= $i; ?&gt;" value="&lt;?= $this-&gt;data['Book'][$i]['publication']; ?&gt;" /&gt;
  &lt;?= $form-&gt;error('Book.'.$i.'.publication'); ?&gt;&lt;br /&gt;
  &lt;label for="BookPublisher&lt;?= $i; ?&gt;"&gt;Publisher&lt;/label&gt; &lt;input type="text" name="data[Book][&lt;?= $i; ?&gt;][publisher]" id="BookPublisher&lt;?= $i; ?&gt;" value="&lt;?= $this-&gt;data['Book'][$i]['publisher']; ?&gt;" /&gt;
  &lt;?= $form-&gt;error('Book.'.$i.'.publisher'); ?&gt;
&lt;/fieldset&gt;
&lt;?php endfor; ?&gt;</pre>
<p>We simply changed the loop to terminate when all the books have been looped over, added a value attribute to the inputs and added an hidden id field so that our records get updated correctly.</p>
<h3>Saving the Submitted Form</h3>
<p>To save the submitted form we loop over each index in the Books array and save it to the database with the authors id. </p>
<p>It is important that Model::create() gets called during each iteration otherwise you will end up inserting on the first iteration and then updating each subsequent iteration. </p>
<p>By using Model::set() we can take advantage of validation rules in the model.  However, any validation error messages wont be associated with the correct Book fields. To get around this we manually invoke Model::validates() and if this fails we reassign the invalid fields to a temporary array.  Then if there are any errors we feed this temporary array back to the model so that the view has the correct data.</p>
<pre>function add(){
  if (!empty($this-&gt;data)) {
    if ($this-&gt;Author-&gt;save()) {
      // grab the id of the Author we just saved
      $author_id = $this-&gt;Author-id;

      $invalidBookFields = array();
      foreach($this-&gt;data['Book'] as $index =&gt; $book) {
        $book = array('Book' =&gt; $book);
        $book['Book']['author_id'] = $author_id;

        // clear any previous Book data
        $this-&gt;Author-&gt;Book-&gt;create();
        // We set the Book data this way so that validation is processed correctly
        $this-&gt;Author-&gt;Book-&gt;set($book);
        if (!$this-&gt;Author-&gt;Book-&gt;validates()) {
          // save the validationErrors and reset for the next iteration
          $invalidBookFields[$index] = $this-&gt;Author-&gt;Book-&gt;validationErrors;
          unset($this-&gt;Author-&gt;Book-&gt;validationErrors);
        } else {
          $this-&gt;Author-&gt;Book-&gt;save();
        }
      }

      if (empty($invalidBookFields)) {
      	// success - set message or redirect
      } else {
      	// put all the errors back in the model so they make it back to the view
      	$this-&gt;Author-&gt;Book-&gt;validationErrors = $invalidBookFields;
      }
    }
  }
}
</pre>
<h3>Enhancements</h3>
<p>If you need to make sure that all Books are valid before saving any of them you will need to loop the Books array twice.  The first loop should validate each Book, then if there are no errors the second loop saves each Book.</p>
<p>If you do not know before hand how many items you need on your form you can use javascript or AJAX to dynamically add form elements as you need them.  </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/27/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/27/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=27&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/08/06/multi-record-forms/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Firefox Logo Crop Circle</title>
		<link>http://lemoncake.wordpress.com/2007/07/23/firefox-logo-crop-circle/</link>
		<comments>http://lemoncake.wordpress.com/2007/07/23/firefox-logo-crop-circle/#comments</comments>
		<pubDate>Sun, 22 Jul 2007 23:50:58 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[crop circle]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[fun]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/07/23/firefox-logo-crop-circle/</guid>
		<description><![CDATA[Just found this while playing around in Google Maps My Maps feature. A 67 metre Firefox logo as a crop circle. Its been around since August 2006 and apparently it&#8217;s not the first of such stunts by a Linux user group at Oregon State University. When they do a job they do it properly, &#8211; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=26&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just found this while playing around in Google Maps My Maps feature. <a href="http://maps.google.com/maps?ll=45.123547,-123.113405&amp;spn=0.002536,0.00479&amp;t=k&amp;z=18&amp;om=1">A 67 metre Firefox logo as a crop circle</a>. </p>
<p><a href="http://maps.google.com/maps?ll=45.123547,-123.113405&amp;spn=0.002536,0.00479&amp;t=k&amp;z=18&amp;om=1" title="Firefox Crop Circle on Google Maps"><img src="http://farm2.static.flickr.com/1400/873133442_b9f153c9ae_o.jpg" width="470" height="362" alt="firefox-crop-circle" /></a></p>
<p>Its been around since August 2006 and apparently it&#8217;s not the first of such stunts by a Linux user group at Oregon State University. When they do a job they do it properly, &#8211; they went all out with helicopters and planes documenting the process.  </p>
<p>Link to the <a href="http://lug.oregonstate.edu/index.php/Projects/Firefox">groups site</a>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/26/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/26/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=26&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/07/23/firefox-logo-crop-circle/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>

		<media:content url="http://farm2.static.flickr.com/1400/873133442_b9f153c9ae_o.jpg" medium="image">
			<media:title type="html">firefox-crop-circle</media:title>
		</media:content>
	</item>
		<item>
		<title>ACL with Groups</title>
		<link>http://lemoncake.wordpress.com/2007/07/19/acl-with-groups/</link>
		<comments>http://lemoncake.wordpress.com/2007/07/19/acl-with-groups/#comments</comments>
		<pubDate>Thu, 19 Jul 2007 12:27:12 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[acl]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/07/19/acl-with-groups/</guid>
		<description><![CDATA[In a previous article I explained how to use the AclBehavior to create models that can be used for ACL. Now the situation is &#8211; I want to assign permission to groups and have Users be a member of a group. I thought this would be easy using the AclBehavior. Turns out I was right, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=25&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In a previous article I explained how to <a href="http://lemoncake.wordpress.com/2007/07/15/using-aclbehavior-in-cakephp-12/">use the AclBehavior</a> to create models that can be used for ACL.</p>
<p>Now the situation is &#8211; I want to assign permission to groups and have Users be a member of a group.  I thought this would be easy using the AclBehavior.  Turns out I was right, but it took me while to realise I was right.</p>
<p>So we are going to use the following Group model.  It should look familiar. The database has a parent_id field in the groups table.  This model allows us to create a heirachy of group roles.</p>
<pre>&lt;?php
class Group extends AppModel {
  var $name = 'Group';
  var $actsAs = array('Acl');

  function parentNode(){
    if (!$this-&gt;id) {
      return null;
    }

    $data = $this-&gt;read();

    if (!$data['Group']['parent_id']){
      return null;
    } else {
      return $data['Group']['parent_id'];
    }
  }

}
?&gt;</pre>
<p>Now, for <a href="http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/">ACL to work the easy way</a>, we need to have our users in the Aro table as well.  In your users table you need a field called group_id, and then use the belongsTo association to relate the user to a group.  We also need to use the AclBehavior to get our users into the aro table.  </p>
<p>Thats all pretty simple and straight forward. The trick is making the user aros children of a group aro.  The parentNode() function is where the magic happens.  Instead of returning a single id, you return an array with a two keys: model and foreign_key.  This will allow the AclBehavior to locate the appropriate parent Aro node.</p>
<pre>&lt;?php
class User extends AppModel {
  var $name = 'User';
  var $belongsTo = array('Group');
  var $actsAs = array('Acl');

  function parentNode(){
    if (!$this-&gt;id) {
      return null;
    }

    $data = $this-&gt;read();

    if (!$data['User']['group_id']){
      return null;
    } else {
      return array('model' =&gt; 'Group', 'foreign_key' =&gt; $data['User']['group_id']);
    }
  }

}
?&gt;</pre>
<p>Now your User Aros are children of Group Aros.  Simply assign permissions to the Group Aros and the Users will automatically inherit them.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/25/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/25/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/25/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=25&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/07/19/acl-with-groups/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Using AuthComponent and ACL in CakePHP 1.2</title>
		<link>http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/</link>
		<comments>http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/#comments</comments>
		<pubDate>Thu, 19 Jul 2007 07:14:23 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[acl]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/</guid>
		<description><![CDATA[The uniqueness issues and also an issue with inheritence has been solved in changset 5588 Important Update (2007-07-24) : Brian brought to my attention a problem with multiple actions that have the same name. This problem is due to an incorrect Sql query in db_acl.php. I have filed Trac Ticket #2976 which includes a patch, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=21&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><ins datetime="2007-08-29T10:03:27+00:00">The uniqueness issues and also an <a href="http://lemoncake.wordpress.com/2007/08/27/update-on-dbacl-ticket-2976/">issue with inheritence</a> has been solved in <a href="https://trac.cakephp.org/changeset/5588">changset 5588</a></ins></p>
<p><del datetime="2007-08-29T10:03:27+00:00"><strong>Important Update (2007-07-24) : </strong> Brian <a href="http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/#comment-75">brought to my attention</a> a problem with multiple actions that have the same name. This problem is due to an incorrect Sql query in db_acl.php.  I have filed <a href="https://trac.cakephp.org/ticket/2976">Trac Ticket #2976</a> which includes a patch, unit test and test fixtures.</del></p>
<p>So I&#8217;ve shown you how to <a href="http://lemoncake.wordpress.com/2007/07/15/using-aclbehavior-in-cakephp-12/">create a User Model that can be used for ACL</a>, but what is next?</p>
<p>The AuthComponent allows you to both authenticate and authorize your users in a relatively simple manner &#8211; once you know how.  This took me a lot of source code digging, mail list browsing and googling to find the way that &#8220;just works&#8221;.</p>
<h2>Setting up Aco&#8217;s, Aro&#8217;s and Permissions</h2>
<p>First of, we need to have some Aro&#8217;s and Aco&#8217;s.  Aro&#8217;s are the User model from above and are simple enough &#8211; you can get away with scaffolding if you want.  </p>
<p>Aco&#8217;s took me a little longer to figure out. There are going to be controller action pairs, naturally, but the catch was how to put these into the database.  It turns out that you need to have Controllers at one level, with actions children of there respective controllers.  This might seem obvious but I was trying to save the actions with an alias of &#8220;controller/action&#8221; when they should just be &#8220;action&#8221;.</p>
<p>Your tree of Aco aliases should look like the following:</p>
<pre>ROOT
|-Controller1
  |-index
  |-action1
  |-action2
|-Controller2
  |-index
  |-action1</pre>
<p>Pretty straight forward once you know how. This way the path can be followed down (or up actually) by the AclComponent.  It also allows you to create wholesale permissions such as denying a whole controller by setting the permissions on the controller level.</p>
<p>Then all you need to do is grant Users access to actions.  Because we are using User models the easist way is with a series of commands like:</p>
<pre>$this-&gt;Acl-&gt;allow(array('model' =&gt; 'User', 'foreign_key' =&gt; $id), 'Controller1/action');</pre>
<h2>Using AuthComponent for Authentication</h2>
<p>The AuthComponent is a really great tool and is very flexible.  This post will only show one way to use it, but there are many other ways to put it to use.</p>
<p>First up, we will use AuthComponent for authentication.  This part is pretty straight forward, but requires a little configuration.  The best place to do this is in AppController::beforeFilter().</p>
<p>You need to include the AclComponent and the AuthComponent in AppController.</p>
<pre>var $components = array('Acl', 'Auth');</pre>
<p><strong>It is very import that you include the AclComponent before the AuthComponent</strong> otherwise you will get this funky error message.</p>
<pre>Fatal error: Call to a member function check() on a non-object in /var/www/geoff/cake/cake/libs/controller/components/acl.php on line 87</pre>
<p>The reason for this is that Components are started in the order they appear in the $components list, and the AuthComponent does all its magic at startup, so when Auth tries to use Acl::check() there is no Acl. </p>
<p>For authentication we need to set the loginAction and loginRedirect properties.</p>
<pre>function beforeFilter(){
  if (isset($this-&gt;Auth)) {
    $this-&gt;Auth-&gt;loginAction = '/users/login';
    $this-&gt;Auth-&gt;loginRedirect = '/users/account';
  }
}</pre>
<p>You can also set the fields that are used for authentication if your user model does not use the default of &#8216;username&#8217; and &#8216;password&#8217;.</p>
<pre>$this-&gt;Auth-&gt;fields = array('username' =&gt; 'login_name', 'password' =&gt; 'p4sswrd');</pre>
<p>It is worth noting that the AuthComponent will hash the password for security reasons.  This is default behaviour and it can not be overriden.  Where I got caught out (again) was that I had a before save on my user model that hashed the password in the same manner as AuthComponent. <strong>Do not hash your passwords at the model level if you have included the AuthComponet at the AppController level.</strong> The AuthComponent will hash it before it gets to your beforeSave and you will end up with double hashed passwords in the database and therefore unable to login.</p>
<p>Another good config option is the userScope property.  It allows you to add other conditions to the authentication query, such as checking a disabled field. </p>
<pre> $this-&gt;Auth-&gt;userScope = array('User.disabled' =&gt; 0);</pre>
<h2>Using AuthComponent for Authorization</h2>
<p>So that was how to set your authentication.  Setting up AuthComponet for authorization against ACL is actually easier.  One extra line of code.</p>
<pre>$this-&gt;Auth-&gt;authorize = 'actions';</pre>
<p>This will use the User Aro&#8217;s created above that corresponds to the User just authenticated, and test it against the current controller and action.  Surprisingly easy. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Final Result</h2>
<p>The final AppController should look like:</p>
<pre>class AppController extends Controller {
  var $helpers = array('Html', 'Javascript', 'Form');
  var $components = array('Acl', 'Auth');
  var $publicControllers = array('pages');

  function beforeFilter(){
    if (isset($this-&gt;Auth)) {
      $this-&gt;Auth-&gt;userScope = array('User.disabled' =&gt; 0);
      $this-&gt;Auth-&gt;loginAction = '/users/login';
      $this-&gt;Auth-&gt;loginRedirect = '/users/account';
      $this-&gt;Auth-&gt;fields = array('username' =&gt; 'username', 'password' =&gt; 'passwrd');
      $this-&gt;Auth-&gt;authorize = 'actions';

      if (in_array(low($this-&gt;params['controller']), $this-&gt;publicControllers)) {
	    $this-&gt;Auth-&gt;allow();
      }
    }
  }
}</pre>
<p>$this-&gt;publicControllers allows you to assign controllers which do not require authentication or authorization.  I mainly use it to grant access to the pages contoller.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/21/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/21/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/21/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=21&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/feed/</wfw:commentRss>
		<slash:comments>69</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Cracked 100</title>
		<link>http://lemoncake.wordpress.com/2007/07/17/cracked-100/</link>
		<comments>http://lemoncake.wordpress.com/2007/07/17/cracked-100/#comments</comments>
		<pubDate>Tue, 17 Jul 2007 03:10:06 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/07/17/cracked-100/</guid>
		<description><![CDATA[Thanks to all the readers yesterday who helped me pass 100 hits in a day &#8211; 135 to be exact. This may not impress some, but I think it is alright for a niche blog that has only been running for 40 days. So cheers to you all.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=23&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Thanks to all the readers yesterday who helped me pass 100 hits in a day &#8211; 135 to be exact.  This may not impress some, but I think it is alright for a niche blog that has only been running for 40 days.  </p>
<p>So cheers to you all. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/23/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/23/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=23&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/07/17/cracked-100/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
		<item>
		<title>Using AclBehavior in CakePHP 1.2</title>
		<link>http://lemoncake.wordpress.com/2007/07/15/using-aclbehavior-in-cakephp-12/</link>
		<comments>http://lemoncake.wordpress.com/2007/07/15/using-aclbehavior-in-cakephp-12/#comments</comments>
		<pubDate>Sun, 15 Jul 2007 00:33:32 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[acl]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[n00b tip]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://lemoncake.wordpress.com/2007/07/15/using-aclbehavior-in-cakephp-12/</guid>
		<description><![CDATA[CakePHP 1.2 has a new AclBehavior which makes using the inbuilt ACL easier. AclBehavior makes the association between your model and the Aro (or Aco) database entry automatic. It handles the insert, updates and deletes whenever you modify your model. All that is required to use the AclBehavior is a function called parentNode(). AclBehavior can [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=22&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>CakePHP 1.2 has a new AclBehavior which makes using the inbuilt ACL easier.  AclBehavior makes the association between your model and the Aro (or Aco) database entry automatic.  It handles the insert, updates and deletes whenever you modify your model.  All that is required to use the AclBehavior is a function called parentNode().  </p>
<p>AclBehavior can be used for creating AROs or ACOs.  Any model may be an Access Request Object, but typically it is either the User model or a Group model that authorization is done on. In either case it is the same for any model you choose.  AclBehavior defaults to creating AROs which is what we want.  As for ACOs, usually these are controllers and/or actions, which don&#8217;t lend themselves to the AclBehavior so well.</p>
<p>First step is to set up your database ACL tables with</p>
<pre>cake acl initdb</pre>
<h4>Basics</h4>
<p>You need to include the behaviour and create a function called parentNode.  This is the minimum required to use AclBehavior. </p>
<pre>&lt;?php
class User extends AppModel {
  var $name = 'User';
  var $actsAs = array('Acl');

  function parentNode(){
  }
}?&gt;</pre>
<h4>What is the parentNode() function for? </h4>
<p>It is used when you have cascading, or inherited permissions, for example a Group model.  The parentNode() function must return the id of the parent Model (not the id of the parent Aro).  Typically this will be the parent_id of your Model, if you are using the standard convention for trees in Cake.</p>
<pre>&lt;?php
class Group extends AppModel {
  var $name = 'Group';
  var $actsAs = array('Acl');

  function parentNode(){
    if (!$this-&gt;id) {
      return null;
    }

    $data = $this-&gt;read();

    if (!$data['Group']['parent_id']){
      return null;
    } else {
      return $data['Group']['parent_id'];
    }
  }

}
?&gt;</pre>
<p>That&#8217;s it. Your model is now associated with an Aro entry in the aro table in your database.</p>
<h4>Further Reading</h4>
<p><del datetime="2007-07-19T11:01:09+00:00">Keep an eye out for my upcoming article on the Auth Component</del>. See my post <a href="http://lemoncake.wordpress.com/2007/07/19/using-authcomponent-and-acl-in-cakephp-12/">Using AuthComponent and ACL in CakePHP 1.2</a><br />
Also see <a href="http://lemoncake.wordpress.com/2007/07/19/acl-with-groups/">Groups with ACL</a> for using groups and users together<br />
In the meantime I highly recommend the article <a href="http://www.ad7six.com/MiBlog/Blogs/view/ACLPart1">Access Control for all (Part 1)</a> by AD7six</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/lemoncake.wordpress.com/22/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/lemoncake.wordpress.com/22/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lemoncake.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lemoncake.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lemoncake.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lemoncake.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lemoncake.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lemoncake.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lemoncake.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lemoncake.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lemoncake.wordpress.com&amp;blog=1201424&amp;post=22&amp;subd=lemoncake&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lemoncake.wordpress.com/2007/07/15/using-aclbehavior-in-cakephp-12/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/2cccfc6fd9ffe56a3701e21fc793dcaa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Geoff</media:title>
		</media:content>
	</item>
	</channel>
</rss>
