<?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>Sat, 13 Mar 2010 23:20:57 +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>All your $base are belong to Ajax</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/6q9P5cPnHPI/</link>
		<comments>http://cakealot.com/2010/03/all-your-base-are-belong-to-ajax/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 23:13:38 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[CakePHP Tricks]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[base]]></category>
		<category><![CDATA[here]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[paths]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[routes]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=488</guid>
		<description><![CDATA[We have custom routes, completly dynamic. We can even move the whole app to a subdirectory and still it works! So nice! But how to deal with that in static Javascript files? What about the Ajax and maybe some JS asset configs like image folders and such? In this small post i will tell you [...]]]></description>
			<content:encoded><![CDATA[<p>We have custom routes, completly dynamic. We can even move the whole app to a subdirectory and still it works! So nice! But how to deal with that in static Javascript files? What about the Ajax and maybe some JS asset configs like image folders and such? In this small post i will tell you a good practice of mine which allows me to forget about that problem.<br />
<span id="more-488"></span><br />
In CakePHP you have two handy properties in the controller, views and helpers. They are called <code>$this->base</code> and <code>$this->here</code>. They are basicly all you will ever need, but most importantly <code>$this->base</code>. </p>
<p>The <code>$base</code> property tells you the current directory of the application (roughly put).  If you application runs in <code>http://example/app/</code> the <code>$base</code> property has the value <code>/app</code>.</p>
<p>The <code>$here</code> property tells you the current directory + the current action path. If you request <code>http://example/app/admin/users/home</code> the <code>$here</code> property has the value <code>/app/admin/users/home</code>.</p>
<p>We can use this info to our advantage when writing Ajax request in our external Javascript files. What i always do is using the JavascriptHelper to generate a code block with exactly these two values.</p>
<pre class="php">$javascript->codeBlock("var base = '{$this->base}, here = '{$this->here}';'");</pre>
<p>I usually throw that line in my layout before i add anythings else, so that this info is available in all my scripts.</p>
<p>Now whenever i want to call something with Ajax i can either use <code>Ajax.Request(base + '/controller/action.json');</code> or simply <code>Ajax.Request(here + '.json')</code>. If i ever decide to move the application i no longer need to worry about the base path. </p>
<p>Same goes for our webroot folder of course: <code>$imgFolder = base + '/img/';</code></p>
<p>Another practice i found useful is when you want to submit a CakePHP form with Ajax. Instead of figuring out what path you need to POST to, just query the action attribute of the form. Much easier than writing the url yourself, even easier than using <code>base</code>.</p>
<pre class="js"><code>// ajax post on all forms, just for demo
$$('form').invoke('observe', 'submit', function(evt){

  var form = evt.element();
  new Ajax.Request(form.readAttribute('action') + '.json', {
    parameters: form.serialize(),
    onComplete: function(xhr) {
      // added .json for fun
      // maybe do something neat with validationErrors
    }
  });

});
</code></pre>
<p>This should help you keeping your Javascript codebase lean. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=6q9P5cPnHPI:UvGNNUdyHgk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=6q9P5cPnHPI:UvGNNUdyHgk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=6q9P5cPnHPI:UvGNNUdyHgk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=6q9P5cPnHPI:UvGNNUdyHgk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=6q9P5cPnHPI:UvGNNUdyHgk: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/6q9P5cPnHPI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2010/03/all-your-base-are-belong-to-ajax/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://cakealot.com/2010/03/all-your-base-are-belong-to-ajax/</feedburner:origLink></item>
		<item>
		<title>QuickTip: Pesky missing layout when requesting extensions</title>
		<link>http://feedproxy.google.com/~r/cakealot/~3/la9lu-i2vmY/</link>
		<comments>http://cakealot.com/2010/03/quicktip-pesky-missing-layout-when-requesting-extensions/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 22:21:20 +0000</pubDate>
		<dc:creator>Kjell</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[CakePHP Tricks]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[layouts]]></category>
		<category><![CDATA[RequestHandler]]></category>
		<category><![CDATA[views]]></category>

		<guid isPermaLink="false">http://cakealot.com/?p=477</guid>
		<description><![CDATA[In CakePHP you can use a different layout (other than default.ctp) for all your views by simply changing the $layout property in your controller. I use this to deliver a different layout for, let&#8217;s say, the admin panel of the application &#8211; or maybe a member area. 
Let&#8217;s stick with the admin panel example:
$this->layout = [...]]]></description>
			<content:encoded><![CDATA[<p>In CakePHP you can use a different layout (other than default.ctp) for all your views by simply changing the <code>$layout</code> property in your controller. I use this to deliver a different layout for, let&#8217;s say, the admin panel of the application &#8211; or maybe a member area. </p>
<p>Let&#8217;s stick with the admin panel example:</p>
<pre class="php"><code>$this->layout = 'admin';</code></pre>
<p>Now we all do some neat Ajax or XML here and there sometimes, and for Ajax we probably end up delivering JSON from the very same actions (&#8221;Yes, CakePHP is smart like that&#8221;). For that you usually start by adding <code>Router::parseExtensions('json')</code> to the routes.php file.<br />
<span id="more-477"></span><br />
This works fine as long as you don&#8217;t call the action for JSON while it is using a different <code>$layout</code>. If we, for example, call <code>/admin/users/index.json</code>, CakePHP will tell us that it is missing the layout view file: <code>APP/views/layouts/json/admin.ctp</code>. Meh! </p>
<p>I am not saying that this is bad. It is actually quiet useful in some scenarios, but in general most people will be happy sharing the same old <code>APP/views/layouts/json/default.ctp</code> with all parts of the application. So&#8230; how to fix this?</p>
<p>Add the RequestHandler component to your app and add the following code to your <code>AppController::beforeFilter()</code> method (create the method if needed):</p>
<pre class="php"><code>if ($this->RequestHandler->isAjax() &#038;&#038; $this->RequestHandler->prefers('json')) {
 	$this->layout = 'default';
}</code></pre>
<p>Now everytime the browser (client) prefers &#8220;json&#8221; the layout is switched back to &#8220;default&#8221;. Simple as that.</p>
<p>You can extend the checks to other formats.</p>
<pre class="php"><code>if ($this->RequestHandler->isAjax() || $this->RequestHandler->isRss() || $this->RequestHandler->isXml()) {
 	$this->layout = 'default';
}</code></pre>
<p>Hope this helps</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/cakealot?a=la9lu-i2vmY:RZlkJ3iyyV4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/cakealot?i=la9lu-i2vmY:RZlkJ3iyyV4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=la9lu-i2vmY:RZlkJ3iyyV4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/cakealot?i=la9lu-i2vmY:RZlkJ3iyyV4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/cakealot?a=la9lu-i2vmY:RZlkJ3iyyV4: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/la9lu-i2vmY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cakealot.com/2010/03/quicktip-pesky-missing-layout-when-requesting-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cakealot.com/2010/03/quicktip-pesky-missing-layout-when-requesting-extensions/</feedburner:origLink></item>
		<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>7</slash:comments>
		<feedburner:origLink>http://cakealot.com/2009/04/eventful-a-cakephp-event-system/</feedburner:origLink></item>
	</channel>
</rss>
