<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Thomas &#187; PHP</title>
	<atom:link href="http://anthonygthomas.com/category/web-development/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://anthonygthomas.com</link>
	<description>Father to two, husband to one, web developer and musician.</description>
	<lastBuildDate>Fri, 27 Apr 2012 19:26:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Simple RSS Parsing and Caching Using PHP</title>
		<link>http://anthonygthomas.com/2011/03/12/simple-rss-parsing-and-caching-using-php/</link>
		<comments>http://anthonygthomas.com/2011/03/12/simple-rss-parsing-and-caching-using-php/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 02:23:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=481</guid>
		<description><![CDATA[I feel like I should begin by stating that my college degree is in English Literature. In other words, I am not formally trained to be a programmer. Still I&#8217;ve spent many years working in PHP. It can be liberating to find out that something you thought would be complicated, is actually not that hard [...]]]></description>
			<content:encoded><![CDATA[<p>I feel like I should begin by stating that my college degree is in English Literature. In other words, I am not formally trained to be a programmer. Still I&#8217;ve spent many years working in PHP. It can be liberating to find out that something you thought would be complicated, is actually not that hard when broken down into discrete steps.</p>
<p>This whole adventure started for me when I went looking for a way to parse an <acronym title="Really Simple Syndication">RSS</acronym> feed. Contrary to those who proclaim that <a href="http://www.google.com/search?sourceid=chrome&#038;ie=UTF-8&#038;q=rss+is+dead" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?sourceid=chrome_038_ie=UTF-8_038_q=rss+is+dead&amp;referer=');">RSS is dead</a>, at it&#8217;s heart, RSS is <acronym title="eXtenxible Markup Language">XML</acronym>. As such it&#8217;s a useful method to access content. In my case, I wanted to parse my blog RSS feed as well as my most recent <a href="http://twitter.com/truetone" onclick="pageTracker._trackPageview('/outgoing/twitter.com/truetone?referer=');">Tweets</a>. That was revelation number one.</p>
<blockquote><p>RSS is XML > XML has a structure that can be put into objects in PHP</p></blockquote>
<p>To many of my friends and colleagues, this may seem incredibly simple. To me it was a revelation that opened up a new door. I&#8217;ve never tried to create an RSS parser before. Suddenly it was less daunting. (Aside: For me, simple truths often come as revelations. To know me is to know this.)<br />
<span id="more-481"></span></p>
<h3>Parsing the RSS Feed</h3>
<p>It turns out that PHP 5 has some really handy tools for dealing with HTML and XML in the <a href="http://php.net/manual/en/class.domdocument.php" onclick="pageTracker._trackPageview('/outgoing/php.net/manual/en/class.domdocument.php?referer=');">DOMDocument</a> class.</p>
<p>First, we create an array to store the XML. Next instantiate <code>DOMDocument</code> and call the <code>load</code> function:</p>
<pre class="brush: php; title: ; notranslate">$doc = new DOMDocument();
$doc-&gt;load($url);</pre>
<p>Then it&#8217;s as simple as looping through the XML nodes and storing what you want in the <code>$xml</code> array. For this use <code>getElementsByTagName</code>:</p>
<pre class="brush: php; title: ; notranslate">foreach ($doc-&gt;getElementsByTagName('item') as $node)
{
    //do stuff
}</pre>
<p>In my case I knew the most I wanted was a simple list with title, description, link and date. Thus:</p>
<pre class="brush: php; title: ; notranslate">foreach ($doc-&gt;getElementsByTagName('item') as $node)
{
    $rss = array (
        'title' =&gt; $node-&gt;getElementsByTagName('title')-&gt;item(0)-&gt;nodeValue,
        'description' =&gt; $node-&gt;getElementsByTagName('description')-&gt;item(0)-&gt;nodeValue,
        'link' =&gt; $node-&gt;getElementsByTagName('link')-&gt;item(0)-&gt;nodeValue,
        'date' =&gt; $node-&gt;getElementsByTagName('pubDate')-&gt;item(0)-&gt;nodeValue
        );
    }
}</pre>
<p>Now each loop loads the information I want into an array called <code>$rss</code>. Next just push that into the <code>$xml</code> array:</p>
<pre class="brush: php; title: ; notranslate">foreach ($doc-&gt;getElementsByTagName('item') as $node)
{
    $rss = array (
        'title' =&gt; $node-&gt;getElementsByTagName('title')-&gt;item(0)-&gt;nodeValue,
        'description' =&gt; $node-&gt;getElementsByTagName('description')-&gt;item(0)-&gt;nodeValue,
        'link' =&gt; $node-&gt;getElementsByTagName('link')-&gt;item(0)-&gt;nodeValue,
        'date' =&gt; $node-&gt;getElementsByTagName('pubDate')-&gt;item(0)-&gt;nodeValue
        );
      array_push($xml, $rss);
    }
}</pre>
<p>Finally I serialized the data to store it in a cache file. So we end up with:</p>
<pre class="brush: php; title: ; notranslate">protected function getFeed($url)
{
    $xml = array();
    $doc = new DOMDocument();
    $doc-&gt;load($url);
    foreach ($doc-&gt;getElementsByTagName('item') as $node)
    {
      $rss = array (
        'title' =&gt; $node-&gt;getElementsByTagName('title')-&gt;item(0)-&gt;nodeValue,
        'description' =&gt; $node-&gt;getElementsByTagName('description')-&gt;item(0)-&gt;nodeValue,
        'link' =&gt; $node-&gt;getElementsByTagName('link')-&gt;item(0)-&gt;nodeValue,
        'date' =&gt; $node-&gt;getElementsByTagName('pubDate')-&gt;item(0)-&gt;nodeValue
        );
      array_push($xml, $rss);
    } //endforeach element ids
    return serialize($xml);
  }
}</pre>
<p>So now we can deal with the RSS information. Next we just have to create a way to cache it so the feed isn&#8217;t unnecessarily pulled in over and over. This is when another liberating revelation came my way. I began to look for methods of caching and I saw the following advice on a forum:</p>
<blockquote><p>Get the feed. Write it to a text file. For each new request, check the mod time of the text file. It enough time has passed, update the file.</p></blockquote>
<p>There are probably more complex caching algorithms than this, but it seemed like a good place to start. So I wrote a caching function. It takes an array with two parameters. The name of the service as the array key and the url of the RSS feed. First we check to see if a cache file exists, and if it does, we check to see whether or not it has expired. I chose an arbitrary span of 60 seconds for my cache file:</p>
<pre class="brush: php; title: ; notranslate">public function checkCache($data=array())
{
    foreach ($data as $service =&gt; $feed)
    {
      $path = '/tmp/' . $service . '.cache';
      if ((!file_exists($path) || time() - filemtime($path) &gt; 60) &amp;&amp; $cache = fopen($path, 'w+'))
      {
           // do stuff
      }
    }
}</pre>
<p>So if there is no file, or the requisite time has expired and the file can be opened we call the aforementioned <code>getFeed</code> function to get the feed data, write it to the file and send it to the webpage:</p>
<pre class="brush: php; title: ; notranslate">$rss_contents = $this-&gt;getFeed($feed);
fwrite($cache, $rss_contents);
fclose($cache);
return unserialize($rss_contents);</pre>
<p>If the cache doesn&#8217;t need to be updated, we simply read it and send the data that way:</p>
<pre class="brush: php; title: ; notranslate">$cache = fopen($path, 'r');
return unserialize(file_get_contents($path)); // remember to unserialize since we serialized it initially
fclose($cache);</pre>
<p>The whole function looks like this:</p>
<pre class="brush: php; title: ; notranslate">public function checkCache($data=array())
{
  foreach ($data as $service =&gt; $feed)
  {
    $path = '/tmp/' . $service . '.cache';
    if ((!file_exists($path) || time() - filemtime($path) &gt; 60) &amp;&amp; $cache = fopen($path, 'w+'))
    {
      $rss_contents = $this-&gt;getFeed($feed);
      fwrite($cache, $rss_contents);
      fclose($cache);
      return unserialize($rss_contents);
    }
    else
    {
      $cache = fopen($path, 'r');
      return unserialize(file_get_contents($path));
      fclose($cache);
    }
  }
}</pre>
<p>The entire class together looks like this:</p>
<pre class="brush: php; title: ; notranslate">&lt;?php
class RssParser
{
  public function checkCache($data=array())
  {
    foreach ($data as $service =&gt; $feed)
    {
      $path = '/tmp/' . $service . '.cache';
      if ((!file_exists($path) || time() - filemtime($path) &gt; 60) &amp;&amp; $cache = fopen($path, 'w+'))
      {
        $rss_contents = $this-&gt;getFeed($feed);
        fwrite($cache, $rss_contents);
        fclose($cache);
        return unserialize($rss_contents);
      }
      else
      {
        $cache = fopen($path, 'r');
        return unserialize(file_get_contents($path));
        fclose($cache);
      }
    }
  }

  protected function getFeed($url)
  {
    $xml = array();
    $doc = new DOMDocument();
    $doc-&gt;load($url);
    foreach ($doc-&gt;getElementsByTagName('item') as $node)
    {
      $rss = array (
        'title' =&gt; $node-&gt;getElementsByTagName('title')-&gt;item(0)-&gt;nodeValue,
        'description' =&gt; $node-&gt;getElementsByTagName('description')-&gt;item(0)-&gt;nodeValue,
        'link' =&gt; $node-&gt;getElementsByTagName('link')-&gt;item(0)-&gt;nodeValue,
        'date' =&gt; $node-&gt;getElementsByTagName('pubDate')-&gt;item(0)-&gt;nodeValue
        );
      array_push($xml, $rss);
    } //endforeach element ids
    return serialize($xml);
  }
}</pre>
<p>Finally, we instantiate it in the page where we&#8217;re going to use it and loop through it:</p>
<pre class="brush: php; title: ; notranslate">&lt;?

include_once('/path/to/rss_parser.class.php'); // include the php file with the class

$parser = new RssParser(); // instantiate the class
$blog_feed = $parser-&gt;checkCache(array('blog' =&gt; 'http://yourdomain.com/feed/')); // load the RSS
?&gt;
&lt;ul&gt;
&lt;?
foreach ($blog_feed as $key =&gt; $items)
{
    if ($key &lt; 5): ?&gt;
	&lt;li&gt;&lt;a href=&quot;&lt;?= $items['link'] ?&gt;&quot;&gt;&lt;?= $items['title'] ?&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;?php
    endif;
} //endforeach
?&gt;
&lt;/ul&gt;</pre>
<p>Done!</p>
<h3>Caveats</h3>
<p>Depending on your server configuration, you may need to put the class in your public directory. If you need to do that, make sure you put it in a directory with &#8217;750&#8242; permissions.</p>
<p>Also, your PHP configuration may not allow you to open urls with <code>fopen</code>. In that case, I suggest you use the <a href="http://us2.php.net/manual/en/book.curl.php" onclick="pageTracker._trackPageview('/outgoing/us2.php.net/manual/en/book.curl.php?referer=');">cURL library</a>.</p>
<p>This is a very simple RSS parsing and caching engine, but it works and it&#8217;s a good start to working with PHP and XML.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2011/03/12/simple-rss-parsing-and-caching-using-php/" rel="bookmark" title="March 12, 2011">Simple RSS Parsing and Caching Using PHP</a></li>
<li><a href="http://anthonygthomas.com/2009/03/22/cakephp-console-acl-help-file/" rel="bookmark" title="March 22, 2009">CakePHP Console ACL Help File</a></li>
<li><a href="http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/" rel="bookmark" title="November 26, 2008">Getting Blueprint CSS &#038; JavaScript Libraries Into Your CakePHP Layout</a></li>
<li><a href="http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/" rel="bookmark" title="May 24, 2010">An Unexpected Problem with CakePHP and Email Elements</a></li>
<li><a href="http://anthonygthomas.com/2012/03/09/using-impress-js/" rel="bookmark" title="March 9, 2012">Using Impress.js</a></li>
</ul>
<p><!-- Similar Posts took 4.643 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2011/03/12/simple-rss-parsing-and-caching-using-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>An Unexpected Problem with CakePHP and Email Elements</title>
		<link>http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/</link>
		<comments>http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/#comments</comments>
		<pubDate>Mon, 24 May 2010 21:27:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[email elements]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=434</guid>
		<description><![CDATA[For several months now I&#8217;ve been triggering functions in my CakePHP controllers using crontabs. It&#8217;s especially handy for summarizing data and sending out reports via email. I&#8217;m about to change jobs and I&#8217;m trying to set up as many systems as I can to help staff manage our data after I leave. Part of that [...]]]></description>
			<content:encoded><![CDATA[<p>For several months now I&#8217;ve been triggering functions in my <a title="CakePHP" href="http://cakephp.org" target="_blank" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP</a> controllers <a href="http://www.lost-in-code.com/programming/php-code/cakephp-crontab/" onclick="pageTracker._trackPageview('/outgoing/www.lost-in-code.com/programming/php-code/cakephp-crontab/?referer=');">using crontabs</a>. It&#8217;s especially handy for summarizing data and sending out reports via email. I&#8217;m about to change jobs and I&#8217;m trying to set up as many systems as I can to help staff manage our data after I leave. Part of that means writing a few more crons to send out more emails. Today while trying to do just that, I ran into something unexpected that held me up for an hour or so until I had an epiphany on my way home. For the purposes of this post, I&#8217;m assuming you&#8217;ve already set up a cron dispatcher and know how to trigger cron jobs.</p>
<p>For one more week I&#8217;m working in a research clinic. One of the things we need to keep track of is who is late in getting us a sample. We need to check for blood and throat samples (which come from swishing some saline around in the mouth). This can be done by hand, but soon the study will grow and the number of participants will make that hard to manage. So I just want to check to see who is late and send out an email to staff to let them know.</p>
<p>This function exists in my Patient controller:<span id="more-434"></span></p>
<pre class="brush: php; highlight: [50,51,52,53]; title: ; notranslate">
function cron_delinquency() {

	if (!defined('CRON_DISPATCHER')) // make sure the request comes through the cron dispatcher
	{
		$this-&gt;redirect('/'); exit('Invalid Request');
	}
	/* this looks up active patients who do not have an patient_id ending in &quot;D&quot;. &quot;D&quot; indicates they are a donor and we only need one specimen from them. */
	$active = $this-&gt;Patient-&gt;find('list', array(
		'conditions' =&gt; array(
			'Patient.id LIKE \'T%\' AND Patient.id NOT LIKE \'%D\'',
			'Patient.withdrawn != \'y\'',
			'Patient.active=&quot;1&quot;'),
		));
	$in = '\''; /* the patient_id's start with a &quot;T&quot; meaning all the patient_id's need to be enclosed in quotes */

	$in .= implode('\', \'', $active); // implode the list of patient_id's

	$in = $in . '\''; // end it all with a quote

	$blds = $this-&gt;Patient-&gt;Specimen-&gt;find('list', array( // find the blood specimens for this group of patients
		'conditions' =&gt; array(
			'Specimen.patient_id IN (' . $in .')',
			'Specimen.type' =&gt; array('BLD')
			),
		'fields' =&gt; array('patient_id', 'draw_date'),
		'order' =&gt; array('patient_id' =&gt; 'ASC', 'draw_date' =&gt; 'ASC')

		));

	$thrs = $this-&gt;Patient-&gt;Specimen-&gt;find('list', array( // find the throat samples for this group of patients
		'conditions' =&gt; array(
			'Specimen.patient_id IN (' . $in .')',
			'Specimen.type' =&gt; array('THR')
			),
		'fields' =&gt; array('patient_id', 'draw_date'),
		'order' =&gt; array('patient_id' =&gt; 'ASC', 'draw_date' =&gt; 'ASC')

		));

/* My Patient model has a function to filter arrays and return only those that are older than the proved Unix timestamp. */
	$delinquentBlood = $this-&gt;Patient-&gt;find_delinquent($blds, 2419200); // 2419200 = 4 weeks; 3628800 = 6 weeks
	$delinquentThroat = $this-&gt;Patient-&gt;find_delinquent($thrs, 3628800);

	if(count($delinquentBlood) &gt; 0 || count($delinquentThroat) &gt; 0) // if we find any who are delinquent
	{

		asort($delinquentBlood); // sort them
		asort($delinquentThroat);

		$data['delinquentBlood'] = $delinquentBlood;
		$data['delinquentThroat'] = $delinquentThroat;
		$data['bloodCounter'] = count($delinquentBlood);
		$data['throatCounter'] = count($delinquentThroat);

		$this-&gt;set('data', $data);

		$this-&gt;Email-&gt;to 	  = $to;
		$this-&gt;Email-&gt;from		= 'LCIS &lt;xxxxxxx@umn.edu&gt;';
		$this-&gt;Email-&gt;subject	= 'PPG Delinquency Report: ' . $bloodCounter .&quot; Subjects With Blood Specimens Due; &quot; . $throatCounter . &quot; With Throat Specimens Due.&quot;;
		$this-&gt;Email-&gt;sendAs	= 'html';
		$this-&gt;Email-&gt;template	= 'viptm_delinquency';
		$this-&gt;Email-&gt;send();
	}
}
</pre>
<p>It&#8217;s that highlighted bit that was really giving me trouble. Previously I had been setting those variables like so:</p>
<pre class="brush: php; title: ; notranslate">$this-&gt;set(compact('delinquentBlood', 'delinquentThroat', 'bloodCounter', 'throatCounter'));</pre>
<p>Ordinarily this would work with any other view, but the email element I have set up for this function was acting as if they variables weren&#8217;t set at all. <em>It wasn&#8217;t until I put them in an array called <code>$data</code>, that I could use them in my email element</em>. It was puzzling and it took me about an hour to figure that out, but once I did my email reports came with beautiful data.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/" rel="bookmark" title="May 24, 2010">An Unexpected Problem with CakePHP and Email Elements</a></li>
<li><a href="http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/" rel="bookmark" title="February 18, 2010">CakePHP: Containable Behavior is Your Friend</a></li>
<li><a href="http://anthonygthomas.com/2011/03/12/simple-rss-parsing-and-caching-using-php/" rel="bookmark" title="March 12, 2011">Simple RSS Parsing and Caching Using PHP</a></li>
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
<li><a href="http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/" rel="bookmark" title="December 10, 2008">Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP</a></li>
</ul>
<p><!-- Similar Posts took 4.363 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP: Containable Behavior is Your Friend</title>
		<link>http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/</link>
		<comments>http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 16:21:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[containable behavior]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[behaviors]]></category>
		<category><![CDATA[containable]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=369</guid>
		<description><![CDATA[When it comes to optimizing your CakePHP queries, you need to abandon Recursive and adopt Containable. In the example below I have the following models: Patient Specimen Result ResultType The associations in the model are: Result belongsTo ResultType hasMany Result Patient hasMany Result Specimen Specimen belongsTo Patient hasMany Result $paginate in the Result Controller Original [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to optimizing your CakePHP queries, you need to abandon Recursive and adopt Containable.</p>
<p>In the example below I have the following models:</p>
<ul>
<li>Patient</li>
<li>Specimen</li>
<li>Result</li>
<li>ResultType</li>
</ul>
<p>The associations in the model are:</p>
<ul>
<li>Result
<ul>
<li>belongsTo
<ul>
<li>ResultType
<ul>
<li>hasMany
<ul>
<li>Result</li>
</ul>
</li>
</ul>
</li>
<li>Patient
<ul>
<li>hasMany
<ul>
<li>Result</li>
<li>Specimen</li>
</ul>
</li>
</ul>
</li>
<li>Specimen
<ul>
<li>belongsTo
<ul>
<li>Patient</li>
</ul>
</li>
<li>hasMany
<ul>
<li>Result</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><span id="more-369"></span></p>
<h3>$paginate in the Result Controller</h3>
<h4>Original version</h4>
<pre class="brush: php; highlight: [12]; title: ; notranslate">var $paginate = array(
		'fields' =&gt; array(
			'ResultType.type',
			'Specimen.draw_date',
			'Result.id',
			'Result.patient_id',
			'Result.specimen_id',
			'Result.result',
			'Result.created',
			'Result.modified'
			),
		'recursive' =&gt; 0,
		'limit' =&gt; 50);</pre>
<h4>The Same Thing Using Containable</h4>
<pre class="brush: php; highlight: [11,12,13,14,15,16,17,18,19,20,21,22,23]; title: ; notranslate">var $paginate = array(
		'fields' =&gt; array(
			'id',
			'patient_id',
			'specimen_id',
			'result',
			'created',
			'modified'
			),
		'limit' =&gt; 50,
		'contain' =&gt; array(
			'ResultType' =&gt; array(
				'fields' =&gt; array(
					'ResultType.type',
					'ResultType.id'
					)
				),
			'Specimen' =&gt; array(
				'fields' =&gt; array(
					'Specimen.id',
					'Specimen.draw_date'
					)
				)
			)
		);</pre>
<h3>The SQL</h3>
<h4>SQL Generated from the Original $paginate var</h4>
<pre class="brush: sql; highlight: [7,8,19,20]; title: ; notranslate">SELECT COUNT(*) AS `count`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
LEFT JOIN `patients` AS `Patient`
ON (`Result`.`patient_id` = `Patient`.`id`)
WHERE 1 = 1

/* 1879 milliseconds */

SELECT `ResultType`.`type`, `Specimen`.`draw_date`, `Result`.`id`, `Result`.`patient_id`, `Result`.`specimen_id`, `Result`.`result`, `Result`.`created`, `Result`.`modified`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
LEFT JOIN `patients` AS `Patient`
ON (`Result`.`patient_id` = `Patient`.`id`)
WHERE 1 = 1
ORDER BY `Result`.`created` desc
LIMIT 50

/* 2106 milliseconds */</pre>
<h4>SQL Generated Using Containable Behavior</h4>
<pre class="brush: sql; title: ; notranslate">SELECT COUNT(*) AS `count`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
WHERE 1 = 1

/* 10 milliseconds */

SELECT `Result`.`id`, `Result`.`patient_id`, `Result`.`specimen_id`, `Result`.`result`, `Result`.`created`, `Result`.`modified`, `ResultType`.`type`, `ResultType`.`id`, `Specimen`.`id`, `Specimen`.`draw_date`
FROM `results` AS `Result`
LEFT JOIN `result_types` AS `ResultType`
ON (`Result`.`result_type_id` = `ResultType`.`id`)
LEFT JOIN `specimens` AS `Specimen`
ON (`Result`.`specimen_id` = `Specimen`.`id`)
WHERE 1 = 1
ORDER BY `Result`.`created` desc
LIMIT 50

/* 19 milliseconds */</pre>
<h3>The Difference</h3>
<p>The first set of queries took nearly 4 seconds. The second: 29 milliseconds. Containable just gives you so much more control over what&#8217;s selected in your query. UsingÂ <code>recursive =&gt; 0</code> still joined the patients table both times because it was associated in the model&#8211;even though in this case we didn&#8217;t need it. Using the Containable Behavior in the second example removed the patients table from the queries altogether.</p>
<p>This is one of the key pitfalls of using a framework like CakePHP; You can get things running quickly, but you have to go back and optimize. Otherwise you can build a heavy load on the server.</p>
<h3>Resources</h3>
<ul>
<li><a title="CakePHP Framework" href="http://cakephp.org" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP</a></li>
<li><a href="http://book.cakephp.org/view/474/Containable" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/474/Containable?referer=');">The Containable Behavior</a></li>
<li><a title="The Recursive Model Attribute" href="http://book.cakephp.org/view/439/recursive" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/439/recursive?referer=');">The Recursive Model Attribute</a></li>
</ul>
<p><strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/" rel="bookmark" title="February 18, 2010">CakePHP: Containable Behavior is Your Friend</a></li>
<li><a href="http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/" rel="bookmark" title="May 24, 2010">An Unexpected Problem with CakePHP and Email Elements</a></li>
<li><a href="http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/" rel="bookmark" title="December 10, 2008">Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/" rel="bookmark" title="November 26, 2008">Getting Blueprint CSS &#038; JavaScript Libraries Into Your CakePHP Layout</a></li>
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
</ul>
<p><!-- Similar Posts took 4.269 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Security in CakePHP</title>
		<link>http://anthonygthomas.com/2009/07/22/simple-security-in-cakephp/</link>
		<comments>http://anthonygthomas.com/2009/07/22/simple-security-in-cakephp/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 01:23:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[components]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=134</guid>
		<description><![CDATA[When I started to dig in to investigate using the Security Component of CakePHP, I was a bit daunted. It took me quite a while to get my head around ACL after all. Then I found this article. Here&#8217;s the crux: The Security component will create a hash based on the form fields produced by [...]]]></description>
			<content:encoded><![CDATA[<p>When I started to dig in to investigate using the <a href="http://book.cakephp.org/view/175/Security-Component" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/175/Security-Component?referer=');">Security Component</a> of <a href="http://cakephp.org" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP</a>, I was a bit daunted. It took me quite a while to get my head around <a href="http://book.cakephp.org/view/171/Access-Control-Lists" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/171/Access-Control-Lists?referer=');">ACL</a> after all. Then I found <a href="http://teknoid.wordpress.com/2008/11/05/make-your-cakephp-forms-a-lot-more-secure/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/teknoid.wordpress.com/2008/11/05/make-your-cakephp-forms-a-lot-more-secure/?referer=');">this article</a>. Here&#8217;s the crux:</p>
<blockquote><p>The Security component will create a hash based on the form fields produced by our Form Helper. If someone tampers with the form fields (by adding or removing or changing any field), the hash is not going to match with the expected one and the add() action will fail.</p>
<p>Yep, itâ€™s that simple.</p></blockquote>
<p>Really? It just can&#8217;t be that easy, can it? Yes. It can. I simply added the Security Component to my controller like so:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">var $components = array('Security');</pre></div></div>

<p>Sure enough, when I reloaded a page with a form in my browser, this hidden field was there:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">&lt;input id=&quot;TokenFields1483167134&quot; name=&quot;data[_Token][fields]&quot; type=&quot;hidden&quot; value=&quot;f513aebc448fabe42c7feedf31d43fa5bd71ec79%3An%3A0%3A%7B%7D&quot; /&gt;</pre></div></div>

<p>I installed a Firefox Add-on that allowed me to tamper with the POST data, and when I submitted the form, it failed, or in CakePHP terms, it was &#8220;<a href="http://book.cakephp.org/view/267/blackHole-object-controller-string-error" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/267/blackHole-object-controller-string-error?referer=');">Blackholed</a>.&#8221; Awesome.</p>
<p>This isn&#8217;t going to protect me from all attacks, but it certainly is a good, easy start to implementing security in my application.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2009/07/22/simple-security-in-cakephp/" rel="bookmark" title="July 22, 2009">Simple Security in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
<li><a href="http://anthonygthomas.com/2010/03/14/display-form-fields-based-on-selection-using-jquery/" rel="bookmark" title="March 14, 2010">Display Form Fields Based on Selection Using JQuery</a></li>
<li><a href="http://anthonygthomas.com/2008/09/22/and-were-back/" rel="bookmark" title="September 22, 2008">And We&#8217;re Back!</a></li>
<li><a href="http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/" rel="bookmark" title="February 18, 2010">CakePHP: Containable Behavior is Your Friend</a></li>
</ul>
<p><!-- Similar Posts took 4.025 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2009/07/22/simple-security-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Roll Your Own CakePHP Components</title>
		<link>http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/</link>
		<comments>http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/#comments</comments>
		<pubDate>Fri, 22 May 2009 13:54:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[components]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[gtd]]></category>
		<category><![CDATA[mcv]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=103</guid>
		<description><![CDATA[As someone who is not formally trained as a programmer, I often understand concepts long before actually putting them into practice. Don&#8217;t Repeat Yourself (DRY) seems simple enough. Of course I don&#8217;t want to repeat myself while programming. Who wants to dig through lines of code to find a litte snippet of logic you once [...]]]></description>
			<content:encoded><![CDATA[<p>As someone who is not formally trained as a programmer, I often understand concepts long before actually putting them into practice. <em>Don&#8217;t Repeat Yourself </em>(DRY) seems simple enough. Of course I don&#8217;t want to repeat myself while programming. Who wants to dig through lines of code to find a litte snippet of logic you once wrote? Still, when you&#8217;re pressed for time, sometimes you just have to <em>Get Things Done</em> (GTD). So best practices go through the window and you hammer out some spaghetti code so you can move on.</p>
<p>It&#8217;s only recently, since I&#8217;ve slowed down to finally understand how to write <a href="http://cakephp.org" target="_blank" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP</a> <a href="http://book.cakephp.org/view/63/Introduction" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/63/Introduction?referer=');">Components</a>, that I&#8217;ve realized that DRY enhances GTD. Now that I&#8217;ve got it all straight in my head, I&#8217;m a component <em>evangelist</em>.</p>
<p>At this point I&#8217;m going to assume that you&#8217;re familiar with MCV architecture and its benefits. Once in a while there&#8217;s a bit of logic that you find yourself coding into a controller that you realize you&#8217;re going to want to use in other controllers. It&#8217;s not specific to the model. That&#8217;s where components come in. They&#8217;re bits of logic that can be used by more than one controller. Let&#8217;s look at a simple one that converts mm/dd/yyyy dates to a Unix timestamp.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> DateComponent <span style="color: #000000; font-weight: bold;">extends</span> Object <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">function</span> mkTimestamp<span style="color: #009900;">&#40;</span><span style="color: #000088;">$sentdate</span><span style="color: #339933;">,</span> <span style="color: #000088;">$senttime</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #000088;">$thedate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sentdate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$senttime</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
			<span style="color: #000088;">$thetime</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$senttime</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$newdate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mktime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$thetime</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$thetime</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #000088;">$thedate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$thedate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$thedate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
			<span style="color: #000088;">$newdate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mktime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #000088;">$thedate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$thedate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$thedate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$newdate</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>The function itself is not all that complicated. The thing is that I&#8217;m going to want to use this where ever I need to convert dates. Since the component is called &#8220;Date&#8221;, it&#8217;s named with the CakePHP convention for components: DateComponent. The file is called date.php and is saved in <code>app/controllers/components</code>.</p>
<p>Now we have to tell our controller(s) to use it. I&#8217;m using it across several controllers, so I&#8217;m adding it to <code>app/app_controller.php</code> by adding it to the <code>$components</code> var: <code>var $components = array('Date');</code></p>
<p>Now I can access it in any controller like so: <code>$tmsmp = $this->Date->mkTimestamp($thedate, $thetime);</code></p>
<p>The whole point is that components don&#8217;t have to be complex, they&#8217;re just code you want to reuse that doesn&#8217;t necessary apply to one model. They will save you time and clean up your controllers.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
<li><a href="http://anthonygthomas.com/2009/07/22/simple-security-in-cakephp/" rel="bookmark" title="July 22, 2009">Simple Security in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/" rel="bookmark" title="May 24, 2010">An Unexpected Problem with CakePHP and Email Elements</a></li>
<li><a href="http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/" rel="bookmark" title="December 10, 2008">Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/" rel="bookmark" title="February 18, 2010">CakePHP: Containable Behavior is Your Friend</a></li>
</ul>
<p><!-- Similar Posts took 4.732 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP Console ACL Help File</title>
		<link>http://anthonygthomas.com/2009/03/22/cakephp-console-acl-help-file/</link>
		<comments>http://anthonygthomas.com/2009/03/22/cakephp-console-acl-help-file/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 15:30:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ACL]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[cli]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=95</guid>
		<description><![CDATA[Every now and then I want to view my help files in pretty, formatted HTML instead of plain text in a text editor or terminal window. Right now I&#8217;m working on setting up some Access Control Lists (ACL) in the CakePHP Console. ACL is a powerful, yet sometimes hard-to-grasp concept. I always figure that if [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then I want to view my help files in pretty, formatted HTML instead of plain text in a text editor or terminal window. Right now I&#8217;m working on setting up some Access Control Lists (ACL) in the <a href="http://book.cakephp.org/view/108/the-cakephp-console" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/108/the-cakephp-console?referer=');">CakePHP Console</a>. ACL is a powerful, yet sometimes hard-to-grasp concept. I always figure that if I want a resource like this, there has to be someone else out there who does, so for your reference and mine, here it is. (By the way, to get to this from the console, simply type <code>cake acl help</code>.)</p>
<p>Usage: <code>cake acl &lt;command&gt; &lt;arg1&gt; &lt;arg2&gt;...<!--formatted--></code><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
Commands:</p>
<p><code>create aro|aco &lt;parent&gt; &lt;node&gt;<!--formatted--></code><br />
Creates a new ACL object &lt;node&gt; under the parent specified by &lt;parent&gt;, an id/alias.<br />
The &lt;parent&gt; and &lt;node&gt; references can be in one of the following formats:</p>
<ul>
<li> &#8211; &lt;model&gt;.&lt;id&gt; &#8211; The node will be bound to a specific record of the given model</li>
<li>- &lt;alias&gt; &#8211; The node will be given a string alias (or path, in the case of &lt;parent&gt;),</li>
</ul>
<p>i.e. &#8216;John&#8217;.Â  When used with &lt;parent&gt;, this takes the form of an alias path,<br />
i.e. &lt;group&gt;/&lt;subgroup&gt;/&lt;parent&gt;.<br />
To add a node at the root level, enter &#8216;root&#8217; or &#8216;/&#8217; as the &lt;parent&gt; parameter.</p>
<p><code>delete aro|aco &lt;node&gt;<!--formatted--></code><br />
Deletes the ACL object with the given &lt;node&gt; reference (see &#8216;create&#8217; for info on node references).</p>
<p><code>setParent aro|aco &lt;node&gt; &lt;parent&gt;<!--formatted--></code><br />
Moves the ACL object specified by &lt;node&gt; beneath the parent ACL object specified by &lt;parent&gt;.<br />
To identify the node and parent, use the row id.</p>
<p><code>getPath aro|aco &lt;node&gt;<!--formatted--></code><br />
Returns the path to the ACL object specified by &lt;node&gt;. This command is useful in determining the inhertiance of permissions for a certain object in the tree.<br />
For more detailed parameter usage info, see help for the &#8216;create&#8217; command.</p>
<p><code>check &lt;aro_id&gt; &lt;aco_id&gt; [&lt;aco_action&gt;] or all<!--formatted--></code><br />
Use this command to check ACL permissions.<br />
For more detailed parameter usage info, see help for the &#8216;create&#8217; command.</p>
<p><code>grant &lt;aro_id&gt; &lt;aco_id&gt; [&lt;aco_action&gt;] or all<!--formatted--></code><br />
Use this command to grant ACL permissions. Once executed, the ARO specified (and its children, if any) will have ALLOW access to the specified ACO action (and the ACO&#8217;s children, if any). For more detailed parameter usage info, see help for the &#8216;create&#8217; command.</p>
<p><code>deny &lt;aro_id&gt; &lt;aco_id&gt; [&lt;aco_action&gt;]or all<!--formatted--></code><br />
Use this command to deny ACL permissions. Once executed, the ARO specified (and its children, if any) will have DENY access to the specified ACO action (and the ACO&#8217;s children, if any). For more detailed parameter usage info, see help for the &#8216;create&#8217; command.</p>
<p><code>inherit &lt;aro_id&gt; &lt;aco_id&gt; [&lt;aco_action&gt;]or all<!--formatted--></code><br />
Use this command to force a child ARO object to inherit its permissions settings from its parent. For more detailed parameter usage info, see help for the &#8216;create&#8217; command.</p>
<p><code>view aro|aco [&lt;node&gt;]<!--formatted--></code><br />
The view command will return the ARO or ACO tree. The optional id/alias parameter allows you to return only a portion of the requested tree. For more detailed parameter usage info, see help for the &#8216;create&#8217; command.</p>
<p><code>initdb</code><br />
Uses this command : <code>cake schema run create DbAcl</code></p>
<p><code>help [&lt;command&gt;]<!--formatted--></code><br />
Displays this help message, or a message on a specific command.</p>
<h3>The &#8216;create&#8217; help file</h3>
<p>Usage: cake acl &lt;command&gt; &lt;arg1&gt; &lt;arg2&gt;&#8230;<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<ul>
<li>Commands:
<ul>
<li><code>create aro|aco &lt;parent&gt; &lt;node&gt;<code> </code><!--formatted--></code>
<ul>
<li>Creates a new ACL object <code>&lt;node&gt;<!--formatted--></code> under the parent specified by <code>&lt;parent&gt;<!--formatted--></code>, an id/alias. The <code>&lt;parent&gt; and &lt;node&gt;<!--formatted--></code> references can be in one of the following formats:
<ul>
<li>- <code>&lt;model&gt;.&lt;id&gt;<!--formatted--></code> &#8211; The node will be bound to a specific record of the given model</li>
<li>- <code>&lt;alias&gt;<!--formatted--></code> &#8211; The node will be given a string alias (or path, in the case of <code>&lt;parent&gt;<!--formatted--></code>), i.e. &#8216;John&#8217;.Â  When used with <code>&lt;parent&gt;<!--formatted--></code>, this takes the form of an alias path, i.e. <code>&lt;group&gt;/&lt;subgroup&gt;/&lt;parent&gt;<!--formatted--></code>. To add a node at the root level, enter &#8216;root&#8217; or &#8216;/&#8217; as the <code>&lt;parent&gt;<!--formatted--></code> parameter.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2009/03/22/cakephp-console-acl-help-file/" rel="bookmark" title="March 22, 2009">CakePHP Console ACL Help File</a></li>
<li><a href="http://anthonygthomas.com/2011/03/12/simple-rss-parsing-and-caching-using-php/" rel="bookmark" title="March 12, 2011">Simple RSS Parsing and Caching Using PHP</a></li>
<li><a href="http://anthonygthomas.com/2008/06/20/wow-acl-is-hard/" rel="bookmark" title="June 20, 2008">Wow. ACL is Hard</a></li>
<li><a href="http://anthonygthomas.com/2008/04/10/googles-appengine/" rel="bookmark" title="April 10, 2008">Google&#8217;s AppEngine</a></li>
<li><a href="http://anthonygthomas.com/2008/11/25/wordpress-auto-update-is-ok-but-the-command-line-is-faster/" rel="bookmark" title="November 25, 2008">WordPress&#8217; Auto Update Is OK, But The Command Line Is Faster</a></li>
</ul>
<p><!-- Similar Posts took 4.498 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2009/03/22/cakephp-console-acl-help-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP</title>
		<link>http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/</link>
		<comments>http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 23:52:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[About the Author]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[This Site]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=66</guid>
		<description><![CDATA[UPDATE (7/22/2009) requestionAction may not be the best solution. Read this. At my day job, I&#8217;m working on an application to keep track of specimens for our lab. A specimen is sent to the lab, then divided into aliquots which are put into boxes and stored in freezers. The previous sentence ought to give you [...]]]></description>
			<content:encoded><![CDATA[<h3>UPDATE (7/22/2009)</h3>
<p>requestionAction may not be the best solution. <a href="http://teknoid.wordpress.com/2009/01/17/can-we-talk-enough-about-requestaction/" onclick="pageTracker._trackPageview('/outgoing/teknoid.wordpress.com/2009/01/17/can-we-talk-enough-about-requestaction/?referer=');">Read this</a>.</p>
<p>At my day job, I&#8217;m working on an application to keep track of specimens for our lab. A specimen is sent to the lab, then divided into aliquots which are put into boxes and stored in freezers. The previous sentence ought to give you some idea of the architecture of the database, which in turn drives the Model for my application.</p>
<p>To take a step back for a second, I&#8217;m developing the application using the <a title="CakePHP" href="http://cakephp.org" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP framework</a> which uses <a href="http://en.wikipedia.org/wiki/Model-view-controller" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Model-view-controller?referer=');">MVC architecture</a>.</p>
<p>As you may have guessed I have specimen, aliquot, boxes and freezers tables. In turn then, I have Specimen, Aliquot, Box and Freezer Models.</p>
<p>The trick here is that I want to alert users when there are aliquots in the system that have not yet been assigned to boxes. It&#8217;s a simple query:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">SELECT COUNT(aliquot.id)
FROM aliquots
WHERE aliquots.box_id IS NULL</pre></div></div>

<p>The problem is that I want the number of unstored aliquots to be displayed on every page in the left column as a persistent reminder that there are are aliquots that need to be put away. I want to do that in a way that maintains the MVC architecture and doesn&#8217;t violate the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Don_27t_repeat_yourself?referer=');">DRY philosophy</a>.</p>
<p>Since the query is run on the aliquots table and each view is generally specific to it&#8217;s own model, I either have to run a recursive query to access data across models&#8211;which adds overhead&#8211;or implement the solution below which lightens the load a bit and is a more elegant bit of code. (<a title="CakePHP Group" href="http://groups.google.com/group/cake-php/browse_thread/thread/b302d650fa9ec36e/82fd46c3d4e9eeec#82fd46c3d4e9eeec" onclick="pageTracker._trackPageview('/outgoing/groups.google.com/group/cake-php/browse_thread/thread/b302d650fa9ec36e/82fd46c3d4e9eeec_82fd46c3d4e9eeec?referer=');">Tip of the hat to Jon Bennet for offering the solution</a>.)</p>
<p><a href="http://api.cakephp.org/class_object.html#c40a38b60a3748b9cf75215b92ee3db1" onclick="pageTracker._trackPageview('/outgoing/api.cakephp.org/class_object.html_c40a38b60a3748b9cf75215b92ee3db1?referer=');">The solution involves CakePHP&#8217;s requestAction()</a>.</p>
<p>I can define the method in my aliquots controller and call it from anywhere. So if aliquots_controller.php has a method that retrieves the data from the model (in this case called &#8216;unstored&#8217;) I can simply put the following code into my layout:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">$unstored = $this-&amp;gt;requestAction('aliquots/unstored');
if(!empty($unstored)) {
echo $html-&amp;gt;link('&lt;strong&gt;' . $unstored['unstored'] . ' aliquots have not been stored.&lt;/strong&gt;', '/aliquots/store');
}</pre></div></div>

<p>I only have to define the method once to use it throughout my application. Problem solved.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/" rel="bookmark" title="December 10, 2008">Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2010/02/18/cakephp-containable-behavior-is-your-friend/" rel="bookmark" title="February 18, 2010">CakePHP: Containable Behavior is Your Friend</a></li>
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
<li><a href="http://anthonygthomas.com/2010/05/24/an-unexpected-problem-with-cakephp-and-email-elements/" rel="bookmark" title="May 24, 2010">An Unexpected Problem with CakePHP and Email Elements</a></li>
<li><a href="http://anthonygthomas.com/2010/03/14/display-form-fields-based-on-selection-using-jquery/" rel="bookmark" title="March 14, 2010">Display Form Fields Based on Selection Using JQuery</a></li>
</ul>
<p><!-- Similar Posts took 4.462 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2008/12/10/use-functions-from-other-controllers-while-maintaining-mvc-architecture-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Blueprint CSS &amp; JavaScript Libraries Into Your CakePHP Layout</title>
		<link>http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/</link>
		<comments>http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 19:55:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blueprint Framework]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=59</guid>
		<description><![CDATA[Updated 12/3/2008 The other day I wrote about getting the Blueprint CSS framework into your WordPress theme. If you&#8217;re developing in CakePHP, it&#8217;s even easier to link multiple style sheets and JavaScript libraries to your layout file. &#60;?php $css = array('blueprint/screen', 'blueprint/ie', 'style'); $jslibraries = array('prototype', 'scriptaculous', 'jquery'); echo $html-&#62;css('blueprint/print', 'stylesheet', 'media="print"'); echo $html-&#62;css($css, 'stylesheet', [...]]]></description>
			<content:encoded><![CDATA[<p>Updated 12/3/2008</p>
<p>The other day I wrote about <a href="http://anthonygthomas.com/2008/11/23/incorporating-blueprint-css-into-your-new-wordpress-theme/">getting the Blueprint CSS framework into your WordPress theme</a>. If you&#8217;re developing in <a href="http://cakephp.org" onclick="pageTracker._trackPageview('/outgoing/cakephp.org?referer=');">CakePHP</a>, it&#8217;s even easier to link multiple style sheets and JavaScript libraries to your <a href="http://book.cakephp.org/view/96/Layouts" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/96/Layouts?referer=');">layout file</a>.</p>
<p><code>&lt;?php</code></p>
<p><code>$css = array('blueprint/screen', 'blueprint/ie', 'style');<br />
$jslibraries = array('prototype', 'scriptaculous', 'jquery');</code><code><span style="text-decoration: line-through;"><br />
</span>echo $html-&gt;css('blueprint/print', 'stylesheet', 'media="print"');</code><code><br />
echo $html-&gt;css($css, 'stylesheet', 'media=â€screen, projectionâ€');<br />
echo $javascript-&gt;link($jslibraries);</code><br />
<code>?&gt;</code></p>
<p>Let&#8217;s take these one at a time.</p>
<p><code>$css = array('blueprint/screen', 'blueprint/ie', 'style');</code></p>
<p><a href="http://book.cakephp.org/view/205/HTML" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/205/HTML?referer=');">CakePHP&#8217;s html helper</a> will load any css file you specify. First, make sure the css files are in <code>app/webroot/css</code>. Then put any css files you want to link to your layout in an array like I have above. You might have noticed that I didn&#8217;t include print in my array. That&#8217;s because we want to add an media=&#8221;print&#8221; as a separate attribute that the other style sheets won&#8217;t have.</p>
<p>Once they&#8217;re loaded into your array, simply put <code>echo $html-&gt;css($css);</code> in the head of your layout. The output will be:<br />
<code>&lt;link rel="stylesheet" type="text/css" href="/app/webroot/css/blueprint/screen.css" /&gt;<br />
&lt;link rel="stylesheet" type="text/css" href="/app/webroot/css/blueprint/ie.css" /&gt;<br />
&lt;link rel="stylesheet" type="text/css" href="/app/webroot/css/style.css" /&gt;</code></p>
<p>We still haven&#8217;t linked our print style sheet. Make sure you link the print style sheet above the others so they override it. We can add <code>media="print"</code> by putting this into our layout head:</p>
<p><code>echo $html-&gt;css('blueprint/print', 'stylesheet', 'media="print"');</code></p>
<p>So now:</p>
<p><code>$css = array('blueprint/screen', 'blueprint/ie', 'style');<br />
</code><code>echo $html-&gt;css('blueprint/print', 'stylesheet', 'media="print"');</code><code><br />
</code><code>echo $html-&gt;css($css, 'stylesheet', 'media=â€screen, projectionâ€');</code></p>
<p>Results in:</p>
<p><code>&lt;link rel="stylesheet" type="text/css" href="/cvp-msi/https/app/webroot/css/blueprint/print.css" media="print" /&gt;<br />
&lt;link rel="stylesheet" type="text/css" href="/cvp-msi/https/app/webroot/css/blueprint/screen.css" media="screen, projection" /&gt;<br />
&lt;link rel="stylesheet" type="text/css" href="/cvp-msi/https/app/webroot/css/blueprint/ie.css" media="screen, projection" /&gt;<br />
&lt;link rel="stylesheet" type="text/css" href="/cvp-msi/https/app/webroot/css/style.css" media="screen, projection" /&gt;</code></p>
<p>Two things to note. In <code>$html-&gt;css($path, $attributes)</code>, the first argument is the path from <code>app/webroot/css</code>. The second argument is html attributes.</p>
<p>Linking JavaScript libraries is very similar.</p>
<p><code>$jslibraries = array('prototype', 'scriptaculous', 'jquery');</code></p>
<p>This will link to <code>prototype.js</code>, <code>scriptaculous.js</code> and <code>jquery.js</code> respectively as long as there in <code>app/webroot/js</code>.</p>
<p>Put <code>echo $javascript-&gt;link($jslibraries);</code> into the head of your layout and you&#8217;re done. You have all three JavaScript libraries at your disposal.</p>
<p>Other good resources:</p>
<ul>
<li><a href="http://book.cakephp.org/view/181/Core-Helpers" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/181/Core-Helpers?referer=');">CakePHP Core Helpers</a></li>
<li><a href="http://book.cakephp.org/view/27/Developing-with-CakePHP" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/27/Developing-with-CakePHP?referer=');">Developing With CakePHP</a></li>
<li><a href="http://api.cakephp.org/class_javascript_helper.html#cab1eb59cacd608ec02e79cfd8710094" onclick="pageTracker._trackPageview('/outgoing/api.cakephp.org/class_javascript_helper.html_cab1eb59cacd608ec02e79cfd8710094?referer=');">CakePHP API JavaScript link Helper</a></li>
<li><a href="http://api.cakephp.org/class_html_helper.html#b8e7fe2bca7be4c25f9a660038131f00" onclick="pageTracker._trackPageview('/outgoing/api.cakephp.org/class_html_helper.html_b8e7fe2bca7be4c25f9a660038131f00?referer=');">CakePHP API CSS link Helper</a></li>
</ul>
<p><strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/" rel="bookmark" title="November 26, 2008">Getting Blueprint CSS &#038; JavaScript Libraries Into Your CakePHP Layout</a></li>
<li><a href="http://anthonygthomas.com/2008/11/23/incorporating-blueprint-css-into-your-new-wordpress-theme/" rel="bookmark" title="November 23, 2008">Incorporating Blueprint CSS Into Your New WordPress Theme</a></li>
<li><a href="http://anthonygthomas.com/2010/02/08/introducing-the-baseline-development-wordpress-theme/" rel="bookmark" title="February 8, 2010">Introducing the Baseline Development WordPress Theme</a></li>
<li><a href="http://anthonygthomas.com/2010/02/16/baseline-theme-version-1-0-1/" rel="bookmark" title="February 16, 2010">Baseline Theme Version 1.0.1</a></li>
<li><a href="http://anthonygthomas.com/2008/11/22/blueprint-css-readme-file/" rel="bookmark" title="November 22, 2008">Blueprint CSS Readme File</a></li>
</ul>
<p><!-- Similar Posts took 4.847 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Incorporating Blueprint CSS Into Your New WordPress Theme</title>
		<link>http://anthonygthomas.com/2008/11/23/incorporating-blueprint-css-into-your-new-wordpress-theme/</link>
		<comments>http://anthonygthomas.com/2008/11/23/incorporating-blueprint-css-into-your-new-wordpress-theme/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 15:07:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blueprint Framework]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[blueprint]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=50</guid>
		<description><![CDATA[If you&#8217;re familiar with the Blueprint CSS framework, you already know it can make your life a lot easier. So how do you get it into your WordPress theme? Luckily, WordPress is designed to make your life easier too. I&#8217;m assuming your know the basics of WordPress Theme Development. That is, at the very least [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re familiar with the <a href="http://www.blueprintcss.org/" onclick="pageTracker._trackPageview('/outgoing/www.blueprintcss.org/?referer=');">Blueprint CSS framework</a>, you already know it can make your life a lot easier. So how do you get it into your <a href="http://wordpress.org" onclick="pageTracker._trackPageview('/outgoing/wordpress.org?referer=');">WordPress</a> theme? Luckily, WordPress is designed to make your life easier too.</p>
<p>I&#8217;m assuming your know the basics of <a href="http://codex.wordpress.org/Theme_Development" onclick="pageTracker._trackPageview('/outgoing/codex.wordpress.org/Theme_Development?referer=');">WordPress Theme Development</a>. That is, at the very least you need:</p>
<ul>
<li>header.php</li>
<li>footer.php</li>
<li>index.php</li>
<li>style.css</li>
</ul>
<p>Put those files in a folder named after your theme. And put that folder in <code>/wordpressroot/wp-content/themes/</code>.</p>
<p>Once you&#8217;ve gotten that far, download the Blueprint CSS Framework and drop the &#8220;blueprint&#8221; folder from that download into your theme&#8217;s directory.</p>
<p>Finally, to include the new CSS files into your theme, just add this code to your header:</p>
<p><code>&lt;link rel="stylesheet" href="&lt;?php bloginfo('stylesheet_directory'); ?&gt;/blueprint/screen.css" type="text/css" media="screen, projection"&gt;<br />
&lt;link rel="stylesheet" href="&lt;?php bloginfo('stylesheet_directory'); ?&gt;/blueprint/print.css" type="text/css" media="print"&gt;<br />
&lt;!--[if IE]&gt;<br />
&lt;link rel="stylesheet" href="&lt;?php bloginfo('stylesheet_directory'); ?&gt;/blueprint/ie.css" type="text/css" media="screen, projection"&gt;<br />
&lt;![endif]--&gt;<br />
&lt;link rel="stylesheet" href="&lt;?php bloginfo('stylesheet_url'); ?&gt;" type="text/css" media="screen" /&gt;</code></p>
<p>Pay attention to the order. You want to make sure that <code>href="&lt;?php bloginfo('stylesheet_url'); ?&gt;"</code> appears last in the list of style sheets. That&#8217;s your <code>style.css</code> where you can tailor the CSS for your specific design.</p>
<p>That&#8217;s it.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2008/11/23/incorporating-blueprint-css-into-your-new-wordpress-theme/" rel="bookmark" title="November 23, 2008">Incorporating Blueprint CSS Into Your New WordPress Theme</a></li>
<li><a href="http://anthonygthomas.com/2010/02/08/introducing-the-baseline-development-wordpress-theme/" rel="bookmark" title="February 8, 2010">Introducing the Baseline Development WordPress Theme</a></li>
<li><a href="http://anthonygthomas.com/2008/11/26/getting-blueprint-css-javascript-libraries-into-your-cakephp-layout/" rel="bookmark" title="November 26, 2008">Getting Blueprint CSS &#038; JavaScript Libraries Into Your CakePHP Layout</a></li>
<li><a href="http://anthonygthomas.com/2010/02/16/baseline-theme-version-1-0-1/" rel="bookmark" title="February 16, 2010">Baseline Theme Version 1.0.1</a></li>
<li><a href="http://anthonygthomas.com/2008/11/22/blueprint-css-readme-file/" rel="bookmark" title="November 22, 2008">Blueprint CSS Readme File</a></li>
</ul>
<p><!-- Similar Posts took 4.574 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2008/11/23/incorporating-blueprint-css-into-your-new-wordpress-theme/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>And We&#8217;re Back!</title>
		<link>http://anthonygthomas.com/2008/09/22/and-were-back/</link>
		<comments>http://anthonygthomas.com/2008/09/22/and-were-back/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 20:55:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ACL]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://anthonygthomas.com/?p=36</guid>
		<description><![CDATA[I have been so incredibly busy the last few months that aside for 140 character Twitter updates, I haven&#8217;t been able to keep this blog updated with my exploits. If you are still paying attention, I was complaining about ACL. After several attempts, I gave up using the built-in ACL component in CakePHP and just [...]]]></description>
			<content:encoded><![CDATA[<p>I have been so incredibly busy the last few months that aside for 140 character Twitter updates, I haven&#8217;t been able to keep this blog updated with my exploits.</p>
<p>If you are still paying attention, <a href="http://anthonygthomas.com/2008/06/20/wow-acl-is-hard/">I was complaining about ACL</a>. After several attempts, I gave up using the <a href="http://book.cakephp.org/view/171/Access-Control-Lists" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/171/Access-Control-Lists?referer=');">built-in ACL component in CakePHP</a> and just decided to keep things simple, <a href="http://book.cakephp.org/view/172/Authentication" onclick="pageTracker._trackPageview('/outgoing/book.cakephp.org/view/172/Authentication?referer=');">use the Auth component</a> with role-based access control. Problem solved.</p>
<p>The development of the application has progressed smoothly since getting over that hurdle.</p>
<p>In the meantime, I&#8217;ve been setting up my own virtual server for hosting websites for my freelance clients. That has been a learning experience in itself. I&#8217;ll post more about that as I formally launch that service.</p>
<p>I&#8217;m also way behind on podcasts for the Minneapoliscast podcast. I hope to resume that at a modest pace this fall.</p>
<p>More later as all of my respective projects get updates including SVN info on my CakePHP app.<strong>Similar Posts:</strong>
<ul class="similar-posts">
<li><a href="http://anthonygthomas.com/2008/09/22/and-were-back/" rel="bookmark" title="September 22, 2008">And We&#8217;re Back!</a></li>
<li><a href="http://anthonygthomas.com/2009/07/22/simple-security-in-cakephp/" rel="bookmark" title="July 22, 2009">Simple Security in CakePHP</a></li>
<li><a href="http://anthonygthomas.com/2008/06/20/wow-acl-is-hard/" rel="bookmark" title="June 20, 2008">Wow. ACL is Hard</a></li>
<li><a href="http://anthonygthomas.com/2009/05/22/roll-your-own-cakephp-components/" rel="bookmark" title="May 22, 2009">Roll Your Own CakePHP Components</a></li>
<li><a href="http://anthonygthomas.com/2009/04/06/minnewebcon-2009/" rel="bookmark" title="April 6, 2009">MinneWebCon 2009</a></li>
</ul>
<p><!-- Similar Posts took 4.116 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://anthonygthomas.com/2008/09/22/and-were-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

