<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>cakealot</title>
	
	<link>http://cakealot.com</link>
	<description>A weblog about CakePHP and related stuff</description>
	<lastBuildDate>Tue, 06 Oct 2009 19:14:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/cakealot" /><feedburner:info uri="cakealot" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://cakealot.com</link><url>http://m3nt0r.de/blog/wp-content/uploads/2008/12/cakealot.png</url><title>Logo</title></image><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcakealot" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/cakealot" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fcakealot" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://my.feedlounge.com/external/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcakealot" src="http://static.feedlounge.com/buttons/subscribe_0.gif">Subscribe with FeedLounge</feedburner:feedFlare><item>
		<title>Force download a custom view using MediaView</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/t7OtxfEV51A/</link>
		<comments>http://cakealot.com/2009/10/force-download-a-custom-view-using-mediaview/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 15:17:50 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP Hints]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[exporting]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[force-download]]></category>
		<category><![CDATA[mediaview]]></category>
		<category><![CDATA[mime]]></category>
		<category><![CDATA[render]]></category>
		<category><![CDATA[tmp]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=468</guid>
		<description><![CDATA[Generally you would need to force-download the file, probably using MediaView. Problem is that it isn't actually a real file for MediaView to work with. Here's a workaround to that.]]></description>
			<content:encoded><![CDATA[<p><strong>Just some quick hint:</strong> Let&#8217;s assume you generate a non-html file using a view, layout and custom extension (sql, xml, json, etc..) and you want to offer the displayed result as a download. &#8211; Generally you would need to force-download the file, probably using MediaView. Problem is that it isn&#8217;t actually a real file for MediaView to work with. </p>
<p>Here&#8217;s a quick workaround to that, using two calls to render() in a single action (comments welcome):</p>
<pre class="sh_php">
public function export() {
  $data = $this->{$this->modelClass}->find('all');
  $this->set(compact('data'));
  $rendered = $this->render();
  $fileext = 'xml'; // optional: $this->params['url']['ext'];
  $filepath = TMP.'rendered'.DS;
  $filename = md5(String::uuid()).'.'.$fileext;
  file_put_contents($filepath.$filename, $rendered); // php5 func
  $this->view = 'Media';
  $params = array(
    'id' => $filename,
    'path' => $filepath,
    'extension' => $fileext,
    'download' => true, // force download
    'name' => low($this->name).'-export' // fancy name
  );
  $this->set($params);
  $this->render(); // init download
}
</pre>
<p>That&#8217;s it. First you render the .ctp using all the fancy helpers, temporarly save the result on your (ram)disk, change the view to Media, reuse almost same variables for the params array and simply call render again. Since we change $this->view in between renders, we can use both view renderer in a row.</p>
<p>DRY: For the extension you could grab the current extension from <code>$this->params['url']['ext']</code> if you used <code>array('ext' => '...')</code> in the <code>HtmlHelper::link()</code> url param. This makes the action even more generic.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=t7OtxfEV51A:2xTzpOh8CJM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=t7OtxfEV51A:2xTzpOh8CJM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=t7OtxfEV51A:2xTzpOh8CJM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=t7OtxfEV51A:2xTzpOh8CJM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=t7OtxfEV51A:2xTzpOh8CJM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/t7OtxfEV51A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/10/force-download-a-custom-view-using-mediaview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/10/force-download-a-custom-view-using-mediaview/</feedburner:origLink></item>
		<item>
		<title>Coda Plugin: PHP Getter/Setter</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/97QJsTVTTGo/</link>
		<comments>http://cakealot.com/2009/08/coda-plugin-php-gettersetter/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 13:55:12 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[coda]]></category>
		<category><![CDATA[macosx]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=459</guid>
		<description><![CDATA[Wrote a plugin for the Coda (Mac) to easily generate common get/set methods for PHP class variables. Download included in this post.]]></description>
			<content:encoded><![CDATA[<p>After being busy busy busy i had some time to write a little plugin for <a href="http://www.panic.com/coda/"><strong>Coda</strong> by Panic</a> which i felt missing for those of us writing PHP classes all day long. </p>
<p><strong>Getter/Setter</strong> is inspired by the function that is included in <strong>Zend Studio for Eclipse</strong> and creates public <code>getVariable</code> and <code>setVariable</code> methods from the member variables you select. </p>
<p>Here&#8217;s a example class:</p>
<pre class="sh_php">
class SomeClass extends SomeOtherClass {

	public $name = 'SomeClass';

	protected $_my_integer = 0;

	protected $_my_boolean = false;

	protected $_my_constant = THIS_IS_MY_CONST;

	private $__someEmptyString = "";

	// this is a $test
	static public $prop;
}
</pre>
<p>You simply select a bunch of member variables (like those above) in your class and hit the command <strong>CTRL + SHIFT + S</strong> (i know, probably there are better ones) to insert the methods. </p>
<p>Example output with just <code>public $name</code> selected:</p>
<pre class="sh_php">
	/**
	 * Get value of $this->name
	 *
	 * @access public
	 * @return string
	 */
	public function getName() {
		return $this->name;
	}

	/**
	 * Set the value of $this->name
	 *
	 * @param string $value
	 * @access public
	 */
	public function setName($value) {
		$this->name = $value;
	}
</pre>
<p>There is some <strong>type detection</strong> in place for the PHPDoc tags aswell as recognition of <code>static</code> variables. </p>
<p>If i do the same command with <code>protected $_my_integer</code>:</p>
<pre class="sh_php">
	/**
	 * Get value of $this->_my_integer
	 *
	 * @access public
	 * @return integer
	 */
</pre>
<p>The return type is now &#8220;integer&#8221; as expected, since that&#8217;s the default value for this member variable.</p>
<p>For <strong>static variables</strong> the assignement is changed from <code>$this</code> to <code>self::</code> and the methods also get a static flag in front of them.</p>
<pre class="sh_php">
	/**
	 * Get value of self::$prop
	 *
	 * @access public
	 * @return mixed
	 */
	static public function getProp() {
		return self::$prop;
	}

	/**
	 * Set the value of self::$prop
	 *
	 * @param mixed $value
	 * @access public
	 */
	static public function setProp($value) {
		self::$prop = $value;
	}
</pre>
<p>It works with single lines, aswell with multiple of course. Default values that are constants are always typed &#8220;mixed&#8221; as i find that definiton appropiate. Constants may contain string, bool, int.. so best guess is mixed. Also &#8220;null&#8221; is treated as &#8220;mixed&#8221; since it&#8217;s .. yeah.. null.</p>
<p>Of course there is some odd behavior which i couldn&#8217;t prevent but given the benefit you have these are acceptable.</p>
<p><strong>Known Issues:</strong></p>
<ul>
<li>Code is generated directly after the selected lines. Not at the end of the class or anywhere else fancy. This kinda sucks, but a quick copy paste after insertion will do.. There is no way for me to discover the code level (closing brace, etc.) and the Coda API doesn&#8217;t tell either.</li>
<li>If you double click a member variable the semicolon is not selected (Coda issue/feature). Since the plugin outputs directly after what has been selected the semicolon is pushed down (after the generated methods). Prevent this by selecting the whole line, or include semicolon.</li>
</ul>
<p>I think it&#8217;s cool anyhow and maybe i get a hang on it and publish some more plugins geared towards CakePHP. </p>
<div><strong>I hope you enjoy this little helper plugin!</strong><br/><br />
<a href="http://static.cakealot.com/wp-content/uploads/2009/08/PHPGetterSetter.codaplugin.zip" style="text-decoration:none;display:block;float:left;margin-right:10px;text-align:center"><img src="http://cakealot.com/wp-includes/images/crystal/archive.png" alt="Download ZIP Archive" style="border:0" /><br />Download</a>With Coda installed the plugin should add and activate itself after you double click the package. If not, you can place it in <code>~/Library/Application Support/Coda/Plug-Ins/</code>. To uninstall just delete the package and restart Coda. If you want to have another shortcut just create one using MacOSX Shortcut Menu in your System Preference Panel.<br />
<br style="clear:both"/>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=97QJsTVTTGo:y4oM73k6_IQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=97QJsTVTTGo:y4oM73k6_IQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=97QJsTVTTGo:y4oM73k6_IQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=97QJsTVTTGo:y4oM73k6_IQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=97QJsTVTTGo:y4oM73k6_IQ:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/97QJsTVTTGo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/08/coda-plugin-php-gettersetter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/08/coda-plugin-php-gettersetter/</feedburner:origLink></item>
		<item>
		<title>Environment: Support methods in param matching</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/XEU4XDf6BFs/</link>
		<comments>http://cakealot.com/2009/07/environment-class-support-methods-in-param-matching/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 06:29:51 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP Tricks]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[domains]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[http_host]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=435</guid>
		<description><![CDATA[Some of you probably remember the fine Environment Class developed by Rafael Bandeira. I still use and love it for handling dev, staging and production environments. And it&#8217;s super awesome that you may create a AppEnvironment class to tweak the config and param mapping. However, i found one thing missing and that&#8217;s support for arrays [...]]]></description>
			<content:encoded><![CDATA[<p>Some of you probably remember the fine <strong>Environment Class</strong> developed <a href="http://rafaelbandeira3.wordpress.com/2008/12/05/handling-multiple-enviroments-on-cakephp/">by Rafael Bandeira</a>. I still use and love it for handling dev, staging and production environments. And it&#8217;s super awesome that you may create a <strong>AppEnvironment</strong> class to tweak the config and param mapping. However, i found one thing missing and that&#8217;s support for arrays when matching the mapped params.</p>
<p>For example: You have one &#8220;development&#8221; environment but you have multiple domains pointing to it and the app needs to behave differently based on that (language preset based on domain extension, vanity urls for user profiles, .. that kind of stuff).<br />
<span id="more-435"></span></p>
<p>There are of course alot of other reasons why that&#8217;s a good a idea. In general to avoid duplicate code and conflicts. To get around all that i needed support for arrays.</p>
<p>One approach to support arrays would be to just add it to the <code>_match($param, $value)</code> method in the Environment class, but it may not have been appropiate in all occassions. So i just followed Rafael&#8217;s lead and simply added support for instance methods. Since we may have our own class for environment config/param mapping (just create <code>app_environment.php</code> in /config/), it&#8217;s a good place to also add some helper methods. </p>
<p>That was the previous code (around line 90). </p>
<pre class="sh_php">if (function_exists($param)) {
	$match = call_user_func($param, $value);
} else {
	$match = (env($param) === $value);
}
if (!$match) {
	return false;
}
</pre>
<p>I just added another &#8220;if-condition&#8221; and used <code>getInstance</code> to get the object.</p>
<pre class="sh_php">$instance = self::getInstance();
if (method_exists($instance, low($param))) {
	$match = call_user_method(low($param), $instance, $value);
} elseif (function_exists($param)) {
	$match = call_user_func($param, $value);
} else {
// ... as above
</pre>
<p>Note the &#8220;<code>low($param)</code>&#8220;. I&#8217;ve set the value of <code>$param</code> to lower-case because param would be HTTP_HOST which doesn&#8217;t makes up for a good method name. Maybe could have used Inflector to make it camelcase just to enforce conventions here &#8211; but that would be overkill. ;-) </p>
<p><strong>Okay.. so what happens here and how can we use that?</strong></p>
<ol>
<li>The <code>getInstance</code> method returns the <code>AppEnvironment</code> object, if present. So it&#8217;s imperative to have it, because we don&#8217;t want to mess with the original class.</li>
<li><code>method_exists</code> looks in <code>AppEnvironment</code> for a lower-case method name of whatever is in <code>$param</code>. In our case this results to &#8220;http_host&#8221;.</li>
<li>If found, it calls the method on the <code>$instance</code> and returns the result. The result should be <code>boolean</code>.</li>
</ol>
<p>I&#8217;ve edited my <code>app_environment.php</code> and added the following method:</p>
<pre class="sh_php">
/**
 * Support Arrays in HTTP_HOST param matching
 *
 * @param mixed $value string or array of hostnames
 * @return boolean
 */
public function http_host($value) {
	if (is_array($value)) {
		foreach ($value as $host) {
			if (env('HTTP_HOST') == $host) {
				return true;
			}
		}
	} else {
		if (env('HTTP_HOST') == $value) {
			return true;
		}
	}
	return false;
}
</pre>
<p>Should be pretty self explaining. Default to false. If <code>$value</code> is an array, walk through it and return true on the first match. If it&#8217;s not an array just check if $value matches the current HTTP_HOST. </p>
<p>With that in place i can now tweak my &#8217;server&#8217; config in the environment setup.</p>
<pre class="sh_php">App::import('Vendor', 'Environment');

Environment::configure('development',
	array(
		'server' => array('localhost', 'testapp-local.com') // there we go!
	),
	array(
		'debug' => Configure::read('Env.development.debug'),
		'security' => Configure::read('Env.development.security')
	)
);
Environment::start();
</pre>
<p>That&#8217;s it. From now on we have the &#8220;development&#8221; environment running if the current HTTP_HOST is either &#8220;localhost&#8221; or &#8220;testapp-local.com&#8221;. </p>
<p><strong>Edit:</strong> Oh.. btw. This is not just about http_host. You can of course add helper methods for any other param.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=XEU4XDf6BFs:iF6n7hQw1wY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=XEU4XDf6BFs:iF6n7hQw1wY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=XEU4XDf6BFs:iF6n7hQw1wY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=XEU4XDf6BFs:iF6n7hQw1wY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=XEU4XDf6BFs:iF6n7hQw1wY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/XEU4XDf6BFs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/07/environment-class-support-methods-in-param-matching/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/07/environment-class-support-methods-in-param-matching/</feedburner:origLink></item>
		<item>
		<title>QLColorCode and CakePHP Templates</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/urvgiN2tik0/</link>
		<comments>http://cakealot.com/2009/07/qlcolorcode-and-cakephp-templates/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 07:37:19 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP Hints]]></category>
		<category><![CDATA[highlight]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[quicklook]]></category>
		<category><![CDATA[views]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=410</guid>
		<description><![CDATA[Mac OSX "Leopard" HowTo: Add CakePHP View extensions to the QLColorCode QuickLook Plugin.]]></description>
			<content:encoded><![CDATA[<p><strong>Mac OSX Hint</strong>: If you use the <a href="http://code.google.com/p/qlcolorcode/" target="_blank">QLColorCode</a> plugin for <strong>QuickLook</strong> to get fancy highlight when viewing a file, you might want to have the same when viewing CakePHP <code>*.ctp</code> and <code>*.thtml</code> files.</p>
<p>It involves a bit of hacking, but not much.<br />
<span id="more-410"></span></p>
<h3>Edit Info.plist</h3>
<p><img src="http://static.cakealot.com/wp-content/uploads/2009/07/filestochange-300x188.png" alt="filestochange" title="filestochange" width="300" height="188" class="alignleft size-medium wp-image-417" />First you need to tell the Plugin about the custom file-types. For that you need to view the package contents of <code>QLColorCode.qlgenerator</code> file.</p>
<p>It should be in <code>/Library/QuickLook</code> or in your home directory <code>~/Library/QuickLook</code>.</p>
<p>Open the &#8220;Contents&#8221; folder and open the <code>Info.plist</code> file. Any decent texteditor will do. Now scroll down to line 270 or so. There you will find the <code>UTTypeConformsTo</code> sections. </p>
<p>I just copied the &#8220;css&#8221; block (from &lt;dict&gt; to &lt;/dict&gt;) and placed it right under it.</p>
<p>- Change the <code>UTTypeDescription</code> to &#8220;PHP File&#8221;.<br />
- Change the <code>UTTypeIdentifier</code> to &#8220;public.php&#8221;. </p>
<p>Then theres a dict-subsection with <code>public.filename-extension</code> as key.<br />
If you followed my steps it should contain &#8220;css&#8221; (if so, replace &#8220;css&#8221; with &#8220;php&#8221;).</p>
<p>- Duplicate the <code>&lt;string&gt;</code> part a couple times and add &#8220;ctp&#8221; and &#8220;thtml&#8221; to the array. </p>
<p>The complete section should then look like this:</p>
<pre class="sh_html"><code>
&lt;dict>
	&lt;key>UTTypeConformsTo&lt;/key>
	&lt;array>
		&lt;string>public.source-code&lt;/string>
	&lt;/array>
	&lt;key>UTTypeDescription&lt;/key>
	&lt;string>PHP File&lt;/string>
	&lt;key>UTTypeIdentifier&lt;/key>
	&lt;string>public.php&lt;/string>
	&lt;key>UTTypeTagSpecification&lt;/key>
	&lt;dict>
		&lt;key>public.filename-extension&lt;/key>
		&lt;array>
			&lt;string>php&lt;/string>
			&lt;string>ctp&lt;/string>
			&lt;string>thtml&lt;/string>
		&lt;/array>
	&lt;/dict>
&lt;/dict>
</code></pre>
<p>Save and close the file. Your QuickLook plugin now recognizes ctp and thtml files. That&#8217;s great, but you need to do one more thing to actually get PHP syntax coloring.</p>
<h3>Edit colorize.sh</h3>
<p>Back in your Finder with the &#8220;package contents&#8221; navigate into the &#8220;Resources&#8221; folder and open the contained &#8220;colorize.sh&#8221;. That&#8217;s a shellscript which does a bit of evaluation before it actually calls the highlight program. </p>
<p>Around line 36 you&#8217;ll find something like a switch-block. Here it&#8217;s called &#8220;case&#8221;&#8230; Anyway. You might recognize the schema here and see that each &#8220;case&#8221; corresponds to a file extension. This is where we jump in and add our <code>.ctp</code> and <code>.thtml</code> sections. </p>
<p>Note that there is no &#8220;break&#8221; statement like in PHP. Each case ends with a double semicolon instead. </p>
<pre class="sh_php"><code>    *.ctp )
        lang=php
        ;;
    *.thtml )
        lang=php
        ;;
</code></pre>
<p>You can put these somewhere in the middle. As said, watch out for the semicolons. Save and close the file. Since you&#8217;ve modified the Info.plist in the first step you might have to let your system know about the changes. Execute the following two commands on your Terminal/shell to refresh the QuickLook service.</p>
<pre class="sh_php">qlmanage -r
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f -v /Library/QuickLook/QLColorCode.qlmanager</pre>
<p>Make sure it&#8217;s pointing to the correct plugin path (at the end of the long command..).<br />
After refreshing QL it should work right away. Go to your &#8220;views&#8221; folder and try it out.</p>
<p><a href="http://static.cakealot.com/wp-content/uploads/2009/07/quicklook-for-ctp.png" class="highslide-image" onclick="return hs.expand(this);" target="_blank" title="opens a new window"><img src="http://static.cakealot.com/wp-content/uploads/2009/07/quicklook-for-ctp-300x235.png" alt="quicklook-for-ctp" title="quicklook-for-ctp" width="300" height="235" class="size-medium wp-image-431" /></a></p>
<p>Enjoy!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=urvgiN2tik0:SL3GaYS7CRk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=urvgiN2tik0:SL3GaYS7CRk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=urvgiN2tik0:SL3GaYS7CRk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=urvgiN2tik0:SL3GaYS7CRk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=urvgiN2tik0:SL3GaYS7CRk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/urvgiN2tik0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/07/qlcolorcode-and-cakephp-templates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/07/qlcolorcode-and-cakephp-templates/</feedburner:origLink></item>
		<item>
		<title>Check ma sprockets!</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/XSLRuMkRdYw/</link>
		<comments>http://cakealot.com/2009/05/check-ma-sprockets/#comments</comments>
		<pubDate>Sun, 17 May 2009 21:39:49 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Assets]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[minification]]></category>
		<category><![CDATA[sprockets]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=390</guid>
		<description><![CDATA[Ever since i heard of Sprockets on Twitter i wanted to use it in my apps. Unfortunatly i am not into Ruby.
Sprockets is a Ruby library that preprocesses and concatenates JavaScript source files. It takes any number of source files and preprocesses them line-by-line in order to build a single concatenation. &#8211; getsprockets.org
I wanted to [...]]]></description>
			<content:encoded><![CDATA[<p>Ever since i heard of Sprockets on Twitter i wanted to use it in my apps. Unfortunatly i am not into Ruby.</p>
<blockquote><p>Sprockets is a Ruby library that preprocesses and concatenates JavaScript source files. It takes any number of source files and preprocesses them line-by-line in order to build a single concatenation. &#8211; <a href="http://www.getsprockets.org/">getsprockets.org</a></p></blockquote>
<p>I wanted to port it to PHP or find clever ways to use it in CakePHP (shell?). But before you start something like this you should check if there isn&#8217;t already a project and so i found <a href="http://github.com/stuartloxton/php-sprockets">PHPSprockets from Stuart Loxton</a>. PHP Sprocket is a port of Sprockets. Cool.. so the meat of sprockets is already available :)</p>
<blockquote><p>PHP Sprockets currently acts as a transparent proxy as default and caches results. Because of this you do not have to initialize any classes in your app and sprocket stays separate.</p></blockquote>
<p>Thanks to GitHub i just <a href="http://github.com/m3nt0r/php-sprockets/">forked the project</a> and began pimping Stuarts class.<br />
Here are the major differences from the orignal port:</p>
<ul>
<li>The main class file has been renamed to “Sprocket” </li>
<li>Commands are now classes. It is easy to extend Sprocket with new commands.</li>
<li>Instead of <span class="caps">YML</span> this fork uses <span class="caps">INI</span> files for providing constants.</li>
<li>Easy to extend due more abstraction, setters and a array based option interface</li>
<li>Seperate render stage (with autoRender option to mimic the original render-on-construct).</li>
<li>Also works with other files, like <span class="caps">CSS</span> and whatever you want to concat.. (see demo)</li>
<li>Selective minification for JS and <span class="caps">CSS</span> out of the box. Just add “minify” (see demo files)</li>
<li>Fully documented sourcecode</li>
</ul>
<p>I also added a demo and there is more info about my rewrite in the repo readme.<br />
Enjoy! &#8211; <a href="http://github.com/m3nt0r/php-sprockets">http://github.com/m3nt0r/php-sprockets</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=XSLRuMkRdYw:aSzzFkikQC8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=XSLRuMkRdYw:aSzzFkikQC8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=XSLRuMkRdYw:aSzzFkikQC8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=XSLRuMkRdYw:aSzzFkikQC8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=XSLRuMkRdYw:aSzzFkikQC8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/XSLRuMkRdYw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/05/check-ma-sprockets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/05/check-ma-sprockets/</feedburner:origLink></item>
		<item>
		<title>Quickie: SecurityComponent, Ajax and input.disabled</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/UFZ6bAKyjcM/</link>
		<comments>http://cakealot.com/2009/04/quickie-securitycomponent-ajax-and-inputdisabled/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 12:59:05 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP Hints]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[blackhole]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=306</guid>
		<description><![CDATA[Watch out for input.disabled = true when using SecurityComponent. A short story about what went wrong and why, plus a sidenote about SecurityComponent and Ajax.]]></description>
			<content:encoded><![CDATA[<p><strong>Don&#8217;t mess wit teh formz.</strong></p>
<p>I thought it&#8217;s cool to disable a field simply by using the <code>disabled</code> Element property. Being distracted by other parts in the app i just applied it and left it alone &#8211; &#8220;How can this be bad, right?&#8221;. After some more time i did test the form again and found myself being blackholed all of a sudden &#8211; whaaa? &#8211; Took me some time to find out what the problem was (grrr).</p>
<h3>Here&#8217;s the reason</h3>
<blockquote><p>If you disable a field using Javascript, the field name and its value never reaches the server. This of course invalidates the Security Token and thus leads to a blackhole.</p></blockquote>
<p>I must admit that this was kinda stupid but that&#8217;s how things can go after some hours in CakePHP-land. :-)</p>
<p>Some &#8220;validation scripts&#8221; also apply disable. So look out for that too. Just don&#8217;t mess around with the fields (..much), and avoid prefilled values using <code>array('value' => 'bla')</code> if plan to change the value with Javascript. A good workaround to that is to set the &#8220;initial value&#8221; on page load using Javascript. SecurityComponent and Ajax then shouldn&#8217;t be a problem at all.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=UFZ6bAKyjcM:xDCVZe4_7-c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=UFZ6bAKyjcM:xDCVZe4_7-c:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=UFZ6bAKyjcM:xDCVZe4_7-c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=UFZ6bAKyjcM:xDCVZe4_7-c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=UFZ6bAKyjcM:xDCVZe4_7-c:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/UFZ6bAKyjcM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/04/quickie-securitycomponent-ajax-and-inputdisabled/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/04/quickie-securitycomponent-ajax-and-inputdisabled/</feedburner:origLink></item>
		<item>
		<title>Fixing missing ssh-askpass on MacOS 10.5</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/2xpJizIEBwI/</link>
		<comments>http://cakealot.com/2009/04/fixing-missing-ssh-askpass-on-macos-105/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 01:46:00 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[macintosh]]></category>
		<category><![CDATA[scm]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=369</guid>
		<description><![CDATA[This helps if you have trouble with missing <code>/usr/libexec/ssh-askpass</code> on Leopard. It's quiet annoying but i found the following shell script and it works perfect for Textmate and probably all other places. This includes not just passwords but also the yes/no for the remote fingerprint question. ]]></description>
			<content:encoded><![CDATA[<p>This helps if you have trouble with missing <code>/usr/libexec/ssh-askpass</code> on Leopard. It&#8217;s quiet annoying but i found the following shell script and it works perfect for Textmate and probably all other places. This includes not just passwords but also the yes/no for the remote fingerprint question. </p>
<pre><code>#! /bin/sh
#
# An SSH_ASKPASS command for MacOS X
#
# Author: Joseph Mocker, Sun Microsystems
#
# To use this script:
#     setenv SSH_ASKPASS "macos-askpass"
#     setenv DISPLAY ":0"
#
TITLE=${MACOS_ASKPASS_TITLE:-"SSH"}

DIALOG="display dialog \"$@\" default answer \"\" with title \"$TITLE\""
DIALOG="$DIALOG with icon caution with hidden answer"

result=`osascript -e 'tell application "Finder"' -e "activate"  -e "$DIALOG" -e 'end tell'`

if [ "$result" = "" ]; then
    exit 1
else
    echo "$result" | sed -e 's/^text returned://' -e 's/, button returned:.*$//'
    exit 0
fi</code></pre>
<p>That&#8217;s the original script <a href="http://www.retep.org/2009/04/ssh-askpass-on-osx-105.html" title="Source">found on Retep&#8217;s Open Source Blog</a>. I&#8217;ve reposted the script here because it was poorly formatted (quotes) and there is one thing to change.<br />
<span id="more-369"></span></p>
<p>Save the above as <strong>ssh-askpass</strong>:</p>
<pre>sudo vi /usr/libexec/ssh-askpass</pre>
<p>Paste the script, save the file (needs sudo password), make it executable</p>
<pre>sudo chmod +x /usr/libexec/ssh-askpass</pre>
<p>The <code>setenv</code> didn&#8217;t work on my 10.5.0 install. So instead, i had to  use &#8220;export&#8221;:</p>
<pre><code>export SSH_ASKPASS="macos-askpass"
export DISPLAY=":0"</code></pre>
<p>Now i pushed current branch in textmate and it worked right away. Great! :)<br />
<img src="http://static.cakealot.com/wp-content/uploads/2009/04/ssh_askpass_screen.png" style="padding-top:1em" alt="ssh_askpass_screen" title="ssh_askpass_screen" width="567" height="395" class="alignnone size-full wp-image-377" /></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=2xpJizIEBwI:Geh3DpZiK9o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=2xpJizIEBwI:Geh3DpZiK9o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=2xpJizIEBwI:Geh3DpZiK9o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=2xpJizIEBwI:Geh3DpZiK9o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=2xpJizIEBwI:Geh3DpZiK9o:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/2xpJizIEBwI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/04/fixing-missing-ssh-askpass-on-macos-105/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/04/fixing-missing-ssh-askpass-on-macos-105/</feedburner:origLink></item>
		<item>
		<title>Eventful – A CakePHP Event System</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/tv2ZuXDSNaQ/</link>
		<comments>http://cakealot.com/2009/04/eventful-a-cakephp-event-system/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 13:27:12 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Behaviors]]></category>
		<category><![CDATA[Callbacks]]></category>
		<category><![CDATA[components]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=343</guid>
		<description><![CDATA[As promised in the comments of the most recent entry i created a repo for my event system. 
It&#8217;s currently under heavy development, yet ready to use. I don&#8217;t think the interface will change much from here on out. The installation is similar to the DebugKit. Put the &#8220;eventful&#8221; plugin into your plugins folder and [...]]]></description>
			<content:encoded><![CDATA[<p>As promised in the comments of the <a href="http://cakealot.com/2009/04/more-on-possible-events-in-cakephp/" title="More on possible events in CakePHP">most recent entry</a> i created a repo for my event system. </p>
<p>It&#8217;s currently under heavy development, yet ready to use. I don&#8217;t think the interface will change much from here on out. The installation is similar to the DebugKit. Put the &#8220;eventful&#8221; plugin into your plugins folder and add the Behavior or Component to your app. This will include all dependencies and the system is ready to use.</p>
<p>Only one thing is different from regular plugins. There is a seperate &#8220;events&#8221; folder which is a empty layout for the system and the place for your event listener classes. </p>
<p>The System is also plugin aware. If you want to enrich your base application with event handlers from plugins just copy the &#8220;events&#8221; folder layout into the plugin directory and prefix the class filenames with the plugin name. (just like app_controller).</p>
<pre class="sh_php"># /app/plugins/pizza/events/controller/pizza_users_controller_events.php
class PizzaUsersControllerEvents extends AppControllerEvents ...</pre>
<p>I&#8217;ve created a (messy) README which goes on about how to use it. Basicly the workflow is: <strong>a)</strong> add the component/behavior, <strong>b)</strong> use the dispatch/dispatchEvent method in your actions/methods, <strong>c)</strong> create or modify the event listener class and add a matching &#8220;on&#8221; method. <strong>d)</strong> go nuts.</p>
<pre class="sh_php">class UsersController extends AppController {
   var $components = array('Eventful.Event');
}</pre>
<pre class="sh_php">class UsersController extends AppController {
   var $components = array('Eventful.Event');
   function logout() {
      $this->Event->dispatch('UserLogout', array(
           'auth' => $this->Auth->user()
      ));
   }
}</pre>
<p>File: /app/events/controller/users_controller_events.php</p>
<pre class="sh_php">class UsersControllerEvents extends AppControllerEvents {
   function onUserLogout() {
      $this->log('User logged out...')
   }
}</pre>
<p>Unlike the original implementation the plugin triggers all handlers of the same name. So if you have a &#8220;userLogout&#8221; event fired from your UsersController::logout() action the dispatchEvent method will trigger all possible candidates. Regardless in which listener class the method is. </p>
<pre class="sh_php">class MembersControllerEvents extends AppControllerEvents {
   function onUserLogout($event) {
      if ($event->auth['isMember'])
          $this->log('Member logged out...')
   }
}</pre>
<p>Enjoy. You can find it on github:</p>
<p><a href=" http://github.com/m3nt0r/eventful-cakephp" title="GitHub.com Repository">http://github.com/m3nt0r/eventful-cakephp</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=tv2ZuXDSNaQ:0w-ooLtHCuk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=tv2ZuXDSNaQ:0w-ooLtHCuk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=tv2ZuXDSNaQ:0w-ooLtHCuk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=tv2ZuXDSNaQ:0w-ooLtHCuk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=tv2ZuXDSNaQ:0w-ooLtHCuk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/tv2ZuXDSNaQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/04/eventful-a-cakephp-event-system/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/04/eventful-a-cakephp-event-system/</feedburner:origLink></item>
		<item>
		<title>More on possible Events in CakePHP</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/BhwTZ4jJME8/</link>
		<comments>http://cakealot.com/2009/04/more-on-possible-events-in-cakephp/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 18:38:52 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[actions]]></category>
		<category><![CDATA[controllers]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[examples]]></category>
		<category><![CDATA[ideas]]></category>
		<category><![CDATA[listener]]></category>
		<category><![CDATA[scenarios]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=53</guid>
		<description><![CDATA[As a follow up to: Events in CakePHP &#8211; I really like it 
Let&#8217;s say you have unkown entities in your project &#8211; totally dynamic. Let it be a plugin, another model, not associated at all. Getting new functionality into an existing app can be a pain. 
Events do help alot in this case, depending [...]]]></description>
			<content:encoded><![CDATA[<p><em>As a follow up to: <a href="http://cakealot.com/2008/12/events-in-cakephp-i-really-like-it/">Events in CakePHP &#8211; I really like it</a></em> </p>
<p>Let&#8217;s say you have unkown entities in your project &#8211; totally dynamic. Let it be a plugin, another model, not associated at all. Getting new functionality into an existing app can be a pain. </p>
<p>Events do help alot in this case, depending on how you layed out the triggers. Events notify all possible candidates (&#8221;can u handle?&#8221;) every time something interesting is happening, like &#8220;user logged in&#8221;, &#8220;new image was uploaded&#8221;, &#8220;post has been edited by xyz&#8221;, and so forth.</p>
<p>In this post i want to explain more about the benefits and how events could make your life alot easier in the long run.  </p>
<h3>Some example</h3>
<p>Think of a users dashboard: A dashboard usually has alot of links to various aspects of the application, often categorized in blocks. You have a block for the user account itself, a block for the latest comments, a block to upload a new image, etc.. </p>
<p>Now maybe user XYZ has access to post blogs, but maybe not. And maybe there is no blogging function at all. We could now bake our blogging MVC and write it into the dashboard action. No problem, right? But the more you add, you more have to maintain and watch out for. I know many projects with complicated group setups and stuff so this isn&#8217;t always that simple. </p>
<p>This is where Events come in handy. Let&#8217;s scratch the above and think our dashboard action is empty and there&#8217;s a single call to the EventDispatcher (the thing i use). If we now simply fire a &#8220;dashboardView&#8221; event <strong>any</strong> part of the codebase that can handle this event will perform its designated task independently. </p>
<pre class="sh_php">
function dashboard() {
    $data = $this->Events->dispatch('dashboardView', array(
        'user_id' => $this->Auth->user('id')
    ));
    $this->set('data', $data);
}
</pre>
<p>This allows the blog-facility (for example) to run code and add data to the dashboard() action, so that the action itself remains clean. </p>
<p>Normally you would load up some settings array with true/false, or you would just add a if/else in the <code>dashboard()</code> action. </p>
<pre class="sh_php">
function dashboard() {
   if ($mayAuthorBlog) ..
   if ($mayPostNews) ..
   if ($justRegistered) ..
   ...
}
</pre>
<p>All this is not necessary when using events, since events usually don&#8217;t care if they are handled. They are just fired and poke around and execute whatever responds. </p>
<p>With &#8220;poking-around&#8221; i mean that you may have multiple handlers for a single event. So the Post, Image, Blog, Friend MVC .. all of them can respond to the current action. Even if they are out of scope.</p>
<h3>The other way around</h3>
<p>If we decide to drop any functionality later on, we just delete the event-listener, or delete the method that usually would respond. A common task may be: &#8220;The blogging dashboard item should not be intergrated into the dashboard anymore&#8221;. Remove the listener from your Blog-MVC and you&#8217;re done. Not touching the working <code>dashboard()</code> action at all.</p>
<p>See, if we wrote this without Events the removal of this functionality would require that we delete the if/else (or what have you) from the <code>dashboard()</code> action, which is destructive and eventually leads to bugs and headaches. Removal of event-listeners don&#8217;t harm your app. </p>
<h3>&#8230;for the non believers</h3>
<p>One can argue: &#8220;Why not simply add a private method for that?&#8221; </p>
<p>Well.. the keyword is <strong>&#8220;unkown&#8221;</strong>. Events enrich a function by providing an <strong>open interface</strong> to hook up to (so to speak). If you wrote something new you just provide the listener for your current/core app and be done with it. </p>
<pre class="sh_php">
class UserControllerEvents extends AppControllerEvents {
   var $name = 'UserController';
   function onDashboardView($event) {
       $event->Controller->User->logVisit($event->user_id);
   }
}

class BlogControllerEvents extends AppControllerEvents {
   var $name = 'BlogController';
   function onDashboardView($event) {
       return $event->Controller->Blog->getMostRecent();
   }
}
</pre>
<p>Private Methods or &#8220;helping&#8221; methods are bound to the main codebase and scope and as such quickly become obsolete or hard to manage. It&#8217;s also not so easy to call other parts of your cake app &#8220;just like that&#8221;. The system described works as one huge layer and has access to everything. </p>
<h3>What do you think?</h3>
<p>Let me know in the comments.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=BhwTZ4jJME8:nTb_-4ilz0Q:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=BhwTZ4jJME8:nTb_-4ilz0Q:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=BhwTZ4jJME8:nTb_-4ilz0Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=BhwTZ4jJME8:nTb_-4ilz0Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=BhwTZ4jJME8:nTb_-4ilz0Q:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/BhwTZ4jJME8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/04/more-on-possible-events-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/04/more-on-possible-events-in-cakephp/</feedburner:origLink></item>
		<item>
		<title>Adding “empty” to list-find, for the lazy</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/Upvsi5HMIlo/</link>
		<comments>http://cakealot.com/2009/04/adding-empty-to-list-find/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 17:32:04 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP Snippets]]></category>
		<category><![CDATA[AppModel]]></category>
		<category><![CDATA[empty]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[list-find]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[select]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=317</guid>
		<description><![CDATA[Currently i use the scaffold views alot to bake a simple admin interface. What annoyed me was that 'empty' is not set on select inputs. I could of course go through all add/edit views and add it, but i thought i rather modify the result to include a empty entry.]]></description>
			<content:encoded><![CDATA[<p>Currently i use the scaffold views alot to bake a simple admin interface. What annoyed me was that &#8216;empty&#8217; is not set on select inputs. I could of course go through all add/edit views and add it, but i thought i rather modify the result to include a empty entry.</p>
<h3>Always add a &#8220;empty&#8221; entry to the result</h3>
<pre class="sh_php">
function find($conditions = null, $fields = array(), $order = null, $recursive = null) {
	if (is_array($conditions)) {
		return parent::find($conditions, $fields, $order, $recursive); // old interface
	} else {
		switch ($conditions) {
			case 'list':
				$result = parent::find($conditions, $fields, $order, $recursive);
				$return = $result; // default

				if (!empty($result)) {
					$return = aa('', __("-- please select --", true));
					foreach ($result as $id => $name)
						$return[$id] = $name;
				}

				return $return;
			break;

			default:
				return parent::find($conditions, $fields, $order, $recursive);
			break;
		}
	}
}
</pre>
<p>Okay, that works and i don&#8217;t have to add &#8216;empty&#8217; everywhere. I modified the method a little further (not actually using it, but maybe someone likes it..) for you to grab. It will still require that you modify all files, but this way you have more control.</p>
<h3>Adding &#8220;empty&#8221; to the find() options array</h3>
<pre class="sh_php">
function find($conditions = null, $fields = array(), $order = null, $recursive = null) {

	if (is_array($conditions)) {
		return parent::find($conditions, $fields, $order, $recursive); // old interface
	} else {
		switch ($conditions) {
			case 'list':
				$result = parent::find($conditions, $fields, $order, $recursive);
				$return = $result; // default

				if (!empty($result) &#038;&#038; isset($fields['empty']) &#038;&#038; $fields['empty'] != false) {
					$return = aa('', $fields['empty']); // begin with whatever is in 'empty'
					foreach ($result as $id => $name)
						$return[$id] = $name;
				}

				return $return;
			break;

			default:
				return parent::find($conditions, $fields, $order, $recursive);
			break;
		}
	}
}
</pre>
<p>Everything above goes to <code>app_model.php</code> of course. With the last snippet you are able to move the &#8220;empty&#8221; option to the controller and go like this:</p>
<pre class="sh_php">
$categories = $this->Category->find('list', array('empty' => __("-- please select --", true)));
</pre>
<p>Enjoy &#038; Happy Easter!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=Upvsi5HMIlo:huaEq2A2AfQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=Upvsi5HMIlo:huaEq2A2AfQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=Upvsi5HMIlo:huaEq2A2AfQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=Upvsi5HMIlo:huaEq2A2AfQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=Upvsi5HMIlo:huaEq2A2AfQ:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/cakealot?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/cakealot/~4/Upvsi5HMIlo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2009/04/adding-empty-to-list-find/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/04/adding-empty-to-list-find/</feedburner:origLink></item>
	</channel>
</rss>
